ASoC: codecs: Enable AB8500 CODEC for Device Tree

We continue to allow the AB8500 CODEC to be registered via the AB8500
Multi Functional Device API, only this time we extract its configuration
from the Device Tree binary.

Acked-by: Ola Lilja <ola.o.lilja@stericsson.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
This commit is contained in:
Lee Jones 2012-07-27 08:50:05 +01:00
Родитель 49731c23be
Коммит db5c811d40
2 изменённых файлов: 85 добавлений и 2 удалений

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

@ -23,7 +23,8 @@ enum amic_type {
/* Mic-biases */ /* Mic-biases */
enum amic_micbias { enum amic_micbias {
AMIC_MICBIAS_VAMIC1, AMIC_MICBIAS_VAMIC1,
AMIC_MICBIAS_VAMIC2 AMIC_MICBIAS_VAMIC2,
AMIC_MICBIAS_UNKNOWN
}; };
/* Bias-voltage */ /* Bias-voltage */
@ -31,7 +32,8 @@ enum ear_cm_voltage {
EAR_CMV_0_95V, EAR_CMV_0_95V,
EAR_CMV_1_10V, EAR_CMV_1_10V,
EAR_CMV_1_27V, EAR_CMV_1_27V,
EAR_CMV_1_58V EAR_CMV_1_58V,
EAR_CMV_UNKNOWN
}; };
/* Analog microphone settings */ /* Analog microphone settings */

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

@ -34,6 +34,7 @@
#include <linux/mfd/abx500/ab8500-sysctrl.h> #include <linux/mfd/abx500/ab8500-sysctrl.h>
#include <linux/mfd/abx500/ab8500-codec.h> #include <linux/mfd/abx500/ab8500-codec.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/of.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
@ -2394,9 +2395,65 @@ struct snd_soc_dai_driver ab8500_codec_dai[] = {
} }
}; };
static void ab8500_codec_of_probe(struct device *dev, struct device_node *np,
struct ab8500_codec_platform_data *codec)
{
u32 value;
if (of_get_property(np, "stericsson,amic1-type-single-ended", NULL))
codec->amics.mic1_type = AMIC_TYPE_SINGLE_ENDED;
else
codec->amics.mic1_type = AMIC_TYPE_DIFFERENTIAL;
if (of_get_property(np, "stericsson,amic2-type-single-ended", NULL))
codec->amics.mic2_type = AMIC_TYPE_SINGLE_ENDED;
else
codec->amics.mic2_type = AMIC_TYPE_DIFFERENTIAL;
/* Has a non-standard Vamic been requested? */
if (of_get_property(np, "stericsson,amic1a-bias-vamic2", NULL))
codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC2;
else
codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC1;
if (of_get_property(np, "stericsson,amic1b-bias-vamic2", NULL))
codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC2;
else
codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC1;
if (of_get_property(np, "stericsson,amic2-bias-vamic1", NULL))
codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC1;
else
codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC2;
if (!of_property_read_u32(np, "stericsson,earpeice-cmv", &value)) {
switch (value) {
case 950 :
codec->ear_cmv = EAR_CMV_0_95V;
break;
case 1100 :
codec->ear_cmv = EAR_CMV_1_10V;
break;
case 1270 :
codec->ear_cmv = EAR_CMV_1_27V;
break;
case 1580 :
codec->ear_cmv = EAR_CMV_1_58V;
break;
default :
codec->ear_cmv = EAR_CMV_UNKNOWN;
dev_err(dev, "Unsuitable earpiece voltage found in DT\n");
}
} else {
dev_warn(dev, "No earpiece voltage found in DT - using default\n");
codec->ear_cmv = EAR_CMV_0_95V;
}
}
static int ab8500_codec_probe(struct snd_soc_codec *codec) static int ab8500_codec_probe(struct snd_soc_codec *codec)
{ {
struct device *dev = codec->dev; struct device *dev = codec->dev;
struct device_node *np = dev->of_node;
struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
struct ab8500_platform_data *pdata; struct ab8500_platform_data *pdata;
struct filter_control *fc; struct filter_control *fc;
@ -2410,6 +2467,30 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
/* Inform SoC Core that we have our own I/O arrangements. */ /* Inform SoC Core that we have our own I/O arrangements. */
codec->control_data = (void *)true; codec->control_data = (void *)true;
if (np) {
if (!pdata)
pdata = devm_kzalloc(dev,
sizeof(struct ab8500_platform_data),
GFP_KERNEL);
if (pdata && !pdata->codec)
pdata->codec
= devm_kzalloc(dev,
sizeof(struct ab8500_codec_platform_data),
GFP_KERNEL);
if (!(pdata && pdata->codec))
return -ENOMEM;
ab8500_codec_of_probe(dev, np, pdata->codec);
} else {
if (!(pdata && pdata->codec)) {
dev_err(dev, "No codec platform data or DT found\n");
return -EINVAL;
}
}
status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); status = ab8500_audio_setup_mics(codec, &pdata->codec->amics);
if (status < 0) { if (status < 0) {
pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); pr_err("%s: Failed to setup mics (%d)!\n", __func__, status);