diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 68cbc15e5d..24729603ff 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -233,6 +233,7 @@ struct wsa_macro_priv { [WSA_MACRO_CHILD_DEVICES_MAX]; int child_count; int ear_spkr_gain; + int wsa_spkrrecv; int spkr_gain_offset; int spkr_mode; int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX]; @@ -291,6 +292,11 @@ static const struct snd_kcontrol_new wsa_int1_vbat_mix_switch[] = { SOC_DAPM_SINGLE("WSA RX1 VBAT Enable", SND_SOC_NOPM, 0, 1, 0) }; +static const char *const wsa_macro_ear_spkrrecv_text[] = { + "OFF", "ON" +}; +static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkrrecv_enum, + wsa_macro_ear_spkrrecv_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum, wsa_macro_ear_spkr_pa_gain_text); static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_spkr_boost_stage_enum, @@ -1703,6 +1709,12 @@ static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component, dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n", __func__, val); } + if(wsa_priv->wsa_spkrrecv) { + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80); + } break; case SND_SOC_DAPM_POST_PMD: /* @@ -1717,6 +1729,10 @@ static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component, dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n", __func__); } + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01); + snd_soc_component_update_bits(component, + BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00); break; } @@ -2093,6 +2109,43 @@ static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol, return 0; } +static int wsa_macro_ear_spkrrecv_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = wsa_priv->wsa_spkrrecv; + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int wsa_macro_ear_spkrrecv_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + wsa_priv->wsa_spkrrecv = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s:spkrrecv status = %d\n", + __func__, wsa_priv->wsa_spkrrecv); + + return 0; +} + static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2354,6 +2407,9 @@ static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol, } static const struct snd_kcontrol_new wsa_macro_snd_controls[] = { + SOC_ENUM_EXT("WSA SPKRRECV", wsa_macro_ear_spkrrecv_enum, + wsa_macro_ear_spkrrecv_get, + wsa_macro_ear_spkrrecv_put), SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum, wsa_macro_ear_spkr_pa_gain_get, wsa_macro_ear_spkr_pa_gain_put), @@ -2742,10 +2798,10 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = { static const struct wsa_macro_reg_mask_val wsa_macro_reg_init[] = { {BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12}, {BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08}, - {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x0C}, + {BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18}, {BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12}, {BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08}, - {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x0C}, + {BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18}, {BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58}, {BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58}, {BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08}, diff --git a/asoc/codecs/lpass-cdc/lpass-cdc-wsa-macro.c b/asoc/codecs/lpass-cdc/lpass-cdc-wsa-macro.c index e629f7bb4f..0356b39276 100644 --- a/asoc/codecs/lpass-cdc/lpass-cdc-wsa-macro.c +++ b/asoc/codecs/lpass-cdc/lpass-cdc-wsa-macro.c @@ -279,7 +279,7 @@ struct lpass_cdc_wsa_macro_priv { struct platform_device *pdev_child_devices [LPASS_CDC_WSA_MACRO_CHILD_DEVICES_MAX]; int child_count; - int ear_spkr_gain; + int wsa_spkrrecv; int spkr_gain_offset; int spkr_mode; int is_softclip_on[LPASS_CDC_WSA_MACRO_SOFTCLIP_MAX]; @@ -323,6 +323,10 @@ static const char * const lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_text[] = { "OFF", "ON" }; +static const char *const lpass_cdc_wsa_macro_ear_spkrrecv_text[] = { + "OFF", "ON" +}; + static const char * const lpass_cdc_wsa_macro_comp_mode_text[] = { "G_21_DB", "G_19P5_DB", "G_18_DB", "G_16P5_DB", "G_15_DB", "G_13P5_DB", "G_12_DB", "G_10P5_DB", "G_9_DB" @@ -336,6 +340,8 @@ static const struct snd_kcontrol_new wsa_int1_vbat_mix_switch[] = { SOC_DAPM_SINGLE("WSA RX1 VBAT Enable", SND_SOC_NOPM, 0, 1, 0) }; +static SOC_ENUM_SINGLE_EXT_DECL(lpass_cdc_wsa_macro_ear_spkrrecv_enum, + lpass_cdc_wsa_macro_ear_spkrrecv_text); static SOC_ENUM_SINGLE_EXT_DECL(lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_enum, lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_text); static SOC_ENUM_SINGLE_EXT_DECL(lpass_cdc_wsa_macro_comp_mode_enum, @@ -1527,6 +1533,9 @@ static int lpass_cdc_wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w u8 gain = 0; u16 reg = 0; + if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) return -EINVAL; @@ -2028,6 +2037,44 @@ static int lpass_cdc_wsa_macro_set_compander(struct snd_kcontrol *kcontrol, return 0; } +static int lpass_cdc_wsa_macro_ear_spkrrecv_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct device *wsa_dev = NULL; + struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL; + + if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = wsa_priv->wsa_spkrrecv; + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int lpass_cdc_wsa_macro_ear_spkrrecv_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct device *wsa_dev = NULL; + struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL; + + if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + + wsa_priv->wsa_spkrrecv = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s:spkrrecv status = %d\n", + __func__, wsa_priv->wsa_spkrrecv); + + return 0; +} + static int lpass_cdc_wsa_macro_comp_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2239,6 +2286,9 @@ static int lpass_cdc_wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontro } static const struct snd_kcontrol_new lpass_cdc_wsa_macro_snd_controls[] = { + SOC_ENUM_EXT("WSA SPKRRECV", lpass_cdc_wsa_macro_ear_spkrrecv_enum, + lpass_cdc_wsa_macro_ear_spkrrecv_get, + lpass_cdc_wsa_macro_ear_spkrrecv_put), SOC_ENUM_EXT("GSM mode Enable", lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_enum, lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_func_get, lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_func_put), @@ -2659,10 +2709,10 @@ static const struct lpass_cdc_wsa_macro_reg_mask_val lpass_cdc_wsa_macro_reg_init[] = { {LPASS_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12}, {LPASS_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08}, - {LPASS_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x0C}, + {LPASS_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x18}, {LPASS_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12}, {LPASS_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08}, - {LPASS_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x0C}, + {LPASS_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x18}, {LPASS_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58}, {LPASS_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58}, {LPASS_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08}, diff --git a/asoc/codecs/lpass-cdc/lpass-cdc-wsa2-macro.c b/asoc/codecs/lpass-cdc/lpass-cdc-wsa2-macro.c index 521a56ad8a..884c24e1d6 100644 --- a/asoc/codecs/lpass-cdc/lpass-cdc-wsa2-macro.c +++ b/asoc/codecs/lpass-cdc/lpass-cdc-wsa2-macro.c @@ -272,6 +272,7 @@ struct lpass_cdc_wsa2_macro_priv { struct snd_soc_component *component; int rx_0_count; int rx_1_count; + int wsa_spkrrecv; unsigned long active_ch_mask[LPASS_CDC_WSA2_MACRO_MAX_DAIS]; unsigned long active_ch_cnt[LPASS_CDC_WSA2_MACRO_MAX_DAIS]; int rx_port_value[LPASS_CDC_WSA2_MACRO_RX_MAX]; @@ -320,6 +321,10 @@ static const char * const lpass_cdc_wsa2_macro_vbat_bcl_gsm_mode_text[] = { "OFF", "ON" }; +static const char *const lpass_cdc_wsa2_macro_ear_spkrrecv_text[] = { + "OFF", "ON" +}; + static const char * const lpass_cdc_wsa2_macro_comp_mode_text[] = { "G_21_DB", "G_19P5_DB", "G_18_DB", "G_16P5_DB", "G_15_DB", "G_13P5_DB", "G_12_DB", "G_10P5_DB", "G_9_DB" @@ -333,6 +338,8 @@ static const struct snd_kcontrol_new wsa2_int1_vbat_mix_switch[] = { SOC_DAPM_SINGLE("WSA2 RX1 VBAT Enable", SND_SOC_NOPM, 0, 1, 0) }; +static SOC_ENUM_SINGLE_EXT_DECL(lpass_cdc_wsa2_macro_ear_spkrrecv_enum, + lpass_cdc_wsa2_macro_ear_spkrrecv_text); static SOC_ENUM_SINGLE_EXT_DECL(lpass_cdc_wsa2_macro_vbat_bcl_gsm_mode_enum, lpass_cdc_wsa2_macro_vbat_bcl_gsm_mode_text); static SOC_ENUM_SINGLE_EXT_DECL(lpass_cdc_wsa2_macro_comp_mode_enum, @@ -1526,6 +1533,9 @@ static int lpass_cdc_wsa2_macro_enable_interpolator(struct snd_soc_dapm_widget * u8 gain = 0; u16 reg = 0; + if (!lpass_cdc_wsa2_macro_get_data(component, &wsa2_dev, &wsa2_priv, __func__)) + return -EINVAL; + if (!lpass_cdc_wsa2_macro_get_data(component, &wsa2_dev, &wsa2_priv, __func__)) return -EINVAL; @@ -2027,6 +2037,43 @@ static int lpass_cdc_wsa2_macro_set_compander(struct snd_kcontrol *kcontrol, return 0; } +static int lpass_cdc_wsa2_macro_ear_spkrrecv_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct device *wsa2_dev = NULL; + struct lpass_cdc_wsa2_macro_priv *wsa2_priv = NULL; + + if (!lpass_cdc_wsa2_macro_get_data(component, &wsa2_dev, &wsa2_priv, __func__)) + return -EINVAL; + + ucontrol->value.integer.value[0] = wsa2_priv->wsa_spkrrecv; + + dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + return 0; +} + +static int lpass_cdc_wsa2_macro_ear_spkrrecv_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct device *wsa2_dev = NULL; + struct lpass_cdc_wsa2_macro_priv *wsa2_priv = NULL; + + if (!lpass_cdc_wsa2_macro_get_data(component, &wsa2_dev, &wsa2_priv, __func__)) + return -EINVAL; + wsa2_priv->wsa_spkrrecv = ucontrol->value.integer.value[0]; + + dev_dbg(component->dev, "%s:spkrrecv status = %d\n", + __func__, wsa2_priv->wsa_spkrrecv); + + return 0; +} + static int lpass_cdc_wsa2_macro_comp_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2238,6 +2285,9 @@ static int lpass_cdc_wsa2_macro_soft_clip_enable_put(struct snd_kcontrol *kcontr } static const struct snd_kcontrol_new lpass_cdc_wsa2_macro_snd_controls[] = { + SOC_ENUM_EXT("WSA2 SPKRRECV", lpass_cdc_wsa2_macro_ear_spkrrecv_enum, + lpass_cdc_wsa2_macro_ear_spkrrecv_get, + lpass_cdc_wsa2_macro_ear_spkrrecv_put), SOC_ENUM_EXT("WSA2_GSM mode Enable", lpass_cdc_wsa2_macro_vbat_bcl_gsm_mode_enum, lpass_cdc_wsa2_macro_vbat_bcl_gsm_mode_func_get, lpass_cdc_wsa2_macro_vbat_bcl_gsm_mode_func_put), @@ -2658,10 +2708,10 @@ static const struct lpass_cdc_wsa2_macro_reg_mask_val lpass_cdc_wsa2_macro_reg_init[] = { {LPASS_CDC_WSA2_BOOST0_BOOST_CFG1, 0x3F, 0x12}, {LPASS_CDC_WSA2_BOOST0_BOOST_CFG2, 0x1C, 0x08}, - {LPASS_CDC_WSA2_COMPANDER0_CTL7, 0x1E, 0x0C}, + {LPASS_CDC_WSA2_COMPANDER0_CTL7, 0x1E, 0x18}, {LPASS_CDC_WSA2_BOOST1_BOOST_CFG1, 0x3F, 0x12}, {LPASS_CDC_WSA2_BOOST1_BOOST_CFG2, 0x1C, 0x08}, - {LPASS_CDC_WSA2_COMPANDER1_CTL7, 0x1E, 0x0C}, + {LPASS_CDC_WSA2_COMPANDER1_CTL7, 0x1E, 0x18}, {LPASS_CDC_WSA2_BOOST0_BOOST_CTL, 0x70, 0x58}, {LPASS_CDC_WSA2_BOOST1_BOOST_CTL, 0x70, 0x58}, {LPASS_CDC_WSA2_RX0_RX_PATH_CFG1, 0x08, 0x08}, diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c index 55f10adb27..5037dfdd41 100644 --- a/asoc/codecs/wsa883x/wsa883x.c +++ b/asoc/codecs/wsa883x/wsa883x.c @@ -530,6 +530,12 @@ static const char * const wsa_dev_mode_text[] = { "speaker", "receiver", "ultrasound" }; +enum { + SPEAKER, + RECEIVER, + ULTRASOUND, +}; + static const struct soc_enum wsa_dev_mode_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_dev_mode_text), wsa_dev_mode_text); @@ -1112,8 +1118,18 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, true); /* Added delay as per HW sequence */ usleep_range(250, 300); - snd_soc_component_update_bits(component, WSA883X_DRE_CTL_1, - 0x01, 0x01); + if (wsa883x->dev_mode == RECEIVER) { + snd_soc_component_update_bits(component, + WSA883X_DRE_CTL_0, + 0xF0, 0x00); + } else if (wsa883x->dev_mode == SPEAKER) { + snd_soc_component_update_bits(component, + WSA883X_DRE_CTL_0, + 0xF0, 0x90); + } + snd_soc_component_update_bits(component, + WSA883X_DRE_CTL_1, + 0x01, 0x01); /* Added delay as per HW sequence */ usleep_range(250, 300);