dect
/
linux-2.6
Archived
13
0
Fork 0

ASoC: wm8994: Simplify button detection code

Currently the WM8994 driver allows the WM8958 microphone detection code to
be replaced in its entirety, providing a default implementation. This
doesn't actually reflect the needs of users well. They generally wish to
replace only the accessory identification parts of the algorithm (eg,
using an external GPIO to provide the equivalent of the JACKDET support in
the WM1811A).

In preparation for supporting these users better refactor the existing code
so that we have separate identification and button detection callbacks,
selecting between them rather than using the mic_detecting flag in the
existing callback. This also simplifies the code by introducing a more
explicit state machine for the detecting and button states.

In anticipation of future refactoring the callback is left in the signature
for wm8958_mic_detect(), it will be removed at a later stage.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
Mark Brown 2012-11-22 17:02:09 +09:00
parent f02b0de0f0
commit 78b76dbec8
2 changed files with 37 additions and 52 deletions

View File

@ -91,8 +91,6 @@ static int wm8994_retune_mobile_base[] = {
WM8994_AIF2_EQ_GAINS_1,
};
static void wm8958_default_micdet(u16 status, void *data);
static const struct wm8958_micd_rate micdet_rates[] = {
{ 32768, true, 1, 4 },
{ 32768, false, 1, 1 },
@ -116,9 +114,6 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
const struct wm8958_micd_rate *rates;
int num_rates;
if (wm8994->jack_cb != wm8958_default_micdet)
return;
idle = !wm8994->jack_mic;
sysclk = snd_soc_read(codec, WM8994_CLOCKING_1);
@ -740,7 +735,7 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
if (!wm8994->jackdet || !wm8994->jack_cb)
if (!wm8994->jackdet || !wm8994->micdet[0].jack)
return;
if (wm8994->active_refcount)
@ -3409,16 +3404,37 @@ static void wm1811_micd_stop(struct snd_soc_codec *codec)
"MICBIAS2");
}
/* Default microphone detection handler for WM8958 - the user can
* override this if they wish.
*/
static void wm8958_default_micdet(u16 status, void *data)
static void wm8958_button_det(struct snd_soc_codec *codec, u16 status)
{
struct snd_soc_codec *codec = data;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int report;
dev_dbg(codec->dev, "MICDET %x\n", status);
report = 0;
if (status & 0x4)
report |= SND_JACK_BTN_0;
if (status & 0x8)
report |= SND_JACK_BTN_1;
if (status & 0x10)
report |= SND_JACK_BTN_2;
if (status & 0x20)
report |= SND_JACK_BTN_3;
if (status & 0x40)
report |= SND_JACK_BTN_4;
if (status & 0x80)
report |= SND_JACK_BTN_5;
snd_soc_jack_report(wm8994->micdet[0].jack, report,
wm8994->btn_mask);
}
static void wm8958_mic_id(struct snd_soc_codec *codec, u16 status)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
/* Either nothing present or just starting detection */
if (!(status & WM8958_MICD_STS)) {
@ -3440,7 +3456,7 @@ static void wm8958_default_micdet(u16 status, void *data)
/* If the measurement is showing a high impedence we've got a
* microphone.
*/
if (wm8994->mic_detecting && (status & 0x600)) {
if (status & 0x600) {
dev_dbg(codec->dev, "Detected microphone\n");
wm8994->mic_detecting = false;
@ -3453,7 +3469,7 @@ static void wm8958_default_micdet(u16 status, void *data)
}
if (wm8994->mic_detecting && status & 0xfc) {
if (status & 0xfc) {
dev_dbg(codec->dev, "Detected headphone\n");
wm8994->mic_detecting = false;
@ -3465,31 +3481,6 @@ static void wm8958_default_micdet(u16 status, void *data)
snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
SND_JACK_HEADSET);
}
/* Report short circuit as a button */
if (wm8994->jack_mic) {
report = 0;
if (status & 0x4)
report |= SND_JACK_BTN_0;
if (status & 0x8)
report |= SND_JACK_BTN_1;
if (status & 0x10)
report |= SND_JACK_BTN_2;
if (status & 0x20)
report |= SND_JACK_BTN_3;
if (status & 0x40)
report |= SND_JACK_BTN_4;
if (status & 0x80)
report |= SND_JACK_BTN_5;
snd_soc_jack_report(wm8994->micdet[0].jack, report,
wm8994->btn_mask);
}
}
/* Deferred mic detection to allow for extra settling time */
@ -3648,18 +3639,14 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
}
if (jack) {
if (!cb) {
dev_dbg(codec->dev, "Using default micdet callback\n");
cb = wm8958_default_micdet;
cb_data = codec;
}
/* No longer supported */
if (cb)
return -EINVAL;
snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS");
snd_soc_dapm_sync(&codec->dapm);
wm8994->micdet[0].jack = jack;
wm8994->jack_cb = cb;
wm8994->jack_cb_data = cb_data;
wm8994->mic_detecting = true;
wm8994->jack_mic = false;
@ -3762,10 +3749,10 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
trace_snd_soc_jack_irq(dev_name(codec->dev));
#endif
if (wm8994->jack_cb)
wm8994->jack_cb(reg, wm8994->jack_cb_data);
if (wm8994->mic_detecting)
wm8958_mic_id(codec, reg);
else
dev_warn(codec->dev, "Accessory detection with no callback\n");
wm8958_button_det(codec, reg);
out:
pm_runtime_put(codec->dev);
@ -4296,7 +4283,7 @@ static int wm8994_resume(struct device *dev)
{
struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
if (wm8994->jackdet && wm8994->jack_cb)
if (wm8994->jackdet && wm8994->jackdet_mode)
regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
WM1811_JACKDET_MODE_MASK,
WM1811_JACKDET_MODE_AUDIO);

View File

@ -137,8 +137,6 @@ struct wm8994_priv {
int jackdet_mode;
struct delayed_work jackdet_bootstrap;
wm8958_micdet_cb jack_cb;
void *jack_cb_data;
int micdet_irq;
int revision;