Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b7c525d authored by Mark Brown's avatar Mark Brown
Browse files

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: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: default avatarLiam Girdwood <lrg@slimlogic.co.uk>
parent 7d700ac8
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -103,6 +103,11 @@ struct wm8994_pdata {
        unsigned int lineout1fb: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 */
        unsigned int micbias1_lvl:1;
        unsigned int micbias2_lvl:1;
+35 −22
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ struct wm8994_priv {
	void *jack_cb_data;
	bool jack_is_mic;
	bool jack_is_video;
	int micdet_irq;

	int revision;
	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->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_resume(codec->dev);

@@ -3150,14 +3157,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)

	switch (control->type) {
	case WM8994:
		ret = wm8994_request_irq(codec->control_data,
					 WM8994_IRQ_MIC1_DET,
					 wm8994_mic_irq, "Mic 1 detect",
		if (wm8994->micdet_irq) {
			ret = request_threaded_irq(wm8994->micdet_irq, NULL,
						   wm8994_mic_irq,
						   IRQF_TRIGGER_RISING,
						   "Mic1 detect",
						   wm8994);
			if (ret != 0)
				dev_warn(codec->dev,
					 "Failed to request Mic1 detect IRQ: %d\n",
					 ret);
		}

		ret = wm8994_request_irq(codec->control_data,
					 WM8994_IRQ_MIC1_SHRT,
@@ -3188,15 +3198,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
		break;

	case WM8958:
		ret = wm8994_request_irq(codec->control_data,
					 WM8994_IRQ_MIC1_DET,
					 wm8958_mic_irq, "Mic detect",
		if (wm8994->micdet_irq) {
			ret = request_threaded_irq(wm8994->micdet_irq, NULL,
						   wm8958_mic_irq,
						   IRQF_TRIGGER_RISING,
						   "Mic detect",
						   wm8994);
			if (ret != 0)
				dev_warn(codec->dev,
					 "Failed to request Mic detect IRQ: %d\n",
					 ret);
		break;
		}
	}

	/* Remember if AIFnLRCLK is configured as a GPIO.  This should be
@@ -3328,7 +3340,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
	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_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:
	kfree(wm8994);
	return ret;
@@ -3345,8 +3358,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)

	switch (control->type) {
	case WM8994:
		wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
				wm8994);
		if (wm8994->micdet_irq)
			free_irq(wm8994->micdet_irq, wm8994);
		wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
				wm8994);
		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;

	case WM8958:
		wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
				wm8994);
		if (wm8994->micdet_irq)
			free_irq(wm8994->micdet_irq, wm8994);
		break;
	}
	kfree(wm8994->retune_mobile_texts);