aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/tlv320dac33.c66
1 files changed, 45 insertions, 21 deletions
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 50d152215abd..68b7ccbf2e7c 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
@@ -355,9 +357,17 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
355static int dac33_hard_power(struct snd_soc_codec *codec, int power) 357static int dac33_hard_power(struct snd_soc_codec *codec, int power)
356{ 358{
357 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 359 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
358 int ret; 360 int ret = 0;
359 361
360 mutex_lock(&dac33->mutex); 362 mutex_lock(&dac33->mutex);
363
364 /* Safety check */
365 if (unlikely(power == dac33->chip_power)) {
366 dev_warn(codec->dev, "Trying to set the same power state: %s\n",
367 power ? "ON" : "OFF");
368 goto exit;
369 }
370
361 if (power) { 371 if (power) {
362 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies), 372 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
363 dac33->supplies); 373 dac33->supplies);
@@ -371,10 +381,6 @@ static int dac33_hard_power(struct snd_soc_codec *codec, int power)
371 gpio_set_value(dac33->power_gpio, 1); 381 gpio_set_value(dac33->power_gpio, 1);
372 382
373 dac33->chip_power = 1; 383 dac33->chip_power = 1;
374
375 dac33_init_chip(codec);
376
377 dac33_soft_power(codec, 1);
378 } else { 384 } else {
379 dac33_soft_power(codec, 0); 385 dac33_soft_power(codec, 0);
380 if (dac33->power_gpio >= 0) 386 if (dac33->power_gpio >= 0)
@@ -396,6 +402,22 @@ exit:
396 return ret; 402 return ret;
397} 403}
398 404
405static int playback_event(struct snd_soc_dapm_widget *w,
406 struct snd_kcontrol *kcontrol, int event)
407{
408 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec);
409
410 switch (event) {
411 case SND_SOC_DAPM_PRE_PMU:
412 if (likely(dac33->substream)) {
413 dac33_calculate_times(dac33->substream);
414 dac33_prepare_chip(dac33->substream);
415 }
416 break;
417 }
418 return 0;
419}
420
399static int dac33_get_nsample(struct snd_kcontrol *kcontrol, 421static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
400 struct snd_ctl_elem_value *ucontrol) 422 struct snd_ctl_elem_value *ucontrol)
401{ 423{
@@ -525,6 +547,8 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
525 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0), 547 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
526 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power", 548 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power",
527 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0), 549 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
550
551 SND_SOC_DAPM_PRE("Prepare Playback", playback_event),
528}; 552};
529 553
530static const struct snd_soc_dapm_route audio_map[] = { 554static const struct snd_soc_dapm_route audio_map[] = {
@@ -567,18 +591,18 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
567 break; 591 break;
568 case SND_SOC_BIAS_STANDBY: 592 case SND_SOC_BIAS_STANDBY:
569 if (codec->bias_level == SND_SOC_BIAS_OFF) { 593 if (codec->bias_level == SND_SOC_BIAS_OFF) {
594 /* Coming from OFF, switch on the codec */
570 ret = dac33_hard_power(codec, 1); 595 ret = dac33_hard_power(codec, 1);
571 if (ret != 0) 596 if (ret != 0)
572 return ret; 597 return ret;
573 }
574 598
575 dac33_soft_power(codec, 0); 599 dac33_init_chip(codec);
600 }
576 break; 601 break;
577 case SND_SOC_BIAS_OFF: 602 case SND_SOC_BIAS_OFF:
578 ret = dac33_hard_power(codec, 0); 603 ret = dac33_hard_power(codec, 0);
579 if (ret != 0) 604 if (ret != 0)
580 return ret; 605 return ret;
581
582 break; 606 break;
583 } 607 }
584 codec->bias_level = level; 608 codec->bias_level = level;
@@ -829,6 +853,16 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
829 } 853 }
830 854
831 mutex_lock(&dac33->mutex); 855 mutex_lock(&dac33->mutex);
856
857 if (!dac33->chip_power) {
858 /*
859 * Chip is not powered yet.
860 * Do the init in the dac33_set_bias_level later.
861 */
862 mutex_unlock(&dac33->mutex);
863 return 0;
864 }
865
832 dac33_soft_power(codec, 0); 866 dac33_soft_power(codec, 0);
833 dac33_soft_power(codec, 1); 867 dac33_soft_power(codec, 1);
834 868
@@ -1035,15 +1069,6 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
1035 1069
1036} 1070}
1037 1071
1038static int dac33_pcm_prepare(struct snd_pcm_substream *substream,
1039 struct snd_soc_dai *dai)
1040{
1041 dac33_calculate_times(substream);
1042 dac33_prepare_chip(substream);
1043
1044 return 0;
1045}
1046
1047static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd, 1072static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
1048 struct snd_soc_dai *dai) 1073 struct snd_soc_dai *dai)
1049{ 1074{
@@ -1336,9 +1361,6 @@ static int dac33_soc_probe(struct platform_device *pdev)
1336 1361
1337 dac33_add_widgets(codec); 1362 dac33_add_widgets(codec);
1338 1363
1339 /* power on device */
1340 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1341
1342 return 0; 1364 return 0;
1343 1365
1344pcm_err: 1366pcm_err:
@@ -1375,6 +1397,8 @@ static int dac33_soc_resume(struct platform_device *pdev)
1375 struct snd_soc_codec *codec = socdev->card->codec; 1397 struct snd_soc_codec *codec = socdev->card->codec;
1376 1398
1377 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1399 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1400 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
1401 dac33_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1378 dac33_set_bias_level(codec, codec->suspend_bias_level); 1402 dac33_set_bias_level(codec, codec->suspend_bias_level);
1379 1403
1380 return 0; 1404 return 0;
@@ -1396,7 +1420,6 @@ static struct snd_soc_dai_ops dac33_dai_ops = {
1396 .startup = dac33_startup, 1420 .startup = dac33_startup,
1397 .shutdown = dac33_shutdown, 1421 .shutdown = dac33_shutdown,
1398 .hw_params = dac33_hw_params, 1422 .hw_params = dac33_hw_params,
1399 .prepare = dac33_pcm_prepare,
1400 .trigger = dac33_pcm_trigger, 1423 .trigger = dac33_pcm_trigger,
1401 .delay = dac33_dai_delay, 1424 .delay = dac33_dai_delay,
1402 .set_sysclk = dac33_set_dai_sysclk, 1425 .set_sysclk = dac33_set_dai_sysclk,
@@ -1450,6 +1473,7 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1450 codec->hw_write = (hw_write_t) i2c_master_send; 1473 codec->hw_write = (hw_write_t) i2c_master_send;
1451 codec->bias_level = SND_SOC_BIAS_OFF; 1474 codec->bias_level = SND_SOC_BIAS_OFF;
1452 codec->set_bias_level = dac33_set_bias_level; 1475 codec->set_bias_level = dac33_set_bias_level;
1476 codec->idle_bias_off = 1;
1453 codec->dai = &dac33_dai; 1477 codec->dai = &dac33_dai;
1454 codec->num_dai = 1; 1478 codec->num_dai = 1;
1455 codec->reg_cache_size = ARRAY_SIZE(dac33_reg); 1479 codec->reg_cache_size = ARRAY_SIZE(dac33_reg);