diff options
Diffstat (limited to 'sound/soc/codecs/ab8500-codec.c')
| -rw-r--r-- | sound/soc/codecs/ab8500-codec.c | 81 | 
1 files changed, 81 insertions, 0 deletions
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 2c1c2524ef8..af547490b4f 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -34,6 +34,7 @@  #include <linux/mfd/abx500/ab8500-sysctrl.h>  #include <linux/mfd/abx500/ab8500-codec.h>  #include <linux/regulator/consumer.h> +#include <linux/of.h>  #include <sound/core.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)  {  	struct device *dev = codec->dev; +	struct device_node *np = dev->of_node;  	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);  	struct ab8500_platform_data *pdata;  	struct filter_control *fc; @@ -2407,6 +2464,30 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)  	/* Setup AB8500 according to board-settings */  	pdata = dev_get_platdata(dev->parent); +	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);  	if (status < 0) {  		pr_err("%s: Failed to setup mics (%d)!\n", __func__, status);  |