diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 52598ef704a6..9ac846f45922 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/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, diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index dd12ad237362..623b64b0e5ec 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/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),