[alsa-devel] ASoC WM8510 Mic PGA problem
Hi all,
I'm facing trouble with programmable mic gain stage and WM8510 ASoC driver.
First of all, the DAPM control "Mic PGA Switch" seems to be operating just the opposite way the codec datasheet suggests. I inverted the control with expected result, PGA now almost works.
When I start capturing, the "Mic PGA" control is instantly turned off again. If I manually enable the control while the capture is running, it works just fine.
Any ideas? Am I missing some DAPM routings?
-Jukka
On Fri, Oct 03, 2008 at 04:20:20PM +0300, ext-jukka.hynninen@vaisala.com wrote:
I'm facing trouble with programmable mic gain stage and WM8510 ASoC driver.
First of all, the DAPM control "Mic PGA Switch" seems to be operating just the opposite way the codec datasheet suggests. I inverted the control with expected result, PGA now almost works.
Yes, that's right - good catch, thanks. I will post a patch for this shortly.
When I start capturing, the "Mic PGA" control is instantly turned off again. If I manually enable the control while the capture is running, it works just fine.
Could you expand on what you're seeing here - what exactly is the user visible behaviour you observe? Are you looking at dapm_widgets in sysfs or something else? Looking at the driver code the power management does need some fixes but I'd like to confirm exactly what you're seeing before looking at them.
It might help if you were able to provide your machine driver.
Quoting Mark Brown:
When I start capturing, the "Mic PGA" control is instantly turned off again. If I manually enable the control while the capture is running,
it
works just fine.
Could you expand on what you're seeing here - what exactly is the user visible behaviour you observe? Are you looking at dapm_widgets in
sysfs
I'm looking at the amixer settings, commands
$> amixer sset "Mic PGA" on $> arecord -c 1 --rate=48000 --format=S16_LE |aplay & $> amixer sget "Mic PGA"
report that the mixer control state is [off] again. Looking at the codec_reg on sysfs verifies that the PGA Mute bit (0x2d:6) is set. Running the first command again gives the expected audible result.
On the contrary, dapm_widget reports "Mic PGA: On".
It might help if you were able to provide your machine driver.
The driver is playpaq_wm8510.c
-Jukka
On Mon, Oct 06, 2008 at 10:20:55AM +0300, ext-jukka.hynninen@vaisala.com wrote:
I'm looking at the amixer settings, commands
$> amixer sset "Mic PGA" on $> arecord -c 1 --rate=48000 --format=S16_LE |aplay & $> amixer sget "Mic PGA"
report that the mixer control state is [off] again. Looking at the codec_reg on sysfs verifies that the PGA Mute bit (0x2d:6) is set.
Could you confirm when the state of the control changes - looks like it's when the recording/playback start?
It might help if you were able to provide your machine driver.
The driver is playpaq_wm8510.c
Ah, right. I don't suppose I could persuade you to join the efforts testing Sedji Gaouaou's recent code to unify the AT91 and AVR32 ASoC platform support? Geoffrey Wossum did offer to help out with that already.
Quoting Mark Brown:
report that the mixer control state is [off] again. Looking at the codec_reg on sysfs verifies that the PGA Mute bit (0x2d:6) is set.
Could you confirm when the state of the control changes - looks like it's when the recording/playback start?
The control changes state when recording starts. Playback has no effect on it.
Ah, right. I don't suppose I could persuade you to join the efforts testing Sedji Gaouaou's recent code to unify the AT91 and AVR32 ASoC platform support? Geoffrey Wossum did offer to help out with that already.
I'm going to give it a try during this week anyway. I'll let you know what it feels like.
-Jukka
On Mon, Oct 06, 2008 at 01:53:34PM +0300, ext-jukka.hynninen@vaisala.com wrote:
The control changes state when recording starts. Playback has no effect on it.
Could you please give the patch below a spin? I've not tested it but I believe it may help.
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 16768a5..b4997c4 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -56,6 +56,9 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = { 0x0001, };
+#define WM8510_POWER1_BIASEN 0x08 +#define WM8510_POWER1_BUFIOEN 0x10 + /* * read wm8510 register cache */ @@ -527,23 +530,35 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute) static int wm8510_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + u16 power1 = wm8510_read_reg_cache(codec, WM8510_POWER1) & ~0x3;
switch (level) { case SND_SOC_BIAS_ON: - wm8510_write(codec, WM8510_POWER1, 0x1ff); - wm8510_write(codec, WM8510_POWER2, 0x1ff); - wm8510_write(codec, WM8510_POWER3, 0x1ff); - break; case SND_SOC_BIAS_PREPARE: + power1 |= 0x1; /* VMID 50k */ + wm8510_write(codec, WM8510_POWER1, power1); + break; + case SND_SOC_BIAS_STANDBY: + power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; + + if (codec->bias_level == SND_SOC_BIAS_OFF) { + /* Initial cap charge at VMID 5k */ + wm8510_write(codec, WM8510_POWER1, power1 | 0x3); + mdelay(100); + } + + power1 |= 0x2; /* VMID 500k */ + wm8510_write(codec, WM8510_POWER1, power1); break; + case SND_SOC_BIAS_OFF: - /* everything off, dac mute, inactive */ - wm8510_write(codec, WM8510_POWER1, 0x0); - wm8510_write(codec, WM8510_POWER2, 0x0); - wm8510_write(codec, WM8510_POWER3, 0x0); + wm8510_write(codec, WM8510_POWER1, 0); + wm8510_write(codec, WM8510_POWER2, 0); + wm8510_write(codec, WM8510_POWER3, 0); break; } + codec->bias_level = level; return 0; } @@ -641,6 +656,7 @@ static int wm8510_init(struct snd_soc_device *socdev) }
/* power on device */ + codec->bias_level = SND_SOC_BIAS_OFF; wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); wm8510_add_controls(codec); wm8510_add_widgets(codec);
Quoting Mark Brown:
The control changes state when recording starts. Playback has no
effect
on it.
Could you please give the patch below a spin? I've not tested it but
I
believe it may help.
Mic PGA still keeps turning off.
Anyway, I noticed an interesting point (applying the patch had no effect on this): The first recording on a freshly booted system seems to complete without changing the status of Mic PGA control.
-Jukka
On Tue, Oct 07, 2008 at 04:29:43PM +0300, ext-jukka.hynninen@vaisala.com wrote:
Anyway, I noticed an interesting point (applying the patch had no effect on this): The first recording on a freshly booted system seems to complete without changing the status of Mic PGA control.
Could you please rebuild ASoC with debug enabled and send the kernel output produced from a failing record? Depending on your kernel version you'll either see some relevant defines at the top of soc-core.c and soc-dapm.c or you should #define DEBUG at the top of those files.
Putting some trace in wm8510_reg_write() logging all the codec writes while doing this would also be interesting.
Quoting Mark Brown:
Could you please rebuild ASoC with debug enabled and send the kernel output produced from a failing record? Depending on your kernel
version
I'm sorry, It seems to be the switch connecting MICN to negative PGA terminal that does not stay on (register 0x2c bit 1)
Here's the result with my remarks inline:
$ amixer sget 'Mic PGA'
Simple mixer control 'Mic PGA',0 Capabilities: switch Playback channels: Mono Capture channels: Mono Mono: [on]
$ arecord -c 1 --rate=48000 --format=S16_LE |aplay
asoc: WM8510 HiFi <-> at91-ssc1 info: asoc: rate mask 0xde asoc: min ch 1 max ch 2 asoc: min rate 8000 max rate 48000 asoc: WM8510 HiFi <-> at91-ssc1 info: asoc: rate mask 0xde asoc: min ch 1 max ch 2 asoc: min rate 8000 max rate 48000 Recording WAVE 'stdin' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono WM8510 register write: 0x04: 10 WM8510 register write: 0x06: d WM8510 register write: 0x06: d WM8510 register write: 0x24: 8 WM8510 register write: 0x25: c WM8510 register write: 0x26: 93 WM8510 register write: 0x27: e9 WM8510 register write: 0x01: 3a WM8510 register write: 0x06: 10d WM8510 register write: 0x06: d WM8510 register write: 0x04: 10 WM8510 register write: 0x07: 0 WM8510 register write: 0x01: 39 WM8510 register write: 0x02: 10 WM8510 register write: 0x02: 14 WM8510 register write: 0x2c: 2 <-- This line missing right after bootup! WM8510 register write: 0x02: 15 WM8510 register write: 0x01: 39 WM8510 register write: 0x0a: 0 Playing WAVE 'stdin' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono WM8510 register write: 0x04: 10 WM8510 register write: 0x06: d WM8510 register write: 0x06: d WM8510 register write: 0x24: 8 WM8510 register write: 0x25: c WM8510 register write: 0x26: 93 WM8510 register write: 0x27: e9 WM8510 register write: 0x01: 39 WM8510 register write: 0x06: 10d WM8510 register write: 0x06: d WM8510 register write: 0x04: 10 WM8510 register write: 0x07: 0 WM8510 register write: 0x03: 1 WM8510 register write: 0x03: 9 WM8510 register write: 0x03: d WM8510 register write: 0x03: 8d WM8510 register write: 0x03: cd WM8510 register write: 0x03: ed WM8510 register write: 0x0a: 0 Aborted by signal Interrupt... <-- Pressed ctrl-c WM8510 register write: 0x02: 14 WM8510 register write: 0x02: 10 WM8510 register write: 0x02: 0 WM8510 register write: 0x01: 29 Aborted by signal Interrupt...
$ pop wq checking: Playback status: inactive waiting: yes
pop wq D1 WM8510 Playback WM8510 register write: 0x01: 29 WM8510 register write: 0x03: 6d WM8510 register write: 0x03: 2d WM8510 register write: 0x03: d WM8510 register write: 0x03: 5 WM8510 register write: 0x03: 1 WM8510 register write: 0x03: 0 pop wq D3 WM8510 Playback WM8510 register write: 0x01: 3a
$
On Tue, Oct 07, 2008 at 05:21:48PM +0300, ext-jukka.hynninen@vaisala.com wrote:
Quoting Mark Brown:
Could you please rebuild ASoC with debug enabled and send the kernel output produced from a failing record? Depending on your kernel
version
I'm sorry, It seems to be the switch connecting MICN to negative PGA terminal that does not stay on (register 0x2c bit 1)
So the ALSA control 'Mic PGA MICN Switch'?
On Tue, Oct 07, 2008 at 05:21:48PM +0300, ext-jukka.hynninen@vaisala.com wrote:
I'm sorry, It seems to be the switch connecting MICN to negative PGA terminal that does not stay on (register 0x2c bit 1)
Ah, I think I see what's going on here. Could you try this patch, please (again, untested)?
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 94cab49..ea524c4 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -227,9 +227,9 @@ SND_SOC_DAPM_PGA("SpkN Out", WM8510_POWER3, 5, 0, NULL, 0), SND_SOC_DAPM_PGA("SpkP Out", WM8510_POWER3, 6, 0, NULL, 0), SND_SOC_DAPM_PGA("Mono Out", WM8510_POWER3, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Mic PGA", WM8510_POWER2, 2, 0, - &wm8510_micpga_controls[0], - ARRAY_SIZE(wm8510_micpga_controls)), +SND_SOC_DAPM_MIXER("Mic PGA", WM8510_POWER2, 2, 0, + &wm8510_micpga_controls[0], + ARRAY_SIZE(wm8510_micpga_controls)), SND_SOC_DAPM_MIXER("Boost Mixer", WM8510_POWER2, 4, 0, &wm8510_boost_controls[0], ARRAY_SIZE(wm8510_boost_controls)),
Quoting Mark Brown:
I'm sorry, It seems to be the switch connecting MICN to negative PGA terminal that does not stay on (register 0x2c bit 1)
Ah, I think I see what's going on here. Could you try this patch,
The latest one did the trick. Now the PGA control works nice and smoothly.
Many thanks!
-Jukka
participants (3)
-
ext-jukka.hynninen@vaisala.com
-
Mark Brown
-
Mark Brown