aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/cs4270.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/cs4270.c')
-rw-r--r--sound/soc/codecs/cs4270.c93
1 files changed, 40 insertions, 53 deletions
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 2c79a24186fd..cd4a9ee38e46 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -395,17 +395,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
395 return -EINVAL; 395 return -EINVAL;
396 } 396 }
397 397
398 /* Freeze and power-down the codec */ 398 /* Set the sample rate */
399
400 ret = snd_soc_write(codec, CS4270_PWRCTL, CS4270_PWRCTL_FREEZE |
401 CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC |
402 CS4270_PWRCTL_PDN);
403 if (ret < 0) {
404 dev_err(codec->dev, "i2c write failed\n");
405 return ret;
406 }
407
408 /* Program the mode control register */
409 399
410 reg = snd_soc_read(codec, CS4270_MODE); 400 reg = snd_soc_read(codec, CS4270_MODE);
411 reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK); 401 reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
@@ -417,7 +407,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
417 return ret; 407 return ret;
418 } 408 }
419 409
420 /* Program the format register */ 410 /* Set the DAI format */
421 411
422 reg = snd_soc_read(codec, CS4270_FORMAT); 412 reg = snd_soc_read(codec, CS4270_FORMAT);
423 reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK); 413 reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);
@@ -440,42 +430,9 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
440 return ret; 430 return ret;
441 } 431 }
442 432
443 /* Disable auto-mute. This feature appears to be buggy, because in
444 some situations, auto-mute will not deactivate when it should. */
445
446 reg = snd_soc_read(codec, CS4270_MUTE);
447 reg &= ~CS4270_MUTE_AUTO;
448 ret = snd_soc_write(codec, CS4270_MUTE, reg);
449 if (ret < 0) {
450 dev_err(codec->dev, "i2c write failed\n");
451 return ret;
452 }
453
454 /* Disable automatic volume control. It's enabled by default, and
455 * it causes volume change commands to be delayed, sometimes until
456 * after playback has started.
457 */
458
459 reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
460 reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
461 ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
462 if (ret < 0) {
463 dev_err(codec->dev, "i2c write failed\n");
464 return ret;
465 }
466
467 /* Thaw and power-up the codec */
468
469 ret = snd_soc_write(codec, CS4270_PWRCTL, 0);
470 if (ret < 0) {
471 dev_err(codec->dev, "i2c write failed\n");
472 return ret;
473 }
474
475 return ret; 433 return ret;
476} 434}
477 435
478#ifdef CONFIG_SND_SOC_CS4270_HWMUTE
479/** 436/**
480 * cs4270_mute - enable/disable the CS4270 external mute 437 * cs4270_mute - enable/disable the CS4270 external mute
481 * @dai: the SOC DAI 438 * @dai: the SOC DAI
@@ -494,22 +451,23 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute)
494 reg6 = snd_soc_read(codec, CS4270_MUTE); 451 reg6 = snd_soc_read(codec, CS4270_MUTE);
495 452
496 if (mute) 453 if (mute)
497 reg6 |= CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B | 454 reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
498 CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
499 else 455 else
500 reg6 &= ~(CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B | 456 reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
501 CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
502 457
503 return snd_soc_write(codec, CS4270_MUTE, reg6); 458 return snd_soc_write(codec, CS4270_MUTE, reg6);
504} 459}
505#else
506#define cs4270_mute NULL
507#endif
508 460
509/* A list of non-DAPM controls that the CS4270 supports */ 461/* A list of non-DAPM controls that the CS4270 supports */
510static const struct snd_kcontrol_new cs4270_snd_controls[] = { 462static const struct snd_kcontrol_new cs4270_snd_controls[] = {
511 SOC_DOUBLE_R("Master Playback Volume", 463 SOC_DOUBLE_R("Master Playback Volume",
512 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1) 464 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1),
465 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
466 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
467 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
468 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
469 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
470 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 0)
513}; 471};
514 472
515/* 473/*
@@ -637,6 +595,7 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
637{ 595{
638 struct snd_soc_codec *codec; 596 struct snd_soc_codec *codec;
639 struct cs4270_private *cs4270; 597 struct cs4270_private *cs4270;
598 unsigned int reg;
640 int ret; 599 int ret;
641 600
642 /* For now, we only support one cs4270 device in the system. See the 601 /* For now, we only support one cs4270 device in the system. See the
@@ -702,6 +661,34 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
702 goto error_free_codec; 661 goto error_free_codec;
703 } 662 }
704 663
664 /* Disable auto-mute. This feature appears to be buggy. In some
665 * situations, auto-mute will not deactivate when it should, so we want
666 * this feature disabled by default. An application (e.g. alsactl) can
667 * re-enabled it by using the controls.
668 */
669
670 reg = cs4270_read_reg_cache(codec, CS4270_MUTE);
671 reg &= ~CS4270_MUTE_AUTO;
672 ret = cs4270_i2c_write(codec, CS4270_MUTE, reg);
673 if (ret < 0) {
674 dev_err(&i2c_client->dev, "i2c write failed\n");
675 return ret;
676 }
677
678 /* Disable automatic volume control. The hardware enables, and it
679 * causes volume change commands to be delayed, sometimes until after
680 * playback has started. An application (e.g. alsactl) can
681 * re-enabled it by using the controls.
682 */
683
684 reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
685 reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
686 ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
687 if (ret < 0) {
688 dev_err(&i2c_client->dev, "i2c write failed\n");
689 return ret;
690 }
691
705 /* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI 692 /* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI
706 * structure for each CS4270 device, but the machine driver needs to 693 * structure for each CS4270 device, but the machine driver needs to
707 * have a pointer to the DAI structure, so for now it must be a global 694 * have a pointer to the DAI structure, so for now it must be a global