Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

SoC: rockchip: rockchip_max98090: Enable MICBIAS for headset keypress detection

The TS3A227E says that the headset keypress detection needs the MICBIAS
power in order to report the key events to ensure proper operation
The headset keypress detection needs the MICBIAS power in order to report
the key events all the time as long as MIC is present. So MICBIAS pin
is forced on when a MICROPHONE is detected.

On Veyron Minnie I observed that if the MICBIAS power is not present and
the key press detection is activated (just because it is enabled when you
insert a headset), it randomly reports a keypress on insert.
E.g. (KEY_PLAYPAUSE)

Event: (SW_HEADPHONE_INSERT), value 1
Event: (SW_MICROPHONE_INSERT), value 1
Event: -------------- SYN_REPORT ------------
Event: (KEY_PLAYPAUSE), value 1

Userspace thinks that KEY_PLAYPAUSE is pressed and produces the annoying
effect that the media player starts a play/pause loop.

Note that, although most of the time the key reported is the one
associated with BTN_0, not always this is true. On my tests I also saw
different keys reported

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Link: https://lore.kernel.org/r/20190719173929.24065-1-enric.balletbo@collabora.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Enric Balletbo i Serra and committed by
Mark Brown
f86621cd 48dfd37a

+32
+32
sound/soc/rockchip/rockchip_max98090.c
··· 61 61 SOC_DAPM_PIN_SWITCH("Speaker"), 62 62 }; 63 63 64 + static int rk_jack_event(struct notifier_block *nb, unsigned long event, 65 + void *data) 66 + { 67 + struct snd_soc_jack *jack = (struct snd_soc_jack *)data; 68 + struct snd_soc_dapm_context *dapm = &jack->card->dapm; 69 + 70 + if (event & SND_JACK_MICROPHONE) 71 + snd_soc_dapm_force_enable_pin(dapm, "MICBIAS"); 72 + else 73 + snd_soc_dapm_disable_pin(dapm, "MICBIAS"); 74 + 75 + snd_soc_dapm_sync(dapm); 76 + 77 + return 0; 78 + } 79 + 80 + static struct notifier_block rk_jack_nb = { 81 + .notifier_call = rk_jack_event, 82 + }; 83 + 84 + static int rk_init(struct snd_soc_pcm_runtime *runtime) 85 + { 86 + /* 87 + * The jack has already been created in the rk_98090_headset_init() 88 + * function. 89 + */ 90 + snd_soc_jack_notifier_register(&headset_jack, &rk_jack_nb); 91 + 92 + return 0; 93 + } 94 + 64 95 static int rk_aif1_hw_params(struct snd_pcm_substream *substream, 65 96 struct snd_pcm_hw_params *params) 66 97 { ··· 150 119 static struct snd_soc_dai_link rk_dailink = { 151 120 .name = "max98090", 152 121 .stream_name = "Audio", 122 + .init = rk_init, 153 123 .ops = &rk_aif1_ops, 154 124 /* set max98090 as slave */ 155 125 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |