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.c85
1 files changed, 50 insertions, 35 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 63b280b06035..8e6e5b016021 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -41,6 +41,11 @@
41/* Register descriptions are here */ 41/* Register descriptions are here */
42#include <linux/mfd/twl4030-audio.h> 42#include <linux/mfd/twl4030-audio.h>
43 43
44/* TWL4030 PMBR1 Register */
45#define TWL4030_PMBR1_REG 0x0D
46/* TWL4030 PMBR1 Register GPIO6 mux bits */
47#define TWL4030_GPIO6_PWM0_MUTE(value) ((value & 0x03) << 2)
48
44/* Shadow register used by the audio driver */ 49/* Shadow register used by the audio driver */
45#define TWL4030_REG_SW_SHADOW 0x4A 50#define TWL4030_REG_SW_SHADOW 0x4A
46#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1) 51#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
@@ -348,19 +353,32 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
348 353
349 pdata = twl4030_get_pdata(codec); 354 pdata = twl4030_get_pdata(codec);
350 355
351 if (pdata && pdata->hs_extmute && 356 if (pdata && pdata->hs_extmute) {
352 gpio_is_valid(pdata->hs_extmute_gpio)) { 357 if (gpio_is_valid(pdata->hs_extmute_gpio)) {
353 int ret; 358 int ret;
354 359
355 if (!pdata->hs_extmute_gpio) 360 if (!pdata->hs_extmute_gpio)
356 dev_warn(codec->dev, 361 dev_warn(codec->dev,
357 "Extmute GPIO is 0 is this correct?\n"); 362 "Extmute GPIO is 0 is this correct?\n");
358 363
359 ret = gpio_request_one(pdata->hs_extmute_gpio, 364 ret = gpio_request_one(pdata->hs_extmute_gpio,
360 GPIOF_OUT_INIT_LOW, "hs_extmute"); 365 GPIOF_OUT_INIT_LOW,
361 if (ret) { 366 "hs_extmute");
362 dev_err(codec->dev, "Failed to get hs_extmute GPIO\n"); 367 if (ret) {
363 pdata->hs_extmute_gpio = -1; 368 dev_err(codec->dev,
369 "Failed to get hs_extmute GPIO\n");
370 pdata->hs_extmute_gpio = -1;
371 }
372 } else {
373 u8 pin_mux;
374
375 /* Set TWL4030 GPIO6 as EXTMUTE signal */
376 twl_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux,
377 TWL4030_PMBR1_REG);
378 pin_mux &= ~TWL4030_GPIO6_PWM0_MUTE(0x03);
379 pin_mux |= TWL4030_GPIO6_PWM0_MUTE(0x02);
380 twl_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux,
381 TWL4030_PMBR1_REG);
364 } 382 }
365 } 383 }
366 384
@@ -1306,6 +1324,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1306 SND_SOC_DAPM_DAC("DAC Left2", NULL, SND_SOC_NOPM, 0, 0), 1324 SND_SOC_DAPM_DAC("DAC Left2", NULL, SND_SOC_NOPM, 0, 0),
1307 SND_SOC_DAPM_DAC("DAC Voice", NULL, SND_SOC_NOPM, 0, 0), 1325 SND_SOC_DAPM_DAC("DAC Voice", NULL, SND_SOC_NOPM, 0, 0),
1308 1326
1327 SND_SOC_DAPM_AIF_IN("VAIFIN", "Voice Playback", 0,
1328 TWL4030_REG_VOICE_IF, 6, 0),
1329
1309 /* Analog bypasses */ 1330 /* Analog bypasses */
1310 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1331 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1311 &twl4030_dapm_abypassr1_control), 1332 &twl4030_dapm_abypassr1_control),
@@ -1438,6 +1459,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1438 SND_SOC_DAPM_ADC("ADC Virtual Left2", NULL, SND_SOC_NOPM, 0, 0), 1459 SND_SOC_DAPM_ADC("ADC Virtual Left2", NULL, SND_SOC_NOPM, 0, 0),
1439 SND_SOC_DAPM_ADC("ADC Virtual Right2", NULL, SND_SOC_NOPM, 0, 0), 1460 SND_SOC_DAPM_ADC("ADC Virtual Right2", NULL, SND_SOC_NOPM, 0, 0),
1440 1461
1462 SND_SOC_DAPM_AIF_OUT("VAIFOUT", "Voice Capture", 0,
1463 TWL4030_REG_VOICE_IF, 5, 0),
1464
1441 /* Analog/Digital mic path selection. 1465 /* Analog/Digital mic path selection.
1442 TX1 Left/Right: either analog Left/Right or Digimic0 1466 TX1 Left/Right: either analog Left/Right or Digimic0
1443 TX2 Left/Right: either analog Left/Right or Digimic1 */ 1467 TX2 Left/Right: either analog Left/Right or Digimic1 */
@@ -1473,10 +1497,15 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1473 SND_SOC_DAPM_SUPPLY("micbias2 select", TWL4030_REG_MICBIAS_CTL, 6, 0, 1497 SND_SOC_DAPM_SUPPLY("micbias2 select", TWL4030_REG_MICBIAS_CTL, 6, 0,
1474 NULL, 0), 1498 NULL, 0),
1475 1499
1476 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0), 1500 /* Microphone bias */
1477 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0), 1501 SND_SOC_DAPM_SUPPLY("Mic Bias 1",
1478 SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0), 1502 TWL4030_REG_MICBIAS_CTL, 0, 0, NULL, 0),
1503 SND_SOC_DAPM_SUPPLY("Mic Bias 2",
1504 TWL4030_REG_MICBIAS_CTL, 1, 0, NULL, 0),
1505 SND_SOC_DAPM_SUPPLY("Headset Mic Bias",
1506 TWL4030_REG_MICBIAS_CTL, 2, 0, NULL, 0),
1479 1507
1508 SND_SOC_DAPM_SUPPLY("VIF Enable", TWL4030_REG_VOICE_IF, 0, 0, NULL, 0),
1480}; 1509};
1481 1510
1482static const struct snd_soc_dapm_route intercon[] = { 1511static const struct snd_soc_dapm_route intercon[] = {
@@ -1485,17 +1514,16 @@ static const struct snd_soc_dapm_route intercon[] = {
1485 {"DAC Left1", NULL, "HiFi Playback"}, 1514 {"DAC Left1", NULL, "HiFi Playback"},
1486 {"DAC Right2", NULL, "HiFi Playback"}, 1515 {"DAC Right2", NULL, "HiFi Playback"},
1487 {"DAC Left2", NULL, "HiFi Playback"}, 1516 {"DAC Left2", NULL, "HiFi Playback"},
1488 {"DAC Voice", NULL, "Voice Playback"}, 1517 {"DAC Voice", NULL, "VAIFIN"},
1489 1518
1490 /* ADC -> Stream mapping */ 1519 /* ADC -> Stream mapping */
1491 {"HiFi Capture", NULL, "ADC Virtual Left1"}, 1520 {"HiFi Capture", NULL, "ADC Virtual Left1"},
1492 {"HiFi Capture", NULL, "ADC Virtual Right1"}, 1521 {"HiFi Capture", NULL, "ADC Virtual Right1"},
1493 {"HiFi Capture", NULL, "ADC Virtual Left2"}, 1522 {"HiFi Capture", NULL, "ADC Virtual Left2"},
1494 {"HiFi Capture", NULL, "ADC Virtual Right2"}, 1523 {"HiFi Capture", NULL, "ADC Virtual Right2"},
1495 {"Voice Capture", NULL, "ADC Virtual Left1"}, 1524 {"VAIFOUT", NULL, "ADC Virtual Left2"},
1496 {"Voice Capture", NULL, "ADC Virtual Right1"}, 1525 {"VAIFOUT", NULL, "ADC Virtual Right2"},
1497 {"Voice Capture", NULL, "ADC Virtual Left2"}, 1526 {"VAIFOUT", NULL, "VIF Enable"},
1498 {"Voice Capture", NULL, "ADC Virtual Right2"},
1499 1527
1500 {"Digital L1 Playback Mixer", NULL, "DAC Left1"}, 1528 {"Digital L1 Playback Mixer", NULL, "DAC Left1"},
1501 {"Digital R1 Playback Mixer", NULL, "DAC Right1"}, 1529 {"Digital R1 Playback Mixer", NULL, "DAC Right1"},
@@ -1510,6 +1538,7 @@ static const struct snd_soc_dapm_route intercon[] = {
1510 {"DAC Right1", NULL, "AIF Enable"}, 1538 {"DAC Right1", NULL, "AIF Enable"},
1511 {"DAC Left2", NULL, "AIF Enable"}, 1539 {"DAC Left2", NULL, "AIF Enable"},
1512 {"DAC Right1", NULL, "AIF Enable"}, 1540 {"DAC Right1", NULL, "AIF Enable"},
1541 {"DAC Voice", NULL, "VIF Enable"},
1513 1542
1514 {"Digital R2 Playback Mixer", NULL, "AIF Enable"}, 1543 {"Digital R2 Playback Mixer", NULL, "AIF Enable"},
1515 {"Digital L2 Playback Mixer", NULL, "AIF Enable"}, 1544 {"Digital L2 Playback Mixer", NULL, "AIF Enable"},
@@ -2267,18 +2296,6 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
2267}, 2296},
2268}; 2297};
2269 2298
2270static int twl4030_soc_suspend(struct snd_soc_codec *codec)
2271{
2272 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2273 return 0;
2274}
2275
2276static int twl4030_soc_resume(struct snd_soc_codec *codec)
2277{
2278 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2279 return 0;
2280}
2281
2282static int twl4030_soc_probe(struct snd_soc_codec *codec) 2299static int twl4030_soc_probe(struct snd_soc_codec *codec)
2283{ 2300{
2284 struct twl4030_priv *twl4030; 2301 struct twl4030_priv *twl4030;
@@ -2316,8 +2333,6 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec)
2316static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { 2333static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2317 .probe = twl4030_soc_probe, 2334 .probe = twl4030_soc_probe,
2318 .remove = twl4030_soc_remove, 2335 .remove = twl4030_soc_remove,
2319 .suspend = twl4030_soc_suspend,
2320 .resume = twl4030_soc_resume,
2321 .read = twl4030_read_reg_cache, 2336 .read = twl4030_read_reg_cache,
2322 .write = twl4030_write, 2337 .write = twl4030_write,
2323 .set_bias_level = twl4030_set_bias_level, 2338 .set_bias_level = twl4030_set_bias_level,