diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-08-19 18:05:05 +0900 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-11-04 23:24:59 +0000 |
commit | 19940b3d55c87d8089a8cb0fa8e5a9918a3846bd (patch) | |
tree | cae1abaac5efabe83003f4352d068bd7034ae6ae /sound/soc | |
parent | 5a3ad6bd6ae0687cb0ecb424d74221920fbc7f38 (diff) | |
download | linux-19940b3d55c87d8089a8cb0fa8e5a9918a3846bd.tar.gz linux-19940b3d55c87d8089a8cb0fa8e5a9918a3846bd.tar.bz2 linux-19940b3d55c87d8089a8cb0fa8e5a9918a3846bd.zip |
ASoC: Ensure we get an impedence reported for WM8958 jack detect
Occasionally we may see an accessory reported before we have a stable
impedance for the accessory. If this happens then reread the status in
order to ensure that the handler can take the appropriate action for the
status change.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/codecs/wm8994.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 9cb16cc853b3..9c982e47eb99 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3030,19 +3030,34 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) { struct wm8994_priv *wm8994 = data; struct snd_soc_codec *codec = wm8994->codec; - int reg; + int reg, count; - reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); - if (reg < 0) { - dev_err(codec->dev, "Failed to read mic detect status: %d\n", - reg); - return IRQ_NONE; - } + /* We may occasionally read a detection without an impedence + * range being provided - if that happens loop again. + */ + count = 10; + do { + reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); + if (reg < 0) { + dev_err(codec->dev, + "Failed to read mic detect status: %d\n", + reg); + return IRQ_NONE; + } - if (!(reg & WM8958_MICD_VALID)) { - dev_dbg(codec->dev, "Mic detect data not valid\n"); - goto out; - } + if (!(reg & WM8958_MICD_VALID)) { + dev_dbg(codec->dev, "Mic detect data not valid\n"); + goto out; + } + + if (!(reg & WM8958_MICD_STS) || (reg & WM8958_MICD_LVL_MASK)) + break; + + msleep(1); + } while (count--); + + if (count == 0) + dev_warn(codec->dev, "No impedence range reported for jack\n"); #ifndef CONFIG_SND_SOC_WM8994_MODULE trace_snd_soc_jack_irq(dev_name(codec->dev)); |