[alsa-devel] snd soc spi read/write

Scott Jiang scott.jiang.linux at gmail.com
Fri Aug 5 08:26:33 CEST 2011


2011/8/5 Mark Brown <broonie at opensource.wolfsonmicro.com>:
> On Fri, Aug 05, 2011 at 10:24:43AM +0800, Scott Jiang wrote:
>
>> hw_write use 16bit reg, cache use 8bit reg, in former version
>>
>>         data[0] = (reg >> 8) & 0xff;
>>         data[1] = reg & 0xff;
>>         data[2] = value;
>>
>>         reg &= 0xff;
>>         if (reg < codec->reg_cache_size)
>>                 cache[reg] = value;
>>
>>         ret = codec->hw_write(codec->control_data, data, 3);
>
> Which is just obviously insane and buggy as with that code the same
> cache slot will be used for 256 different registers that differ only in
> the upper byte.
>
>> now in do_hw_write
>>         if (!snd_soc_codec_volatile_register(codec, reg) &&
>>             reg < codec->driver->reg_cache_size &&
>>             !codec->cache_bypass) {
>>                 ret = snd_soc_cache_write(codec, reg, value);
>>                 if (ret < 0)
>>                         return -1;
>>         }
>> reg > reg_cache_size, so will not write to cache
>
> Which is exactly what we'd expect - we won't have allocated a cache
> beyond register reg_cache_size and the driver is telling us not to cache
> those registers.
>
>> > Note that all this code will be replaced with regmap for 3.2.
>
>> Do you mean I must update to 3.2 to solve this problem?
>
> I don't see any problem here.  What is the problem you're experiencing?
>

My register address is 0x806(8bit global addr + 8bit reg addr), for
example,  reg_cache_size is 0x20.
snd_soc_cache_write will not be called. And kernel oops in do_hw_read

BUG_ON(!codec->hw_read);

That is what I found when asoc was upgraded to 3.0, my codec is ad1938.

The key issue is register is 8 bits, hardware needs 16 bits addr. If I
change reg_cache_size to 2^16=64K, I think everything goes well.
But it will waste a lot of memory for only 32 registers.


More information about the Alsa-devel mailing list