[alsa-devel] ASOC and 12 bit volume control

Mark Brown broonie at opensource.wolfsonmicro.com
Sun Jul 20 14:56:39 CEST 2008

On Sat, Jul 19, 2008 at 10:18:55PM -0400, Jon Smirl wrote:

> How do I define a volume control that is the bottom 12 bits of a 32
> bit register?

> #define SOC_SINGLE_VALUE(reg, shift, max, invert) ((reg) | ((shift) << 8) |\
> 	((shift) << 12) | ((max) << 16) | ((invert) << 24))

> This looks like it only support an 8 bit max. Is there another way to do it?

SOC_SINGLE() (or SOC_SINGLE_TLV() if you've got dB scale information for
the volume control, which is likely?) is the way to do it but like you
say it's not able to cope currently.  Since invert is a boolean so there
should actually be enough space to store a 12 bit max so it shouldn't be
such a major job to adjust for this unless I'm missing something, I've
only had a brief look.

Also note that the core currently has assumptions in it that registers
aren't bigger than 16 bits - the main thing is that it uses unsigned
shorts for passing them around.  Someone posted in the past week about
fixing this.

If you don't want to do core changes then either write a custom control
or (if the stuff in the upper bits will allow it) adjust the shift to
ignore the bottom 4 bits of the control.  The ASoC control macros all
boil down to standard ALSA controls types and you can mix in regular ALSA
controls without problems if required - the macros just save having to
implement standard register accesses by hand.

More information about the Alsa-devel mailing list