Skip to content

Commit

Permalink
ASoC: wm8994: Allow a delay between jack insertion and microphone detect
Browse files Browse the repository at this point in the history
This can be used to provide some additional settling time to ensure that
we don't start microphone detection while the microphone pin is connected
to one of the headphone pins.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Mark Brown committed Oct 15, 2012
1 parent ddffeb8 commit c0cc3f1
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 19 deletions.
5 changes: 5 additions & 0 deletions include/linux/mfd/wm8994/pdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ struct wm8994_pdata {
unsigned int lineout1fb:1;
unsigned int lineout2fb:1;

/* Delay between detecting a jack and starting microphone
* detect (specified in ms)
*/
int micdet_delay;

/* IRQ for microphone detection if brought out directly as a
* signal.
*/
Expand Down
74 changes: 55 additions & 19 deletions sound/soc/codecs/wm8994.c
Original file line number Diff line number Diff line change
Expand Up @@ -3470,11 +3470,46 @@ static void wm8958_default_micdet(u16 status, void *data)
}
}

/* Deferred mic detection to allow for extra settling time */
static void wm1811_mic_work(struct work_struct *work)
{
struct wm8994_priv *wm8994 = container_of(work, struct wm8994_priv,
mic_work.work);
struct snd_soc_codec *codec = wm8994->hubs.codec;

pm_runtime_get_sync(codec->dev);

/* If required for an external cap force MICBIAS on */
if (wm8994->pdata->jd_ext_cap) {
snd_soc_dapm_force_enable_pin(&codec->dapm,
"MICBIAS2");
snd_soc_dapm_sync(&codec->dapm);
}

mutex_lock(&wm8994->accdet_lock);

dev_dbg(codec->dev, "Starting mic detection\n");

/*
* Start off measument of microphone impedence to find out
* what's actually there.
*/
wm8994->mic_detecting = true;
wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);

snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
WM8958_MICD_ENA, WM8958_MICD_ENA);

mutex_unlock(&wm8994->accdet_lock);

pm_runtime_put(codec->dev);
}

static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
{
struct wm8994_priv *wm8994 = data;
struct snd_soc_codec *codec = wm8994->hubs.codec;
int reg;
int reg, delay;
bool present;

pm_runtime_get_sync(codec->dev);
Expand Down Expand Up @@ -3505,18 +3540,14 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
WM1811_JACKDET_DB, 0);

/*
* Start off measument of microphone impedence to find
* out what's actually there.
*/
wm8994->mic_detecting = true;
wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);

snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
WM8958_MICD_ENA, WM8958_MICD_ENA);
delay = wm8994->pdata->micdet_delay;
schedule_delayed_work(&wm8994->mic_work,
msecs_to_jiffies(delay));
} else {
dev_dbg(codec->dev, "Jack not detected\n");

cancel_delayed_work_sync(&wm8994->mic_work);

snd_soc_update_bits(codec, WM8958_MICBIAS2,
WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);

Expand All @@ -3533,14 +3564,9 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)

mutex_unlock(&wm8994->accdet_lock);

/* If required for an external cap force MICBIAS on */
if (wm8994->pdata->jd_ext_cap) {
if (present)
snd_soc_dapm_force_enable_pin(&codec->dapm,
"MICBIAS2");
else
snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
}
/* Turn off MICBIAS if it was on for an external cap */
if (wm8994->pdata->jd_ext_cap && !present)
snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");

if (present)
snd_soc_jack_report(wm8994->micdet[0].jack,
Expand Down Expand Up @@ -3763,10 +3789,20 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);

mutex_init(&wm8994->accdet_lock);
INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap,
wm1811_jackdet_bootstrap);

switch (control->type) {
case WM8994:
INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
break;
case WM1811:
INIT_DELAYED_WORK(&wm8994->mic_work, wm1811_mic_work);
break;
default:
break;
}

for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
init_completion(&wm8994->fll_locked[i]);

Expand Down

0 comments on commit c0cc3f1

Please sign in to comment.