Skip to content

Commit

Permalink
ASoC: wm8994: Bring WM8994 accessory detection up to date
Browse files Browse the repository at this point in the history
Make the mechanism used for WM8994 more like that for WM1811 and WM8958:
provide the logic to distinguish between headphone and headset and hard
code the reporting of sensible SND_JACK values. Should integration with
other detection mechanisms be required we can add appropriate callbacks
(though some integrations should be able to use the subsystem ones).

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Mark Brown committed Feb 6, 2012
1 parent 27060b3 commit 87092e3
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 24 deletions.
82 changes: 61 additions & 21 deletions sound/soc/codecs/wm8994.c
Original file line number Diff line number Diff line change
Expand Up @@ -2946,8 +2946,6 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
* @codec: WM8994 codec
* @jack: jack to report detection events on
* @micbias: microphone bias to detect on
* @det: value to report for presence detection
* @shrt: value to report for short detection
*
* Enable microphone detection via IRQ on the WM8994. If GPIOs are
* being used to bring out signals to the processor then only platform
Expand All @@ -2958,43 +2956,63 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
* and micbias2_lvl platform data members.
*/
int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
int micbias, int det, int shrt)
int micbias)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_micdet *micdet;
struct wm8994 *control = wm8994->wm8994;
int reg;
int reg, ret;

if (control->type != WM8994)
if (control->type != WM8994) {
dev_warn(codec->dev, "Not a WM8994\n");
return -EINVAL;
}

switch (micbias) {
case 1:
micdet = &wm8994->micdet[0];
if (jack)
ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
"MICBIAS1");
else
ret = snd_soc_dapm_disable_pin(&codec->dapm,
"MICBIAS1");
break;
case 2:
micdet = &wm8994->micdet[1];
if (jack)
ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
"MICBIAS1");
else
ret = snd_soc_dapm_disable_pin(&codec->dapm,
"MICBIAS1");
break;
default:
dev_warn(codec->dev, "Invalid MICBIAS %d\n", micbias);
return -EINVAL;
}
}

dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n",
micbias, det, shrt);
if (ret != 0)
dev_warn(codec->dev, "Failed to configure MICBIAS%d: %d\n",
micbias, ret);

dev_dbg(codec->dev, "Configuring microphone detection on %d %p\n",
micbias, jack);

/* Store the configuration */
micdet->jack = jack;
micdet->det = det;
micdet->shrt = shrt;
micdet->detecting = true;

/* If either of the jacks is set up then enable detection */
if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
reg = WM8994_MICD_ENA;
else
else
reg = 0;

snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);

snd_soc_dapm_sync(&codec->dapm);

return 0;
}
EXPORT_SYMBOL_GPL(wm8994_mic_detect);
Expand All @@ -3020,20 +3038,42 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
dev_dbg(codec->dev, "Microphone status: %x\n", reg);

report = 0;
if (reg & WM8994_MIC1_DET_STS)
report |= priv->micdet[0].det;
if (reg & WM8994_MIC1_SHRT_STS)
report |= priv->micdet[0].shrt;
if (reg & WM8994_MIC1_DET_STS) {
if (priv->micdet[0].detecting)
report = SND_JACK_HEADSET;
}
if (reg & WM8994_MIC1_SHRT_STS) {
if (priv->micdet[0].detecting)
report = SND_JACK_HEADPHONE;
else
report |= SND_JACK_BTN_0;
}
if (report)
priv->micdet[0].detecting = false;
else
priv->micdet[0].detecting = true;

snd_soc_jack_report(priv->micdet[0].jack, report,
priv->micdet[0].det | priv->micdet[0].shrt);
SND_JACK_HEADSET | SND_JACK_BTN_0);

report = 0;
if (reg & WM8994_MIC2_DET_STS)
report |= priv->micdet[1].det;
if (reg & WM8994_MIC2_SHRT_STS)
report |= priv->micdet[1].shrt;
if (reg & WM8994_MIC2_DET_STS) {
if (priv->micdet[1].detecting)
report = SND_JACK_HEADSET;
}
if (reg & WM8994_MIC2_SHRT_STS) {
if (priv->micdet[1].detecting)
report = SND_JACK_HEADPHONE;
else
report |= SND_JACK_BTN_0;
}
if (report)
priv->micdet[1].detecting = false;
else
priv->micdet[1].detecting = true;

snd_soc_jack_report(priv->micdet[1].jack, report,
priv->micdet[1].det | priv->micdet[1].shrt);
SND_JACK_HEADSET | SND_JACK_BTN_0);

return IRQ_HANDLED;
}
Expand Down
5 changes: 2 additions & 3 deletions sound/soc/codecs/wm8994.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
typedef void (*wm8958_micdet_cb)(u16 status, void *data);

int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
int micbias, int det, int shrt);
int micbias);
int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
wm8958_micdet_cb cb, void *cb_data);

Expand All @@ -46,8 +46,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec);

struct wm8994_micdet {
struct snd_soc_jack *jack;
int det;
int shrt;
bool detecting;
};

/* codec private data */
Expand Down

0 comments on commit 87092e3

Please sign in to comment.