Message ID | 20240625084303.2273911-1-shumingf@realtek.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 50b8affb5665efa028998ad2c116b1106623409e |
Headers | show |
Series | [v2] ASoC: rt711-sdca: add GE selected mode control | expand |
> -----Original Message----- > From: shumingf@realtek.com <shumingf@realtek.com> > Sent: Tuesday, June 25, 2024 4:43 PM > To: broonie@kernel.org; lgirdwood@gmail.com > Cc: linux-sound@vger.kernel.org; lars@metafoo.de; flove@realtek.com; > oder_chiou@realtek.com; jack.yu@realtek.com; derek.fang@realtek.com; > Bossart, Pierre-louis <pierre-louis.bossart@intel.com>; Liao, Bard > <bard.liao@intel.com>; Shuming Fan <shumingf@realtek.com> > Subject: [PATCH v2] ASoC: rt711-sdca: add GE selected mode control > > From: Shuming Fan <shumingf@realtek.com> > > The SDCA spec defines a 'selected_mode' control which can override > the 'detected_mode' reported by hardware. > This is useful for platform integration as well as in cases > where the hardware(e.g. 3.5mm jack cable) is not able to accurately detect the > jack type. > > Signed-off-by: Shuming Fan <shumingf@realtek.com> Tested-by: yung-chuan.liao@linux.intel.com > --- > sound/soc/codecs/rt711-sdca.c | 72 > +++++++++++++++++++++++++++++++++++ > sound/soc/codecs/rt711-sdca.h | 1 + > 2 files changed, 73 insertions(+) > > diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c > index 1e8dbfc3ecd9..dd6ccf17afd4 100644 > --- a/sound/soc/codecs/rt711-sdca.c > +++ b/sound/soc/codecs/rt711-sdca.c > @@ -81,6 +81,24 @@ static void rt711_sdca_reset(struct rt711_sdca_priv > *rt711) > RT711_HDA_LEGACY_RESET_CTL, 0x1, 0x1); > } > > +static void rt711_sdca_ge_force_jack_type(struct rt711_sdca_priv *rt711, > unsigned int det_mode) > +{ > + switch (det_mode) { > + case 0x00: > + rt711_sdca_index_update_bits(rt711, RT711_VENDOR_REG, > RT711_COMBO_JACK_AUTO_CTL1, 0x8400, 0x0000); > + rt711_sdca_index_update_bits(rt711, > RT711_VENDOR_HDA_CTL, RT711_PUSH_BTN_INT_CTL0, 0x10, 0x00); > + break; > + case 0x03: > + rt711_sdca_index_update_bits(rt711, RT711_VENDOR_REG, > RT711_COMBO_JACK_AUTO_CTL1, 0x8400, 0x8000); > + rt711_sdca_index_update_bits(rt711, > RT711_VENDOR_HDA_CTL, RT711_PUSH_BTN_INT_CTL0, 0x17, 0x13); > + break; > + case 0x05: > + rt711_sdca_index_update_bits(rt711, RT711_VENDOR_REG, > RT711_COMBO_JACK_AUTO_CTL1, 0x8400, 0x8400); > + rt711_sdca_index_update_bits(rt711, > RT711_VENDOR_HDA_CTL, RT711_PUSH_BTN_INT_CTL0, 0x17, 0x15); > + break; > + } > +} > + > static int rt711_sdca_calibration(struct rt711_sdca_priv *rt711) > { > unsigned int val, loop_rc = 0, loop_dc = 0; > @@ -248,6 +266,8 @@ static int rt711_sdca_headset_detect(struct > rt711_sdca_priv *rt711) > unsigned int det_mode; > int ret; > > + rt711_sdca_ge_force_jack_type(rt711, rt711->ge_mode_override); > + > /* get detected_mode */ > ret = regmap_read(rt711->regmap, > SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, > RT711_SDCA_ENT_GE49, RT711_SDCA_CTL_DETECTED_MODE, 0), > @@ -790,6 +810,56 @@ static int rt711_sdca_fu0f_capture_put(struct > snd_kcontrol *kcontrol, > return changed; > } > > +static int rt711_sdca_ge_select_get(struct snd_kcontrol *kcontrol, > + struct snd_ctl_elem_value *ucontrol) > +{ > + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; > + struct snd_soc_component *component = > snd_soc_kcontrol_component(kcontrol); > + struct rt711_sdca_priv *rt711 = > snd_soc_component_get_drvdata(component); > + unsigned int val, item; > + > + val = (rt711->ge_mode_override >> e->shift_l) & e->mask; > + item = snd_soc_enum_val_to_item(e, val); > + ucontrol->value.enumerated.item[0] = item; > + return 0; > +} > + > +static int rt711_sdca_ge_select_put(struct snd_kcontrol *kcontrol, > + struct snd_ctl_elem_value *ucontrol) > +{ > + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; > + unsigned int *item = ucontrol->value.enumerated.item; > + struct snd_soc_component *component = > snd_soc_kcontrol_component(kcontrol); > + struct rt711_sdca_priv *rt711 = > snd_soc_component_get_drvdata(component); > + unsigned int val, change = 0; > + > + if (item[0] >= e->items) > + return -EINVAL; > + > + val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; > + if (rt711->ge_mode_override != val) { > + rt711->ge_mode_override = val; > + change = 1; > + } > + > + return change; > +} > + > +static const char * const rt711_sdca_ge_select[] = { > + "Auto", > + "Headphone", > + "Headset", > +}; > + > +static int rt711_sdca_ge_select_values[] = { > + 0, > + 3, > + 5, > +}; > + > +static SOC_VALUE_ENUM_SINGLE_DECL(rt711_sdca_ge_mode_enum, > SND_SOC_NOPM, > + 0, 0x7, rt711_sdca_ge_select, rt711_sdca_ge_select_values); > + > static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6525, 75, 0); > static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0); > static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); > @@ -824,6 +894,8 @@ static const struct snd_kcontrol_new > rt711_sdca_snd_controls[] = { > SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, > RT711_SDCA_ENT_PLATFORM_FU15, RT711_SDCA_CTL_FU_CH_GAIN, > CH_R), > 8, 3, 0, > rt711_sdca_set_gain_get, rt711_sdca_set_gain_put, > mic_vol_tlv), > + SOC_ENUM_EXT("GE49 Selected Mode", > rt711_sdca_ge_mode_enum, > + rt711_sdca_ge_select_get, rt711_sdca_ge_select_put), > }; > > static int rt711_sdca_mux_get(struct snd_kcontrol *kcontrol, > diff --git a/sound/soc/codecs/rt711-sdca.h b/sound/soc/codecs/rt711- > sdca.h > index 11d421e8ab2b..15263dcb0314 100644 > --- a/sound/soc/codecs/rt711-sdca.h > +++ b/sound/soc/codecs/rt711-sdca.h > @@ -33,6 +33,7 @@ struct rt711_sdca_priv { > int hw_ver; > bool fu0f_dapm_mute, fu0f_mixer_l_mute, fu0f_mixer_r_mute; > bool fu1e_dapm_mute, fu1e_mixer_l_mute, fu1e_mixer_r_mute; > + unsigned int ge_mode_override; > }; > > /* NID */ > -- > 2.34.1
On Tue, 25 Jun 2024 16:43:03 +0800, shumingf@realtek.com wrote: > The SDCA spec defines a 'selected_mode' control which can override > the 'detected_mode' reported by hardware. > This is useful for platform integration as well as in cases > where the hardware(e.g. 3.5mm jack cable) is not able to accurately detect the jack type. > > Applied to https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next Thanks! [1/1] ASoC: rt711-sdca: add GE selected mode control commit: 50b8affb5665efa028998ad2c116b1106623409e All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark
diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index 1e8dbfc3ecd9..dd6ccf17afd4 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -81,6 +81,24 @@ static void rt711_sdca_reset(struct rt711_sdca_priv *rt711) RT711_HDA_LEGACY_RESET_CTL, 0x1, 0x1); } +static void rt711_sdca_ge_force_jack_type(struct rt711_sdca_priv *rt711, unsigned int det_mode) +{ + switch (det_mode) { + case 0x00: + rt711_sdca_index_update_bits(rt711, RT711_VENDOR_REG, RT711_COMBO_JACK_AUTO_CTL1, 0x8400, 0x0000); + rt711_sdca_index_update_bits(rt711, RT711_VENDOR_HDA_CTL, RT711_PUSH_BTN_INT_CTL0, 0x10, 0x00); + break; + case 0x03: + rt711_sdca_index_update_bits(rt711, RT711_VENDOR_REG, RT711_COMBO_JACK_AUTO_CTL1, 0x8400, 0x8000); + rt711_sdca_index_update_bits(rt711, RT711_VENDOR_HDA_CTL, RT711_PUSH_BTN_INT_CTL0, 0x17, 0x13); + break; + case 0x05: + rt711_sdca_index_update_bits(rt711, RT711_VENDOR_REG, RT711_COMBO_JACK_AUTO_CTL1, 0x8400, 0x8400); + rt711_sdca_index_update_bits(rt711, RT711_VENDOR_HDA_CTL, RT711_PUSH_BTN_INT_CTL0, 0x17, 0x15); + break; + } +} + static int rt711_sdca_calibration(struct rt711_sdca_priv *rt711) { unsigned int val, loop_rc = 0, loop_dc = 0; @@ -248,6 +266,8 @@ static int rt711_sdca_headset_detect(struct rt711_sdca_priv *rt711) unsigned int det_mode; int ret; + rt711_sdca_ge_force_jack_type(rt711, rt711->ge_mode_override); + /* get detected_mode */ ret = regmap_read(rt711->regmap, SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT711_SDCA_ENT_GE49, RT711_SDCA_CTL_DETECTED_MODE, 0), @@ -790,6 +810,56 @@ static int rt711_sdca_fu0f_capture_put(struct snd_kcontrol *kcontrol, return changed; } +static int rt711_sdca_ge_select_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); + unsigned int val, item; + + val = (rt711->ge_mode_override >> e->shift_l) & e->mask; + item = snd_soc_enum_val_to_item(e, val); + ucontrol->value.enumerated.item[0] = item; + return 0; +} + +static int rt711_sdca_ge_select_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int *item = ucontrol->value.enumerated.item; + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); + unsigned int val, change = 0; + + if (item[0] >= e->items) + return -EINVAL; + + val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; + if (rt711->ge_mode_override != val) { + rt711->ge_mode_override = val; + change = 1; + } + + return change; +} + +static const char * const rt711_sdca_ge_select[] = { + "Auto", + "Headphone", + "Headset", +}; + +static int rt711_sdca_ge_select_values[] = { + 0, + 3, + 5, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(rt711_sdca_ge_mode_enum, SND_SOC_NOPM, + 0, 0x7, rt711_sdca_ge_select, rt711_sdca_ge_select_values); + static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6525, 75, 0); static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0); static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); @@ -824,6 +894,8 @@ static const struct snd_kcontrol_new rt711_sdca_snd_controls[] = { SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT711_SDCA_ENT_PLATFORM_FU15, RT711_SDCA_CTL_FU_CH_GAIN, CH_R), 8, 3, 0, rt711_sdca_set_gain_get, rt711_sdca_set_gain_put, mic_vol_tlv), + SOC_ENUM_EXT("GE49 Selected Mode", rt711_sdca_ge_mode_enum, + rt711_sdca_ge_select_get, rt711_sdca_ge_select_put), }; static int rt711_sdca_mux_get(struct snd_kcontrol *kcontrol, diff --git a/sound/soc/codecs/rt711-sdca.h b/sound/soc/codecs/rt711-sdca.h index 11d421e8ab2b..15263dcb0314 100644 --- a/sound/soc/codecs/rt711-sdca.h +++ b/sound/soc/codecs/rt711-sdca.h @@ -33,6 +33,7 @@ struct rt711_sdca_priv { int hw_ver; bool fu0f_dapm_mute, fu0f_mixer_l_mute, fu0f_mixer_r_mute; bool fu1e_dapm_mute, fu1e_mixer_l_mute, fu1e_mixer_r_mute; + unsigned int ge_mode_override; }; /* NID */