[alsa-devel] ASoC: TI codecs and their crazy variable length registers
I'm working on a TI codec attached via I2C. Just to make things interesting the registers have varying byte lengths of - 1,4,8,12,20 bytes. What's the best strategy for using regmap with it?
My idea was to make five sparse regmaps, one for each of the five lengths? Chip has about 75 registers. The 20 byte ones are biquad coefficients.
Also, does regmap restore MMIO registers after a suspend? Allwinner has code in their drivers for drivers for saving/restoring the DAI registers over a suspend.
Sven Brandau made a really nice driver for the sta350, I'm using it as a guide. The chips are fairly similar. But no variable length registers on that chip.
On Wed, Jul 30, 2014 at 05:56:36PM -0400, jonsmirl@gmail.com wrote:
I'm working on a TI codec attached via I2C. Just to make things interesting the registers have varying byte lengths of - 1,4,8,12,20 bytes. What's the best strategy for using regmap with it?
I'd use the reg_read() and reg_write() callbacks to hide the registers that will fit in an integer, the rest of the stack can pretend they've got 32 bit values which should improve code reuse. The larger registers are going to need custom controls I expect but that's probably a given anyway, and if they're coefficeints they'll be fairly simple binary controls.
It should be possible to write a standard ASoC control type for binary blocks that can be written with a single I2C transfer...
Also, does regmap restore MMIO registers after a suspend? Allwinner has code in their drivers for drivers for saving/restoring the DAI registers over a suspend.
It can be used to do that, same as anything else you need to a cache sync. The Tegra audio drivers do this - that's why regmap-mmio was originally written.
On 07/31/2014 01:17 AM, Mark Brown wrote:
On Wed, Jul 30, 2014 at 05:56:36PM -0400, jonsmirl@gmail.com wrote:
I'm working on a TI codec attached via I2C. Just to make things interesting the registers have varying byte lengths of - 1,4,8,12,20 bytes. What's the best strategy for using regmap with it?
I'd use the reg_read() and reg_write() callbacks to hide the registers that will fit in an integer, the rest of the stack can pretend they've got 32 bit values which should improve code reuse.[...]
The adau1701 is a driver that for example does this.
On Thu, Jul 31, 2014 at 3:01 AM, Lars-Peter Clausen lars@metafoo.de wrote:
On 07/31/2014 01:17 AM, Mark Brown wrote:
On Wed, Jul 30, 2014 at 05:56:36PM -0400, jonsmirl@gmail.com wrote:
I'm working on a TI codec attached via I2C. Just to make things interesting the registers have varying byte lengths of - 1,4,8,12,20 bytes. What's the best strategy for using regmap with it?
I'd use the reg_read() and reg_write() callbacks to hide the registers that will fit in an integer, the rest of the stack can pretend they've got 32 bit values which should improve code reuse.[...]
The adau1701 is a driver that for example does this.
Then use regmap_raw_read/regmap_raw_write for the registers over four bytes?
This might work generically if the size function was a regmap callback...
static int adau1701_reg_write(void *context, unsigned int reg, unsigned int value) { struct i2c_client *client = context; unsigned int i; unsigned int size; uint8_t buf[5]; int ret;
size = adau1701_register_size(&client->dev, reg); if (size == 0) return -EINVAL;
buf[0] = reg >> 8; buf[1] = reg & 0xff;
for (i = size + 1; i >= 2; --i) { buf[i] = value; value >>= 8; }
participants (3)
-
jonsmirl@gmail.com
-
Lars-Peter Clausen
-
Mark Brown