[alsa-devel] Problem setting mixer switch with amixer/alsactl.

Hi,
I have a system with a wm9713 ac97 codec. It has a single speaker connected to SPKL and OUT4 in BTL config.
Currently I'm setting up the audio path with a small script using amixer: amixer cset numid=90 2 # Out4 Mux = Inv2 amixer cset numid=95 3 # Left Speaker Out Mux = Speaker amixer cset numid=88 2 # DAC Inv Mux 2 = Speaker amixer cset numid=31 1 # Out4 Playback Switch = on amixer cset numid=2 1,0 # Speaker Playback Switch = L:on, R:off
and also: amixer cset numid=62 1 # Speaker Mixer PCM Playback Switch = on
If I do all of the above except for setting 'Speaker Mixer PCM Playback Switch' and then un-mute that in the full alsamixer program, the audio works through the speaker. If I run the 'Speaker Mixer PCM Playback Switch' amixer command (either before or after setting it with alsamixer), the audio stops working. Once that's happened I can't get it back at all without a full reboot (even suspend/resume doesn't help).
Setting it with alsamixer so it works and then using alsactl to save and restore the config also breaks it.
I'm not sure how to go about debugging this one, can anyone help?
Also, is there a way to (and should I) set the DAC -> SPKMIX -> INV2 -> OUT4 etc in my platform definition in the kernel code, rather than doing it with amixer?
Oliver Ford

On Wed, Oct 22, 2008 at 07:47:20PM +0100, Oliver Ford wrote:
Setting it with alsamixer so it works and then using alsactl to save and restore the config also breaks it.
I'm not sure how to go about debugging this one, can anyone help?
Please send an alsactl save file with the offending configuration - I'll try to reproduce (though possibly not before Monday).
Could you please also expand on "audio stops working" - for example, do you get any diagnostics in dmesg, do applications appear to think they are running normally, is there any noise at all (eg, static) and do any other audio paths work?
Also, is there a way to (and should I) set the DAC -> SPKMIX -> INV2 -> OUT4 etc in my platform definition in the kernel code, rather than doing it with amixer?
The recommended approach is to do this from user space. Direct register writes when probing should also do the trick if you want to do it in-kernel but it's not so robust against future changes.

Mark Brown wrote:
Please send an alsactl save file with the offending configuration
Attached. I saved this file when the audio was working (i.e having turned the offending control on with alsamixer) but restoring it stops it working.
- I'll try to reproduce (though possibly not before Monday).
Thanks.
Could you please also expand on "audio stops working" - for example, do you get any diagnostics in dmesg, do applications appear to think they are running normally, is there any noise at all (eg, static) and do any other audio paths work?
No unusual dmesg output, the apps think nothing is wrong. It seems that just the offending control (or the actual DACL/R -> SPKMIX mixer channel) stops working. I can still get audio through the headphones, still can get clicks when turning everything else on and off. I can even get audio on the speaker by the alternate routes: DACL -> HPMIXL -> SPKL and DACR -> HPMIXR -> INV2 -> OUT4. Routing SPKMIX to the headphones gives no output on the headphones.
Oliver
state.hpipaq214 { control.1 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 31' iface MIXER name 'Speaker Playback Volume' value 1 } control.2 { comment.access 'read write' comment.type BOOLEAN comment.count 2 iface MIXER name 'Speaker Playback Switch' value.0 true value.1 false } control.3 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 31' iface MIXER name 'Headphone Playback Volume' value 31 } control.4 { comment.access 'read write' comment.type BOOLEAN comment.count 2 iface MIXER name 'Headphone Playback Switch' value.0 false value.1 false } control.5 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 31' iface MIXER name 'Line In Volume' value 23 } control.6 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 31' iface MIXER name 'PCM Playback Volume' value 6 } control.7 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 31' iface MIXER name 'Mic 1 Volume' value 23 } control.8 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 31' iface MIXER name 'Mic 2 Volume' value 23 } control.9 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Mic Boost (+20dB) Switch' value false } control.10 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 7' iface MIXER name 'Mic Headphone Mixer Volume' value 5 } control.11 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Capture Switch' value true } control.12 { comment.access 'read write' comment.type ENUMERATED comment.count 2 comment.item.0 '+1.5dB Steps' comment.item.1 '+0.75dB Steps' iface MIXER name 'Capture Volume Steps' value.0 '+1.5dB Steps' value.1 '+1.5dB Steps' } control.13 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 31' iface MIXER name 'Capture Volume' value 0 } control.14 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Capture ZC Switch' value false } control.15 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 7' iface MIXER name 'Capture to Headphone Volume' value 5 } control.16 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Capture to Mono Boost (+20dB) Switch' value false } control.17 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Capture ADC Boost (+20dB) Switch' value false } control.18 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 15' iface MIXER name 'ALC Target Volume' value 11 } control.19 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 15' iface MIXER name 'ALC Hold Time' value 0 } control.20 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 15' iface MIXER name 'ALC Decay Time ' value 3 } control.21 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 15' iface MIXER name 'ALC Attack Time' value 2 } control.22 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 None comment.item.1 Left comment.item.2 Right comment.item.3 Stereo iface MIXER name 'ALC Function' value None } control.23 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 7' iface MIXER name 'ALC Max Volume' value 7 } control.24 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 3' iface MIXER name 'ALC ZC Timeout' value 3 } control.25 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'ALC ZC Switch' value false } control.26 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'ALC NG Switch' value false } control.27 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 'Constant Gain' comment.item.1 Mute iface MIXER name 'ALC NG Type' value 'Constant Gain' } control.28 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 31' iface MIXER name 'ALC NG Threshold' value 0 } control.29 { comment.access 'read write' comment.type BOOLEAN comment.count 2 iface MIXER name 'Speaker Playback ZC Switch' value.0 false value.1 false } control.30 { comment.access 'read write' comment.type BOOLEAN comment.count 2 iface MIXER name 'Headphone Playback ZC Switch' value.0 false value.1 false } control.31 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Out4 Playback Switch' value true } control.32 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Out4 Playback ZC Switch' value false } control.33 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 63' iface MIXER name 'Out4 Playback Volume' value 63 } control.34 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Out3 Playback Switch' value false } control.35 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Out3 Playback ZC Switch' value false } control.36 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 63' iface MIXER name 'Out3 Playback Volume' value 62 } control.37 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 31' iface MIXER name 'Mono Capture Volume' value 23 } control.38 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Mono Playback Switch' value false } control.39 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Mono Playback ZC Switch' value false } control.40 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 31' iface MIXER name 'Mono Playback Volume' value 31 } control.41 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 7' iface MIXER name 'PC Beep Playback Headphone Volume' value 5 } control.42 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 7' iface MIXER name 'PC Beep Playback Speaker Volume' value 5 } control.43 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 7' iface MIXER name 'PC Beep Playback Mono Volume' value 5 } control.44 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 7' iface MIXER name 'Voice Playback Headphone Volume' value 5 } control.45 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 7' iface MIXER name 'Voice Playback Master Volume' value 5 } control.46 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 7' iface MIXER name 'Voice Playback Mono Volume' value 5 } control.47 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 7' iface MIXER name 'Aux Playback Headphone Volume' value 5 } control.48 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 7' iface MIXER name 'Aux Playback Master Volume' value 5 } control.49 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 7' iface MIXER name 'Aux Playback Mono Volume' value 5 } control.50 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 'Linear Control' comment.item.1 'Adaptive Boost' iface MIXER name 'Bass Control' value 'Linear Control' } control.51 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Bass Cut-off Switch' value true } control.52 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Tone Cut-off Switch' value true } control.53 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Playback Attenuate (-6dB) Switch' value false } control.54 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 15' iface MIXER name 'Bass Volume' value 0 } control.55 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 15' iface MIXER name 'Tone Volume' value 0 } control.56 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name '3D Upper Cut-off Switch' value false } control.57 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name '3D Lower Cut-off Switch' value false } control.58 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 15' iface MIXER name '3D Depth' value 15 } control.59 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Speaker Mixer PC Beep Playback ' value false } control.60 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Speaker Mixer Voice Playback Sw' value false } control.61 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Speaker Mixer Aux Playback Swit' value false } control.62 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Speaker Mixer PCM Playback Swit' value true } control.63 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Speaker Mixer MonoIn Playback S' value false } control.64 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Speaker Mixer Bypass Playback S' value false } control.65 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Mono Mixer PC Beep Playback Swi' value false } control.66 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Mono Mixer Voice Playback Switc' value false } control.67 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Mono Mixer Aux Playback Switch' value false } control.68 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Mono Mixer PCM Playback Switch' value false } control.69 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Mono Mixer Bypass Playback Swit' value false } control.70 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Mono Mixer Mic 1 Sidetone Switc' value false } control.71 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Mono Mixer Mic 2 Sidetone Switc' value false } control.72 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Right HP Mixer PC Beep Playback' value false } control.73 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Right HP Mixer Voice Playback S' value false } control.74 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Right HP Mixer Aux Playback Swi' value false } control.75 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Right HP Mixer PCM Playback Swi' value false } control.76 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Right HP Mixer MonoIn Playback ' value false } control.77 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Right HP Mixer Bypass Playback ' value false } control.78 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Left HP Mixer PC Beep Playback ' value false } control.79 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Left HP Mixer Voice Playback Sw' value false } control.80 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Left HP Mixer Aux Playback Swit' value false } control.81 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Left HP Mixer PCM Playback Swit' value false } control.82 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Left HP Mixer MonoIn Playback S' value false } control.83 { comment.access 'read write' comment.type BOOLEAN comment.count 1 iface MIXER name 'Left HP Mixer Bypass Playback S' value false } control.84 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 MPB comment.item.1 MPA iface MIXER name 'Mic B Source' value MPB } control.85 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 'Mic 1' comment.item.1 'Mic 2 A' comment.item.2 'Mic 2 B' iface MIXER name 'Mic A Source' value 'Mic 1' } control.86 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 'Mic 1' comment.item.1 'Mic 2' comment.item.2 Line comment.item.3 'Mono In' comment.item.4 Headphone comment.item.5 Speaker comment.item.6 'Mono Out' comment.item.7 Zh iface MIXER name 'Right Capture Source' value 'Mic 1' } control.87 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 'Mic 1' comment.item.1 'Mic 2' comment.item.2 Line comment.item.3 'Mono In' comment.item.4 Headphone comment.item.5 Speaker comment.item.6 'Mono Out' comment.item.7 Zh iface MIXER name 'Left Capture Source' value 'Mic 1' } control.88 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Off comment.item.1 Mono comment.item.2 Speaker comment.item.3 'Left Headphone' comment.item.4 'Right Headphone' comment.item.5 'Headphone Mono' comment.item.6 NC comment.item.7 Vmid iface MIXER name 'DAC Inv Mux 2' value Speaker } control.89 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Off comment.item.1 Mono comment.item.2 Speaker comment.item.3 'Left Headphone' comment.item.4 'Right Headphone' comment.item.5 'Headphone Mono' comment.item.6 NC comment.item.7 Vmid iface MIXER name 'DAC Inv Mux 1' value Off } control.90 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Vmid comment.item.1 Zh comment.item.2 'Inv 2' comment.item.3 'Inv 2 Vmid' iface MIXER name 'Out 4 Mux' value 'Inv 2' } control.91 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Vmid comment.item.1 Zh comment.item.2 'Inv 1' comment.item.3 'Inv 1 Vmid' iface MIXER name 'Out 3 Mux' value Vmid } control.92 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Vmid comment.item.1 Zh comment.item.2 Headphone iface MIXER name 'Right Headphone Out Mux' value Vmid } control.93 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Vmid comment.item.1 Zh comment.item.2 Headphone iface MIXER name 'Left Headphone Out Mux' value Vmid } control.94 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Vmid comment.item.1 Zh comment.item.2 Headphone comment.item.3 Speaker comment.item.4 Inv comment.item.5 'Headphone Vmid' comment.item.6 'Speaker Vmid' comment.item.7 'Inv Vmid' iface MIXER name 'Right Speaker Out Mux' value Vmid } control.95 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Vmid comment.item.1 Zh comment.item.2 Headphone comment.item.3 Speaker comment.item.4 Inv comment.item.5 'Headphone Vmid' comment.item.6 'Speaker Vmid' comment.item.7 'Inv Vmid' iface MIXER name 'Left Speaker Out Mux' value Speaker } control.96 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Vmid comment.item.1 Zh comment.item.2 Mono comment.item.3 Inv iface MIXER name 'Mono Out Mux' value Vmid } control.97 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Stereo comment.item.1 Left comment.item.2 Right comment.item.3 Mute iface MIXER name 'Capture Mono Mux' value Mute } control.98 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Stereo comment.item.1 'Mic 1' comment.item.2 'Mic 2' comment.item.3 Mute iface MIXER name 'Sidetone Mux' value Mute } control.99 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Stereo comment.item.1 Left comment.item.2 Right comment.item.3 Mute iface MIXER name 'Capture Headphone Mux' value Mute } control.100 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 Headphone comment.item.1 Mic comment.item.2 Line comment.item.3 Headset comment.item.4 Off iface MIXER name 'Jack Function' value Headphone } control.101 { comment.access 'read write' comment.type ENUMERATED comment.count 1 comment.item.0 On comment.item.1 Off iface MIXER name 'Speaker Function' value On } }

