Re: snd soc spi read/write

Takashi Iwai
2011-08-05T06:11:37Z

At Fri, 5 Aug 2011 10:24:43 +0800,
Scott Jiang wrote:
>
> 2011/8/4 Mark Brown <broonie@opensource.wolfsonmicro.com>:
> > On Thu, Aug 04, 2011 at 06:24:04PM +0800, Scott Jiang wrote:
> >
> >> My version is linux 3.0, I found snd_soc_spi_read/write didn't work at
> >> 16-8 bit mode.
> >> The addr is 16bit, the function compares reg with reg_cache_size. This
> >> certainly causes failure.
> >> In the former version, reg &= 0xff seems right. So how to use
> >> snd_soc_16_8_write now?
> >
> > reg &= 0xff is clearly broken for 16 bit register values...
>
> 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);
>
> 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

The problem is that the current cache code doesn't take care of
special register-index values like 16_8 case. In 16-8 case, usually
only the lower 8 bit indicates the real register index while the upper
8 bit is some (usually constant) control bits. Thus, it worked well
in the former version by masking with 0xff.

A quick fix would to introduce again the 0xff masking. Of course,
this isn't a right thing, but would be enough for the current code,
as regmap will replace in future anyway.

> > 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?

Not yet :) regmap has the same issue for now, as far as I see.

I guess reg_mask_bits is needed in struct regmap_config in addition
for supporting such a case.

thanks,

Takashi