diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-04-26 20:06:56 +0100 |
---|---|---|
committer | Andreas Blaesius <skate4life@gmx.de> | 2016-04-30 11:03:58 +0200 |
commit | c56d7a776b16c30cb61c9618d61951d336d4dd95 (patch) | |
tree | 0e53bf805a84b8be9305122f1a0a84ec3edf48ac /sound | |
parent | 3e0f0b2a926774ed4e65f1396f76d656bd2672fc (diff) | |
download | kernel_samsung_espresso10-c56d7a776b16c30cb61c9618d61951d336d4dd95.zip kernel_samsung_espresso10-c56d7a776b16c30cb61c9618d61951d336d4dd95.tar.gz kernel_samsung_espresso10-c56d7a776b16c30cb61c9618d61951d336d4dd95.tar.bz2 |
ASoC: wm_hubs: Special case headphones for digital paths in more use cases
The optimisations which we can do with caching the headphone DCS result in
wm_hubs have only been enabled in cases where class W is enabled. However,
there are more use cases which can benefit from the cache, especially with
WM8994 series devices with their more advanced digital routing.
Rather than keying off the class W information from the CODECs have a
check in wm_hubs for a suitable path and use that to determine if we can
deploy our headphone optimisations.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/wm8993.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/wm8994.c | 6 | ||||
-rw-r--r-- | sound/soc/codecs/wm_hubs.c | 48 | ||||
-rw-r--r-- | sound/soc/codecs/wm_hubs.h | 5 |
4 files changed, 46 insertions, 15 deletions
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 22f35dd..adf42ef 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -734,7 +734,6 @@ static int class_w_put(struct snd_kcontrol *kcontrol, 0); } wm8993->class_w_users++; - wm8993->hubs_data.class_w = true; } /* Implement the change */ @@ -751,7 +750,6 @@ static int class_w_put(struct snd_kcontrol *kcontrol, WM8993_CP_DYN_V); } wm8993->class_w_users--; - wm8993->hubs_data.class_w = false; } dev_dbg(codec->dev, "Indirect DAC use count now %d\n", diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index c8c714a..f6d2b4b 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1122,13 +1122,11 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec) WM8994_CP_DYN_PWR | WM8994_CP_DYN_SRC_SEL_MASK, source | WM8994_CP_DYN_PWR); - wm8994->hubs.class_w = true; - + } else { dev_dbg(codec->dev, "Class W disabled\n"); snd_soc_update_bits(codec, WM8994_CLASS_W_1, WM8994_CP_DYN_PWR, 0); - wm8994->hubs.class_w = false; } } @@ -3929,7 +3927,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm8994->hubs.dcs_readback_mode = 2; wm8994->hubs.no_series_update = 1; wm8994->hubs.hp_startup_mode = 1; - wm8994->hubs.no_cache_class_w = true; + wm8994->hubs.no_cache_dac_hp_direct = true; wm8994->fll_byp = true; switch (wm8994->revision) { diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 5c65093..c06b5b5 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -110,6 +110,42 @@ irqreturn_t wm_hubs_dcs_done(int irq, void *data) } EXPORT_SYMBOL_GPL(wm_hubs_dcs_done); +static bool wm_hubs_dac_hp_direct(struct snd_soc_codec *codec) +{ + int reg; + + /* If we're going via the mixer we'll need to do additional checks */ + reg = snd_soc_read(codec, WM8993_OUTPUT_MIXER1); + if (!(reg & WM8993_DACL_TO_HPOUT1L)) { + if (reg & ~WM8993_DACL_TO_MIXOUTL) { + dev_vdbg(codec->dev, "Analogue paths connected: %x\n", + reg & ~WM8993_DACL_TO_HPOUT1L); + return false; + } else { + dev_vdbg(codec->dev, "HPL connected to mixer\n"); + return false; + } + } else { + dev_vdbg(codec->dev, "HPL connected to DAC\n"); + } + + reg = snd_soc_read(codec, WM8993_OUTPUT_MIXER2); + if (!(reg & WM8993_DACR_TO_HPOUT1R)) { + if (reg & ~WM8993_DACR_TO_MIXOUTR) { + dev_vdbg(codec->dev, "Analogue paths connected: %x\n", + reg & ~WM8993_DACR_TO_HPOUT1R); + return false; + } else { + dev_vdbg(codec->dev, "HPR connected to mixer\n"); + return false; + } + } else { + dev_vdbg(codec->dev, "HPR connected to DAC\n"); + } + + return true; +} + /* * Startup calibration of the DC servo */ @@ -130,10 +166,10 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) /* If we're using a digital only path and have a previously * callibrated DC servo offset stored then use that. */ - if (hubs->class_w && hubs->class_w_dcs) { + if (wm_hubs_dac_hp_direct(codec) && hubs->dac_hp_direct_dcs) { dev_dbg(codec->dev, "Using cached DC servo offset %x\n", - hubs->class_w_dcs); - snd_soc_write(codec, dcs_reg, hubs->class_w_dcs); + hubs->dac_hp_direct_dcs); + snd_soc_write(codec, dcs_reg, hubs->dac_hp_direct_dcs); wait_for_dc_servo(codec, WM8993_DCS_TRIG_DAC_WR_0 | WM8993_DCS_TRIG_DAC_WR_1); @@ -208,8 +244,8 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) /* Save the callibrated offset if we're in class W mode and * therefore don't have any analogue signal mixed in. */ - if (hubs->class_w && !hubs->no_cache_class_w) - hubs->class_w_dcs = dcs_cfg; + if (wm_hubs_dac_hp_direct(codec) && !hubs->no_cache_dac_hp_direct) + hubs->dac_hp_direct_dcs = dcs_cfg; } /* @@ -225,7 +261,7 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); /* Updating the analogue gains invalidates the DC servo cache */ - hubs->class_w_dcs = 0; + hubs->dac_hp_direct_dcs = 0; /* If we're applying an offset correction then updating the * callibration would be likely to introduce further offsets. */ diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h index 5705276..8bb9f1b 100644 --- a/sound/soc/codecs/wm_hubs.h +++ b/sound/soc/codecs/wm_hubs.h @@ -30,9 +30,8 @@ struct wm_hubs_data { int series_startup; int no_series_update; - bool no_cache_class_w; - bool class_w; - u16 class_w_dcs; + bool no_cache_dac_hp_direct; + u16 dac_hp_direct_dcs; bool lineout1_se; bool lineout1n_ena; |