When debugging audio codec, it is sometimes necessary to read the value of the codec register to confirm that the register was successfully configured.
Remember before debugging wm8978, found this codec register can not read, each read the result is 0xFF.
Later on Linux debugging wm8978, with Snd_soc_read () and can read the configured value, I feel very surprised. There was no scrutiny at the time.
The two days are free, the Linux kernel looked at the relevant code, found that the I2C read and write codec code in SOUND/SOC/SOC-CACHE.C.
Many functions like Snd_soc_x_y_read () and snd_soc_x_y_write () are defined in this. c file, X represents address digits, Y code
The number of data bits, such as Snd_soc_7_9_read () for the address is 7 bits, the data is 9-bit Codec,wolfson codec most of this is the case.
There is also a specific codec driver to set the X,y value of the interface, so as to select the corresponding read-write function, this interface is:
int snd_soc_codec_set_cache_io (struct Snd_soc_codec *codec,
int addr_bits, int data_bits,
Enum Snd_soc_control_type Control)
For example, the following configuration calls are wm8960.c:
RET =snd_soc_codec_set_cache_io (Codec,7,9,control);
Now, let's talk about Snd_soc_x_y_write () such functions as:
static unsigned int snd_soc_7_9_read (struct Snd_soc_codec *codec,
unsigned int reg)
{
U16 *cache = codec->reg_cache;
if (reg >= codec->reg_cache_size)
return-1;
return Cache[reg];
}
A look at the code, the original read here, unexpectedly not from the register of codec read out, but from a cache to read out.
Look at the corresponding write function is clear, the original in the write when the value of the register is cached in the cache, read
Read directly from the cache.
static int snd_soc_7_9_write (struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
U16 *cache = codec->reg_cache;
U8 Data[2];
int ret;
BUG_ON (Codec->volatile_register);
Data[0] = (reg << 1) | ((Value >> 8) & 0x0001);
DATA[1] = value & 0x00ff;
if (Reg < codec->reg_cache_size)
Cache[reg] = value;
if (codec->cache_only) {
Codec->cache_sync = 1;
return 0;
}
dev_dbg (Codec->dev, "0x%x = 0x%x\n", Reg, value);
ret = Codec->hw_write (Codec->control_data, data, 2);
if (ret = 2)
return 0;
if (Ret < 0)
&nbs P; return ret;
else
return-eio
, a strange question has a good explanation recently:
after I2C configuration sensor, play music through Aplay without movement (no sound), but read codec through Snd_soc_read () ( wm8960) The value of each register
is normal (and the same configuration as normal playback), with an oscilloscope measured codec Lrck pin, nothing (this should have clock output, because
Codec is configured as Master mode). The original Snd_soc_read () read the value is previously written in the cache, not the real codec has been configured in the value,
Obviously codec is not configured properly, so there is no Lrck signal output.