diff options
Diffstat (limited to 'sound/soc/codecs/twl4030.c')
-rw-r--r-- | sound/soc/codecs/twl4030.c | 85 |
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 | ||
1482 | static const struct snd_soc_dapm_route intercon[] = { | 1511 | static 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 | ||
2270 | static 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 | |||
2276 | static 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 | |||
2282 | static int twl4030_soc_probe(struct snd_soc_codec *codec) | 2299 | static 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) | |||
2316 | static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { | 2333 | static 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, |