On Wed, Oct 22, 2008 at 11:56:49PM +0100, Oliver Ford wrote:
Mark Brown wrote:
Please send an alsactl save file with the offending configuration
Attached. I saved this file when the audio was working (i.e having turned the offending control on with alsamixer) but restoring it stops it working.
OK, thanks. I've had a brief look at this here but so far as I can tell I'm not able to see these problems on my system. I am using a completely different machine, though, with different hardware and I haven't checked through your configuration in detail. I'll have a more detailed look early next week.
No unusual dmesg output, the apps think nothing is wrong. It seems that just the offending control (or the actual DACL/R -> SPKMIX mixer channel) stops working. I can still get audio through the
but only via amixer, yes?
One other thing that would be useful would be to put trace which logs the register writes in ac97_write() in the driver and then try testing both using alsamixer and then amixer to do the final enable of the Speaker Mixer PCM Playback Switch.
state.hpipaq214 { control.1 { comment.access 'read write' comment.type INTEGER comment.count 1 comment.range '0 - 31' iface MIXER name 'Speaker Playback Volume' value 1 }
That's rather low...

Mark Brown wrote:
OK, thanks. I've had a brief look at this here but so far as I can tell I'm not able to see these problems on my system. I am using a completely different machine, though, with different hardware and I haven't checked through your configuration in detail. I'll have a more detailed look early next week.
Ok, thanks. I'll keep poking around and see if I can find anything.
No unusual dmesg output, the apps think nothing is wrong. It seems that just the offending control (or the actual DACL/R -> SPKMIX mixer channel) stops working. I can still get audio through the
but only via amixer, yes?
Yes, It only stops working when the mixer switch is changed with amixer.
One other thing that would be useful would be to put trace which logs the register writes in ac97_write() in the driver and then try testing both using alsamixer and then amixer to do the final enable of the Speaker Mixer PCM Playback Switch.
I already have the register writes outputted, I'll compare the logs tonight.
name 'Speaker Playback Volume' value 1
}
That's rather low...
Yes it is, well spotted, I look at that tonight as well.
Thanks for the help,
Oliver

