aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-05-07 11:38:26 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-05-07 11:38:26 -0400
commit305787649826d6c84a6f9f71bc3318460610aba4 (patch)
treeb36cfe60e6f806414b1e6c042f0be233f114986f /sound/soc
parentc4806174c516d26bf4a72db1789cfc96e4950d07 (diff)
parentaeb29a82de7c80d4d0253b042f17eb1f725b08f1 (diff)
Merge branch 'topic/asoc' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6 into for-2.6.35
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/tlv320aic3x.c25
-rw-r--r--sound/soc/codecs/tlv320dac33.c223
-rw-r--r--sound/soc/codecs/tpa6130a2.c99
-rw-r--r--sound/soc/codecs/twl4030.c86
-rw-r--r--sound/soc/omap/Kconfig10
-rw-r--r--sound/soc/omap/Makefile2
-rw-r--r--sound/soc/omap/omap3pandora.c2
-rw-r--r--sound/soc/omap/rx51.c294
-rw-r--r--sound/soc/omap/zoom2.c3
9 files changed, 601 insertions, 143 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 584bc1e67f76..d57372be7a96 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -38,6 +38,7 @@
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/pm.h> 39#include <linux/pm.h>
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/gpio.h>
41#include <linux/regulator/consumer.h> 42#include <linux/regulator/consumer.h>
42#include <linux/platform_device.h> 43#include <linux/platform_device.h>
43#include <sound/core.h> 44#include <sound/core.h>
@@ -47,6 +48,7 @@
47#include <sound/soc-dapm.h> 48#include <sound/soc-dapm.h>
48#include <sound/initval.h> 49#include <sound/initval.h>
49#include <sound/tlv.h> 50#include <sound/tlv.h>
51#include <sound/tlv320aic3x.h>
50 52
51#include "tlv320aic3x.h" 53#include "tlv320aic3x.h"
52 54
@@ -64,6 +66,7 @@ struct aic3x_priv {
64 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES]; 66 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
65 unsigned int sysclk; 67 unsigned int sysclk;
66 int master; 68 int master;
69 int gpio_reset;
67}; 70};
68 71
69/* 72/*
@@ -1278,6 +1281,10 @@ static int aic3x_unregister(struct aic3x_priv *aic3x)
1278 snd_soc_unregister_dai(&aic3x_dai); 1281 snd_soc_unregister_dai(&aic3x_dai);
1279 snd_soc_unregister_codec(&aic3x->codec); 1282 snd_soc_unregister_codec(&aic3x->codec);
1280 1283
1284 if (aic3x->gpio_reset >= 0) {
1285 gpio_set_value(aic3x->gpio_reset, 0);
1286 gpio_free(aic3x->gpio_reset);
1287 }
1281 regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); 1288 regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1282 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); 1289 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1283 1290
@@ -1302,6 +1309,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1302{ 1309{
1303 struct snd_soc_codec *codec; 1310 struct snd_soc_codec *codec;
1304 struct aic3x_priv *aic3x; 1311 struct aic3x_priv *aic3x;
1312 struct aic3x_pdata *pdata = i2c->dev.platform_data;
1305 int ret, i; 1313 int ret, i;
1306 1314
1307 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); 1315 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
@@ -1318,6 +1326,15 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1318 1326
1319 i2c_set_clientdata(i2c, aic3x); 1327 i2c_set_clientdata(i2c, aic3x);
1320 1328
1329 aic3x->gpio_reset = -1;
1330 if (pdata && pdata->gpio_reset >= 0) {
1331 ret = gpio_request(pdata->gpio_reset, "tlv320aic3x reset");
1332 if (ret != 0)
1333 goto err_gpio;
1334 aic3x->gpio_reset = pdata->gpio_reset;
1335 gpio_direction_output(aic3x->gpio_reset, 0);
1336 }
1337
1321 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) 1338 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1322 aic3x->supplies[i].supply = aic3x_supply_names[i]; 1339 aic3x->supplies[i].supply = aic3x_supply_names[i];
1323 1340
@@ -1335,11 +1352,19 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1335 goto err_enable; 1352 goto err_enable;
1336 } 1353 }
1337 1354
1355 if (aic3x->gpio_reset >= 0) {
1356 udelay(1);
1357 gpio_set_value(aic3x->gpio_reset, 1);
1358 }
1359
1338 return aic3x_register(codec); 1360 return aic3x_register(codec);
1339 1361
1340err_enable: 1362err_enable:
1341 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); 1363 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1342err_get: 1364err_get:
1365 if (aic3x->gpio_reset >= 0)
1366 gpio_free(aic3x->gpio_reset);
1367err_gpio:
1343 kfree(aic3x); 1368 kfree(aic3x);
1344 return ret; 1369 return ret;
1345} 1370}
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 3eddaec728c1..ad5e2636c944 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -61,6 +61,8 @@
61#define US_TO_SAMPLES(rate, us) \ 61#define US_TO_SAMPLES(rate, us) \
62 (rate / (1000000 / us)) 62 (rate / (1000000 / us))
63 63
64static void dac33_calculate_times(struct snd_pcm_substream *substream);
65static int dac33_prepare_chip(struct snd_pcm_substream *substream);
64 66
65static struct snd_soc_codec *tlv320dac33_codec; 67static struct snd_soc_codec *tlv320dac33_codec;
66 68
@@ -91,6 +93,7 @@ struct tlv320dac33_priv {
91 struct work_struct work; 93 struct work_struct work;
92 struct snd_soc_codec codec; 94 struct snd_soc_codec codec;
93 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES]; 95 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
96 struct snd_pcm_substream *substream;
94 int power_gpio; 97 int power_gpio;
95 int chip_power; 98 int chip_power;
96 int irq; 99 int irq;
@@ -284,45 +287,47 @@ static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
284 return ret; 287 return ret;
285} 288}
286 289
287static void dac33_restore_regs(struct snd_soc_codec *codec) 290static void dac33_init_chip(struct snd_soc_codec *codec)
288{ 291{
289 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 292 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
290 u8 *cache = codec->reg_cache;
291 u8 data[2];
292 int i, ret;
293 293
294 if (!dac33->chip_power) 294 if (unlikely(!dac33->chip_power))
295 return; 295 return;
296 296
297 for (i = DAC33_PWR_CTRL; i <= DAC33_INTP_CTRL_B; i++) { 297 /* 44-46: DAC Control Registers */
298 data[0] = i; 298 /* A : DAC sample rate Fsref/1.5 */
299 data[1] = cache[i]; 299 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
300 /* Skip the read only registers */ 300 /* B : DAC src=normal, not muted */
301 if ((i >= DAC33_INT_OSC_STATUS && 301 dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
302 i <= DAC33_INT_OSC_FREQ_RAT_READ_B) || 302 DAC33_DACSRCL_LEFT);
303 (i >= DAC33_FIFO_WPTR_MSB && i <= DAC33_FIFO_IRQ_FLAG) || 303 /* C : (defaults) */
304 i == DAC33_DAC_STATUS_FLAGS || 304 dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
305 i == DAC33_SRC_EST_REF_CLK_RATIO_A || 305
306 i == DAC33_SRC_EST_REF_CLK_RATIO_B) 306 /* 73 : volume soft stepping control,
307 continue; 307 clock source = internal osc (?) */
308 ret = codec->hw_write(codec->control_data, data, 2); 308 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
309 if (ret != 2) 309
310 dev_err(codec->dev, "Write failed (%d)\n", ret); 310 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
311 } 311
312 for (i = DAC33_LDAC_PWR_CTRL; i <= DAC33_LINEL_TO_LLO_VOL; i++) { 312 /* Restore only selected registers (gains mostly) */
313 data[0] = i; 313 dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL,
314 data[1] = cache[i]; 314 dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL));
315 ret = codec->hw_write(codec->control_data, data, 2); 315 dac33_write(codec, DAC33_RDAC_DIG_VOL_CTRL,
316 if (ret != 2) 316 dac33_read_reg_cache(codec, DAC33_RDAC_DIG_VOL_CTRL));
317 dev_err(codec->dev, "Write failed (%d)\n", ret); 317
318 } 318 dac33_write(codec, DAC33_LINEL_TO_LLO_VOL,
319 for (i = DAC33_LINER_TO_RLO_VOL; i <= DAC33_OSC_TRIM; i++) { 319 dac33_read_reg_cache(codec, DAC33_LINEL_TO_LLO_VOL));
320 data[0] = i; 320 dac33_write(codec, DAC33_LINER_TO_RLO_VOL,
321 data[1] = cache[i]; 321 dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL));
322 ret = codec->hw_write(codec->control_data, data, 2); 322}
323 if (ret != 2) 323
324 dev_err(codec->dev, "Write failed (%d)\n", ret); 324static inline void dac33_read_id(struct snd_soc_codec *codec)
325 } 325{
326 u8 reg;
327
328 dac33_read(codec, DAC33_DEVICE_ID_MSB, &reg);
329 dac33_read(codec, DAC33_DEVICE_ID_LSB, &reg);
330 dac33_read(codec, DAC33_DEVICE_REV_ID, &reg);
326} 331}
327 332
328static inline void dac33_soft_power(struct snd_soc_codec *codec, int power) 333static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
@@ -341,9 +346,17 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
341static int dac33_hard_power(struct snd_soc_codec *codec, int power) 346static int dac33_hard_power(struct snd_soc_codec *codec, int power)
342{ 347{
343 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 348 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
344 int ret; 349 int ret = 0;
345 350
346 mutex_lock(&dac33->mutex); 351 mutex_lock(&dac33->mutex);
352
353 /* Safety check */
354 if (unlikely(power == dac33->chip_power)) {
355 dev_warn(codec->dev, "Trying to set the same power state: %s\n",
356 power ? "ON" : "OFF");
357 goto exit;
358 }
359
347 if (power) { 360 if (power) {
348 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies), 361 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
349 dac33->supplies); 362 dac33->supplies);
@@ -357,11 +370,6 @@ static int dac33_hard_power(struct snd_soc_codec *codec, int power)
357 gpio_set_value(dac33->power_gpio, 1); 370 gpio_set_value(dac33->power_gpio, 1);
358 371
359 dac33->chip_power = 1; 372 dac33->chip_power = 1;
360
361 /* Restore registers */
362 dac33_restore_regs(codec);
363
364 dac33_soft_power(codec, 1);
365 } else { 373 } else {
366 dac33_soft_power(codec, 0); 374 dac33_soft_power(codec, 0);
367 if (dac33->power_gpio >= 0) 375 if (dac33->power_gpio >= 0)
@@ -383,6 +391,22 @@ exit:
383 return ret; 391 return ret;
384} 392}
385 393
394static int playback_event(struct snd_soc_dapm_widget *w,
395 struct snd_kcontrol *kcontrol, int event)
396{
397 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec);
398
399 switch (event) {
400 case SND_SOC_DAPM_PRE_PMU:
401 if (likely(dac33->substream)) {
402 dac33_calculate_times(dac33->substream);
403 dac33_prepare_chip(dac33->substream);
404 }
405 break;
406 }
407 return 0;
408}
409
386static int dac33_get_nsample(struct snd_kcontrol *kcontrol, 410static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
387 struct snd_ctl_elem_value *ucontrol) 411 struct snd_ctl_elem_value *ucontrol)
388{ 412{
@@ -512,6 +536,8 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
512 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0), 536 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
513 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power", 537 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power",
514 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0), 538 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
539
540 SND_SOC_DAPM_PRE("Prepare Playback", playback_event),
515}; 541};
516 542
517static const struct snd_soc_dapm_route audio_map[] = { 543static const struct snd_soc_dapm_route audio_map[] = {
@@ -554,18 +580,18 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
554 break; 580 break;
555 case SND_SOC_BIAS_STANDBY: 581 case SND_SOC_BIAS_STANDBY:
556 if (codec->bias_level == SND_SOC_BIAS_OFF) { 582 if (codec->bias_level == SND_SOC_BIAS_OFF) {
583 /* Coming from OFF, switch on the codec */
557 ret = dac33_hard_power(codec, 1); 584 ret = dac33_hard_power(codec, 1);
558 if (ret != 0) 585 if (ret != 0)
559 return ret; 586 return ret;
560 }
561 587
562 dac33_soft_power(codec, 0); 588 dac33_init_chip(codec);
589 }
563 break; 590 break;
564 case SND_SOC_BIAS_OFF: 591 case SND_SOC_BIAS_OFF:
565 ret = dac33_hard_power(codec, 0); 592 ret = dac33_hard_power(codec, 0);
566 if (ret != 0) 593 if (ret != 0)
567 return ret; 594 return ret;
568
569 break; 595 break;
570 } 596 }
571 codec->bias_level = level; 597 codec->bias_level = level;
@@ -708,6 +734,31 @@ static void dac33_oscwait(struct snd_soc_codec *codec)
708 "internal oscillator calibration failed\n"); 734 "internal oscillator calibration failed\n");
709} 735}
710 736
737static int dac33_startup(struct snd_pcm_substream *substream,
738 struct snd_soc_dai *dai)
739{
740 struct snd_soc_pcm_runtime *rtd = substream->private_data;
741 struct snd_soc_device *socdev = rtd->socdev;
742 struct snd_soc_codec *codec = socdev->card->codec;
743 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
744
745 /* Stream started, save the substream pointer */
746 dac33->substream = substream;
747
748 return 0;
749}
750
751static void dac33_shutdown(struct snd_pcm_substream *substream,
752 struct snd_soc_dai *dai)
753{
754 struct snd_soc_pcm_runtime *rtd = substream->private_data;
755 struct snd_soc_device *socdev = rtd->socdev;
756 struct snd_soc_codec *codec = socdev->card->codec;
757 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
758
759 dac33->substream = NULL;
760}
761
711static int dac33_hw_params(struct snd_pcm_substream *substream, 762static int dac33_hw_params(struct snd_pcm_substream *substream,
712 struct snd_pcm_hw_params *params, 763 struct snd_pcm_hw_params *params,
713 struct snd_soc_dai *dai) 764 struct snd_soc_dai *dai)
@@ -791,6 +842,16 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
791 } 842 }
792 843
793 mutex_lock(&dac33->mutex); 844 mutex_lock(&dac33->mutex);
845
846 if (!dac33->chip_power) {
847 /*
848 * Chip is not powered yet.
849 * Do the init in the dac33_set_bias_level later.
850 */
851 mutex_unlock(&dac33->mutex);
852 return 0;
853 }
854
794 dac33_soft_power(codec, 0); 855 dac33_soft_power(codec, 0);
795 dac33_soft_power(codec, 1); 856 dac33_soft_power(codec, 1);
796 857
@@ -997,15 +1058,6 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
997 1058
998} 1059}
999 1060
1000static int dac33_pcm_prepare(struct snd_pcm_substream *substream,
1001 struct snd_soc_dai *dai)
1002{
1003 dac33_calculate_times(substream);
1004 dac33_prepare_chip(substream);
1005
1006 return 0;
1007}
1008
1009static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd, 1061static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
1010 struct snd_soc_dai *dai) 1062 struct snd_soc_dai *dai)
1011{ 1063{
@@ -1269,35 +1321,6 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
1269 return 0; 1321 return 0;
1270} 1322}
1271 1323
1272static void dac33_init_chip(struct snd_soc_codec *codec)
1273{
1274 /* 44-46: DAC Control Registers */
1275 /* A : DAC sample rate Fsref/1.5 */
1276 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
1277 /* B : DAC src=normal, not muted */
1278 dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
1279 DAC33_DACSRCL_LEFT);
1280 /* C : (defaults) */
1281 dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
1282
1283 /* 64-65 : L&R DAC power control
1284 Line In -> OUT 1V/V Gain, DAC -> OUT 4V/V Gain*/
1285 dac33_write(codec, DAC33_LDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
1286 dac33_write(codec, DAC33_RDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
1287
1288 /* 73 : volume soft stepping control,
1289 clock source = internal osc (?) */
1290 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
1291
1292 /* 66 : LOP/LOM Modes */
1293 dac33_write(codec, DAC33_OUT_AMP_CM_CTRL, 0xff);
1294
1295 /* 68 : LOM inverted from LOP */
1296 dac33_write(codec, DAC33_OUT_AMP_CTRL, (3<<2));
1297
1298 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
1299}
1300
1301static int dac33_soc_probe(struct platform_device *pdev) 1324static int dac33_soc_probe(struct platform_device *pdev)
1302{ 1325{
1303 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1326 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -1311,11 +1334,6 @@ static int dac33_soc_probe(struct platform_device *pdev)
1311 socdev->card->codec = codec; 1334 socdev->card->codec = codec;
1312 dac33 = snd_soc_codec_get_drvdata(codec); 1335 dac33 = snd_soc_codec_get_drvdata(codec);
1313 1336
1314 /* Power up the codec */
1315 dac33_hard_power(codec, 1);
1316 /* Set default configuration */
1317 dac33_init_chip(codec);
1318
1319 /* register pcms */ 1337 /* register pcms */
1320 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1338 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1321 if (ret < 0) { 1339 if (ret < 0) {
@@ -1332,12 +1350,6 @@ static int dac33_soc_probe(struct platform_device *pdev)
1332 1350
1333 dac33_add_widgets(codec); 1351 dac33_add_widgets(codec);
1334 1352
1335 /* power on device */
1336 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1337
1338 /* Bias level configuration has enabled regulator an extra time */
1339 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1340
1341 return 0; 1353 return 0;
1342 1354
1343pcm_err: 1355pcm_err:
@@ -1374,6 +1386,8 @@ static int dac33_soc_resume(struct platform_device *pdev)
1374 struct snd_soc_codec *codec = socdev->card->codec; 1386 struct snd_soc_codec *codec = socdev->card->codec;
1375 1387
1376 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1388 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1389 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
1390 dac33_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1377 dac33_set_bias_level(codec, codec->suspend_bias_level); 1391 dac33_set_bias_level(codec, codec->suspend_bias_level);
1378 1392
1379 return 0; 1393 return 0;
@@ -1392,8 +1406,9 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320dac33);
1392#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE 1406#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE
1393 1407
1394static struct snd_soc_dai_ops dac33_dai_ops = { 1408static struct snd_soc_dai_ops dac33_dai_ops = {
1409 .startup = dac33_startup,
1410 .shutdown = dac33_shutdown,
1395 .hw_params = dac33_hw_params, 1411 .hw_params = dac33_hw_params,
1396 .prepare = dac33_pcm_prepare,
1397 .trigger = dac33_pcm_trigger, 1412 .trigger = dac33_pcm_trigger,
1398 .delay = dac33_dai_delay, 1413 .delay = dac33_dai_delay,
1399 .set_sysclk = dac33_set_dai_sysclk, 1414 .set_sysclk = dac33_set_dai_sysclk,
@@ -1447,6 +1462,7 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1447 codec->hw_write = (hw_write_t) i2c_master_send; 1462 codec->hw_write = (hw_write_t) i2c_master_send;
1448 codec->bias_level = SND_SOC_BIAS_OFF; 1463 codec->bias_level = SND_SOC_BIAS_OFF;
1449 codec->set_bias_level = dac33_set_bias_level; 1464 codec->set_bias_level = dac33_set_bias_level;
1465 codec->idle_bias_off = 1;
1450 codec->dai = &dac33_dai; 1466 codec->dai = &dac33_dai;
1451 codec->num_dai = 1; 1467 codec->num_dai = 1;
1452 codec->reg_cache_size = ARRAY_SIZE(dac33_reg); 1468 codec->reg_cache_size = ARRAY_SIZE(dac33_reg);
@@ -1487,8 +1503,6 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1487 goto error_gpio; 1503 goto error_gpio;
1488 } 1504 }
1489 gpio_direction_output(dac33->power_gpio, 0); 1505 gpio_direction_output(dac33->power_gpio, 0);
1490 } else {
1491 dac33->chip_power = 1;
1492 } 1506 }
1493 1507
1494 /* Check if the IRQ number is valid and request it */ 1508 /* Check if the IRQ number is valid and request it */
@@ -1526,12 +1540,14 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1526 goto err_get; 1540 goto err_get;
1527 } 1541 }
1528 1542
1529 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies), 1543 /* Read the tlv320dac33 ID registers */
1530 dac33->supplies); 1544 ret = dac33_hard_power(codec, 1);
1531 if (ret != 0) { 1545 if (ret != 0) {
1532 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); 1546 dev_err(codec->dev, "Failed to power up codec: %d\n", ret);
1533 goto err_enable; 1547 goto error_codec;
1534 } 1548 }
1549 dac33_read_id(codec);
1550 dac33_hard_power(codec, 0);
1535 1551
1536 ret = snd_soc_register_codec(codec); 1552 ret = snd_soc_register_codec(codec);
1537 if (ret != 0) { 1553 if (ret != 0) {
@@ -1546,14 +1562,9 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1546 goto error_codec; 1562 goto error_codec;
1547 } 1563 }
1548 1564
1549 /* Shut down the codec for now */
1550 dac33_hard_power(codec, 0);
1551
1552 return ret; 1565 return ret;
1553 1566
1554error_codec: 1567error_codec:
1555 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1556err_enable:
1557 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies); 1568 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1558err_get: 1569err_get:
1559 if (dac33->irq >= 0) { 1570 if (dac33->irq >= 0) {
@@ -1577,7 +1588,9 @@ static int __devexit dac33_i2c_remove(struct i2c_client *client)
1577 struct tlv320dac33_priv *dac33; 1588 struct tlv320dac33_priv *dac33;
1578 1589
1579 dac33 = i2c_get_clientdata(client); 1590 dac33 = i2c_get_clientdata(client);
1580 dac33_hard_power(&dac33->codec, 0); 1591
1592 if (unlikely(dac33->chip_power))
1593 dac33_hard_power(&dac33->codec, 0);
1581 1594
1582 if (dac33->power_gpio >= 0) 1595 if (dac33->power_gpio >= 0)
1583 gpio_free(dac33->power_gpio); 1596 gpio_free(dac33->power_gpio);
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 958d49c969ac..31f67b527ca1 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -46,6 +46,9 @@ static const char *tpa6140a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
46 "AVdd", 46 "AVdd",
47}; 47};
48 48
49#define TPA6130A2_GAIN_MAX 0x3f
50#define TPA6140A2_GAIN_MAX 0x1f
51
49/* This struct is used to save the context */ 52/* This struct is used to save the context */
50struct tpa6130a2_data { 53struct tpa6130a2_data {
51 struct mutex mutex; 54 struct mutex mutex;
@@ -53,6 +56,8 @@ struct tpa6130a2_data {
53 struct regulator_bulk_data supplies[TPA6130A2_NUM_SUPPLIES]; 56 struct regulator_bulk_data supplies[TPA6130A2_NUM_SUPPLIES];
54 int power_gpio; 57 int power_gpio;
55 unsigned char power_state; 58 unsigned char power_state;
59 enum tpa_model id;
60 int gain_limit;
56}; 61};
57 62
58static int tpa6130a2_i2c_read(int reg) 63static int tpa6130a2_i2c_read(int reg)
@@ -175,6 +180,40 @@ exit:
175 return ret; 180 return ret;
176} 181}
177 182
183static int tpa6130a2_info_volsw(struct snd_kcontrol *kcontrol,
184 struct snd_ctl_elem_info *uinfo)
185{
186 struct soc_mixer_control *mc =
187 (struct soc_mixer_control *)kcontrol->private_value;
188 struct tpa6130a2_data *data;
189
190 BUG_ON(tpa6130a2_client == NULL);
191 data = i2c_get_clientdata(tpa6130a2_client);
192
193 mutex_lock(&data->mutex);
194 switch (mc->reg) {
195 case TPA6130A2_REG_VOL_MUTE:
196 if (data->gain_limit != mc->max)
197 mc->max = data->gain_limit;
198 break;
199 default:
200 dev_err(&tpa6130a2_client->dev,
201 "Invalid register: 0x02%x\n", mc->reg);
202 goto out;
203 }
204 if (unlikely(mc->max == 1))
205 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
206 else
207 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
208
209 uinfo->count = 1;
210 uinfo->value.integer.min = 0;
211 uinfo->value.integer.max = mc->max;
212out:
213 mutex_unlock(&data->mutex);
214 return 0;
215}
216
178static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol, 217static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
179 struct snd_ctl_elem_value *ucontrol) 218 struct snd_ctl_elem_value *ucontrol)
180{ 219{
@@ -238,6 +277,15 @@ static int tpa6130a2_set_reg(struct snd_kcontrol *kcontrol,
238 return 1; 277 return 1;
239} 278}
240 279
280#define SOC_SINGLE_EXT_TLV_TPA(xname, xreg, xshift, xmax, xinvert, tlv_array) \
281{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
282 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
283 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
284 .tlv.p = (tlv_array), \
285 .info = tpa6130a2_info_volsw, \
286 .get = tpa6130a2_get_reg, .put = tpa6130a2_set_reg, \
287 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
288
241/* 289/*
242 * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going 290 * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
243 * down in gain. 291 * down in gain.
@@ -257,10 +305,22 @@ static const unsigned int tpa6130_tlv[] = {
257}; 305};
258 306
259static const struct snd_kcontrol_new tpa6130a2_controls[] = { 307static const struct snd_kcontrol_new tpa6130a2_controls[] = {
260 SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume", 308 SOC_SINGLE_EXT_TLV_TPA("TPA6130A2 Headphone Playback Volume",
261 TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0, 309 TPA6130A2_REG_VOL_MUTE, 0, TPA6130A2_GAIN_MAX, 0,
262 tpa6130a2_get_reg, tpa6130a2_set_reg, 310 tpa6130_tlv),
263 tpa6130_tlv), 311};
312
313static const unsigned int tpa6140_tlv[] = {
314 TLV_DB_RANGE_HEAD(3),
315 0, 8, TLV_DB_SCALE_ITEM(-5900, 400, 0),
316 9, 16, TLV_DB_SCALE_ITEM(-2500, 200, 0),
317 17, 31, TLV_DB_SCALE_ITEM(-1000, 100, 0),
318};
319
320static const struct snd_kcontrol_new tpa6140a2_controls[] = {
321 SOC_SINGLE_EXT_TLV_TPA("TPA6140A2 Headphone Playback Volume",
322 TPA6130A2_REG_VOL_MUTE, 1, TPA6140A2_GAIN_MAX, 0,
323 tpa6140_tlv),
264}; 324};
265 325
266/* 326/*
@@ -368,13 +428,22 @@ static const struct snd_soc_dapm_route audio_map[] = {
368 428
369int tpa6130a2_add_controls(struct snd_soc_codec *codec) 429int tpa6130a2_add_controls(struct snd_soc_codec *codec)
370{ 430{
431 struct tpa6130a2_data *data;
432
433 BUG_ON(tpa6130a2_client == NULL);
434 data = i2c_get_clientdata(tpa6130a2_client);
435
371 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets, 436 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets,
372 ARRAY_SIZE(tpa6130a2_dapm_widgets)); 437 ARRAY_SIZE(tpa6130a2_dapm_widgets));
373 438
374 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 439 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
375 440
376 return snd_soc_add_controls(codec, tpa6130a2_controls, 441 if (data->id == TPA6140A2)
377 ARRAY_SIZE(tpa6130a2_controls)); 442 return snd_soc_add_controls(codec, tpa6140a2_controls,
443 ARRAY_SIZE(tpa6140a2_controls));
444 else
445 return snd_soc_add_controls(codec, tpa6130a2_controls,
446 ARRAY_SIZE(tpa6130a2_controls));
378 447
379} 448}
380EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); 449EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
@@ -407,6 +476,7 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
407 476
408 pdata = client->dev.platform_data; 477 pdata = client->dev.platform_data;
409 data->power_gpio = pdata->power_gpio; 478 data->power_gpio = pdata->power_gpio;
479 data->id = pdata->id;
410 480
411 mutex_init(&data->mutex); 481 mutex_init(&data->mutex);
412 482
@@ -425,20 +495,35 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
425 gpio_direction_output(data->power_gpio, 0); 495 gpio_direction_output(data->power_gpio, 0);
426 } 496 }
427 497
428 switch (pdata->id) { 498 switch (data->id) {
429 case TPA6130A2: 499 case TPA6130A2:
430 for (i = 0; i < ARRAY_SIZE(data->supplies); i++) 500 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
431 data->supplies[i].supply = tpa6130a2_supply_names[i]; 501 data->supplies[i].supply = tpa6130a2_supply_names[i];
502 if (pdata->limit_gain > 0 &&
503 pdata->limit_gain < TPA6130A2_GAIN_MAX)
504 data->gain_limit = pdata->limit_gain;
505 else
506 data->gain_limit = TPA6130A2_GAIN_MAX;
432 break; 507 break;
433 case TPA6140A2: 508 case TPA6140A2:
434 for (i = 0; i < ARRAY_SIZE(data->supplies); i++) 509 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
435 data->supplies[i].supply = tpa6140a2_supply_names[i];; 510 data->supplies[i].supply = tpa6140a2_supply_names[i];;
511 if (pdata->limit_gain > 0 &&
512 pdata->limit_gain < TPA6140A2_GAIN_MAX)
513 data->gain_limit = pdata->limit_gain;
514 else
515 data->gain_limit = TPA6140A2_GAIN_MAX;
436 break; 516 break;
437 default: 517 default:
438 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n", 518 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
439 pdata->id); 519 pdata->id);
440 for (i = 0; i < ARRAY_SIZE(data->supplies); i++) 520 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
441 data->supplies[i].supply = tpa6130a2_supply_names[i]; 521 data->supplies[i].supply = tpa6130a2_supply_names[i];
522 if (pdata->limit_gain > 0 &&
523 pdata->limit_gain < TPA6130A2_GAIN_MAX)
524 data->gain_limit = pdata->limit_gain;
525 else
526 data->gain_limit = TPA6130A2_GAIN_MAX;
442 } 527 }
443 528
444 ret = regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), 529 ret = regulator_bulk_get(dev, ARRAY_SIZE(data->supplies),
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 2e025a3a2618..b717a03dfacf 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -123,6 +123,8 @@ struct twl4030_priv {
123 struct snd_soc_codec codec; 123 struct snd_soc_codec codec;
124 124
125 unsigned int codec_powered; 125 unsigned int codec_powered;
126
127 /* reference counts of AIF/APLL users */
126 unsigned int apll_enabled; 128 unsigned int apll_enabled;
127 129
128 struct snd_pcm_substream *master_substream; 130 struct snd_pcm_substream *master_substream;
@@ -259,22 +261,22 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
259static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable) 261static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
260{ 262{
261 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 263 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
262 int status; 264 int status = -1;
263
264 if (enable == twl4030->apll_enabled)
265 return;
266 265
267 if (enable) 266 if (enable) {
268 /* Enable PLL */ 267 twl4030->apll_enabled++;
269 status = twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL); 268 if (twl4030->apll_enabled == 1)
270 else 269 status = twl4030_codec_enable_resource(
271 /* Disable PLL */ 270 TWL4030_CODEC_RES_APLL);
272 status = twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL); 271 } else {
272 twl4030->apll_enabled--;
273 if (!twl4030->apll_enabled)
274 status = twl4030_codec_disable_resource(
275 TWL4030_CODEC_RES_APLL);
276 }
273 277
274 if (status >= 0) 278 if (status >= 0)
275 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status); 279 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
276
277 twl4030->apll_enabled = enable;
278} 280}
279 281
280static void twl4030_power_up(struct snd_soc_codec *codec) 282static void twl4030_power_up(struct snd_soc_codec *codec)
@@ -672,6 +674,31 @@ static int apll_event(struct snd_soc_dapm_widget *w,
672 return 0; 674 return 0;
673} 675}
674 676
677static int aif_event(struct snd_soc_dapm_widget *w,
678 struct snd_kcontrol *kcontrol, int event)
679{
680 u8 audio_if;
681
682 audio_if = twl4030_read_reg_cache(w->codec, TWL4030_REG_AUDIO_IF);
683 switch (event) {
684 case SND_SOC_DAPM_PRE_PMU:
685 /* Enable AIF */
686 /* enable the PLL before we use it to clock the DAI */
687 twl4030_apll_enable(w->codec, 1);
688
689 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
690 audio_if | TWL4030_AIF_EN);
691 break;
692 case SND_SOC_DAPM_POST_PMD:
693 /* disable the DAI before we stop it's source PLL */
694 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
695 audio_if & ~TWL4030_AIF_EN);
696 twl4030_apll_enable(w->codec, 0);
697 break;
698 }
699 return 0;
700}
701
675static void headset_ramp(struct snd_soc_codec *codec, int ramp) 702static void headset_ramp(struct snd_soc_codec *codec, int ramp)
676{ 703{
677 struct snd_soc_device *socdev = codec->socdev; 704 struct snd_soc_device *socdev = codec->socdev;
@@ -1167,8 +1194,6 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1167 SND_SOC_DAPM_INPUT("DIGIMIC1"), 1194 SND_SOC_DAPM_INPUT("DIGIMIC1"),
1168 1195
1169 /* Outputs */ 1196 /* Outputs */
1170 SND_SOC_DAPM_OUTPUT("OUTL"),
1171 SND_SOC_DAPM_OUTPUT("OUTR"),
1172 SND_SOC_DAPM_OUTPUT("EARPIECE"), 1197 SND_SOC_DAPM_OUTPUT("EARPIECE"),
1173 SND_SOC_DAPM_OUTPUT("PREDRIVEL"), 1198 SND_SOC_DAPM_OUTPUT("PREDRIVEL"),
1174 SND_SOC_DAPM_OUTPUT("PREDRIVER"), 1199 SND_SOC_DAPM_OUTPUT("PREDRIVER"),
@@ -1180,6 +1205,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1180 SND_SOC_DAPM_OUTPUT("HFR"), 1205 SND_SOC_DAPM_OUTPUT("HFR"),
1181 SND_SOC_DAPM_OUTPUT("VIBRA"), 1206 SND_SOC_DAPM_OUTPUT("VIBRA"),
1182 1207
1208 /* AIF and APLL clocks for running DAIs (including loopback) */
1209 SND_SOC_DAPM_OUTPUT("Virtual HiFi OUT"),
1210 SND_SOC_DAPM_INPUT("Virtual HiFi IN"),
1211 SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"),
1212
1183 /* DACs */ 1213 /* DACs */
1184 SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback", 1214 SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback",
1185 SND_SOC_NOPM, 0, 0), 1215 SND_SOC_NOPM, 0, 0),
@@ -1243,7 +1273,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1243 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event, 1273 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1244 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD), 1274 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1245 1275
1246 SND_SOC_DAPM_SUPPLY("AIF Enable", TWL4030_REG_AUDIO_IF, 0, 0, NULL, 0), 1276 SND_SOC_DAPM_SUPPLY("AIF Enable", SND_SOC_NOPM, 0, 0, aif_event,
1277 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1247 1278
1248 /* Output MIXER controls */ 1279 /* Output MIXER controls */
1249 /* Earpiece */ 1280 /* Earpiece */
@@ -1373,10 +1404,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1373 {"Digital Voice Playback Mixer", NULL, "DAC Voice"}, 1404 {"Digital Voice Playback Mixer", NULL, "DAC Voice"},
1374 1405
1375 /* Supply for the digital part (APLL) */ 1406 /* Supply for the digital part (APLL) */
1376 {"Digital R1 Playback Mixer", NULL, "APLL Enable"},
1377 {"Digital L1 Playback Mixer", NULL, "APLL Enable"},
1378 {"Digital R2 Playback Mixer", NULL, "APLL Enable"},
1379 {"Digital L2 Playback Mixer", NULL, "APLL Enable"},
1380 {"Digital Voice Playback Mixer", NULL, "APLL Enable"}, 1407 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1381 1408
1382 {"Digital R1 Playback Mixer", NULL, "AIF Enable"}, 1409 {"Digital R1 Playback Mixer", NULL, "AIF Enable"},
@@ -1450,8 +1477,14 @@ static const struct snd_soc_dapm_route intercon[] = {
1450 {"Vibra Mux", "AudioR2", "DAC Right2"}, 1477 {"Vibra Mux", "AudioR2", "DAC Right2"},
1451 1478
1452 /* outputs */ 1479 /* outputs */
1453 {"OUTL", NULL, "Analog L2 Playback Mixer"}, 1480 /* Must be always connected (for AIF and APLL) */
1454 {"OUTR", NULL, "Analog R2 Playback Mixer"}, 1481 {"Virtual HiFi OUT", NULL, "Digital L1 Playback Mixer"},
1482 {"Virtual HiFi OUT", NULL, "Digital R1 Playback Mixer"},
1483 {"Virtual HiFi OUT", NULL, "Digital L2 Playback Mixer"},
1484 {"Virtual HiFi OUT", NULL, "Digital R2 Playback Mixer"},
1485 /* Must be always connected (for APLL) */
1486 {"Virtual Voice OUT", NULL, "Digital Voice Playback Mixer"},
1487 /* Physical outputs */
1455 {"EARPIECE", NULL, "Earpiece PGA"}, 1488 {"EARPIECE", NULL, "Earpiece PGA"},
1456 {"PREDRIVEL", NULL, "PredriveL PGA"}, 1489 {"PREDRIVEL", NULL, "PredriveL PGA"},
1457 {"PREDRIVER", NULL, "PredriveR PGA"}, 1490 {"PREDRIVER", NULL, "PredriveR PGA"},
@@ -1465,6 +1498,12 @@ static const struct snd_soc_dapm_route intercon[] = {
1465 {"VIBRA", NULL, "Vibra Route"}, 1498 {"VIBRA", NULL, "Vibra Route"},
1466 1499
1467 /* Capture path */ 1500 /* Capture path */
1501 /* Must be always connected (for AIF and APLL) */
1502 {"ADC Virtual Left1", NULL, "Virtual HiFi IN"},
1503 {"ADC Virtual Right1", NULL, "Virtual HiFi IN"},
1504 {"ADC Virtual Left2", NULL, "Virtual HiFi IN"},
1505 {"ADC Virtual Right2", NULL, "Virtual HiFi IN"},
1506 /* Physical inputs */
1468 {"Analog Left", "Main Mic Capture Switch", "MAINMIC"}, 1507 {"Analog Left", "Main Mic Capture Switch", "MAINMIC"},
1469 {"Analog Left", "Headset Mic Capture Switch", "HSMIC"}, 1508 {"Analog Left", "Headset Mic Capture Switch", "HSMIC"},
1470 {"Analog Left", "AUXL Capture Switch", "AUXL"}, 1509 {"Analog Left", "AUXL Capture Switch", "AUXL"},
@@ -1497,11 +1536,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1497 {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, 1536 {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
1498 {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, 1537 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1499 1538
1500 {"ADC Virtual Left1", NULL, "APLL Enable"},
1501 {"ADC Virtual Right1", NULL, "APLL Enable"},
1502 {"ADC Virtual Left2", NULL, "APLL Enable"},
1503 {"ADC Virtual Right2", NULL, "APLL Enable"},
1504
1505 {"ADC Virtual Left1", NULL, "AIF Enable"}, 1539 {"ADC Virtual Left1", NULL, "AIF Enable"},
1506 {"ADC Virtual Right1", NULL, "AIF Enable"}, 1540 {"ADC Virtual Right1", NULL, "AIF Enable"},
1507 {"ADC Virtual Left2", NULL, "AIF Enable"}, 1541 {"ADC Virtual Left2", NULL, "AIF Enable"},
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index f11963c21873..83be4a76d2bb 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -18,6 +18,16 @@ config SND_OMAP_SOC_N810
18 help 18 help
19 Say Y if you want to add support for SoC audio on Nokia N810. 19 Say Y if you want to add support for SoC audio on Nokia N810.
20 20
21config SND_OMAP_SOC_RX51
22 tristate "SoC Audio support for Nokia RX-51"
23 depends on SND_OMAP_SOC && MACH_NOKIA_RX51
24 select OMAP_MCBSP
25 select SND_OMAP_SOC_MCBSP
26 select SND_SOC_TLV320AIC3X
27 help
28 Say Y if you want to add support for SoC audio on Nokia RX-51
29 hardware. This is also known as Nokia N900 product.
30
21config SND_OMAP_SOC_AMS_DELTA 31config SND_OMAP_SOC_AMS_DELTA
22 tristate "SoC Audio support for Amstrad E3 (Delta) videophone" 32 tristate "SoC Audio support for Amstrad E3 (Delta) videophone"
23 depends on SND_OMAP_SOC && MACH_AMS_DELTA 33 depends on SND_OMAP_SOC && MACH_AMS_DELTA
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 0bc00ca14b37..3a75755f25e4 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
9 9
10# OMAP Machine Support 10# OMAP Machine Support
11snd-soc-n810-objs := n810.o 11snd-soc-n810-objs := n810.o
12snd-soc-rx51-objs := rx51.o
12snd-soc-ams-delta-objs := ams-delta.o 13snd-soc-ams-delta-objs := ams-delta.o
13snd-soc-osk5912-objs := osk5912.o 14snd-soc-osk5912-objs := osk5912.o
14snd-soc-overo-objs := overo.o 15snd-soc-overo-objs := overo.o
@@ -22,6 +23,7 @@ snd-soc-zoom2-objs := zoom2.o
22snd-soc-igep0020-objs := igep0020.o 23snd-soc-igep0020-objs := igep0020.o
23 24
24obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 25obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
26obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o
25obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o 27obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
26obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o 28obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
27obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o 29obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index de10f76baded..87ce842fa2e8 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -188,8 +188,6 @@ static int omap3pandora_out_init(struct snd_soc_codec *codec)
188 int ret; 188 int ret;
189 189
190 /* All TWL4030 output pins are floating */ 190 /* All TWL4030 output pins are floating */
191 snd_soc_dapm_nc_pin(codec, "OUTL");
192 snd_soc_dapm_nc_pin(codec, "OUTR");
193 snd_soc_dapm_nc_pin(codec, "EARPIECE"); 191 snd_soc_dapm_nc_pin(codec, "EARPIECE");
194 snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); 192 snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
195 snd_soc_dapm_nc_pin(codec, "PREDRIVER"); 193 snd_soc_dapm_nc_pin(codec, "PREDRIVER");
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
new file mode 100644
index 000000000000..47d831ef2dbb
--- /dev/null
+++ b/sound/soc/omap/rx51.c
@@ -0,0 +1,294 @@
1/*
2 * rx51.c -- SoC audio for Nokia RX-51
3 *
4 * Copyright (C) 2008 - 2009 Nokia Corporation
5 *
6 * Contact: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 * Eduardo Valentin <eduardo.valentin@nokia.com>
8 * Jarkko Nikula <jhnikula@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#include <linux/delay.h>
27#include <linux/gpio.h>
28#include <linux/platform_device.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33
34#include <asm/mach-types.h>
35
36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38#include "../codecs/tlv320aic3x.h"
39
40/*
41 * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This
42 * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c
43 */
44#define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7)
45
46static int rx51_spk_func;
47static int rx51_dmic_func;
48
49static void rx51_ext_control(struct snd_soc_codec *codec)
50{
51 if (rx51_spk_func)
52 snd_soc_dapm_enable_pin(codec, "Ext Spk");
53 else
54 snd_soc_dapm_disable_pin(codec, "Ext Spk");
55 if (rx51_dmic_func)
56 snd_soc_dapm_enable_pin(codec, "DMic");
57 else
58 snd_soc_dapm_disable_pin(codec, "DMic");
59
60 snd_soc_dapm_sync(codec);
61}
62
63static int rx51_startup(struct snd_pcm_substream *substream)
64{
65 struct snd_pcm_runtime *runtime = substream->runtime;
66 struct snd_soc_pcm_runtime *rtd = substream->private_data;
67 struct snd_soc_codec *codec = rtd->socdev->card->codec;
68
69 snd_pcm_hw_constraint_minmax(runtime,
70 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
71 rx51_ext_control(codec);
72
73 return 0;
74}
75
76static int rx51_hw_params(struct snd_pcm_substream *substream,
77 struct snd_pcm_hw_params *params)
78{
79 struct snd_soc_pcm_runtime *rtd = substream->private_data;
80 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
81 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
82 int err;
83
84 /* Set codec DAI configuration */
85 err = snd_soc_dai_set_fmt(codec_dai,
86 SND_SOC_DAIFMT_DSP_A |
87 SND_SOC_DAIFMT_IB_NF |
88 SND_SOC_DAIFMT_CBM_CFM);
89 if (err < 0)
90 return err;
91
92 /* Set cpu DAI configuration */
93 err = snd_soc_dai_set_fmt(cpu_dai,
94 SND_SOC_DAIFMT_DSP_A |
95 SND_SOC_DAIFMT_IB_NF |
96 SND_SOC_DAIFMT_CBM_CFM);
97 if (err < 0)
98 return err;
99
100 /* Set the codec system clock for DAC and ADC */
101 return snd_soc_dai_set_sysclk(codec_dai, 0, 19200000,
102 SND_SOC_CLOCK_IN);
103}
104
105static struct snd_soc_ops rx51_ops = {
106 .startup = rx51_startup,
107 .hw_params = rx51_hw_params,
108};
109
110static int rx51_get_spk(struct snd_kcontrol *kcontrol,
111 struct snd_ctl_elem_value *ucontrol)
112{
113 ucontrol->value.integer.value[0] = rx51_spk_func;
114
115 return 0;
116}
117
118static int rx51_set_spk(struct snd_kcontrol *kcontrol,
119 struct snd_ctl_elem_value *ucontrol)
120{
121 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
122
123 if (rx51_spk_func == ucontrol->value.integer.value[0])
124 return 0;
125
126 rx51_spk_func = ucontrol->value.integer.value[0];
127 rx51_ext_control(codec);
128
129 return 1;
130}
131
132static int rx51_spk_event(struct snd_soc_dapm_widget *w,
133 struct snd_kcontrol *k, int event)
134{
135 if (SND_SOC_DAPM_EVENT_ON(event))
136 gpio_set_value(RX51_SPEAKER_AMP_TWL_GPIO, 1);
137 else
138 gpio_set_value(RX51_SPEAKER_AMP_TWL_GPIO, 0);
139
140 return 0;
141}
142
143static int rx51_get_input(struct snd_kcontrol *kcontrol,
144 struct snd_ctl_elem_value *ucontrol)
145{
146 ucontrol->value.integer.value[0] = rx51_dmic_func;
147
148 return 0;
149}
150
151static int rx51_set_input(struct snd_kcontrol *kcontrol,
152 struct snd_ctl_elem_value *ucontrol)
153{
154 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
155
156 if (rx51_dmic_func == ucontrol->value.integer.value[0])
157 return 0;
158
159 rx51_dmic_func = ucontrol->value.integer.value[0];
160 rx51_ext_control(codec);
161
162 return 1;
163}
164
165static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
166 SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
167 SND_SOC_DAPM_MIC("DMic", NULL),
168};
169
170static const struct snd_soc_dapm_route audio_map[] = {
171 {"Ext Spk", NULL, "HPLOUT"},
172 {"Ext Spk", NULL, "HPROUT"},
173
174 {"DMic Rate 64", NULL, "Mic Bias 2V"},
175 {"Mic Bias 2V", NULL, "DMic"},
176};
177
178static const char *spk_function[] = {"Off", "On"};
179static const char *input_function[] = {"ADC", "Digital Mic"};
180
181static const struct soc_enum rx51_enum[] = {
182 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
183 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_function), input_function),
184};
185
186static const struct snd_kcontrol_new aic34_rx51_controls[] = {
187 SOC_ENUM_EXT("Speaker Function", rx51_enum[0],
188 rx51_get_spk, rx51_set_spk),
189 SOC_ENUM_EXT("Input Select", rx51_enum[1],
190 rx51_get_input, rx51_set_input),
191};
192
193static int rx51_aic34_init(struct snd_soc_codec *codec)
194{
195 int err;
196
197 /* Set up NC codec pins */
198 snd_soc_dapm_nc_pin(codec, "MIC3L");
199 snd_soc_dapm_nc_pin(codec, "MIC3R");
200 snd_soc_dapm_nc_pin(codec, "LINE1R");
201
202 /* Add RX-51 specific controls */
203 err = snd_soc_add_controls(codec, aic34_rx51_controls,
204 ARRAY_SIZE(aic34_rx51_controls));
205 if (err < 0)
206 return err;
207
208 /* Add RX-51 specific widgets */
209 snd_soc_dapm_new_controls(codec, aic34_dapm_widgets,
210 ARRAY_SIZE(aic34_dapm_widgets));
211
212 /* Set up RX-51 specific audio path audio_map */
213 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
214
215 snd_soc_dapm_sync(codec);
216
217 return 0;
218}
219
220/* Digital audio interface glue - connects codec <--> CPU */
221static struct snd_soc_dai_link rx51_dai[] = {
222 {
223 .name = "TLV320AIC34",
224 .stream_name = "AIC34",
225 .cpu_dai = &omap_mcbsp_dai[0],
226 .codec_dai = &aic3x_dai,
227 .init = rx51_aic34_init,
228 .ops = &rx51_ops,
229 },
230};
231
232/* Audio private data */
233static struct aic3x_setup_data rx51_aic34_setup = {
234 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
235 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
236};
237
238/* Audio card */
239static struct snd_soc_card rx51_sound_card = {
240 .name = "RX-51",
241 .dai_link = rx51_dai,
242 .num_links = ARRAY_SIZE(rx51_dai),
243 .platform = &omap_soc_platform,
244};
245
246/* Audio subsystem */
247static struct snd_soc_device rx51_snd_devdata = {
248 .card = &rx51_sound_card,
249 .codec_dev = &soc_codec_dev_aic3x,
250 .codec_data = &rx51_aic34_setup,
251};
252
253static struct platform_device *rx51_snd_device;
254
255static int __init rx51_soc_init(void)
256{
257 int err;
258
259 if (!machine_is_nokia_rx51())
260 return -ENODEV;
261
262 rx51_snd_device = platform_device_alloc("soc-audio", -1);
263 if (!rx51_snd_device) {
264 err = -ENOMEM;
265 goto err1;
266 }
267
268 platform_set_drvdata(rx51_snd_device, &rx51_snd_devdata);
269 rx51_snd_devdata.dev = &rx51_snd_device->dev;
270 *(unsigned int *)rx51_dai[0].cpu_dai->private_data = 1; /* McBSP2 */
271
272 err = platform_device_add(rx51_snd_device);
273 if (err)
274 goto err2;
275
276 return 0;
277err2:
278 platform_device_put(rx51_snd_device);
279err1:
280
281 return err;
282}
283
284static void __exit rx51_soc_exit(void)
285{
286 platform_device_unregister(rx51_snd_device);
287}
288
289module_init(rx51_soc_init);
290module_exit(rx51_soc_exit);
291
292MODULE_AUTHOR("Nokia Corporation");
293MODULE_DESCRIPTION("ALSA SoC Nokia RX-51");
294MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index f90a2ac888cf..50a94ee76ecc 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -181,9 +181,6 @@ static int zoom2_twl4030_init(struct snd_soc_codec *codec)
181 snd_soc_dapm_nc_pin(codec, "CARKITMIC"); 181 snd_soc_dapm_nc_pin(codec, "CARKITMIC");
182 snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); 182 snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
183 snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); 183 snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
184
185 snd_soc_dapm_nc_pin(codec, "OUTL");
186 snd_soc_dapm_nc_pin(codec, "OUTR");
187 snd_soc_dapm_nc_pin(codec, "EARPIECE"); 184 snd_soc_dapm_nc_pin(codec, "EARPIECE");
188 snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); 185 snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
189 snd_soc_dapm_nc_pin(codec, "PREDRIVER"); 186 snd_soc_dapm_nc_pin(codec, "PREDRIVER");