Browse Source

Merge "asoc: codecs: bolero: Fix L/R swap issue on bolero RX"

qctecmdr 5 years ago
parent
commit
ee29c8d3d7
2 changed files with 227 additions and 27 deletions
  1. 101 19
      asoc/codecs/bolero/rx-macro.c
  2. 126 8
      asoc/codecs/bolero/wsa-macro.c

+ 101 - 19
asoc/codecs/bolero/rx-macro.c

@@ -351,6 +351,7 @@ static int rx_macro_hw_params(struct snd_pcm_substream *substream,
 static int rx_macro_get_channel_map(struct snd_soc_dai *dai,
 				unsigned int *tx_num, unsigned int *tx_slot,
 				unsigned int *rx_num, unsigned int *rx_slot);
+static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute);
 static int rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol);
 static int rx_macro_mux_get(struct snd_kcontrol *kcontrol,
@@ -641,6 +642,7 @@ static const struct snd_kcontrol_new rx_mix_tx0_mux =
 static struct snd_soc_dai_ops rx_macro_dai_ops = {
 	.hw_params = rx_macro_hw_params,
 	.get_channel_map = rx_macro_get_channel_map,
+	.digital_mute = rx_macro_digital_mute,
 };
 
 static struct snd_soc_dai_driver rx_macro_dai[] = {
@@ -915,9 +917,9 @@ static int rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
 						component, int_mux_cfg0);
 			int_mux_cfg1_val = snd_soc_component_read32(
 						component, int_mux_cfg1);
-			inp0_sel = int_mux_cfg0_val & 0x07;
-			inp1_sel = (int_mux_cfg0_val >> 4) & 0x038;
-			inp2_sel = (int_mux_cfg1_val >> 4) & 0x038;
+			inp0_sel = int_mux_cfg0_val & 0x0F;
+			inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F;
+			inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F;
 			if ((inp0_sel == int_1_mix1_inp) ||
 			    (inp1_sel == int_1_mix1_inp) ||
 			    (inp2_sel == int_1_mix1_inp)) {
@@ -968,7 +970,7 @@ static int rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
 		for (j = 0; j < INTERP_MAX; j++) {
 			int_mux_cfg1_val = snd_soc_component_read32(
 						component, int_mux_cfg1) &
-						0x07;
+						0x0F;
 			if (int_mux_cfg1_val == int_2_inp) {
 				int_fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL +
 						0x80 * j;
@@ -1127,6 +1129,57 @@ static int rx_macro_get_channel_map(struct snd_soc_dai *dai,
 	return 0;
 }
 
+static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_component *component = dai->component;
+	struct device *rx_dev = NULL;
+	struct rx_macro_priv *rx_priv = NULL;
+	uint16_t j = 0, reg = 0, mix_reg = 0, dsm_reg = 0;
+	u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
+	u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
+
+	if (mute)
+		return 0;
+
+	if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	switch (dai->id) {
+	case RX_MACRO_AIF1_PB:
+	case RX_MACRO_AIF2_PB:
+	case RX_MACRO_AIF3_PB:
+	case RX_MACRO_AIF4_PB:
+	for (j = 0; j < INTERP_MAX; j++) {
+		reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL +
+				(j * RX_MACRO_RX_PATH_OFFSET);
+		mix_reg = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL +
+				(j * RX_MACRO_RX_PATH_OFFSET);
+		dsm_reg = BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL +
+				(j * RX_MACRO_RX_PATH_OFFSET);
+		if (j == INTERP_AUX)
+			dsm_reg = BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL;
+		int_mux_cfg0 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8;
+		int_mux_cfg1 = int_mux_cfg0 + 4;
+		int_mux_cfg0_val = snd_soc_component_read32(component,
+							int_mux_cfg0);
+		int_mux_cfg1_val = snd_soc_component_read32(component,
+							int_mux_cfg1);
+		if (snd_soc_component_read32(component, dsm_reg) & 0x01) {
+			if (int_mux_cfg0_val || (int_mux_cfg1_val & 0xF0))
+				snd_soc_component_update_bits(component,
+							reg, 0x20, 0x20);
+			if (int_mux_cfg1_val & 0x0F)
+				snd_soc_component_update_bits(component,
+							mix_reg, 0x20, 0x20);
+		}
+	}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
 static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv,
 				 bool mclk_enable, bool dapm)
 {
@@ -1483,8 +1536,6 @@ static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
 		rx_macro_set_idle_detect_thr(component, rx_priv, w->shift,
 					INTERP_MIX_PATH);
 		rx_macro_enable_interp_clk(component, event, w->shift);
-		/* Clk enable */
-		snd_soc_component_update_bits(component, mix_reg, 0x20, 0x20);
 		break;
 	case SND_SOC_DAPM_POST_PMU:
 		snd_soc_component_write(component, gain_reg,
@@ -1503,6 +1554,42 @@ static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
+static bool rx_macro_adie_lb(struct snd_soc_component *component,
+			     int interp_idx)
+{
+	u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
+	u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
+	u8 int_n_inp0 = 0, int_n_inp1 = 0, int_n_inp2 = 0;
+
+	int_mux_cfg0 = BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8;
+	int_mux_cfg1 = int_mux_cfg0 + 4;
+	int_mux_cfg0_val = snd_soc_component_read32(component, int_mux_cfg0);
+	int_mux_cfg1_val = snd_soc_component_read32(component, int_mux_cfg1);
+
+	int_n_inp0 = int_mux_cfg0_val & 0x0F;
+	if (int_n_inp0 == INTn_1_INP_SEL_DEC0 ||
+		int_n_inp0 == INTn_1_INP_SEL_DEC1 ||
+		int_n_inp0 == INTn_1_INP_SEL_IIR0 ||
+		int_n_inp0 == INTn_1_INP_SEL_IIR1)
+		return true;
+
+	int_n_inp1 = int_mux_cfg0_val >> 4;
+	if (int_n_inp1 == INTn_1_INP_SEL_DEC0 ||
+		int_n_inp1 == INTn_1_INP_SEL_DEC1 ||
+		int_n_inp1 == INTn_1_INP_SEL_IIR0 ||
+		int_n_inp1 == INTn_1_INP_SEL_IIR1)
+		return true;
+
+	int_n_inp2 = int_mux_cfg1_val >> 4;
+	if (int_n_inp2 == INTn_1_INP_SEL_DEC0 ||
+		int_n_inp2 == INTn_1_INP_SEL_DEC1 ||
+		int_n_inp2 == INTn_1_INP_SEL_IIR0 ||
+		int_n_inp2 == INTn_1_INP_SEL_IIR1)
+		return true;
+
+	return false;
+}
+
 static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w,
 					struct snd_kcontrol *kcontrol,
 					int event)
@@ -1535,6 +1622,9 @@ static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w,
 		rx_macro_set_idle_detect_thr(component, rx_priv, w->shift,
 						INTERP_MAIN_PATH);
 		rx_macro_enable_interp_clk(component, event, w->shift);
+		if (rx_macro_adie_lb(component, w->shift))
+			snd_soc_component_update_bits(component,
+						reg, 0x20, 0x20);
 		break;
 	case SND_SOC_DAPM_POST_PMU:
 		snd_soc_component_write(component, gain_reg,
@@ -2352,9 +2442,6 @@ static int rx_macro_enable_interp_clk(struct snd_soc_component *component,
 					0x10, 0x10);
 			snd_soc_component_update_bits(component, dsm_reg,
 					0x01, 0x01);
-			/* Clk enable */
-			snd_soc_component_update_bits(component, main_reg,
-					0x20, 0x20);
 			snd_soc_component_update_bits(component, rx_cfg2_reg,
 					0x03, 0x03);
 			rx_macro_load_compander_coeff(component, rx_priv,
@@ -2427,17 +2514,21 @@ static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w,
 {
 	struct snd_soc_component *component =
 				snd_soc_dapm_to_component(w->dapm);
-	u16 sidetone_reg = 0;
+	u16 sidetone_reg = 0, fs_reg = 0;
 
 	dev_dbg(component->dev, "%s %d %d\n", __func__, event, w->shift);
 	sidetone_reg = BOLERO_CDC_RX_RX0_RX_PATH_CFG1 +
 			RX_MACRO_RX_PATH_OFFSET * (w->shift);
+	fs_reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL +
+			RX_MACRO_RX_PATH_OFFSET * (w->shift);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		rx_macro_enable_interp_clk(component, event, w->shift);
 		snd_soc_component_update_bits(component, sidetone_reg,
 					0x10, 0x10);
+		snd_soc_component_update_bits(component, fs_reg,
+					0x20, 0x20);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		snd_soc_component_update_bits(component, sidetone_reg,
@@ -3546,15 +3637,6 @@ static int rx_macro_init(struct snd_soc_component *component)
 	snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC3_INP");
 	snd_soc_dapm_sync(dapm);
 
-	snd_soc_component_update_bits(component,
-				BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL,
-				0x01, 0x01);
-	snd_soc_component_update_bits(component,
-				BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL,
-				0x01, 0x01);
-	snd_soc_component_update_bits(component,
-				BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL,
-				0x01, 0x01);
 	snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX0_RX_PATH_SEC7,
 				0x07, 0x02);
 	snd_soc_component_update_bits(component, BOLERO_CDC_RX_RX1_RX_PATH_SEC7,

+ 126 - 8
asoc/codecs/bolero/wsa-macro.c

@@ -88,6 +88,16 @@ enum {
 	WSA_MACRO_SOFTCLIP_MAX
 };
 
+enum {
+	INTn_1_INP_SEL_ZERO = 0,
+	INTn_1_INP_SEL_RX0,
+	INTn_1_INP_SEL_RX1,
+	INTn_1_INP_SEL_RX2,
+	INTn_1_INP_SEL_RX3,
+	INTn_1_INP_SEL_DEC0,
+	INTn_1_INP_SEL_DEC1,
+};
+
 struct interp_sample_rate {
 	int sample_rate;
 	int rate_val;
@@ -129,6 +139,7 @@ static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
 static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
 				unsigned int *tx_num, unsigned int *tx_slot,
 				unsigned int *rx_num, unsigned int *rx_slot);
+static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute);
 /* Hold instance to soundwire platform device */
 struct wsa_macro_swr_ctrl_data {
 	struct platform_device *wsa_swr_pdev;
@@ -358,6 +369,7 @@ static const struct snd_kcontrol_new rx_mix_ec1_mux =
 static struct snd_soc_dai_ops wsa_macro_dai_ops = {
 	.hw_params = wsa_macro_hw_params,
 	.get_channel_map = wsa_macro_get_channel_map,
+	.digital_mute = wsa_macro_digital_mute,
 };
 
 static struct snd_soc_dai_driver wsa_macro_dai[] = {
@@ -794,6 +806,53 @@ static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
 	return 0;
 }
 
+static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_component *component = dai->component;
+	struct device *wsa_dev = NULL;
+	struct wsa_macro_priv *wsa_priv = NULL;
+	uint16_t j = 0, reg = 0, mix_reg = 0, dsm_reg = 0;
+	u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
+	u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
+
+	if (mute)
+		return 0;
+
+	if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	switch (dai->id) {
+	case WSA_MACRO_AIF1_PB:
+	case WSA_MACRO_AIF_MIX1_PB:
+	for (j = 0; j < NUM_INTERPOLATORS; j++) {
+		reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
+				(j * WSA_MACRO_RX_PATH_OFFSET);
+		mix_reg = BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL +
+				(j * WSA_MACRO_RX_PATH_OFFSET);
+		dsm_reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
+				(j * WSA_MACRO_RX_PATH_OFFSET) +
+				WSA_MACRO_RX_PATH_DSMDEM_OFFSET;
+		int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + j * 8;
+		int_mux_cfg1 = int_mux_cfg0 + 4;
+		int_mux_cfg0_val = snd_soc_component_read32(component,
+							int_mux_cfg0);
+		int_mux_cfg1_val = snd_soc_component_read32(component,
+							int_mux_cfg1);
+		if (snd_soc_component_read32(component, dsm_reg) & 0x01) {
+			if (int_mux_cfg0_val || (int_mux_cfg1_val & 0x38))
+				snd_soc_component_update_bits(component, reg,
+							0x20, 0x20);
+			if (int_mux_cfg1_val & 0x07)
+				snd_soc_component_update_bits(component,
+						mix_reg, 0x20, 0x20);
+		}
+	}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
 static int wsa_macro_mclk_enable(struct wsa_macro_priv *wsa_priv,
 				 bool mclk_enable, bool dapm)
 {
@@ -1102,6 +1161,8 @@ static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
 		snd_soc_component_write(component, gain_reg, val);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_component_update_bits(component,
+					w->reg, 0x20, 0x00);
 		break;
 	}
 
@@ -1323,6 +1384,58 @@ static int wsa_macro_config_softclip(struct snd_soc_component *component,
 	return 0;
 }
 
+static bool wsa_macro_adie_lb(struct snd_soc_component *component,
+			      int interp_idx)
+{
+	u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
+	u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
+	u8 int_n_inp0 = 0, int_n_inp1 = 0, int_n_inp2 = 0;
+
+	int_mux_cfg0 = BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8;
+	int_mux_cfg1 = int_mux_cfg0 + 4;
+	int_mux_cfg0_val = snd_soc_component_read32(component, int_mux_cfg0);
+	int_mux_cfg1_val = snd_soc_component_read32(component, int_mux_cfg1);
+
+	int_n_inp0 = int_mux_cfg0_val & 0x0F;
+	if (int_n_inp0 == INTn_1_INP_SEL_DEC0 ||
+		int_n_inp0 == INTn_1_INP_SEL_DEC1)
+		return true;
+
+	int_n_inp1 = int_mux_cfg0_val >> 4;
+	if (int_n_inp1 == INTn_1_INP_SEL_DEC0 ||
+		int_n_inp1 == INTn_1_INP_SEL_DEC1)
+		return true;
+
+	int_n_inp2 = int_mux_cfg1_val >> 4;
+	if (int_n_inp2 == INTn_1_INP_SEL_DEC0 ||
+		int_n_inp2 == INTn_1_INP_SEL_DEC1)
+		return true;
+
+	return false;
+}
+
+static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w,
+				      struct snd_kcontrol *kcontrol,
+				      int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	u16 reg = 0;
+
+	reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL +
+			WSA_MACRO_RX_PATH_OFFSET * w->shift;
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (wsa_macro_adie_lb(component, w->shift))
+			snd_soc_component_update_bits(component,
+						reg, 0x20, 0x20);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
 static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
 {
 	u16 prim_int_reg = 0;
@@ -1370,8 +1483,6 @@ static int wsa_macro_enable_prim_interpolator(
 			snd_soc_component_update_bits(component,
 				prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
 				0x1, 0x1);
-			snd_soc_component_update_bits(component, prim_int_reg,
-					    1 << 0x5, 1 << 0x5);
 		}
 		if ((reg != prim_int_reg) &&
 		    ((snd_soc_component_read32(
@@ -1384,6 +1495,9 @@ static int wsa_macro_enable_prim_interpolator(
 		if (wsa_priv->prim_int_users[ind] == 0) {
 			snd_soc_component_update_bits(component, prim_int_reg,
 					1 << 0x5, 0 << 0x5);
+			snd_soc_component_update_bits(component,
+				prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
+				0x1, 0x0);
 			snd_soc_component_update_bits(component, prim_int_reg,
 					0x40, 0x40);
 			snd_soc_component_update_bits(component, prim_int_reg,
@@ -2382,8 +2496,8 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
 	SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
 		&rx0_prim_inp2_mux, wsa_macro_enable_swr,
 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, 0, 0,
-		&rx0_mix_mux, wsa_macro_enable_mix_path,
+	SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL,
+		0, 0, &rx0_mix_mux, wsa_macro_enable_mix_path,
 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 	SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
 		&rx1_prim_inp0_mux, wsa_macro_enable_swr,
@@ -2394,11 +2508,15 @@ static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
 	SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
 		&rx1_prim_inp2_mux, wsa_macro_enable_swr,
 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, 0, 0,
-		&rx1_mix_mux, wsa_macro_enable_mix_path,
+	SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL,
+		0, 0, &rx1_mix_mux, wsa_macro_enable_mix_path,
 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MIXER("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
-	SND_SOC_DAPM_MIXER("WSA_RX INT1 MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM,
+			0, 0, NULL, 0, wsa_macro_enable_main_path,
+			SND_SOC_DAPM_PRE_PMU),
+	SND_SOC_DAPM_MIXER_E("WSA_RX INT1 MIX", SND_SOC_NOPM,
+			1, 0, NULL, 0, wsa_macro_enable_main_path,
+			SND_SOC_DAPM_PRE_PMU),
 	SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
 	SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),