Oliver Ford wrote:
name 'Speaker Playback Volume' value 1 }
This is unrelated, I have just left it there from playing around.
One other thing that would be useful would be to put trace which logs the register writes in ac97_write() in the driver and then try testing both using alsamixer and then amixer to do the final enable of the Speaker Mixer PCM Playback Switch.
Well...
In terms of the control's direct effect, setting it in alsamixer gives: pxa2xx_ac97_write: 0c = af08
setting it in amixer: pxa2xx_ac97_write: 0c = af09
Am I right in understanding that setting all the controls in amixer doesn't actually enable the control in the codec chip at that time but that the powering on/off is done by soc-dapm.c when the the DAC is actually enabled when playing some audio? This appears to be what is happening when it does work (looking at the log). I hadn't realised this.
However, after running the offending amixer command this no longer happens. It seems that the dapm_power_widgets() function determines that the DAC is off and so doesn't power any widgets on at all.
I've put some debugging in pxa2xx-ac97-write and in dapm_power_widgets() and the log is attached (stripped of non-audio stuff).
Oliver
Clean boot...
** run speaker.sh setup without PCM->speaker setting... ** pxa2xx_ac97_write: 000c = ef08 pxa2xx_ac97_write: 001c = 0002 pxa2xx_ac97_write: 001c = 1802 pxa2xx_ac97_write: 001e = 0800 pxa2xx_ac97_write: 0006 = 0081 pxa2xx_ac97_write: 0002 = 0080
** run alsamixer, set PCM->speaker on: ** pxa2xx_ac97_write: 000c = af08
# aplay /stuff/400Hz-wav.wav +hpipaq214_startup() hpipaq214-audio: Enabling iPAQ Speaker... hpipaq214_startup, gpio96 -> on -hpipaq214_startup()
Playing WAVE '/stuff/400Hz-wav.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Mono pxa2xx_ac97_write: 002a = 0411 pxa2xx_ac97_write: 002c = ac44 DAPM: Path Widget 'DAC Inv Mux 2': off --> on DAPM: Path Widget 'Out 4 Mux': off --> on DAPM: Path Widget 'Left Speaker Out Mux': off --> on DAPM: DAC Widget 'Right DAC': off --> on (w->active==1) pxa2xx_ac97_write: 003c = 3abf DAPM: DAC Widget 'Left DAC': off --> on (w->active==1) pxa2xx_ac97_write: 003c = 3a3f DAPM: Path Widget 'AC97 Mixer': off --> on DAPM: Path Widget 'Speaker Mixer': off --> on pxa2xx_ac97_write: 003c = 3a3d DAPM: Path Widget 'Out 4': off --> on pxa2xx_ac97_write: 003e = efff DAPM: Path Widget 'Left Speaker': off --> on pxa2xx_ac97_write: 003e = eeff freq changed, set PCD to 5 (LCCR3 = 04700005, LCCR4 = 80000000) DAPM: Path Widget 'iPAQ Speaker': off --> on pxa2xx_ac97_write: 003c = 1a3d hpipaq214_shutdown, gpio96 -> off
** aplay exits. **
** ... few seconds delay ... **
DAPM: Path Widget 'iPAQ Speaker': on --> off DAPM: Path Widget 'Out 4': on --> off pxa2xx_ac97_write: 003e = feff DAPM: Path Widget 'Left Speaker': on --> off pxa2xx_ac97_write: 003e = ffff DAPM: Path Widget 'AC97 Mixer': on --> off DAPM: Path Widget 'Speaker Mixer': on --> off pxa2xx_ac97_write: 003c = 1a3f DAPM: Path Widget 'Right DAC': on --> off pxa2xx_ac97_write: 003c = 1a7f DAPM: Path Widget 'Left DAC': on --> off pxa2xx_ac97_write: 003c = 1aff DAPM: Path Widget 'DAC Inv Mux 2': on --> off DAPM: Path Widget 'Out 4 Mux': on --> off DAPM: Path Widget 'Left Speaker Out Mux': on --> off pxa2xx_ac97_write: 003c = 1aff pxa2xx_ac97_write: 0026 = 0000
** all quiet **
# # # amixer cset numid=62 1 pxa2xx_ac97_write: 000c = af09 numid=62,iface=MIXER,name='Speaker Mixer PCM Playback Swit' ; type=BOOLEAN,access=rw---,values=1 : values=on
# aplay /stuff/400Hz-wav.wav +hpipaq214_startup() hpipaq214-audio: Enabling iPAQ Speaker... hpipaq214_startup, gpio96 -> on -hpipaq214_startup()
Playing WAVE '/stuff/400Hz-wav.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Mono freq changed, set PCD to 5 (LCCR3 = 04700005, LCCR4 = 80000000) pxa2xx_ac97_write: 002a = 0411 pxa2xx_ac97_write: 002c = ac44 DAPM: DAC Widget 'Right DAC': off --> off (w->active==1) DAPM: DAC Widget 'Left DAC': off --> off (w->active==1) pxa2xx_ac97_write: 003c = 1aff hpipaq214_shutdown, gpio96 -> off # # pxa2xx_ac97_write: 003c = 1aff pxa2xx_ac97_write: 0026 = 0000

