diff options
author | Hans de Goede <hdegoede@redhat.com> | 2021-08-02 16:24:59 +0200 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2021-08-02 16:47:45 +0200 |
commit | 044c76571277bb87dd3318e55c7ae46a0c27ab0f (patch) | |
tree | 7b9bddfb95a5f9f29e0b3d50c7a8303bdbb579e4 /sound/soc/intel/boards/bytcr_rt5640.c | |
parent | ASoC: Intel: bytcr_rt5640: Add a byt_rt5640_get_codec_dai() helper (diff) | |
download | linux-044c76571277bb87dd3318e55c7ae46a0c27ab0f.tar.xz linux-044c76571277bb87dd3318e55c7ae46a0c27ab0f.zip |
ASoC: Intel: bytcr_rt5640: Add support for a second headphones output
Some devices (HP Elitepad 1000 G2) have a second headphones output
(1 on the dock, 2nd on the tablet itself) which is implemented through
the line-out output of the codec combined with an external hp-amp
which gets enabled through the codec's GPIO1 pin.
Add support for this through a new BYT_RT5640_LINEOUT_AS_HP2 quirk,
note users are expected to use this combined with the
BYT_RT5640_LINEOUT quirk. If that quirk is not set the new quirk is
ignored.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20210802142501.991985-5-hdegoede@redhat.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel/boards/bytcr_rt5640.c')
-rw-r--r-- | sound/soc/intel/boards/bytcr_rt5640.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 70faba13450c..54302a86f8df 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -74,6 +74,7 @@ enum { #define BYT_RT5640_MCLK_25MHZ BIT(23) #define BYT_RT5640_NO_SPEAKERS BIT(24) #define BYT_RT5640_LINEOUT BIT(25) +#define BYT_RT5640_LINEOUT_AS_HP2 BIT(26) #define BYTCR_INPUT_DEFAULTS \ (BYT_RT5640_IN3_MAP | \ @@ -142,6 +143,8 @@ static void log_quirks(struct device *dev) dev_info(dev, "quirk NO_SPEAKERS enabled\n"); if (byt_rt5640_quirk & BYT_RT5640_LINEOUT) dev_info(dev, "quirk LINEOUT enabled\n"); + if (byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2) + dev_info(dev, "quirk LINEOUT_AS_HP2 enabled\n"); if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) dev_info(dev, "quirk DIFF_MIC enabled\n"); if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) { @@ -287,12 +290,39 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, return 0; } +static int byt_rt5640_event_lineout(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + unsigned int gpio_ctrl3_val = RT5640_GP1_PF_OUT; + struct snd_soc_dai *codec_dai; + + if (!(byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2)) + return 0; + + /* + * On devices which use line-out as a second headphones output, + * the codec's GPIO1 pin is used to enable an external HP-amp. + */ + + codec_dai = byt_rt5640_get_codec_dai(w->dapm); + if (!codec_dai) + return -EIO; + + if (SND_SOC_DAPM_EVENT_ON(event)) + gpio_ctrl3_val |= RT5640_GP1_OUT_HI; + + snd_soc_component_update_bits(codec_dai->component, RT5640_GPIO_CTRL3, + RT5640_GP1_PF_MASK | RT5640_GP1_OUT_MASK, gpio_ctrl3_val); + + return 0; +} + static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Internal Mic", NULL), SND_SOC_DAPM_SPK("Speaker", NULL), - SND_SOC_DAPM_LINE("Line Out", NULL), + SND_SOC_DAPM_LINE("Line Out", byt_rt5640_event_lineout), SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -1480,8 +1510,12 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) spk_type = "stereo"; } - if (byt_rt5640_quirk & BYT_RT5640_LINEOUT) - lineout_string = " cfg-lineout:1"; + if (byt_rt5640_quirk & BYT_RT5640_LINEOUT) { + if (byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2) + lineout_string = " cfg-hp2:lineout"; + else + lineout_string = " cfg-lineout:1"; + } snprintf(byt_rt5640_components, sizeof(byt_rt5640_components), "cfg-spk:%d cfg-mic:%s aif:%d%s", cfg_spk, |