diff --git a/[refs] b/[refs] index c7702ab9e70e..a101563d2a5f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9e30d7718bb7402c7bdee631ad2aae2658c324f0 +refs/heads/master: d5e9ba1d58b6da1c58a91113fc350ece97ec5a0b diff --git a/trunk/sound/soc/codecs/Kconfig b/trunk/sound/soc/codecs/Kconfig index a195303603e0..628a591c728f 100644 --- a/trunk/sound/soc/codecs/Kconfig +++ b/trunk/sound/soc/codecs/Kconfig @@ -67,12 +67,6 @@ config SND_SOC_AK4535 config SND_SOC_CS4270 tristate -# Cirrus Logic CS4270 Codec Hardware Mute Support -# Select if you have external muting circuitry attached to your CS4270. -config SND_SOC_CS4270_HWMUTE - bool - depends on SND_SOC_CS4270 - # Cirrus Logic CS4270 Codec VD = 3.3V Errata # Select if you are affected by the errata where the part will not function # if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will diff --git a/trunk/sound/soc/codecs/cs4270.c b/trunk/sound/soc/codecs/cs4270.c index 2c79a24186fd..cd4a9ee38e46 100644 --- a/trunk/sound/soc/codecs/cs4270.c +++ b/trunk/sound/soc/codecs/cs4270.c @@ -395,17 +395,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - /* Freeze and power-down the codec */ - - ret = snd_soc_write(codec, CS4270_PWRCTL, CS4270_PWRCTL_FREEZE | - CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | - CS4270_PWRCTL_PDN); - if (ret < 0) { - dev_err(codec->dev, "i2c write failed\n"); - return ret; - } - - /* Program the mode control register */ + /* Set the sample rate */ reg = snd_soc_read(codec, CS4270_MODE); reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK); @@ -417,7 +407,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, return ret; } - /* Program the format register */ + /* Set the DAI format */ reg = snd_soc_read(codec, CS4270_FORMAT); reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK); @@ -440,42 +430,9 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, return ret; } - /* Disable auto-mute. This feature appears to be buggy, because in - some situations, auto-mute will not deactivate when it should. */ - - reg = snd_soc_read(codec, CS4270_MUTE); - reg &= ~CS4270_MUTE_AUTO; - ret = snd_soc_write(codec, CS4270_MUTE, reg); - if (ret < 0) { - dev_err(codec->dev, "i2c write failed\n"); - return ret; - } - - /* Disable automatic volume control. It's enabled by default, and - * it causes volume change commands to be delayed, sometimes until - * after playback has started. - */ - - reg = cs4270_read_reg_cache(codec, CS4270_TRANS); - reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO); - ret = cs4270_i2c_write(codec, CS4270_TRANS, reg); - if (ret < 0) { - dev_err(codec->dev, "i2c write failed\n"); - return ret; - } - - /* Thaw and power-up the codec */ - - ret = snd_soc_write(codec, CS4270_PWRCTL, 0); - if (ret < 0) { - dev_err(codec->dev, "i2c write failed\n"); - return ret; - } - return ret; } -#ifdef CONFIG_SND_SOC_CS4270_HWMUTE /** * cs4270_mute - enable/disable the CS4270 external mute * @dai: the SOC DAI @@ -494,22 +451,23 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute) reg6 = snd_soc_read(codec, CS4270_MUTE); if (mute) - reg6 |= CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B | - CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B; + reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B; else - reg6 &= ~(CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B | - CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B); + reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B); return snd_soc_write(codec, CS4270_MUTE, reg6); } -#else -#define cs4270_mute NULL -#endif /* A list of non-DAPM controls that the CS4270 supports */ static const struct snd_kcontrol_new cs4270_snd_controls[] = { SOC_DOUBLE_R("Master Playback Volume", - CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1) + CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1), + SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0), + SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0), + SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0), + SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1), + SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0), + SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 0) }; /* @@ -637,6 +595,7 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client, { struct snd_soc_codec *codec; struct cs4270_private *cs4270; + unsigned int reg; int ret; /* 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, goto error_free_codec; } + /* Disable auto-mute. This feature appears to be buggy. In some + * situations, auto-mute will not deactivate when it should, so we want + * this feature disabled by default. An application (e.g. alsactl) can + * re-enabled it by using the controls. + */ + + reg = cs4270_read_reg_cache(codec, CS4270_MUTE); + reg &= ~CS4270_MUTE_AUTO; + ret = cs4270_i2c_write(codec, CS4270_MUTE, reg); + if (ret < 0) { + dev_err(&i2c_client->dev, "i2c write failed\n"); + return ret; + } + + /* Disable automatic volume control. The hardware enables, and it + * causes volume change commands to be delayed, sometimes until after + * playback has started. An application (e.g. alsactl) can + * re-enabled it by using the controls. + */ + + reg = cs4270_read_reg_cache(codec, CS4270_TRANS); + reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO); + ret = cs4270_i2c_write(codec, CS4270_TRANS, reg); + if (ret < 0) { + dev_err(&i2c_client->dev, "i2c write failed\n"); + return ret; + } + /* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI * structure for each CS4270 device, but the machine driver needs to * have a pointer to the DAI structure, so for now it must be a global diff --git a/trunk/sound/soc/omap/n810.c b/trunk/sound/soc/omap/n810.c index 9f037cd0191d..25593fee9121 100644 --- a/trunk/sound/soc/omap/n810.c +++ b/trunk/sound/soc/omap/n810.c @@ -72,7 +72,7 @@ static int n810_startup(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->card->codec; + struct snd_soc_codec *codec = rtd->socdev->codec; snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); diff --git a/trunk/sound/soc/pxa/corgi.c b/trunk/sound/soc/pxa/corgi.c index 0d41be33d572..1ba25a559524 100644 --- a/trunk/sound/soc/pxa/corgi.c +++ b/trunk/sound/soc/pxa/corgi.c @@ -100,7 +100,7 @@ static void corgi_ext_control(struct snd_soc_codec *codec) static int corgi_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->card->codec; + struct snd_soc_codec *codec = rtd->socdev->codec; /* check the jack status at stream startup */ corgi_ext_control(codec); diff --git a/trunk/sound/soc/pxa/palm27x.c b/trunk/sound/soc/pxa/palm27x.c index 29958cd9daec..4a9cf3083af0 100644 --- a/trunk/sound/soc/pxa/palm27x.c +++ b/trunk/sound/soc/pxa/palm27x.c @@ -55,7 +55,7 @@ static void palm27x_ext_control(struct snd_soc_codec *codec) static int palm27x_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->card->codec; + struct snd_soc_codec *codec = rtd->socdev->codec; /* check the jack status at stream startup */ palm27x_ext_control(codec); diff --git a/trunk/sound/soc/pxa/poodle.c b/trunk/sound/soc/pxa/poodle.c index 3a62d4354ef6..6e9827189fff 100644 --- a/trunk/sound/soc/pxa/poodle.c +++ b/trunk/sound/soc/pxa/poodle.c @@ -77,7 +77,7 @@ static void poodle_ext_control(struct snd_soc_codec *codec) static int poodle_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->card->codec; + struct snd_soc_codec *codec = rtd->socdev->codec; /* check the jack status at stream startup */ poodle_ext_control(codec); diff --git a/trunk/sound/soc/pxa/spitz.c b/trunk/sound/soc/pxa/spitz.c index 1aafd8c645a1..a3b9e6bdf979 100644 --- a/trunk/sound/soc/pxa/spitz.c +++ b/trunk/sound/soc/pxa/spitz.c @@ -109,7 +109,7 @@ static void spitz_ext_control(struct snd_soc_codec *codec) static int spitz_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->card->codec; + struct snd_soc_codec *codec = rtd->socdev->codec; /* check the jack status at stream startup */ spitz_ext_control(codec); diff --git a/trunk/sound/soc/pxa/tosa.c b/trunk/sound/soc/pxa/tosa.c index 09b5bada03b9..c77194f74c9b 100644 --- a/trunk/sound/soc/pxa/tosa.c +++ b/trunk/sound/soc/pxa/tosa.c @@ -82,7 +82,7 @@ static void tosa_ext_control(struct snd_soc_codec *codec) static int tosa_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->card->codec; + struct snd_soc_codec *codec = rtd->socdev->codec; /* check the jack status at stream startup */ tosa_ext_control(codec);