• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/sound/soc/
1/*
2 * soc-cache.c  --  ASoC register cache helpers
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 *  This program is free software; you can redistribute  it and/or modify it
9 *  under  the terms of  the GNU General  Public License as published by the
10 *  Free Software Foundation;  either version 2 of the  License, or (at your
11 *  option) any later version.
12 */
13
14#include <linux/i2c.h>
15#include <linux/spi/spi.h>
16#include <sound/soc.h>
17
18static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
19				     unsigned int reg)
20{
21	u16 *cache = codec->reg_cache;
22	if (reg >= codec->reg_cache_size)
23		return -1;
24	return cache[reg];
25}
26
27static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
28			     unsigned int value)
29{
30	u16 *cache = codec->reg_cache;
31	u8 data[2];
32	int ret;
33
34	BUG_ON(codec->volatile_register);
35
36	data[0] = (reg << 4) | ((value >> 8) & 0x000f);
37	data[1] = value & 0x00ff;
38
39	if (reg < codec->reg_cache_size)
40		cache[reg] = value;
41
42	if (codec->cache_only) {
43		codec->cache_sync = 1;
44		return 0;
45	}
46
47	dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
48
49	ret = codec->hw_write(codec->control_data, data, 2);
50	if (ret == 2)
51		return 0;
52	if (ret < 0)
53		return ret;
54	else
55		return -EIO;
56}
57
58#if defined(CONFIG_SPI_MASTER)
59static int snd_soc_4_12_spi_write(void *control_data, const char *data,
60				 int len)
61{
62	struct spi_device *spi = control_data;
63	struct spi_transfer t;
64	struct spi_message m;
65	u8 msg[2];
66
67	if (len <= 0)
68		return 0;
69
70	msg[0] = data[1];
71	msg[1] = data[0];
72
73	spi_message_init(&m);
74	memset(&t, 0, (sizeof t));
75
76	t.tx_buf = &msg[0];
77	t.len = len;
78
79	spi_message_add_tail(&t, &m);
80	spi_sync(spi, &m);
81
82	return len;
83}
84#else
85#define snd_soc_4_12_spi_write NULL
86#endif
87
88static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
89				     unsigned int reg)
90{
91	u16 *cache = codec->reg_cache;
92	if (reg >= codec->reg_cache_size)
93		return -1;
94	return cache[reg];
95}
96
97static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
98			     unsigned int value)
99{
100	u16 *cache = codec->reg_cache;
101	u8 data[2];
102	int ret;
103
104	BUG_ON(codec->volatile_register);
105
106	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
107	data[1] = value & 0x00ff;
108
109	if (reg < codec->reg_cache_size)
110		cache[reg] = value;
111
112	if (codec->cache_only) {
113		codec->cache_sync = 1;
114		return 0;
115	}
116
117	dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
118
119	ret = codec->hw_write(codec->control_data, data, 2);
120	if (ret == 2)
121		return 0;
122	if (ret < 0)
123		return ret;
124	else
125		return -EIO;
126}
127
128#if defined(CONFIG_SPI_MASTER)
129static int snd_soc_7_9_spi_write(void *control_data, const char *data,
130				 int len)
131{
132	struct spi_device *spi = control_data;
133	struct spi_transfer t;
134	struct spi_message m;
135	u8 msg[2];
136
137	if (len <= 0)
138		return 0;
139
140	msg[0] = data[0];
141	msg[1] = data[1];
142
143	spi_message_init(&m);
144	memset(&t, 0, (sizeof t));
145
146	t.tx_buf = &msg[0];
147	t.len = len;
148
149	spi_message_add_tail(&t, &m);
150	spi_sync(spi, &m);
151
152	return len;
153}
154#else
155#define snd_soc_7_9_spi_write NULL
156#endif
157
158static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
159			     unsigned int value)
160{
161	u8 *cache = codec->reg_cache;
162	u8 data[2];
163
164	BUG_ON(codec->volatile_register);
165
166	reg &= 0xff;
167	data[0] = reg;
168	data[1] = value & 0xff;
169
170	if (reg < codec->reg_cache_size)
171		cache[reg] = value;
172
173	if (codec->cache_only) {
174		codec->cache_sync = 1;
175		return 0;
176	}
177
178	dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
179
180	if (codec->hw_write(codec->control_data, data, 2) == 2)
181		return 0;
182	else
183		return -EIO;
184}
185
186static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
187				     unsigned int reg)
188{
189	u8 *cache = codec->reg_cache;
190	reg &= 0xff;
191	if (reg >= codec->reg_cache_size)
192		return -1;
193	return cache[reg];
194}
195
196static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
197			      unsigned int value)
198{
199	u16 *reg_cache = codec->reg_cache;
200	u8 data[3];
201
202	data[0] = reg;
203	data[1] = (value >> 8) & 0xff;
204	data[2] = value & 0xff;
205
206	if (!snd_soc_codec_volatile_register(codec, reg)
207		&& reg < codec->reg_cache_size)
208			reg_cache[reg] = value;
209
210	if (codec->cache_only) {
211		codec->cache_sync = 1;
212		return 0;
213	}
214
215	dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
216
217	if (codec->hw_write(codec->control_data, data, 3) == 3)
218		return 0;
219	else
220		return -EIO;
221}
222
223static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
224				      unsigned int reg)
225{
226	u16 *cache = codec->reg_cache;
227
228	if (reg >= codec->reg_cache_size ||
229	    snd_soc_codec_volatile_register(codec, reg)) {
230		if (codec->cache_only)
231			return -EINVAL;
232
233		return codec->hw_read(codec, reg);
234	} else {
235		return cache[reg];
236	}
237}
238
239#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
240static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
241					  unsigned int r)
242{
243	struct i2c_msg xfer[2];
244	u8 reg = r;
245	u8 data;
246	int ret;
247	struct i2c_client *client = codec->control_data;
248
249	/* Write register */
250	xfer[0].addr = client->addr;
251	xfer[0].flags = 0;
252	xfer[0].len = 1;
253	xfer[0].buf = &reg;
254
255	/* Read data */
256	xfer[1].addr = client->addr;
257	xfer[1].flags = I2C_M_RD;
258	xfer[1].len = 1;
259	xfer[1].buf = &data;
260
261	ret = i2c_transfer(client->adapter, xfer, 2);
262	if (ret != 2) {
263		dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
264		return 0;
265	}
266
267	return data;
268}
269#else
270#define snd_soc_8_8_read_i2c NULL
271#endif
272
273#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
274static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
275					  unsigned int r)
276{
277	struct i2c_msg xfer[2];
278	u8 reg = r;
279	u16 data;
280	int ret;
281	struct i2c_client *client = codec->control_data;
282
283	/* Write register */
284	xfer[0].addr = client->addr;
285	xfer[0].flags = 0;
286	xfer[0].len = 1;
287	xfer[0].buf = &reg;
288
289	/* Read data */
290	xfer[1].addr = client->addr;
291	xfer[1].flags = I2C_M_RD;
292	xfer[1].len = 2;
293	xfer[1].buf = (u8 *)&data;
294
295	ret = i2c_transfer(client->adapter, xfer, 2);
296	if (ret != 2) {
297		dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
298		return 0;
299	}
300
301	return (data >> 8) | ((data & 0xff) << 8);
302}
303#else
304#define snd_soc_8_16_read_i2c NULL
305#endif
306
307#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
308static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
309					  unsigned int r)
310{
311	struct i2c_msg xfer[2];
312	u16 reg = r;
313	u8 data;
314	int ret;
315	struct i2c_client *client = codec->control_data;
316
317	/* Write register */
318	xfer[0].addr = client->addr;
319	xfer[0].flags = 0;
320	xfer[0].len = 2;
321	xfer[0].buf = (u8 *)&reg;
322
323	/* Read data */
324	xfer[1].addr = client->addr;
325	xfer[1].flags = I2C_M_RD;
326	xfer[1].len = 1;
327	xfer[1].buf = &data;
328
329	ret = i2c_transfer(client->adapter, xfer, 2);
330	if (ret != 2) {
331		dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
332		return 0;
333	}
334
335	return data;
336}
337#else
338#define snd_soc_16_8_read_i2c NULL
339#endif
340
341static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
342				     unsigned int reg)
343{
344	u8 *cache = codec->reg_cache;
345
346	reg &= 0xff;
347	if (reg >= codec->reg_cache_size)
348		return -1;
349	return cache[reg];
350}
351
352static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
353			     unsigned int value)
354{
355	u8 *cache = codec->reg_cache;
356	u8 data[3];
357	int ret;
358
359	BUG_ON(codec->volatile_register);
360
361	data[0] = (reg >> 8) & 0xff;
362	data[1] = reg & 0xff;
363	data[2] = value;
364
365	reg &= 0xff;
366	if (reg < codec->reg_cache_size)
367		cache[reg] = value;
368
369	if (codec->cache_only) {
370		codec->cache_sync = 1;
371		return 0;
372	}
373
374	dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
375
376	ret = codec->hw_write(codec->control_data, data, 3);
377	if (ret == 3)
378		return 0;
379	if (ret < 0)
380		return ret;
381	else
382		return -EIO;
383}
384
385#if defined(CONFIG_SPI_MASTER)
386static int snd_soc_16_8_spi_write(void *control_data, const char *data,
387				 int len)
388{
389	struct spi_device *spi = control_data;
390	struct spi_transfer t;
391	struct spi_message m;
392	u8 msg[3];
393
394	if (len <= 0)
395		return 0;
396
397	msg[0] = data[0];
398	msg[1] = data[1];
399	msg[2] = data[2];
400
401	spi_message_init(&m);
402	memset(&t, 0, (sizeof t));
403
404	t.tx_buf = &msg[0];
405	t.len = len;
406
407	spi_message_add_tail(&t, &m);
408	spi_sync(spi, &m);
409
410	return len;
411}
412#else
413#define snd_soc_16_8_spi_write NULL
414#endif
415
416#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
417static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
418					   unsigned int r)
419{
420	struct i2c_msg xfer[2];
421	u16 reg = cpu_to_be16(r);
422	u16 data;
423	int ret;
424	struct i2c_client *client = codec->control_data;
425
426	/* Write register */
427	xfer[0].addr = client->addr;
428	xfer[0].flags = 0;
429	xfer[0].len = 2;
430	xfer[0].buf = (u8 *)&reg;
431
432	/* Read data */
433	xfer[1].addr = client->addr;
434	xfer[1].flags = I2C_M_RD;
435	xfer[1].len = 2;
436	xfer[1].buf = (u8 *)&data;
437
438	ret = i2c_transfer(client->adapter, xfer, 2);
439	if (ret != 2) {
440		dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
441		return 0;
442	}
443
444	return be16_to_cpu(data);
445}
446#else
447#define snd_soc_16_16_read_i2c NULL
448#endif
449
450static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
451				       unsigned int reg)
452{
453	u16 *cache = codec->reg_cache;
454
455	if (reg >= codec->reg_cache_size ||
456	    snd_soc_codec_volatile_register(codec, reg)) {
457		if (codec->cache_only)
458			return -EINVAL;
459
460		return codec->hw_read(codec, reg);
461	}
462
463	return cache[reg];
464}
465
466static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
467			       unsigned int value)
468{
469	u16 *cache = codec->reg_cache;
470	u8 data[4];
471	int ret;
472
473	data[0] = (reg >> 8) & 0xff;
474	data[1] = reg & 0xff;
475	data[2] = (value >> 8) & 0xff;
476	data[3] = value & 0xff;
477
478	if (reg < codec->reg_cache_size)
479		cache[reg] = value;
480
481	if (codec->cache_only) {
482		codec->cache_sync = 1;
483		return 0;
484	}
485
486	dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
487
488	ret = codec->hw_write(codec->control_data, data, 4);
489	if (ret == 4)
490		return 0;
491	if (ret < 0)
492		return ret;
493	else
494		return -EIO;
495}
496
497static struct {
498	int addr_bits;
499	int data_bits;
500	int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
501	int (*spi_write)(void *, const char *, int);
502	unsigned int (*read)(struct snd_soc_codec *, unsigned int);
503	unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
504} io_types[] = {
505	{
506		.addr_bits = 4, .data_bits = 12,
507		.write = snd_soc_4_12_write, .read = snd_soc_4_12_read,
508		.spi_write = snd_soc_4_12_spi_write,
509	},
510	{
511		.addr_bits = 7, .data_bits = 9,
512		.write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
513		.spi_write = snd_soc_7_9_spi_write,
514	},
515	{
516		.addr_bits = 8, .data_bits = 8,
517		.write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
518		.i2c_read = snd_soc_8_8_read_i2c,
519	},
520	{
521		.addr_bits = 8, .data_bits = 16,
522		.write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
523		.i2c_read = snd_soc_8_16_read_i2c,
524	},
525	{
526		.addr_bits = 16, .data_bits = 8,
527		.write = snd_soc_16_8_write, .read = snd_soc_16_8_read,
528		.i2c_read = snd_soc_16_8_read_i2c,
529		.spi_write = snd_soc_16_8_spi_write,
530	},
531	{
532		.addr_bits = 16, .data_bits = 16,
533		.write = snd_soc_16_16_write, .read = snd_soc_16_16_read,
534		.i2c_read = snd_soc_16_16_read_i2c,
535	},
536};
537
538/**
539 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
540 *
541 * @codec: CODEC to configure.
542 * @type: Type of cache.
543 * @addr_bits: Number of bits of register address data.
544 * @data_bits: Number of bits of data per register.
545 * @control: Control bus used.
546 *
547 * Register formats are frequently shared between many I2C and SPI
548 * devices.  In order to promote code reuse the ASoC core provides
549 * some standard implementations of CODEC read and write operations
550 * which can be set up using this function.
551 *
552 * The caller is responsible for allocating and initialising the
553 * actual cache.
554 *
555 * Note that at present this code cannot be used by CODECs with
556 * volatile registers.
557 */
558int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
559			       int addr_bits, int data_bits,
560			       enum snd_soc_control_type control)
561{
562	int i;
563
564	for (i = 0; i < ARRAY_SIZE(io_types); i++)
565		if (io_types[i].addr_bits == addr_bits &&
566		    io_types[i].data_bits == data_bits)
567			break;
568	if (i == ARRAY_SIZE(io_types)) {
569		printk(KERN_ERR
570		       "No I/O functions for %d bit address %d bit data\n",
571		       addr_bits, data_bits);
572		return -EINVAL;
573	}
574
575	codec->write = io_types[i].write;
576	codec->read = io_types[i].read;
577
578	switch (control) {
579	case SND_SOC_CUSTOM:
580		break;
581
582	case SND_SOC_I2C:
583#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
584		codec->hw_write = (hw_write_t)i2c_master_send;
585#endif
586		if (io_types[i].i2c_read)
587			codec->hw_read = io_types[i].i2c_read;
588		break;
589
590	case SND_SOC_SPI:
591		if (io_types[i].spi_write)
592			codec->hw_write = io_types[i].spi_write;
593		break;
594	}
595
596	return 0;
597}
598EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
599