On Thu, Oct 23, 2008 at 11:55:05PM +0100, Oliver Ford wrote:
In terms of the control's direct effect, setting it in alsamixer gives: pxa2xx_ac97_write: 0c = af08
setting it in amixer: pxa2xx_ac97_write: 0c = af09
On the one hand, that's odd. On the other hand, the low bit of register 0xc is just a volume control for the right DAC so shouldn't make any odds really.
However, after running the offending amixer command this no longer happens. It seems that the dapm_power_widgets() function determines that the DAC is off and so doesn't power any widgets on at all.
Well, it determines that there's not a complete path so it doesn't bother powering anything up which isn't *quite* the same thing. It does look like that's what's happening here - I can reproduce similar behaviour here, though it's not quite the same system. I'll try to fix this tomorrow.

On Wed, Oct 22, 2008 at 07:47:20PM +0100, Oliver Ford wrote:
Currently I'm setting up the audio path with a small script using amixer: amixer cset numid=90 2 # Out4 Mux = Inv2
BTW, when posting stuff with amixer please use the plain text version of the control name rather than the numeric ID - it makes life very much easier.

Mark Brown wrote:
BTW, when posting stuff with amixer please use the plain text version of the control name rather than the numeric ID - it makes life very much easier.
Ok, will do. This also reminds me of something that might help...
The offending mixer switch has the truncated text name 'Speaker Mixer PCM Playback Swit' under amixer but it obviously is supposed to be 'Switch' on the end. I don't know if that might somehow cause problems?
Oliver

