ASoC: wm8994: Use audio mode for jack detection when system is active

When we are out of system sleep always use audio mode for jack detection
in order to avoid potential performance issues handing off between modes.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
Mark Brown 2012-03-04 02:16:01 +00:00
Родитель 56cea3f1e7
Коммит 4752a88719
2 изменённых файлов: 49 добавлений и 29 удалений

Просмотреть файл

@ -685,8 +685,6 @@ SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0,
static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
u16 old = snd_soc_read(codec, WM8994_ANTIPOP_2)
& WM1811_JACKDET_MODE_MASK;
if (!wm8994->jackdet || !wm8994->jack_cb)
return;
@ -694,28 +692,17 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
if (wm8994->active_refcount)
mode = WM1811_JACKDET_MODE_AUDIO;
if (mode == old)
if (mode == wm8994->jackdet_mode)
return;
wm8994->jackdet_mode = mode;
/* Always use audio mode to detect while the system is active */
if (mode != WM1811_JACKDET_MODE_NONE)
mode = WM1811_JACKDET_MODE_AUDIO;
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
WM1811_JACKDET_MODE_MASK, mode);
switch (mode) {
case WM1811_JACKDET_MODE_MIC:
case WM1811_JACKDET_MODE_AUDIO:
switch (old) {
case WM1811_JACKDET_MODE_MIC:
case WM1811_JACKDET_MODE_AUDIO:
break;
default:
msleep(2);
break;
}
default:
break;
}
}
static void active_reference(struct snd_soc_codec *codec)
@ -2749,7 +2736,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
};
#ifdef CONFIG_PM
static int wm8994_suspend(struct snd_soc_codec *codec)
static int wm8994_codec_suspend(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994 *control = wm8994->wm8994;
@ -2783,7 +2770,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec)
return 0;
}
static int wm8994_resume(struct snd_soc_codec *codec)
static int wm8994_codec_resume(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994 *control = wm8994->wm8994;
@ -2842,8 +2829,8 @@ static int wm8994_resume(struct snd_soc_codec *codec)
return 0;
}
#else
#define wm8994_suspend NULL
#define wm8994_resume NULL
#define wm8994_codec_suspend NULL
#define wm8994_codec_resume NULL
#endif
static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
@ -3955,8 +3942,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
.probe = wm8994_codec_probe,
.remove = wm8994_codec_remove,
.suspend = wm8994_suspend,
.resume = wm8994_resume,
.suspend = wm8994_codec_suspend,
.resume = wm8994_codec_resume,
.set_bias_level = wm8994_set_bias_level,
};
@ -3983,11 +3970,43 @@ static int __devexit wm8994_remove(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int wm8994_suspend(struct device *dev)
{
struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
/* Drop down to power saving mode when system is suspended */
if (wm8994->jackdet && !wm8994->active_refcount)
regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
WM1811_JACKDET_MODE_MASK,
wm8994->jackdet_mode);
return 0;
}
static int wm8994_resume(struct device *dev)
{
struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
if (wm8994->jackdet && wm8994->jack_cb)
regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
WM1811_JACKDET_MODE_MASK,
WM1811_JACKDET_MODE_AUDIO);
return 0;
}
#endif
static const struct dev_pm_ops wm8994_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(wm8994_suspend, wm8994_resume)
};
static struct platform_driver wm8994_codec_driver = {
.driver = {
.name = "wm8994-codec",
.owner = THIS_MODULE,
},
.name = "wm8994-codec",
.owner = THIS_MODULE,
.pm = &wm8994_pm_ops,
},
.probe = wm8994_probe,
.remove = __devexit_p(wm8994_remove),
};

Просмотреть файл

@ -122,6 +122,7 @@ struct wm8994_priv {
bool jack_mic;
int btn_mask;
bool jackdet;
int jackdet_mode;
wm8958_micdet_cb jack_cb;
void *jack_cb_data;