ASoC: Add spi hw read function for 16 addr 8 data mode for ad193x fix

[This will be used by the ad193x driver to fix the fact that the
original author of the driver put a bodge for their particular chip into
a the generic ASoC register I/O abstraction layer which looked like an
obvious bug which ended up getting fixed in 3.0.  Sadly there were no
comments documenting what was going on.  A minimally invasive correction
to the driver is to remove the register cache support and go direct to
the hardware all the time so we're adding a new feature -- broonie]

Signed-off-by: Scott Jiang <scott.jiang.linux@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
Scott Jiang 2011-08-12 18:04:13 -04:00 committed by Mark Brown
parent 25ea524bed
commit 396a2e79cd

View File

@ -205,6 +205,25 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
#define snd_soc_16_8_read_i2c NULL #define snd_soc_16_8_read_i2c NULL
#endif #endif
#if defined(CONFIG_SPI_MASTER)
static unsigned int snd_soc_16_8_read_spi(struct snd_soc_codec *codec,
unsigned int r)
{
struct spi_device *spi = codec->control_data;
const u16 reg = cpu_to_be16(r | 0x100);
u8 data;
int ret;
ret = spi_write_then_read(spi, &reg, 2, &data, 1);
if (ret < 0)
return 0;
return data;
}
#else
#define snd_soc_16_8_read_spi NULL
#endif
static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value) unsigned int value)
{ {
@ -295,6 +314,7 @@ static struct {
int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int); int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
unsigned int (*read)(struct snd_soc_codec *, unsigned int); unsigned int (*read)(struct snd_soc_codec *, unsigned int);
unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
unsigned int (*spi_read)(struct snd_soc_codec *, unsigned int);
} io_types[] = { } io_types[] = {
{ {
.addr_bits = 4, .data_bits = 12, .addr_bits = 4, .data_bits = 12,
@ -318,6 +338,7 @@ static struct {
.addr_bits = 16, .data_bits = 8, .addr_bits = 16, .data_bits = 8,
.write = snd_soc_16_8_write, .write = snd_soc_16_8_write,
.i2c_read = snd_soc_16_8_read_i2c, .i2c_read = snd_soc_16_8_read_i2c,
.spi_read = snd_soc_16_8_read_spi,
}, },
{ {
.addr_bits = 16, .data_bits = 16, .addr_bits = 16, .data_bits = 16,
@ -383,6 +404,8 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
#ifdef CONFIG_SPI_MASTER #ifdef CONFIG_SPI_MASTER
codec->hw_write = do_spi_write; codec->hw_write = do_spi_write;
#endif #endif
if (io_types[i].spi_read)
codec->hw_read = io_types[i].spi_read;
codec->control_data = container_of(codec->dev, codec->control_data = container_of(codec->dev,
struct spi_device, struct spi_device,