Browse Source

Merge "ASoC: wcd938x: Update DMIC enable sequence on WCD938x"

qctecmdr 5 years ago
parent
commit
a74c6e2c7c
1 changed files with 42 additions and 32 deletions
  1. 42 32
      asoc/codecs/wcd938x/wcd938x.c

+ 42 - 32
asoc/codecs/wcd938x/wcd938x.c

@@ -1026,49 +1026,51 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w,
 	struct snd_soc_component *component =
 				snd_soc_dapm_to_component(w->dapm);
 	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
-	u16 dmic_clk_reg;
+	u16 dmic_clk_reg, dmic_clk_en_reg;
 	s32 *dmic_clk_cnt;
-	unsigned int dmic;
-	char *wname;
-	int ret = 0;
-
-	wname = strpbrk(w->name, "012345");
-
-	if (!wname) {
-		dev_err(component->dev, "%s: widget not found\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = kstrtouint(wname, 10, &dmic);
-	if (ret < 0) {
-		dev_err(component->dev, "%s: Invalid DMIC line on the codec\n",
-			__func__);
-		return -EINVAL;
-	}
+	u8 dmic_ctl_shift = 0;
+	u8 dmic_clk_shift = 0;
+	u8 dmic_clk_mask = 0;
 
 	dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
 		w->name, event);
 
-	switch (dmic) {
+	switch (w->shift) {
 	case 0:
 	case 1:
 		dmic_clk_cnt = &(wcd938x->dmic_0_1_clk_cnt);
-		dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC1_CTL;
+		dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_1_2;
+		dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC1_CTL;
+		dmic_clk_mask = 0x0F;
+		dmic_clk_shift = 0x00;
+		dmic_ctl_shift = 0x00;
 		break;
 	case 2:
 	case 3:
 		dmic_clk_cnt = &(wcd938x->dmic_2_3_clk_cnt);
-		dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC2_CTL;
+		dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_1_2;
+		dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC2_CTL;
+		dmic_clk_mask = 0xF0;
+		dmic_clk_shift = 0x04;
+		dmic_ctl_shift = 0x01;
 		break;
 	case 4:
 	case 5:
 		dmic_clk_cnt = &(wcd938x->dmic_4_5_clk_cnt);
-		dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC3_CTL;
+		dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_3_4;
+		dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC3_CTL;
+		dmic_clk_mask = 0x0F;
+		dmic_clk_shift = 0x00;
+		dmic_ctl_shift = 0x02;
 		break;
 	case 6:
 	case 7:
 		dmic_clk_cnt = &(wcd938x->dmic_6_7_clk_cnt);
-		dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC4_CTL;
+		dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_3_4;
+		dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC4_CTL;
+		dmic_clk_mask = 0xF0;
+		dmic_clk_shift = 0x04;
+		dmic_ctl_shift = 0x03;
 		break;
 	default:
 		dev_err(component->dev, "%s: Invalid DMIC Selection\n",
@@ -1076,27 +1078,35 @@ static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w,
 		return -EINVAL;
 	};
 	dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
-			__func__, event,  dmic, *dmic_clk_cnt);
+			__func__, event,  (w->shift +1), *dmic_clk_cnt);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		snd_soc_component_update_bits(component,
-				WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x80);
-		/* enable clock scaling */
+				WCD938X_DIGITAL_CDC_AMIC_CTL,
+				(0x01 << dmic_ctl_shift), 0x00);
+		/* 250us sleep as per HW requirement */
+		usleep_range(250, 260);
+		/* Setting DMIC clock rate to 2.4MHz */
 		snd_soc_component_update_bits(component,
-				WCD938X_DIGITAL_CDC_DMIC_CTL, 0x06, 0x06);
+					      dmic_clk_reg, dmic_clk_mask,
+					      (0x03 << dmic_clk_shift));
 		snd_soc_component_update_bits(component,
-						dmic_clk_reg, 0x07, 0x02);
-		snd_soc_component_update_bits(component,
-						dmic_clk_reg, 0x08, 0x08);
+					      dmic_clk_en_reg, 0x08, 0x08);
+		/* enable clock scaling */
 		snd_soc_component_update_bits(component,
-						dmic_clk_reg, 0x70, 0x20);
+				WCD938X_DIGITAL_CDC_DMIC_CTL, 0x06, 0x06);
 		wcd938x_tx_connect_port(component, DMIC0 + (w->shift), true);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		wcd938x_tx_connect_port(component, DMIC0 + (w->shift), false);
+		snd_soc_component_update_bits(component,
+				WCD938X_DIGITAL_CDC_AMIC_CTL,
+				(0x01 << dmic_ctl_shift),
+				(0x01 << dmic_ctl_shift));
+		snd_soc_component_update_bits(component,
+					      dmic_clk_en_reg, 0x08, 0x00);
 		break;
-
 	};
 	return 0;
 }