Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 135d405d authored by Laxminath Kasam's avatar Laxminath Kasam Committed by Gerrit - the friendly Code Review server
Browse files

asoc: bolero: Update dmic sample rate config for VA macro



Add support for DMICs of different sampling rates
with respective clk_div config update in VA macro
register.

Change-Id: I8faa46774cf1fe561af3bd7a284bc7d37f85cb9d
Signed-off-by: default avatarLaxminath Kasam <lkasam@codeaurora.org>
parent fa05d989
Loading
Loading
Loading
Loading
+86 −5
Original line number Diff line number Diff line
@@ -39,7 +39,11 @@
#define  CF_MIN_3DB_75HZ		0x1
#define  CF_MIN_3DB_150HZ		0x2

#define VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED 0
#define VA_MACRO_MCLK_FREQ 9600000
#define VA_MACRO_TX_PATH_OFFSET 0x80
#define VA_MACRO_TX_DMIC_CLK_DIV_MASK 0x0E
#define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01

#define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS	40

@@ -66,6 +70,15 @@ enum {
	VA_MACRO_DEC_MAX,
};

enum {
	VA_MACRO_CLK_DIV_2,
	VA_MACRO_CLK_DIV_3,
	VA_MACRO_CLK_DIV_4,
	VA_MACRO_CLK_DIV_6,
	VA_MACRO_CLK_DIV_8,
	VA_MACRO_CLK_DIV_16,
};

struct va_mute_work {
	struct va_macro_priv *va_priv;
	u32 decimator;
@@ -94,6 +107,7 @@ struct va_macro_priv {
	s32 dmic_2_3_clk_cnt;
	s32 dmic_4_5_clk_cnt;
	s32 dmic_6_7_clk_cnt;
	u16 dmic_clk_div;
	u16 va_mclk_users;
	char __iomem *va_io_base;
	struct regulator *micb_supply;
@@ -415,22 +429,22 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w,
	case 0:
	case 1:
		dmic_clk_cnt = &(va_priv->dmic_0_1_clk_cnt);
		dmic_clk_reg = BOLERO_CDC_VA_TX0_TX_PATH_CTL;
		dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL;
		break;
	case 2:
	case 3:
		dmic_clk_cnt = &(va_priv->dmic_2_3_clk_cnt);
		dmic_clk_reg = BOLERO_CDC_VA_TX1_TX_PATH_CTL;
		dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL;
		break;
	case 4:
	case 5:
		dmic_clk_cnt = &(va_priv->dmic_4_5_clk_cnt);
		dmic_clk_reg = BOLERO_CDC_VA_TX2_TX_PATH_CTL;
		dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL;
		break;
	case 6:
	case 7:
		dmic_clk_cnt = &(va_priv->dmic_6_7_clk_cnt);
		dmic_clk_reg = BOLERO_CDC_VA_TX3_TX_PATH_CTL;
		dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL;
		break;
	default:
		dev_err(va_dev, "%s: Invalid DMIC Selection\n",
@@ -446,6 +460,10 @@ static int va_macro_enable_dmic(struct snd_soc_dapm_widget *w,
		if (*dmic_clk_cnt == 1) {
			snd_soc_update_bits(codec, dmic_clk_reg,
					dmic_clk_en, dmic_clk_en);
			snd_soc_update_bits(codec, dmic_clk_reg,
					VA_MACRO_TX_DMIC_CLK_DIV_MASK,
					va_priv->dmic_clk_div <<
					VA_MACRO_TX_DMIC_CLK_DIV_SHFT);
		}
		break;
	case SND_SOC_DAPM_POST_PMD:
@@ -1255,6 +1273,56 @@ static const struct snd_kcontrol_new va_macro_snd_controls[] = {
			  0, -84, 40, digital_gain),
};

static int va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
				      struct va_macro_priv *va_priv)
{
	u32 div_factor;
	u32 mclk_rate = VA_MACRO_MCLK_FREQ;

	if (dmic_sample_rate == VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED ||
	    mclk_rate % dmic_sample_rate != 0)
		goto undefined_rate;

	div_factor = mclk_rate / dmic_sample_rate;

	switch (div_factor) {
	case 2:
		va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_2;
		break;
	case 3:
		va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_3;
		break;
	case 4:
		va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_4;
		break;
	case 6:
		va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_6;
		break;
	case 8:
		va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_8;
		break;
	case 16:
		va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_16;
		break;
	default:
		/* Any other DIV factor is invalid */
		goto undefined_rate;
	}

	/* Valid dmic DIV factors */
	dev_dbg(va_priv->dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n",
		__func__, div_factor, mclk_rate);

	return dmic_sample_rate;

undefined_rate:
	dev_dbg(va_priv->dev, "%s: Invalid rate %d, for mclk %d\n",
		 __func__, dmic_sample_rate, mclk_rate);
	dmic_sample_rate = VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED;

	return dmic_sample_rate;
}

static int va_macro_init(struct snd_soc_codec *codec)
{
	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
@@ -1355,7 +1423,7 @@ static int va_macro_probe(struct platform_device *pdev)
{
	struct macro_ops ops;
	struct va_macro_priv *va_priv;
	u32 va_base_addr;
	u32 va_base_addr, sample_rate = 0;
	char __iomem *va_io_base;
	struct clk *va_core_clk;
	bool va_without_decimation = false;
@@ -1363,6 +1431,7 @@ static int va_macro_probe(struct platform_device *pdev)
	const char *micb_voltage_str = "qcom,va-vdd-micb-voltage";
	const char *micb_current_str = "qcom,va-vdd-micb-current";
	int ret = 0;
	const char *dmic_sample_rate = "qcom,va-dmic-sample-rate";

	va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv),
			    GFP_KERNEL);
@@ -1381,6 +1450,18 @@ static int va_macro_probe(struct platform_device *pdev)
					"qcom,va-without-decimation");

	va_priv->va_without_decimation = va_without_decimation;
	ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate,
				   &sample_rate);
	if (ret) {
		dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
			__func__, sample_rate);
		va_priv->dmic_clk_div = VA_MACRO_CLK_DIV_2;
	} else {
		if (va_macro_validate_dmic_sample_rate(
		sample_rate, va_priv) == VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED)
			return -EINVAL;
	}

	va_io_base = devm_ioremap(&pdev->dev, va_base_addr,
				  VA_MAX_OFFSET);
	if (!va_io_base) {