aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/twl4030.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/twl4030.c')
-rw-r--r--sound/soc/codecs/twl4030.c157
1 files changed, 112 insertions, 45 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 391fcfc7b63b..e7f608996c41 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -26,8 +26,11 @@
26#include <linux/pm.h> 26#include <linux/pm.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/of.h>
30#include <linux/of_gpio.h>
29#include <linux/i2c/twl.h> 31#include <linux/i2c/twl.h>
30#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/gpio.h>
31#include <sound/core.h> 34#include <sound/core.h>
32#include <sound/pcm.h> 35#include <sound/pcm.h>
33#include <sound/pcm_params.h> 36#include <sound/pcm_params.h>
@@ -152,8 +155,7 @@ struct twl4030_priv {
152 u8 predrivel_enabled, predriver_enabled; 155 u8 predrivel_enabled, predriver_enabled;
153 u8 carkitl_enabled, carkitr_enabled; 156 u8 carkitl_enabled, carkitr_enabled;
154 157
155 /* Delay needed after enabling the digimic interface */ 158 struct twl4030_codec_data *pdata;
156 unsigned int digimic_delay;
157}; 159};
158 160
159/* 161/*
@@ -295,13 +297,73 @@ static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
295 297
296} 298}
297 299
298static void twl4030_init_chip(struct snd_soc_codec *codec) 300static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata,
301 struct device_node *node)
302{
303 int value;
304
305 of_property_read_u32(node, "ti,digimic_delay",
306 &pdata->digimic_delay);
307 of_property_read_u32(node, "ti,ramp_delay_value",
308 &pdata->ramp_delay_value);
309 of_property_read_u32(node, "ti,offset_cncl_path",
310 &pdata->offset_cncl_path);
311 if (!of_property_read_u32(node, "ti,hs_extmute", &value))
312 pdata->hs_extmute = value;
313
314 pdata->hs_extmute_gpio = of_get_named_gpio(node,
315 "ti,hs_extmute_gpio", 0);
316 if (gpio_is_valid(pdata->hs_extmute_gpio))
317 pdata->hs_extmute = 1;
318}
319
320static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec)
299{ 321{
300 struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev); 322 struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
323 struct device_node *twl4030_codec_node = NULL;
324
325 twl4030_codec_node = of_find_node_by_name(codec->dev->parent->of_node,
326 "codec");
327
328 if (!pdata && twl4030_codec_node) {
329 pdata = devm_kzalloc(codec->dev,
330 sizeof(struct twl4030_codec_data),
331 GFP_KERNEL);
332 if (!pdata) {
333 dev_err(codec->dev, "Can not allocate memory\n");
334 return NULL;
335 }
336 twl4030_setup_pdata_of(pdata, twl4030_codec_node);
337 }
338
339 return pdata;
340}
341
342static void twl4030_init_chip(struct snd_soc_codec *codec)
343{
344 struct twl4030_codec_data *pdata;
301 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 345 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
302 u8 reg, byte; 346 u8 reg, byte;
303 int i = 0; 347 int i = 0;
304 348
349 pdata = twl4030_get_pdata(codec);
350
351 if (pdata && pdata->hs_extmute &&
352 gpio_is_valid(pdata->hs_extmute_gpio)) {
353 int ret;
354
355 if (!pdata->hs_extmute_gpio)
356 dev_warn(codec->dev,
357 "Extmute GPIO is 0 is this correct?\n");
358
359 ret = gpio_request_one(pdata->hs_extmute_gpio,
360 GPIOF_OUT_INIT_LOW, "hs_extmute");
361 if (ret) {
362 dev_err(codec->dev, "Failed to get hs_extmute GPIO\n");
363 pdata->hs_extmute_gpio = -1;
364 }
365 }
366
305 /* Check defaults, if instructed before anything else */ 367 /* Check defaults, if instructed before anything else */
306 if (pdata && pdata->check_defaults) 368 if (pdata && pdata->check_defaults)
307 twl4030_check_defaults(codec); 369 twl4030_check_defaults(codec);
@@ -331,7 +393,7 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
331 if (!pdata) 393 if (!pdata)
332 return; 394 return;
333 395
334 twl4030->digimic_delay = pdata->digimic_delay; 396 twl4030->pdata = pdata;
335 397
336 reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 398 reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
337 reg &= ~TWL4030_RAMP_DELAY; 399 reg &= ~TWL4030_RAMP_DELAY;
@@ -732,9 +794,9 @@ static int aif_event(struct snd_soc_dapm_widget *w,
732 794
733static void headset_ramp(struct snd_soc_codec *codec, int ramp) 795static void headset_ramp(struct snd_soc_codec *codec, int ramp)
734{ 796{
735 struct twl4030_codec_data *pdata = codec->dev->platform_data;
736 unsigned char hs_gain, hs_pop; 797 unsigned char hs_gain, hs_pop;
737 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 798 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
799 struct twl4030_codec_data *pdata = twl4030->pdata;
738 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 800 /* Base values for ramp delay calculation: 2^19 - 2^26 */
739 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, 801 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
740 8388608, 16777216, 33554432, 67108864}; 802 8388608, 16777216, 33554432, 67108864};
@@ -748,8 +810,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
748 /* Enable external mute control, this dramatically reduces 810 /* Enable external mute control, this dramatically reduces
749 * the pop-noise */ 811 * the pop-noise */
750 if (pdata && pdata->hs_extmute) { 812 if (pdata && pdata->hs_extmute) {
751 if (pdata->set_hs_extmute) { 813 if (gpio_is_valid(pdata->hs_extmute_gpio)) {
752 pdata->set_hs_extmute(1); 814 gpio_set_value(pdata->hs_extmute_gpio, 1);
753 } else { 815 } else {
754 hs_pop |= TWL4030_EXTMUTE; 816 hs_pop |= TWL4030_EXTMUTE;
755 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 817 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -786,8 +848,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
786 848
787 /* Disable external mute */ 849 /* Disable external mute */
788 if (pdata && pdata->hs_extmute) { 850 if (pdata && pdata->hs_extmute) {
789 if (pdata->set_hs_extmute) { 851 if (gpio_is_valid(pdata->hs_extmute_gpio)) {
790 pdata->set_hs_extmute(0); 852 gpio_set_value(pdata->hs_extmute_gpio, 0);
791 } else { 853 } else {
792 hs_pop &= ~TWL4030_EXTMUTE; 854 hs_pop &= ~TWL4030_EXTMUTE;
793 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 855 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -847,9 +909,10 @@ static int digimic_event(struct snd_soc_dapm_widget *w,
847 struct snd_kcontrol *kcontrol, int event) 909 struct snd_kcontrol *kcontrol, int event)
848{ 910{
849 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); 911 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
912 struct twl4030_codec_data *pdata = twl4030->pdata;
850 913
851 if (twl4030->digimic_delay) 914 if (pdata && pdata->digimic_delay)
852 twl4030_wait_ms(twl4030->digimic_delay); 915 twl4030_wait_ms(pdata->digimic_delay);
853 return 0; 916 return 0;
854} 917}
855 918
@@ -999,7 +1062,7 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
999 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1062 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1000 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1063 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1001 unsigned short val; 1064 unsigned short val;
1002 unsigned short mask, bitmask; 1065 unsigned short mask;
1003 1066
1004 if (twl4030->configured) { 1067 if (twl4030->configured) {
1005 dev_err(codec->dev, 1068 dev_err(codec->dev,
@@ -1007,18 +1070,16 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
1007 return -EBUSY; 1070 return -EBUSY;
1008 } 1071 }
1009 1072
1010 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1011 ;
1012 if (ucontrol->value.enumerated.item[0] > e->max - 1) 1073 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1013 return -EINVAL; 1074 return -EINVAL;
1014 1075
1015 val = ucontrol->value.enumerated.item[0] << e->shift_l; 1076 val = ucontrol->value.enumerated.item[0] << e->shift_l;
1016 mask = (bitmask - 1) << e->shift_l; 1077 mask = e->mask << e->shift_l;
1017 if (e->shift_l != e->shift_r) { 1078 if (e->shift_l != e->shift_r) {
1018 if (ucontrol->value.enumerated.item[1] > e->max - 1) 1079 if (ucontrol->value.enumerated.item[1] > e->max - 1)
1019 return -EINVAL; 1080 return -EINVAL;
1020 val |= ucontrol->value.enumerated.item[1] << e->shift_r; 1081 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
1021 mask |= (bitmask - 1) << e->shift_r; 1082 mask |= e->mask << e->shift_r;
1022 } 1083 }
1023 1084
1024 return snd_soc_update_bits(codec, e->reg, mask, val); 1085 return snd_soc_update_bits(codec, e->reg, mask, val);
@@ -1239,16 +1300,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1239 SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"), 1300 SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"),
1240 1301
1241 /* DACs */ 1302 /* DACs */
1242 SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback", 1303 SND_SOC_DAPM_DAC("DAC Right1", NULL, SND_SOC_NOPM, 0, 0),
1243 SND_SOC_NOPM, 0, 0), 1304 SND_SOC_DAPM_DAC("DAC Left1", NULL, SND_SOC_NOPM, 0, 0),
1244 SND_SOC_DAPM_DAC("DAC Left1", "Left Front HiFi Playback", 1305 SND_SOC_DAPM_DAC("DAC Right2", NULL, SND_SOC_NOPM, 0, 0),
1245 SND_SOC_NOPM, 0, 0), 1306 SND_SOC_DAPM_DAC("DAC Left2", NULL, SND_SOC_NOPM, 0, 0),
1246 SND_SOC_DAPM_DAC("DAC Right2", "Right Rear HiFi Playback", 1307 SND_SOC_DAPM_DAC("DAC Voice", NULL, SND_SOC_NOPM, 0, 0),
1247 SND_SOC_NOPM, 0, 0),
1248 SND_SOC_DAPM_DAC("DAC Left2", "Left Rear HiFi Playback",
1249 SND_SOC_NOPM, 0, 0),
1250 SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback",
1251 SND_SOC_NOPM, 0, 0),
1252 1308
1253 /* Analog bypasses */ 1309 /* Analog bypasses */
1254 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1310 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
@@ -1377,14 +1433,10 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1377 1433
1378 /* Introducing four virtual ADC, since TWL4030 have four channel for 1434 /* Introducing four virtual ADC, since TWL4030 have four channel for
1379 capture */ 1435 capture */
1380 SND_SOC_DAPM_ADC("ADC Virtual Left1", "Left Front Capture", 1436 SND_SOC_DAPM_ADC("ADC Virtual Left1", NULL, SND_SOC_NOPM, 0, 0),
1381 SND_SOC_NOPM, 0, 0), 1437 SND_SOC_DAPM_ADC("ADC Virtual Right1", NULL, SND_SOC_NOPM, 0, 0),
1382 SND_SOC_DAPM_ADC("ADC Virtual Right1", "Right Front Capture", 1438 SND_SOC_DAPM_ADC("ADC Virtual Left2", NULL, SND_SOC_NOPM, 0, 0),
1383 SND_SOC_NOPM, 0, 0), 1439 SND_SOC_DAPM_ADC("ADC Virtual Right2", NULL, SND_SOC_NOPM, 0, 0),
1384 SND_SOC_DAPM_ADC("ADC Virtual Left2", "Left Rear Capture",
1385 SND_SOC_NOPM, 0, 0),
1386 SND_SOC_DAPM_ADC("ADC Virtual Right2", "Right Rear Capture",
1387 SND_SOC_NOPM, 0, 0),
1388 1440
1389 /* Analog/Digital mic path selection. 1441 /* Analog/Digital mic path selection.
1390 TX1 Left/Right: either analog Left/Right or Digimic0 1442 TX1 Left/Right: either analog Left/Right or Digimic0
@@ -1428,6 +1480,23 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1428}; 1480};
1429 1481
1430static const struct snd_soc_dapm_route intercon[] = { 1482static const struct snd_soc_dapm_route intercon[] = {
1483 /* Stream -> DAC mapping */
1484 {"DAC Right1", NULL, "HiFi Playback"},
1485 {"DAC Left1", NULL, "HiFi Playback"},
1486 {"DAC Right2", NULL, "HiFi Playback"},
1487 {"DAC Left2", NULL, "HiFi Playback"},
1488 {"DAC Voice", NULL, "Voice Playback"},
1489
1490 /* ADC -> Stream mapping */
1491 {"HiFi Capture", NULL, "ADC Virtual Left1"},
1492 {"HiFi Capture", NULL, "ADC Virtual Right1"},
1493 {"HiFi Capture", NULL, "ADC Virtual Left2"},
1494 {"HiFi Capture", NULL, "ADC Virtual Right2"},
1495 {"Voice Capture", NULL, "ADC Virtual Left1"},
1496 {"Voice Capture", NULL, "ADC Virtual Right1"},
1497 {"Voice Capture", NULL, "ADC Virtual Left2"},
1498 {"Voice Capture", NULL, "ADC Virtual Right2"},
1499
1431 {"Digital L1 Playback Mixer", NULL, "DAC Left1"}, 1500 {"Digital L1 Playback Mixer", NULL, "DAC Left1"},
1432 {"Digital R1 Playback Mixer", NULL, "DAC Right1"}, 1501 {"Digital R1 Playback Mixer", NULL, "DAC Right1"},
1433 {"Digital L2 Playback Mixer", NULL, "DAC Left2"}, 1502 {"Digital L2 Playback Mixer", NULL, "DAC Left2"},
@@ -2172,7 +2241,7 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
2172 .formats = TWL4030_FORMATS, 2241 .formats = TWL4030_FORMATS,
2173 .sig_bits = 24,}, 2242 .sig_bits = 24,},
2174 .capture = { 2243 .capture = {
2175 .stream_name = "Capture", 2244 .stream_name = "HiFi Capture",
2176 .channels_min = 2, 2245 .channels_min = 2,
2177 .channels_max = 4, 2246 .channels_max = 4,
2178 .rates = TWL4030_RATES, 2247 .rates = TWL4030_RATES,
@@ -2189,7 +2258,7 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
2189 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, 2258 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
2190 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 2259 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
2191 .capture = { 2260 .capture = {
2192 .stream_name = "Capture", 2261 .stream_name = "Voice Capture",
2193 .channels_min = 1, 2262 .channels_min = 1,
2194 .channels_max = 2, 2263 .channels_max = 2,
2195 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, 2264 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
@@ -2214,7 +2283,8 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
2214{ 2283{
2215 struct twl4030_priv *twl4030; 2284 struct twl4030_priv *twl4030;
2216 2285
2217 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); 2286 twl4030 = devm_kzalloc(codec->dev, sizeof(struct twl4030_priv),
2287 GFP_KERNEL);
2218 if (twl4030 == NULL) { 2288 if (twl4030 == NULL) {
2219 dev_err(codec->dev, "Can not allocate memory\n"); 2289 dev_err(codec->dev, "Can not allocate memory\n");
2220 return -ENOMEM; 2290 return -ENOMEM;
@@ -2231,11 +2301,15 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
2231static int twl4030_soc_remove(struct snd_soc_codec *codec) 2301static int twl4030_soc_remove(struct snd_soc_codec *codec)
2232{ 2302{
2233 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 2303 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2304 struct twl4030_codec_data *pdata = twl4030->pdata;
2234 2305
2235 /* Reset registers to their chip default before leaving */ 2306 /* Reset registers to their chip default before leaving */
2236 twl4030_reset_registers(codec); 2307 twl4030_reset_registers(codec);
2237 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2308 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2238 kfree(twl4030); 2309
2310 if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio))
2311 gpio_free(pdata->hs_extmute_gpio);
2312
2239 return 0; 2313 return 0;
2240} 2314}
2241 2315
@@ -2262,13 +2336,6 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2262 2336
2263static int __devinit twl4030_codec_probe(struct platform_device *pdev) 2337static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2264{ 2338{
2265 struct twl4030_codec_data *pdata = pdev->dev.platform_data;
2266
2267 if (!pdata) {
2268 dev_err(&pdev->dev, "platform_data is missing\n");
2269 return -EINVAL;
2270 }
2271
2272 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030, 2339 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
2273 twl4030_dai, ARRAY_SIZE(twl4030_dai)); 2340 twl4030_dai, ARRAY_SIZE(twl4030_dai));
2274} 2341}