On 3 June 2010 02:07, Stuart Longland redhatter@gentoo.org wrote:
Hi all...
I'm posting this via GMane since my server at home seems to be down, hopefully it gets through. I hope to put a version of the TLV320AIC3204 driver that I've been working on up there -- I did try posting it to the list, but I suspect it's either been left in the moderation queue or silently dropped. In short, I got the sound working; just testing playback for now... Recording should work, once I get the mixer set up.
My query though; the mixer on this CODEC provides gain settings, helpfully scaled in dB, as signed integers. For instance; the four line level output drivers: Headphone left/right,and Line Out left/right, can all be adjusted in gain from -6dB through to +29dB.
These are set in individual registers as the lower 6 bits; so: -6 dB is represented as 111010 (0x3a) 29 dB is represented as 011101 (0x1d)
However; it treats the bitfield as unsigned, which is wrong in this case. The bitfield is a signed integer in two's complement format. How do I convince ALSA that these integers have a sign bit?
ALSA is not set up to convert bitfields to dB values. It can only convert integers to dB values. These integers normally being 32bit. So, I think you will have to write some code in your driver to convert these 6bit signed integers to 32bit unsigned integers and then pass the 32bit unsigned integer to user land. Something like: u32 value; /* Make the value an unsigned int even though we think it is a 6bit signed in. */
/* sign extend tmp from 6 bit signed to 32bit signed */ if (value & 0x20) value = value | 0xffffffe0; /* moved the value from the signed range to the unsigned range. */ value = value + 6;
Other way: /* reduce value to 6 bit signed value. value = value - 6; value = value & 0x3f;
Kind Regards
James