[alsa-devel] [PATCH] ASoC: UDA134X Codec: Fix mute/unmute code mistake and add ADC/DAC power control support

Shine Liu shinel at foxmail.com
Mon Aug 17 10:36:56 CEST 2009


There is a mistake in current uda134x_mute function: mute_reg has been
changed in line 162 or line 164, so uda134x_write should write
"mute_reg" but not "mute_reg & ~(1<<2)" to 
UDA134X_DATA010.

Besides, because there is no DAPM configuration for uda134x, when system
starts up, snd_soc_int_card calls snd_soc_dapm_new_widgets, and
snd_soc_dapm_new_widgets calls dapm_power_widgets. In function
dapm_power_widgets, codec->dapm_widgets has no list entry, so sys_power
retains it's original value zero. Then
snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_PREPARE) and  
snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_STANDBY) are called
sequentially. Finally, the uda134x codec goes to STANDBY mode, so the
ADC/DAC power control bits of UDA134X_STATUS1 register keeps the 0
value.

UDA134X has no trigger function currently, and the ADC/DAC power control
bits of UDA134X_STATUS1 register are not exported in
uda1341_snd_controls, so there's no way to enable the ADC/DAC power
control bits when you want to use the codec. When playing with aplay or
recording with arecord, there is no sound output or no wave input.

I have added the uda134x_trigger function, which turns on/off the
ADC/DAC power control bits according the substream type and the command.
I also exported the ADC/DAC power control bits to uda1341_snd_controls,
so we can also turn these bits on/off as we need via a mixer tool like
alsamixer.

The patch created against linux-2.6.31-rc3.
Tested on a s3c2440 development board with UDA1341TS codec.


Signed-off-by: Shine Liu <shinel at foxmail.com> 

--- sound/soc/codecs/uda134x.c.orig	2009-07-14 09:18:52.000000000 +0800
+++ sound/soc/codecs/uda134x.c	2009-08-17 13:46:57.000000000 +0800
@@ -163,7 +163,7 @@
 	else
 		mute_reg &= ~(1<<2);
 
-	uda134x_write(codec, UDA134X_DATA010, mute_reg & ~(1<<2));
+	uda134x_write(codec, UDA134X_DATA010, mute_reg);
 
 	return 0;
 }
@@ -339,6 +339,38 @@
 	return 0;
 }
 
+static int uda134x_trigger(struct snd_pcm_substream *substream,
+			   int cmd, struct snd_soc_dai *dai)
+{
+	int stream = substream->stream;
+	struct snd_soc_codec *codec = dai->codec;
+	u8 power_ctrl_reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
+
+	pr_debug("%s stream: %d, cmd: %d\n", __func__, stream, cmd);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+			power_ctrl_reg |= (1<<0);
+		else
+			power_ctrl_reg |= (1<<1);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+			power_ctrl_reg &= ~(1<<0);
+		else
+			power_ctrl_reg &= ~(1<<1);
+		break;
+
+	default:
+		return 0;
+	}
+
+	uda134x_write(codec, UDA134X_STATUS1, power_ctrl_reg);
+	return 0;
+}
+
 static int uda134x_set_bias_level(struct snd_soc_codec *codec,
 				  enum snd_soc_bias_level level)
 {
@@ -416,6 +448,8 @@
 SOC_SINGLE("ADC Polarity Switch", UDA134X_STATUS1, 4, 1, 0),
 SOC_SINGLE("DAC Polarity Switch", UDA134X_STATUS1, 3, 1, 0),
 SOC_SINGLE("Double Speed Playback Switch", UDA134X_STATUS1, 2, 1, 0),
+SOC_SINGLE("ADC Power Switch", UDA134X_STATUS1, 1, 1, 0),
+SOC_SINGLE("DAC Power Switch", UDA134X_STATUS1, 0, 1, 0),
 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
 };
 
@@ -438,6 +472,7 @@
 	.digital_mute	= uda134x_mute,
 	.set_sysclk	= uda134x_set_dai_sysclk,
 	.set_fmt	= uda134x_set_dai_fmt,
+	.trigger	= uda134x_trigger,
 };
 
 struct snd_soc_dai uda134x_dai = {





More information about the Alsa-devel mailing list