On Thu, Oct 23, 2008 at 02:56:42PM +0100, Oliver Ford wrote:
The offending mixer switch has the truncated text name 'Speaker Mixer PCM Playback Swit' under amixer but it obviously is supposed to be 'Switch' on the end. I don't know if that might somehow cause problems?
This is normal - shouldn't be an issue except in UI terms, ALSA limits the length of names.

Mark Brown broonie@sirena.org.uk writes:
On Thu, Oct 23, 2008 at 02:56:42PM +0100, Oliver Ford wrote:
The offending mixer switch has the truncated text name 'Speaker Mixer PCM Playback Swit' under amixer but it obviously is supposed to be 'Switch' on the end. I don't know if that might somehow cause problems?
This is normal - shouldn't be an issue except in UI terms, ALSA limits the length of names.
Mark, I don't think that's true. I had that problem several monthes ago (remember my patch about alsa controls length ?).
Do you remember that patch, which went into asoc-v2 ? :
-- Robert

On Thu, Oct 23, 2008 at 07:45:20PM +0200, Robert Jarzmik wrote:
Mark Brown broonie@sirena.org.uk writes:
This is normal - shouldn't be an issue except in UI terms, ALSA limits the length of names.
Mark, I don't think that's true. I had that problem several monthes ago (remember my patch about alsa controls length ?).
Do you remember that patch, which went into asoc-v2 ? :
All this patch does is change the limit, there is still a limit on the length of control names in ALSA but as I say it's purely a cosmetic issue.

