ASoC: Support WM8958 direct microphone detection IRQ

Allow direct routing of the WM8958 microphone detection signal to a GPIO
to be used, saving the need to demux the interrupt.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
This commit is contained in:
Mark Brown 2011-02-17 20:05:44 -08:00
Родитель 7d700ac8d9
Коммит 9b7c525dfa
2 изменённых файлов: 40 добавлений и 22 удалений

Просмотреть файл

@ -103,6 +103,11 @@ struct wm8994_pdata {
unsigned int lineout1fb:1; unsigned int lineout1fb:1;
unsigned int lineout2fb:1; unsigned int lineout2fb:1;
/* IRQ for microphone detection if brought out directly as a
* signal.
*/
int micdet_irq;
/* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */ /* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */
unsigned int micbias1_lvl:1; unsigned int micbias1_lvl:1;
unsigned int micbias2_lvl:1; unsigned int micbias2_lvl:1;

Просмотреть файл

@ -104,6 +104,7 @@ struct wm8994_priv {
void *jack_cb_data; void *jack_cb_data;
bool jack_is_mic; bool jack_is_mic;
bool jack_is_video; bool jack_is_video;
int micdet_irq;
int revision; int revision;
struct wm8994_pdata *pdata; struct wm8994_pdata *pdata;
@ -3102,6 +3103,12 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
wm8994->pdata = dev_get_platdata(codec->dev->parent); wm8994->pdata = dev_get_platdata(codec->dev->parent);
wm8994->codec = codec; wm8994->codec = codec;
if (wm8994->pdata && wm8994->pdata->micdet_irq)
wm8994->micdet_irq = wm8994->pdata->micdet_irq;
else if (wm8994->pdata && wm8994->pdata->irq_base)
wm8994->micdet_irq = wm8994->pdata->irq_base +
WM8994_IRQ_MIC1_DET;
pm_runtime_enable(codec->dev); pm_runtime_enable(codec->dev);
pm_runtime_resume(codec->dev); pm_runtime_resume(codec->dev);
@ -3150,14 +3157,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
switch (control->type) { switch (control->type) {
case WM8994: case WM8994:
ret = wm8994_request_irq(codec->control_data, if (wm8994->micdet_irq) {
WM8994_IRQ_MIC1_DET, ret = request_threaded_irq(wm8994->micdet_irq, NULL,
wm8994_mic_irq, "Mic 1 detect", wm8994_mic_irq,
wm8994); IRQF_TRIGGER_RISING,
if (ret != 0) "Mic1 detect",
dev_warn(codec->dev, wm8994);
"Failed to request Mic1 detect IRQ: %d\n", if (ret != 0)
ret); dev_warn(codec->dev,
"Failed to request Mic1 detect IRQ: %d\n",
ret);
}
ret = wm8994_request_irq(codec->control_data, ret = wm8994_request_irq(codec->control_data,
WM8994_IRQ_MIC1_SHRT, WM8994_IRQ_MIC1_SHRT,
@ -3188,15 +3198,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
break; break;
case WM8958: case WM8958:
ret = wm8994_request_irq(codec->control_data, if (wm8994->micdet_irq) {
WM8994_IRQ_MIC1_DET, ret = request_threaded_irq(wm8994->micdet_irq, NULL,
wm8958_mic_irq, "Mic detect", wm8958_mic_irq,
wm8994); IRQF_TRIGGER_RISING,
if (ret != 0) "Mic detect",
dev_warn(codec->dev, wm8994);
"Failed to request Mic detect IRQ: %d\n", if (ret != 0)
ret); dev_warn(codec->dev,
break; "Failed to request Mic detect IRQ: %d\n",
ret);
}
} }
/* Remember if AIFnLRCLK is configured as a GPIO. This should be /* Remember if AIFnLRCLK is configured as a GPIO. This should be
@ -3328,7 +3340,8 @@ err_irq:
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); if (wm8994->micdet_irq)
free_irq(wm8994->micdet_irq, wm8994);
err: err:
kfree(wm8994); kfree(wm8994);
return ret; return ret;
@ -3345,8 +3358,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
switch (control->type) { switch (control->type) {
case WM8994: case WM8994:
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, if (wm8994->micdet_irq)
wm8994); free_irq(wm8994->micdet_irq, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
wm8994); wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
@ -3356,8 +3369,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
break; break;
case WM8958: case WM8958:
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, if (wm8994->micdet_irq)
wm8994); free_irq(wm8994->micdet_irq, wm8994);
break; break;
} }
kfree(wm8994->retune_mobile_texts); kfree(wm8994->retune_mobile_texts);