Commit 3a423157 authored by Mark Brown's avatar Mark Brown

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: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: default avatarLiam Girdwood <lrg@slimlogic.co.uk>
parent 11cef5f0
...@@ -1535,6 +1535,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, ...@@ -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, static int wm8994_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level) enum snd_soc_bias_level level)
{ {
struct wm8994 *control = codec->control_data;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
switch (level) { switch (level) {
...@@ -1551,7 +1552,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, ...@@ -1551,7 +1552,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
/* Tweak DC servo and DSP configuration for /* Tweak DC servo and DSP configuration for
* improved performance. */ * improved performance. */
if (wm8994->revision < 4) { if (control->type == WM8994 && wm8994->revision < 4) {
/* Tweak DC servo and DSP configuration for /* Tweak DC servo and DSP configuration for
* improved performance. */ * improved performance. */
snd_soc_write(codec, 0x102, 0x3); snd_soc_write(codec, 0x102, 0x3);
...@@ -2264,8 +2265,12 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, ...@@ -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_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_micdet *micdet; struct wm8994_micdet *micdet;
struct wm8994 *control = codec->control_data;
int reg; int reg;
if (control->type != WM8994)
return -EINVAL;
switch (micbias) { switch (micbias) {
case 1: case 1:
micdet = &wm8994->micdet[0]; micdet = &wm8994->micdet[0];
...@@ -2334,11 +2339,13 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) ...@@ -2334,11 +2339,13 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
static int wm8994_codec_probe(struct snd_soc_codec *codec) static int wm8994_codec_probe(struct snd_soc_codec *codec)
{ {
struct wm8994 *control;
struct wm8994_priv *wm8994; struct wm8994_priv *wm8994;
struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret, i; int ret, i;
codec->control_data = dev_get_drvdata(codec->dev->parent); codec->control_data = dev_get_drvdata(codec->dev->parent);
control = codec->control_data;
wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL); wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
if (wm8994 == NULL) if (wm8994 == NULL)
...@@ -2369,41 +2376,67 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) ...@@ -2369,41 +2376,67 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
/* Set revision-specific configuration */ /* Set revision-specific configuration */
wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
switch (wm8994->revision) { switch (control->type) {
case 2: case WM8994:
case 3: switch (wm8994->revision) {
wm8994->hubs.dcs_codes = -5; case 2:
wm8994->hubs.hp_startup_mode = 1; case 3:
wm8994->hubs.dcs_codes = -5;
wm8994->hubs.hp_startup_mode = 1;
wm8994->hubs.dcs_readback_mode = 1;
break;
default:
wm8994->hubs.dcs_readback_mode = 1;
break;
}
case WM8958:
wm8994->hubs.dcs_readback_mode = 1; wm8994->hubs.dcs_readback_mode = 1;
break; break;
default: default:
wm8994->hubs.dcs_readback_mode = 1;
break; break;
} }
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET, switch (control->type) {
wm8994_mic_irq, "Mic 1 detect", wm8994); case WM8994:
if (ret != 0) ret = wm8994_request_irq(codec->control_data,
dev_warn(codec->dev, WM8994_IRQ_MIC1_DET,
"Failed to request Mic1 detect IRQ: %d\n", ret); wm8994_mic_irq, "Mic 1 detect",
wm8994);
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, if (ret != 0)
wm8994_mic_irq, "Mic 1 short", wm8994); dev_warn(codec->dev,
if (ret != 0) "Failed to request Mic1 detect IRQ: %d\n",
dev_warn(codec->dev, ret);
"Failed to request Mic1 short IRQ: %d\n", ret);
ret = wm8994_request_irq(codec->control_data,
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET, WM8994_IRQ_MIC1_SHRT,
wm8994_mic_irq, "Mic 2 detect", wm8994); wm8994_mic_irq, "Mic 1 short",
if (ret != 0) wm8994);
dev_warn(codec->dev, if (ret != 0)
"Failed to request Mic2 detect IRQ: %d\n", ret); dev_warn(codec->dev,
"Failed to request Mic1 short IRQ: %d\n",
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, ret);
wm8994_mic_irq, "Mic 2 short", wm8994);
if (ret != 0) ret = wm8994_request_irq(codec->control_data,
dev_warn(codec->dev, WM8994_IRQ_MIC2_DET,
"Failed to request Mic2 short IRQ: %d\n", ret); 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 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
* configured on init - if a system wants to do this dynamically * configured on init - if a system wants to do this dynamically
...@@ -2496,13 +2529,22 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) ...@@ -2496,13 +2529,22 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
static int wm8994_codec_remove(struct snd_soc_codec *codec) static int wm8994_codec_remove(struct snd_soc_codec *codec)
{ {
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(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_set_bias_level(codec, SND_SOC_BIAS_OFF);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); switch (control->type) {
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); case WM8994:
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); 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->retune_mobile_texts);
kfree(wm8994->drc_texts); kfree(wm8994->drc_texts);
kfree(wm8994); kfree(wm8994);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment