mirror of https://gitee.com/openkylin/linux.git
ASoC: wm8994: Simplify button detection code
Currently the WM8994 driver allows the WM8958 microphone detection code to be replaced in its entirety, providing a default implementation. This doesn't actually reflect the needs of users well. They generally wish to replace only the accessory identification parts of the algorithm (eg, using an external GPIO to provide the equivalent of the JACKDET support in the WM1811A). In preparation for supporting these users better refactor the existing code so that we have separate identification and button detection callbacks, selecting between them rather than using the mic_detecting flag in the existing callback. This also simplifies the code by introducing a more explicit state machine for the detecting and button states. In anticipation of future refactoring the callback is left in the signature for wm8958_mic_detect(), it will be removed at a later stage. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
parent
f02b0de0f0
commit
78b76dbec8
|
@ -91,8 +91,6 @@ static int wm8994_retune_mobile_base[] = {
|
|||
WM8994_AIF2_EQ_GAINS_1,
|
||||
};
|
||||
|
||||
static void wm8958_default_micdet(u16 status, void *data);
|
||||
|
||||
static const struct wm8958_micd_rate micdet_rates[] = {
|
||||
{ 32768, true, 1, 4 },
|
||||
{ 32768, false, 1, 1 },
|
||||
|
@ -116,9 +114,6 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
|
|||
const struct wm8958_micd_rate *rates;
|
||||
int num_rates;
|
||||
|
||||
if (wm8994->jack_cb != wm8958_default_micdet)
|
||||
return;
|
||||
|
||||
idle = !wm8994->jack_mic;
|
||||
|
||||
sysclk = snd_soc_read(codec, WM8994_CLOCKING_1);
|
||||
|
@ -740,7 +735,7 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
|
|||
{
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (!wm8994->jackdet || !wm8994->jack_cb)
|
||||
if (!wm8994->jackdet || !wm8994->micdet[0].jack)
|
||||
return;
|
||||
|
||||
if (wm8994->active_refcount)
|
||||
|
@ -3409,16 +3404,37 @@ static void wm1811_micd_stop(struct snd_soc_codec *codec)
|
|||
"MICBIAS2");
|
||||
}
|
||||
|
||||
/* Default microphone detection handler for WM8958 - the user can
|
||||
* override this if they wish.
|
||||
*/
|
||||
static void wm8958_default_micdet(u16 status, void *data)
|
||||
static void wm8958_button_det(struct snd_soc_codec *codec, u16 status)
|
||||
{
|
||||
struct snd_soc_codec *codec = data;
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
int report;
|
||||
|
||||
dev_dbg(codec->dev, "MICDET %x\n", status);
|
||||
report = 0;
|
||||
if (status & 0x4)
|
||||
report |= SND_JACK_BTN_0;
|
||||
|
||||
if (status & 0x8)
|
||||
report |= SND_JACK_BTN_1;
|
||||
|
||||
if (status & 0x10)
|
||||
report |= SND_JACK_BTN_2;
|
||||
|
||||
if (status & 0x20)
|
||||
report |= SND_JACK_BTN_3;
|
||||
|
||||
if (status & 0x40)
|
||||
report |= SND_JACK_BTN_4;
|
||||
|
||||
if (status & 0x80)
|
||||
report |= SND_JACK_BTN_5;
|
||||
|
||||
snd_soc_jack_report(wm8994->micdet[0].jack, report,
|
||||
wm8994->btn_mask);
|
||||
}
|
||||
|
||||
static void wm8958_mic_id(struct snd_soc_codec *codec, u16 status)
|
||||
{
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
/* Either nothing present or just starting detection */
|
||||
if (!(status & WM8958_MICD_STS)) {
|
||||
|
@ -3440,7 +3456,7 @@ static void wm8958_default_micdet(u16 status, void *data)
|
|||
/* If the measurement is showing a high impedence we've got a
|
||||
* microphone.
|
||||
*/
|
||||
if (wm8994->mic_detecting && (status & 0x600)) {
|
||||
if (status & 0x600) {
|
||||
dev_dbg(codec->dev, "Detected microphone\n");
|
||||
|
||||
wm8994->mic_detecting = false;
|
||||
|
@ -3453,7 +3469,7 @@ static void wm8958_default_micdet(u16 status, void *data)
|
|||
}
|
||||
|
||||
|
||||
if (wm8994->mic_detecting && status & 0xfc) {
|
||||
if (status & 0xfc) {
|
||||
dev_dbg(codec->dev, "Detected headphone\n");
|
||||
wm8994->mic_detecting = false;
|
||||
|
||||
|
@ -3465,31 +3481,6 @@ static void wm8958_default_micdet(u16 status, void *data)
|
|||
snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
|
||||
SND_JACK_HEADSET);
|
||||
}
|
||||
|
||||
/* Report short circuit as a button */
|
||||
if (wm8994->jack_mic) {
|
||||
report = 0;
|
||||
if (status & 0x4)
|
||||
report |= SND_JACK_BTN_0;
|
||||
|
||||
if (status & 0x8)
|
||||
report |= SND_JACK_BTN_1;
|
||||
|
||||
if (status & 0x10)
|
||||
report |= SND_JACK_BTN_2;
|
||||
|
||||
if (status & 0x20)
|
||||
report |= SND_JACK_BTN_3;
|
||||
|
||||
if (status & 0x40)
|
||||
report |= SND_JACK_BTN_4;
|
||||
|
||||
if (status & 0x80)
|
||||
report |= SND_JACK_BTN_5;
|
||||
|
||||
snd_soc_jack_report(wm8994->micdet[0].jack, report,
|
||||
wm8994->btn_mask);
|
||||
}
|
||||
}
|
||||
|
||||
/* Deferred mic detection to allow for extra settling time */
|
||||
|
@ -3648,18 +3639,14 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
|
|||
}
|
||||
|
||||
if (jack) {
|
||||
if (!cb) {
|
||||
dev_dbg(codec->dev, "Using default micdet callback\n");
|
||||
cb = wm8958_default_micdet;
|
||||
cb_data = codec;
|
||||
}
|
||||
/* No longer supported */
|
||||
if (cb)
|
||||
return -EINVAL;
|
||||
|
||||
snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS");
|
||||
snd_soc_dapm_sync(&codec->dapm);
|
||||
|
||||
wm8994->micdet[0].jack = jack;
|
||||
wm8994->jack_cb = cb;
|
||||
wm8994->jack_cb_data = cb_data;
|
||||
|
||||
wm8994->mic_detecting = true;
|
||||
wm8994->jack_mic = false;
|
||||
|
@ -3762,10 +3749,10 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
|
|||
trace_snd_soc_jack_irq(dev_name(codec->dev));
|
||||
#endif
|
||||
|
||||
if (wm8994->jack_cb)
|
||||
wm8994->jack_cb(reg, wm8994->jack_cb_data);
|
||||
if (wm8994->mic_detecting)
|
||||
wm8958_mic_id(codec, reg);
|
||||
else
|
||||
dev_warn(codec->dev, "Accessory detection with no callback\n");
|
||||
wm8958_button_det(codec, reg);
|
||||
|
||||
out:
|
||||
pm_runtime_put(codec->dev);
|
||||
|
@ -4296,7 +4283,7 @@ static int wm8994_resume(struct device *dev)
|
|||
{
|
||||
struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
|
||||
|
||||
if (wm8994->jackdet && wm8994->jack_cb)
|
||||
if (wm8994->jackdet && wm8994->jackdet_mode)
|
||||
regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
|
||||
WM1811_JACKDET_MODE_MASK,
|
||||
WM1811_JACKDET_MODE_AUDIO);
|
||||
|
|
|
@ -137,8 +137,6 @@ struct wm8994_priv {
|
|||
int jackdet_mode;
|
||||
struct delayed_work jackdet_bootstrap;
|
||||
|
||||
wm8958_micdet_cb jack_cb;
|
||||
void *jack_cb_data;
|
||||
int micdet_irq;
|
||||
|
||||
int revision;
|
||||
|
|
Loading…
Reference in New Issue