diff options
-rw-r--r-- | sound/soc/codecs/wm8996.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 8e8f8d1fef91..cde11ca9d9e4 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -90,6 +90,7 @@ struct wm8996_priv { | |||
90 | struct snd_soc_jack *jack; | 90 | struct snd_soc_jack *jack; |
91 | bool detecting; | 91 | bool detecting; |
92 | bool jack_mic; | 92 | bool jack_mic; |
93 | int jack_flips; | ||
93 | wm8996_polarity_fn polarity_cb; | 94 | wm8996_polarity_fn polarity_cb; |
94 | 95 | ||
95 | #ifdef CONFIG_GPIOLIB | 96 | #ifdef CONFIG_GPIOLIB |
@@ -2437,6 +2438,7 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
2437 | wm8996->jack = jack; | 2438 | wm8996->jack = jack; |
2438 | wm8996->detecting = true; | 2439 | wm8996->detecting = true; |
2439 | wm8996->polarity_cb = polarity_cb; | 2440 | wm8996->polarity_cb = polarity_cb; |
2441 | wm8996->jack_flips = 0; | ||
2440 | 2442 | ||
2441 | if (wm8996->polarity_cb) | 2443 | if (wm8996->polarity_cb) |
2442 | wm8996->polarity_cb(codec, 0); | 2444 | wm8996->polarity_cb(codec, 0); |
@@ -2552,6 +2554,19 @@ static void wm8996_hpdet_start(struct snd_soc_codec *codec) | |||
2552 | WM8996_HP_POLL, WM8996_HP_POLL); | 2554 | WM8996_HP_POLL, WM8996_HP_POLL); |
2553 | } | 2555 | } |
2554 | 2556 | ||
2557 | static void wm8996_report_headphone(struct snd_soc_codec *codec) | ||
2558 | { | ||
2559 | dev_dbg(codec->dev, "Headphone detected\n"); | ||
2560 | wm8996_hpdet_start(codec); | ||
2561 | |||
2562 | /* Increase the detection rate a bit for responsiveness. */ | ||
2563 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, | ||
2564 | WM8996_MICD_RATE_MASK | | ||
2565 | WM8996_MICD_BIAS_STARTTIME_MASK, | ||
2566 | 7 << WM8996_MICD_RATE_SHIFT | | ||
2567 | 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT); | ||
2568 | } | ||
2569 | |||
2555 | static void wm8996_micd(struct snd_soc_codec *codec) | 2570 | static void wm8996_micd(struct snd_soc_codec *codec) |
2556 | { | 2571 | { |
2557 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | 2572 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); |
@@ -2571,6 +2586,7 @@ static void wm8996_micd(struct snd_soc_codec *codec) | |||
2571 | dev_dbg(codec->dev, "Jack removal detected\n"); | 2586 | dev_dbg(codec->dev, "Jack removal detected\n"); |
2572 | wm8996->jack_mic = false; | 2587 | wm8996->jack_mic = false; |
2573 | wm8996->detecting = true; | 2588 | wm8996->detecting = true; |
2589 | wm8996->jack_flips = 0; | ||
2574 | snd_soc_jack_report(wm8996->jack, 0, | 2590 | snd_soc_jack_report(wm8996->jack, 0, |
2575 | SND_JACK_LINEOUT | SND_JACK_HEADSET | | 2591 | SND_JACK_LINEOUT | SND_JACK_HEADSET | |
2576 | SND_JACK_BTN_0); | 2592 | SND_JACK_BTN_0); |
@@ -2611,9 +2627,17 @@ static void wm8996_micd(struct snd_soc_codec *codec) | |||
2611 | /* If we detected a lower impedence during initial startup | 2627 | /* If we detected a lower impedence during initial startup |
2612 | * then we probably have the wrong polarity, flip it. Don't | 2628 | * then we probably have the wrong polarity, flip it. Don't |
2613 | * do this for the lowest impedences to speed up detection of | 2629 | * do this for the lowest impedences to speed up detection of |
2614 | * plain headphones. | 2630 | * plain headphones. If both polarities report a low |
2631 | * impedence then give up and report headphones. | ||
2615 | */ | 2632 | */ |
2616 | if (wm8996->detecting && (val & 0x3f0)) { | 2633 | if (wm8996->detecting && (val & 0x3f0)) { |
2634 | wm8996->jack_flips++; | ||
2635 | |||
2636 | if (wm8996->jack_flips > 1) { | ||
2637 | wm8996_report_headphone(codec); | ||
2638 | return; | ||
2639 | } | ||
2640 | |||
2617 | reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2); | 2641 | reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2); |
2618 | reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC | | 2642 | reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC | |
2619 | WM8996_MICD_BIAS_SRC; | 2643 | WM8996_MICD_BIAS_SRC; |
@@ -2640,17 +2664,7 @@ static void wm8996_micd(struct snd_soc_codec *codec) | |||
2640 | snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0, | 2664 | snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0, |
2641 | SND_JACK_BTN_0); | 2665 | SND_JACK_BTN_0); |
2642 | } else if (wm8996->detecting) { | 2666 | } else if (wm8996->detecting) { |
2643 | dev_dbg(codec->dev, "Headphone detected\n"); | 2667 | wm8996_report_headphone(codec); |
2644 | wm8996_hpdet_start(codec); | ||
2645 | |||
2646 | /* Increase the detection rate a bit for | ||
2647 | * responsiveness. | ||
2648 | */ | ||
2649 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, | ||
2650 | WM8996_MICD_RATE_MASK | | ||
2651 | WM8996_MICD_BIAS_STARTTIME_MASK, | ||
2652 | 7 << WM8996_MICD_RATE_SHIFT | | ||
2653 | 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT); | ||
2654 | } | 2668 | } |
2655 | } | 2669 | } |
2656 | } | 2670 | } |