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

Commit d7b35570 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: wm8996: Handle failures to determine accessory polarity



If we get an indeterminate impedance with both headset polarities then
give up and report the accessory as a headphone rather than continually
retrying.

Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 62c1c401
Loading
Loading
Loading
Loading
+26 −12
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ struct wm8996_priv {
	struct snd_soc_jack *jack;
	bool detecting;
	bool jack_mic;
	int jack_flips;
	wm8996_polarity_fn polarity_cb;

#ifdef CONFIG_GPIOLIB
@@ -2437,6 +2438,7 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
	wm8996->jack = jack;
	wm8996->detecting = true;
	wm8996->polarity_cb = polarity_cb;
	wm8996->jack_flips = 0;

	if (wm8996->polarity_cb)
		wm8996->polarity_cb(codec, 0);
@@ -2552,6 +2554,19 @@ static void wm8996_hpdet_start(struct snd_soc_codec *codec)
			    WM8996_HP_POLL, WM8996_HP_POLL);
}

static void wm8996_report_headphone(struct snd_soc_codec *codec)
{
	dev_dbg(codec->dev, "Headphone detected\n");
	wm8996_hpdet_start(codec);

	/* Increase the detection rate a bit for responsiveness. */
	snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
			    WM8996_MICD_RATE_MASK |
			    WM8996_MICD_BIAS_STARTTIME_MASK,
			    7 << WM8996_MICD_RATE_SHIFT |
			    7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
}

static void wm8996_micd(struct snd_soc_codec *codec)
{
	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
@@ -2571,6 +2586,7 @@ static void wm8996_micd(struct snd_soc_codec *codec)
		dev_dbg(codec->dev, "Jack removal detected\n");
		wm8996->jack_mic = false;
		wm8996->detecting = true;
		wm8996->jack_flips = 0;
		snd_soc_jack_report(wm8996->jack, 0,
				    SND_JACK_LINEOUT | SND_JACK_HEADSET |
				    SND_JACK_BTN_0);
@@ -2611,9 +2627,17 @@ static void wm8996_micd(struct snd_soc_codec *codec)
	/* If we detected a lower impedence during initial startup
	 * then we probably have the wrong polarity, flip it.  Don't
	 * do this for the lowest impedences to speed up detection of
	 * plain headphones.
	 * plain headphones.  If both polarities report a low
	 * impedence then give up and report headphones.
	 */
	if (wm8996->detecting && (val & 0x3f0)) {
		wm8996->jack_flips++;

		if (wm8996->jack_flips > 1) {
			wm8996_report_headphone(codec);
			return;
		}

		reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2);
		reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC |
			WM8996_MICD_BIAS_SRC;
@@ -2640,17 +2664,7 @@ static void wm8996_micd(struct snd_soc_codec *codec)
			snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0,
					    SND_JACK_BTN_0);
		} else if (wm8996->detecting) {
			dev_dbg(codec->dev, "Headphone detected\n");
			wm8996_hpdet_start(codec);

			/* Increase the detection rate a bit for
			 * responsiveness.
			 */
			snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
					    WM8996_MICD_RATE_MASK |
					    WM8996_MICD_BIAS_STARTTIME_MASK,
					    7 << WM8996_MICD_RATE_SHIFT |
					    7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
			wm8996_report_headphone(codec);
		}
	}
}