Browse Source

Merge branch 'for-2.6.30' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6 into topic/asoc

Takashi Iwai 16 years ago
parent
commit
f1464ede55
3 changed files with 44 additions and 60 deletions
  1. 0 6
      sound/soc/codecs/Kconfig
  2. 40 53
      sound/soc/codecs/cs4270.c
  3. 4 1
      sound/soc/soc-core.c

+ 0 - 6
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

+ 40 - 53
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

+ 4 - 1
sound/soc/soc-core.c

@@ -1382,7 +1382,10 @@ int snd_soc_init_card(struct snd_soc_device *socdev)
 
 	mutex_lock(&codec->mutex);
 #ifdef CONFIG_SND_SOC_AC97_BUS
-	if (ac97) {
+	/* Only instantiate AC97 if not already done by the adaptor
+	 * for the generic AC97 subsystem.
+	 */
+	if (ac97 && strcmp(codec->name, "AC97") != 0) {
 		ret = soc_ac97_dev_register(codec);
 		if (ret < 0) {
 			printk(KERN_ERR "asoc: AC97 device register failed\n");