Mark Brown broonie@sirena.org.uk writes:
On Thu, Oct 23, 2008 at 07:45:20PM +0200, Robert Jarzmik wrote:
Mark Brown broonie@sirena.org.uk writes:
All this patch does is change the limit, there is still a limit on the length of control names in ALSA but as I say it's purely a cosmetic issue.
I don't quite agree on the "cosmetic".
If I recall correctly, that name is used in dapm path setup. If the name is incorrect (truncated), some dapm elements are not switched on. I'm speaking from memory, I'll try to browse my git repository to track it back. Notice that I'm really busy ATM, so I don't have enough manpower to test immediatly.
I'll try to revert my patch and see the effects at the end of the next week.
-- Robert

On Fri, Oct 24, 2008 at 09:09:33PM +0200, Robert Jarzmik wrote:
If I recall correctly, that name is used in dapm path setup. If the name is incorrect (truncated), some dapm elements are not switched on. I'm speaking from memory, I'll try to browse my git repository to track it back. Notice that I'm really busy ATM, so I don't have enough manpower to test immediatly.
Hrm, that's possible I suppose though I don't recall it being mentioned at the time and can't see any truncations that would make any difference for here.
I'll try to revert my patch and see the effects at the end of the next week.
I should be able to look into this myself on Monday.

