ASoC: Initial WM8958 audio configuration

The WM8958 is a WM8994 derivative. This patch merely ensures that some
revision specific configuration for WM8994 is not enabled on WM8994,
additional patches will add support for the new features introduced on
the WM8958.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
This commit is contained in:
Mark Brown 2010-11-26 15:21:06 +00:00
parent 11cef5f07b
commit 3a42315740
1 changed files with 73 additions and 31 deletions

View File

@ -1535,6 +1535,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
static int wm8994_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
struct wm8994 *control = codec->control_data;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
switch (level) {
@ -1551,7 +1552,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Tweak DC servo and DSP configuration for
* improved performance. */
if (wm8994->revision < 4) {
if (control->type == WM8994 && wm8994->revision < 4) {
/* Tweak DC servo and DSP configuration for
* improved performance. */
snd_soc_write(codec, 0x102, 0x3);
@ -2264,8 +2265,12 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_micdet *micdet;
struct wm8994 *control = codec->control_data;
int reg;
if (control->type != WM8994)
return -EINVAL;
switch (micbias) {
case 1:
micdet = &wm8994->micdet[0];
@ -2334,11 +2339,13 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
static int wm8994_codec_probe(struct snd_soc_codec *codec)
{
struct wm8994 *control;
struct wm8994_priv *wm8994;
struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret, i;
codec->control_data = dev_get_drvdata(codec->dev->parent);
control = codec->control_data;
wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
if (wm8994 == NULL)
@ -2369,6 +2376,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
/* Set revision-specific configuration */
wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
switch (control->type) {
case WM8994:
switch (wm8994->revision) {
case 2:
case 3:
@ -2381,29 +2390,53 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
break;
}
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
wm8994_mic_irq, "Mic 1 detect", wm8994);
if (ret != 0)
dev_warn(codec->dev,
"Failed to request Mic1 detect IRQ: %d\n", ret);
case WM8958:
wm8994->hubs.dcs_readback_mode = 1;
break;
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
wm8994_mic_irq, "Mic 1 short", wm8994);
if (ret != 0)
dev_warn(codec->dev,
"Failed to request Mic1 short IRQ: %d\n", ret);
default:
break;
}
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
wm8994_mic_irq, "Mic 2 detect", wm8994);
switch (control->type) {
case WM8994:
ret = wm8994_request_irq(codec->control_data,
WM8994_IRQ_MIC1_DET,
wm8994_mic_irq, "Mic 1 detect",
wm8994);
if (ret != 0)
dev_warn(codec->dev,
"Failed to request Mic2 detect IRQ: %d\n", ret);
"Failed to request Mic1 detect IRQ: %d\n",
ret);
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
wm8994_mic_irq, "Mic 2 short", wm8994);
ret = wm8994_request_irq(codec->control_data,
WM8994_IRQ_MIC1_SHRT,
wm8994_mic_irq, "Mic 1 short",
wm8994);
if (ret != 0)
dev_warn(codec->dev,
"Failed to request Mic2 short IRQ: %d\n", ret);
"Failed to request Mic1 short IRQ: %d\n",
ret);
ret = wm8994_request_irq(codec->control_data,
WM8994_IRQ_MIC2_DET,
wm8994_mic_irq, "Mic 2 detect",
wm8994);
if (ret != 0)
dev_warn(codec->dev,
"Failed to request Mic2 detect IRQ: %d\n",
ret);
ret = wm8994_request_irq(codec->control_data,
WM8994_IRQ_MIC2_SHRT,
wm8994_mic_irq, "Mic 2 short",
wm8994);
if (ret != 0)
dev_warn(codec->dev,
"Failed to request Mic2 short IRQ: %d\n",
ret);
break;
}
/* Remember if AIFnLRCLK is configured as a GPIO. This should be
* configured on init - if a system wants to do this dynamically
@ -2496,13 +2529,22 @@ err:
static int wm8994_codec_remove(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994 *control = codec->control_data;
wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
switch (control->type) {
case WM8994:
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
wm8994);
break;
}
kfree(wm8994->retune_mobile_texts);
kfree(wm8994->drc_texts);
kfree(wm8994);