aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-cache.c
diff options
context:
space:
mode:
authorBarry Song <21cnbao@gmail.com>2010-01-26 22:46:18 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-01-27 05:43:09 -0500
commit994dc4245d3f50329da4ead453a5dfcfbc716a0d (patch)
tree1523d8129ccf168d953c44e500a01e5f13cb8dbf /sound/soc/soc-cache.c
parent63b62ab0d52c736b3274b294df962e0a4b7aae79 (diff)
ASoC: ad1938: use soc-cache framework for codec registers access
Signed-off-by: Barry Song <Barry.Song@analog.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-cache.c')
-rw-r--r--sound/soc/soc-cache.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index cde7b63de113..097e33510a7a 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -233,6 +233,108 @@ static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
233#define snd_soc_8_16_read_i2c NULL 233#define snd_soc_8_16_read_i2c NULL
234#endif 234#endif
235 235
236#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
237static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
238 unsigned int r)
239{
240 struct i2c_msg xfer[2];
241 u16 reg = r;
242 u8 data;
243 int ret;
244 struct i2c_client *client = codec->control_data;
245
246 /* Write register */
247 xfer[0].addr = client->addr;
248 xfer[0].flags = 0;
249 xfer[0].len = 2;
250 xfer[0].buf = (u8 *)&reg;
251
252 /* Read data */
253 xfer[1].addr = client->addr;
254 xfer[1].flags = I2C_M_RD;
255 xfer[1].len = 1;
256 xfer[1].buf = &data;
257
258 ret = i2c_transfer(client->adapter, xfer, 2);
259 if (ret != 2) {
260 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
261 return 0;
262 }
263
264 return data;
265}
266#else
267#define snd_soc_16_8_read_i2c NULL
268#endif
269
270static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
271 unsigned int reg)
272{
273 u16 *cache = codec->reg_cache;
274
275 reg &= 0xff;
276 if (reg >= codec->reg_cache_size)
277 return -1;
278 return cache[reg];
279}
280
281static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
282 unsigned int value)
283{
284 u16 *cache = codec->reg_cache;
285 u8 data[3];
286 int ret;
287
288 BUG_ON(codec->volatile_register);
289
290 data[0] = (reg >> 8) & 0xff;
291 data[1] = reg & 0xff;
292 data[2] = value;
293
294 reg &= 0xff;
295 if (reg < codec->reg_cache_size)
296 cache[reg] = value;
297 ret = codec->hw_write(codec->control_data, data, 3);
298 if (ret == 3)
299 return 0;
300 if (ret < 0)
301 return ret;
302 else
303 return -EIO;
304}
305
306#if defined(CONFIG_SPI_MASTER)
307static int snd_soc_16_8_spi_write(void *control_data, const char *data,
308 int len)
309{
310 struct spi_device *spi = control_data;
311 struct spi_transfer t;
312 struct spi_message m;
313 u8 msg[3];
314
315 if (len <= 0)
316 return 0;
317
318 msg[0] = data[0];
319 msg[1] = data[1];
320 msg[2] = data[2];
321
322 spi_message_init(&m);
323 memset(&t, 0, (sizeof t));
324
325 t.tx_buf = &msg[0];
326 t.len = len;
327
328 spi_message_add_tail(&t, &m);
329 spi_sync(spi, &m);
330
331 return len;
332}
333#else
334#define snd_soc_16_8_spi_write NULL
335#endif
336
337
236static struct { 338static struct {
237 int addr_bits; 339 int addr_bits;
238 int data_bits; 340 int data_bits;
@@ -260,6 +362,12 @@ static struct {
260 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read, 362 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
261 .i2c_read = snd_soc_8_16_read_i2c, 363 .i2c_read = snd_soc_8_16_read_i2c,
262 }, 364 },
365 {
366 .addr_bits = 16, .data_bits = 8,
367 .write = snd_soc_16_8_write, .read = snd_soc_16_8_read,
368 .i2c_read = snd_soc_16_8_read_i2c,
369 .spi_write = snd_soc_16_8_spi_write,
370 },
263}; 371};
264 372
265/** 373/**