On Fri, Oct 24, 2008 at 09:09:33PM +0200, Robert Jarzmik wrote:
Mark Brown broonie@sirena.org.uk writes:
All this patch does is change the limit, there is still a limit on the length of control names in ALSA but as I say it's purely a cosmetic issue.
I don't quite agree on the "cosmetic".
If I recall correctly, that name is used in dapm path setup. If the name is incorrect (truncated), some dapm elements are not switched on. I'm speaking from memory, I'll try to browse my git repository to track it back. Notice that I'm really busy ATM, so I don't have enough manpower to test immediatly.
It looks like you might've been right after all. I still can't see where this makes a difference to the speaker paths but the patch below seems to resolve the issues I'm seeing here.
Oliver, could you test the patch below please?
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 28da235..fdb4d2c 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -293,7 +293,7 @@ static int dapm_new_mixer(struct snd_soc_codec *codec, struct snd_soc_dapm_widget *w) { int i, ret = 0; - char name[32]; + size_t name_len; struct snd_soc_dapm_path *path;
/* add kcontrol */ @@ -307,11 +307,16 @@ static int dapm_new_mixer(struct snd_soc_codec *codec, continue;
/* add dapm control with long name */ - snprintf(name, 32, "%s %s", w->name, w->kcontrols[i].name); - path->long_name = kstrdup (name, GFP_KERNEL); + name_len = 2 + strlen(w->name) + + strlen(w->kcontrols[i].name); + path->long_name = kmalloc(name_len, GFP_KERNEL); if (path->long_name == NULL) return -ENOMEM;
+ snprintf(path->long_name, name_len, "%s %s", + w->name, w->kcontrols[i].name); + path->long_name[name_len - 1] = '\0'; + path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, path->long_name); ret = snd_ctl_add(codec->card, path->kcontrol);

On Tue, Oct 28, 2008 at 01:10:31PM +0000, Mark Brown wrote:
It looks like you might've been right after all. I still can't see where this makes a difference to the speaker paths but the patch below seems to resolve the issues I'm seeing here.
Oliver, could you test the patch below please?
Gah, sorry - it doesn't help, I was masking the problem another way.

At Tue, 28 Oct 2008 15:34:36 +0000, Mark Brown wrote:
On Tue, Oct 28, 2008 at 01:10:31PM +0000, Mark Brown wrote:
It looks like you might've been right after all. I still can't see where this makes a difference to the speaker paths but the patch below seems to resolve the issues I'm seeing here.
Oliver, could you test the patch below please?
Gah, sorry - it doesn't help, I was masking the problem another way.
... and I think soc-dapm should warn if the string is too long, at least, so that you can notice and fix them.
Takashi

On Tue, Oct 28, 2008 at 04:41:33PM +0100, Takashi Iwai wrote:
Mark Brown wrote:
Gah, sorry - it doesn't help, I was masking the problem another way.
... and I think soc-dapm should warn if the string is too long, at least, so that you can notice and fix them.
Well, with the patch supplied (which I intend to push anyway) ASoC won't enforce any limit and will just pass the string onto the ALSA core - probably best to warn in snd_ctl_new1(). I'll take a look.

At Tue, 28 Oct 2008 15:48:57 +0000, Mark Brown wrote:
On Tue, Oct 28, 2008 at 04:41:33PM +0100, Takashi Iwai wrote:
Mark Brown wrote:
Gah, sorry - it doesn't help, I was masking the problem another way.
... and I think soc-dapm should warn if the string is too long, at least, so that you can notice and fix them.
Well, with the patch supplied (which I intend to push anyway) ASoC won't enforce any limit and will just pass the string onto the ALSA core - probably best to warn in snd_ctl_new1(). I'll take a look.
Agreed, it'd be a good place.
Takashi

Mark Brown wrote:
On Tue, Oct 28, 2008 at 01:10:31PM +0000, Mark Brown wrote:
It looks like you might've been right after all. I still can't see where this makes a difference to the speaker paths but the patch below seems to resolve the issues I'm seeing here.
Oliver, could you test the patch below please?
Gah, sorry - it doesn't help, I was masking the problem another way.
Ok, well I tried it anyway and it doesn't solve the problem.
I've done a lot more tracing and think I may have found something relevant. I'm not entirely sure what is supposed to be happening so can't figure it out myself, but maybe you will know...
When turning the PCM->Speaker mixer on and off in alsamixer (before its broken) the mixer's widget->value seems to flick between 0x4000 and 0x0000. After breaking it with amixer it flicks between 0x4001 and 0x4000, both of which fire the lines: if (val) /* new connection */ path->connect = invert ? 0:1; in dapm_mixer_update_power().
I've put some debugging to report whats happening to path->connect in dapm_mixer_update_power() and this is what happens:
ON in alsamixer when working: +dapm_mixer_update_power(kcontrol=Speaker Mixer PCM Playback Switch, reg=0000000c, val=00000000, val_mask=00004001, invert=00000001) found path for kcontrol: name='PCM Playback Switch', long_name='Speaker Mixer PCM Playback Switch' val=false: path->connect: 0 --> 1 -dapm_mixer_update_power()
OFF in alsamixer when working: +dapm_mixer_update_power(kcontrol=Speaker Mixer PCM Playback Switch, reg=0000000c, val=00004000, val_mask=00004001, invert=00000001) found path for kcontrol: name='PCM Playback Switch', long_name='Speaker Mixer PCM Playback Switch' val=true: path->connect: 1 --> 0 -dapm_mixer_update_power()
Leaving it on in alsamixer and running the amixer on command. This happens: +dapm_mixer_update_power(kcontrol=Speaker Mixer PCM Playback Switch, reg=0000000c, val=00000001, val_mask=00004001, invert=00000001) found path for kcontrol: name='PCM Playback Switch', long_name='Speaker Mixer PCM Playback Switch' val=true: path->connect: 1 --> 0 +dapm_power_widgets()
i.e it seems to turn it off?
From then on, any further attempts to turn it on in amixer give: +dapm_mixer_update_power(kcontrol=Speaker Mixer PCM Playback Switch, reg=0000000c, val=00004001, val_mask=00004001, invert=00000001) found path for kcontrol: name='PCM Playback Switch', long_name='Speaker Mixer PCM Playback Switch' val=true: path->connect: 0 --> 0 +dapm_power_widgets()
Any further off/on toggling in alsamixer once broken just results in: +dapm_mixer_update_power(kcontrol=Speaker Mixer PCM Playback Switch, reg=0000000c, val=00004001, val_mask=00004001, invert=00000001) found path for kcontrol: name='PCM Playback Switch', long_name='Speaker Mixer PCM Playback Switch' val=true: path->connect: 0 --> 0 +dapm_power_widgets()
+dapm_mixer_update_power(kcontrol=Speaker Mixer PCM Playback Switch, reg=0000000c, val=00000001, val_mask=00004001, invert=00000001) found path for kcontrol: name='PCM Playback Switch', long_name='Speaker Mixer PCM Playback Switch' val=true: path->connect: 0 --> 0 +dapm_power_widgets()
Does that give you any ideas of what happening on my system?
Thanks,
Oliver

On Tue, Oct 28, 2008 at 09:51:02PM +0000, Oliver Ford wrote:
Does that give you any ideas of what happening on my system?
Not more than I had already - that's the lowest level of the symptom, DAPM doesn't think the speaker mixer has any active inputs so leaves it and the output path from it off. Unfortunately I've not been able to devote my full attention to this yet.

On Tue, Oct 28, 2008 at 09:51:02PM +0000, Oliver Ford wrote:
Does that give you any ideas of what happening on my system?
OK, I see what the problem is now. The conversion to allow larger than 8 bits missed some things, causing the power control to look at unrelated bits in the register when determining if the path is active. I won't be able to fix it today since I have to go and get my eyes examined (no wonder it took me so long to spot this!) but I expect I'll have a patch tomorrow.

On Wed, Oct 29, 2008 at 04:04:51PM +0000, Mark Brown wrote:
I won't be able to fix it today since I have to go and get my eyes examined (no wonder it took me so long to spot this!) but I expect I'll have a patch tomorrow.
Please try this, it resolves the problems I'm seeing here:
commit 9fafa720f6dd4a7a9476bef0d78fee14af401c14 Author: Mark Brown broonie@opensource.wolfsonmicro.com Date: Thu Oct 30 11:32:47 2008 +0000
ASoC: Fix mono controls after conversion to support full int masks
When ASoC was converted to support full int width masks SOC_SINGLE_VALUE() omitted the assignment of rshift, causing the control operatins to report some mono controls as stereo. This happened to work some of the time due to a confusion between shift and min in snd_soc_info_volsw().
Signed-off-by: Mark Brown broonie@opensource.wolfsonmicro.com
diff --git a/include/sound/soc.h b/include/sound/soc.h index d33825d..da0040b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -28,7 +28,8 @@ */ #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \ ((unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .shift = xshift, .max = xmax, .invert = xinvert}) + {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \ + .invert = xinvert}) #define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ ((unsigned long)&(struct soc_mixer_control) \ {.reg = xreg, .max = xmax, .invert = xinvert}) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 0399fff..a17f864 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1563,7 +1563,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; int max = mc->max; - unsigned int shift = mc->min; + unsigned int shift = mc->shift; unsigned int rshift = mc->rshift;
if (max == 1)

Mark Brown wrote:
Please try this, it resolves the problems I'm seeing here:
commit 9fafa720f6dd4a7a9476bef0d78fee14af401c14 Author: Mark Brown broonie@opensource.wolfsonmicro.com Date: Thu Oct 30 11:32:47 2008 +0000
...
Yes, that seems to fix it.
Thanks for all your efforts in resolving this one.
Oliver
participants (4)
-
Mark Brown
-
Oliver Ford
-
Robert Jarzmik
-
Takashi Iwai