[alsa-devel] ASOC and 12 bit volume control
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?
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.
Another problem is the crossbar mixer. It is a full 8x4 crossbar with 28 bit gain controls on each path. There are four 32 byte registers, each register holds 8 32 bit wide gain fields. There are several more mixers with 28 bit gain controls.
28 bit gain fields are all on all of the bass/loudness/etc control.
On 7/20/08, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
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.
On Sun, Jul 20, 2008 at 11:51:12AM -0400, Jon Smirl wrote:
Another problem is the crossbar mixer. It is a full 8x4 crossbar with 28 bit gain controls on each path. There are four 32 byte registers, each register holds 8 32 bit wide gain fields. There are several more mixers with 28 bit gain controls.
I think that the best thing for these 32 byte registers is a new control type. If they're as frequently implemented in TI CODECs as it seems then it'd be worth pulling them into core but the fact that they're 32 byte would probably mean contortions trying to fit them into the same abstraction as registers that can be manipulated in a simple type. It's also possible that the combination of large registers and high resolution fields within them may mean that special treatment is warranted in order to avoid blocking user applications too much with high volume register writes, but I'm not sure if that's a real issue or not.
28 bit gain fields are all on all of the bass/loudness/etc control.
Are any of these 28 bit controls not in 32 byte registers?
On 7/20/08, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
On Sun, Jul 20, 2008 at 11:51:12AM -0400, Jon Smirl wrote:
Another problem is the crossbar mixer. It is a full 8x4 crossbar with 28 bit gain controls on each path. There are four 32 byte registers, each register holds 8 32 bit wide gain fields. There are several more mixers with 28 bit gain controls.
I think that the best thing for these 32 byte registers is a new control type. If they're as frequently implemented in TI CODECs as it seems then it'd be worth pulling them into core but the fact that they're 32 byte would probably mean contortions trying to fit them into the same abstraction as registers that can be manipulated in a simple type. It's also possible that the combination of large registers and high resolution fields within them may mean that special treatment is warranted in order to avoid blocking user applications too much with high volume register writes, but I'm not sure if that's a real issue or not.
These chips are capable of processing 192K 24b HD quality audio. Datasheet http://www.ti.com/lit/gpn/tas5504 Do the Intel HD audio chips have similar controls?
I believe the TI codecs are implemented with a combination of an 8051 core controlling a DSP. The i2c interface is talking to the 8051 core, not real hardware registers. The 8051 takes the incoming i2c messages and stores them in RAM and uses the info to manipulate the DSP.
28 bit gain fields are all on all of the bass/loudness/etc control.
Are any of these 28 bit controls not in 32 byte registers?
0x41-48, input mixers 8x4 crossbar 32 byte register, contains 8 5.23 input gains in 32b fields. 0x49-0x50, bass management 4 bytes, contain 5.23 coefficients 0x89-0x90, bass and treble bypass 8 bytes, contains two 5.23 coefficients 0xa2-a9, DRC bypass 8 bytes, contains two 5.23 gains output 4x4 crossbar, more 5.23 gains
The chip supports DRC (compression and expansion), some of the DRC parameters are 48bits in 25.23 format. Loudness is 25.23 too. 0x92 and 0x94 are examples of 64 bit registers.
On Sun, Jul 20, 2008 at 02:47:31PM -0400, Jon Smirl wrote:
On 7/20/08, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
also possible that the combination of large registers and high resolution fields within them may mean that special treatment is warranted in order to avoid blocking user applications too much with high volume register writes, but I'm not sure if that's a real issue or not.
These chips are capable of processing 192K 24b HD quality audio. Datasheet http://www.ti.com/lit/gpn/tas5504 Do the Intel HD audio chips have similar controls?
A brief look suggests that there's nothing over 32 bits in the register map.
I believe the TI codecs are implemented with a combination of an 8051 core controlling a DSP. The i2c interface is talking to the 8051 core, not real hardware registers. The 8051 takes the incoming i2c messages and stores them in RAM and uses the info to manipulate the DSP.
The issue is the time taken to do the I/O via the I2C bus, not the implementation in the chip - if anything I'd expect this to be slower than a direct hardware implementation but not perceptibly. If applications try to step through all the values for a control with anything approaching the available resolution then that'd be a lot of data being written. Like I say, it may not be a practical issue (I'd expect applications to be smarter) but it raised my eyebrows.
Are any of these 28 bit controls not in 32 byte registers?
0x49-0x50, bass management 4 bytes, contain 5.23 coefficients
The chip supports DRC (compression and expansion), some of the DRC parameters are 48bits in 25.23 format. Loudness is 25.23 too. 0x92 and 0x94 are examples of 64 bit registers.
OK, so the bass management looks like it should be able to fit in a processor word?
On 7/20/08, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
On Sun, Jul 20, 2008 at 02:47:31PM -0400, Jon Smirl wrote:
On 7/20/08, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
also possible that the combination of large registers and high resolution fields within them may mean that special treatment is warranted in order to avoid blocking user applications too much with high volume register writes, but I'm not sure if that's a real issue or not.
These chips are capable of processing 192K 24b HD quality audio. Datasheet http://www.ti.com/lit/gpn/tas5504 Do the Intel HD audio chips have similar controls?
A brief look suggests that there's nothing over 32 bits in the register map.
Many of the registers are over 32 bits. They vary from 8 bits up to 1024 bits. Most of the large registers (1024 bit) contain multiple 32 bit fields. For example a 8x4 crossbar register is 1024 bits, it has 8 fields, each field is a 5.23 gain.
A the beginning of section 5 there is a table of the registers and their length in bytes.
I believe the TI codecs are implemented with a combination of an 8051 core controlling a DSP. The i2c interface is talking to the 8051 core, not real hardware registers. The 8051 takes the incoming i2c messages and stores them in RAM and uses the info to manipulate the DSP.
The issue is the time taken to do the I/O via the I2C bus, not the implementation in the chip - if anything I'd expect this to be slower than a direct hardware implementation but not perceptibly. If applications try to step through all the values for a control with anything approaching the available resolution then that'd be a lot of data being written. Like I say, it may not be a practical issue (I'd expect applications to be smarter) but it raised my eyebrows.
Yes, stepping through 4096 volume levels individually would be a pain. A UI would need to initially move in larger increments.
I have thought about building a pseudo interface for the chip that would be compatible with the existing ASLA controls, and then using an IOCTL to bypass for finer control. But isn't this problem going to reoccur as we encounter more HD audio level hardware?
Are any of these 28 bit controls not in 32 byte registers?
0x49-0x50, bass management 4 bytes, contain 5.23 coefficients
The chip supports DRC (compression and expansion), some of the DRC parameters are 48bits in 25.23 format. Loudness is 25.23 too. 0x92 and 0x94 are examples of 64 bit registers.
OK, so the bass management looks like it should be able to fit in a processor word?
If the word is 64 bits.
To support this chip you could add the concept of fields to ALSA registers. Fields would be 32 bit. For backward compatibility the existing chips would just set field to 0.
To change a mixer gain, would write a 32b value to field 4 of register 0x41. I can use my register cache inside the driver to update field 4 of the 1024b register and then rewrite the entire register.
There also needs to be the ability to read/write 64 bit values for DRC and loudness.
On Sun, Jul 20, 2008 at 03:51:20PM -0400, Jon Smirl wrote:
The issue is the time taken to do the I/O via the I2C bus, not the implementation in the chip - if anything I'd expect this to be slower than a direct hardware implementation but not perceptibly. If applications try to step through all the values for a control with anything approaching the available resolution then that'd be a lot of data being written. Like I say, it may not be a practical issue (I'd expect applications to be smarter) but it raised my eyebrows.
Yes, stepping through 4096 volume levels individually would be a pain. A UI would need to initially move in larger increments.
I have thought about building a pseudo interface for the chip that would be compatible with the existing ASLA controls, and then using an
I'd just ignore it initially and if it's a problem look at doing things like deferring the register writes by a short amount. Most UIs won't be able to display anything like the resolution required to cause trouble in the first place - they are scaling the resolution of the control into the resolution of the UI anyway.
IOCTL to bypass for finer control. But isn't this problem going to reoccur as we encounter more HD audio level hardware?
My own expectation would be that if it is a serious issue it'll be dealt with in user space - my concern here was that the effects are being magnified by the combination of the slow control bus and the large registers that contain the controls. As I say, it may not be a real issue.
0x49-0x50, bass management 4 bytes, contain 5.23 coefficients
...
OK, so the bass management looks like it should be able to fit in a processor word?
If the word is 64 bits.
Err... you said it's 4 bytes?
To support this chip you could add the concept of fields to ALSA
ASoC?
registers. Fields would be 32 bit. For backward compatibility the existing chips would just set field to 0.
The use of a shift plus mask is largely a function of the fact that that maps well onto how datasheets are usually written - I'm not sure that using numbered fields would help there. I'm also not sure that it's a good idea to build the 32 bit assumption in - someone is bound to come up with controls that are either larger that or cross a 32 bit boundary within a register.
On 7/20/08, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
On Sun, Jul 20, 2008 at 03:51:20PM -0400, Jon Smirl wrote:
The issue is the time taken to do the I/O via the I2C bus, not the implementation in the chip - if anything I'd expect this to be slower than a direct hardware implementation but not perceptibly. If applications try to step through all the values for a control with anything approaching the available resolution then that'd be a lot of data being written. Like I say, it may not be a practical issue (I'd expect applications to be smarter) but it raised my eyebrows.
Yes, stepping through 4096 volume levels individually would be a pain. A UI would need to initially move in larger increments.
I have thought about building a pseudo interface for the chip that would be compatible with the existing ASLA controls, and then using an
I'd just ignore it initially and if it's a problem look at doing things like deferring the register writes by a short amount. Most UIs won't be able to display anything like the resolution required to cause trouble in the first place - they are scaling the resolution of the control into the resolution of the UI anyway.
IOCTL to bypass for finer control. But isn't this problem going to reoccur as we encounter more HD audio level hardware?
My own expectation would be that if it is a serious issue it'll be dealt with in user space - my concern here was that the effects are being magnified by the combination of the slow control bus and the large registers that contain the controls. As I say, it may not be a real issue.
0x49-0x50, bass management 4 bytes, contain 5.23 coefficients
OK, so the bass management looks like it should be able to fit in a processor word?
If the word is 64 bits.
Err... you said it's 4 bytes?
The chip supports DRC (compression and expansion), some of the DRC parameters are 48bits in 25.23 format. Loudness is 25.23 too. 0x92 and 0x94 are examples of 64 bit registers.
Most registers are 5.23. About eight of them are 25.23. 5.23 fits in 4 bytes, 25.23 (48bits) needs 2 words, 8 bytes.
To support this chip you could add the concept of fields to ALSA
ASoC?
registers. Fields would be 32 bit. For backward compatibility the existing chips would just set field to 0.
The use of a shift plus mask is largely a function of the fact that that maps well onto how datasheets are usually written - I'm not sure that using numbered fields would help there. I'm also not sure that it's a good idea to build the 32 bit assumption in - someone is bound to come up with controls that are either larger that or cross a 32 bit boundary within a register.
A better idea might be to expand the current 'shift' from 4 bits to 8 bits. And then allow masks for upto 64 bits. But this messes with the current register interface since you would need to pass the value and shift into the driver.
I have registers that are 256 bits. That's a 32 bit value with a shift of 224. Another is 64 bits with a shift of zero.
The problem is encoding all of this into .private_value, it's too small.
I have to go read the control code since I don't know exactly how it works. I haven't located any doc for it.
participants (2)
-
Jon Smirl
-
Mark Brown