soc-cache.c revision c358e640a669b528b32af5442c92b856de623e1c
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#include <linux/lzo.h>
18#include <linux/bitmap.h>
19#include <linux/rbtree.h>
20
21#include <trace/events/asoc.h>
22
23static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
24				     unsigned int reg)
25{
26	int ret;
27	unsigned int val;
28
29	if (reg >= codec->driver->reg_cache_size ||
30		snd_soc_codec_volatile_register(codec, reg) ||
31		codec->cache_bypass) {
32			if (codec->cache_only)
33				return -1;
34
35			BUG_ON(!codec->hw_read);
36			return codec->hw_read(codec, reg);
37	}
38
39	ret = snd_soc_cache_read(codec, reg, &val);
40	if (ret < 0)
41		return -1;
42	return val;
43}
44
45static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
46			     unsigned int value)
47{
48	u8 data[2];
49	int ret;
50
51	data[0] = (reg << 4) | ((value >> 8) & 0x000f);
52	data[1] = value & 0x00ff;
53
54	if (!snd_soc_codec_volatile_register(codec, reg) &&
55		reg < codec->driver->reg_cache_size &&
56		!codec->cache_bypass) {
57		ret = snd_soc_cache_write(codec, reg, value);
58		if (ret < 0)
59			return -1;
60	}
61
62	if (codec->cache_only) {
63		codec->cache_sync = 1;
64		return 0;
65	}
66
67	ret = codec->hw_write(codec->control_data, data, 2);
68	if (ret == 2)
69		return 0;
70	if (ret < 0)
71		return ret;
72	else
73		return -EIO;
74}
75
76#if defined(CONFIG_SPI_MASTER)
77static int snd_soc_4_12_spi_write(void *control_data, const char *data,
78				 int len)
79{
80	struct spi_device *spi = control_data;
81	struct spi_transfer t;
82	struct spi_message m;
83	u8 msg[2];
84
85	if (len <= 0)
86		return 0;
87
88	msg[0] = data[1];
89	msg[1] = data[0];
90
91	spi_message_init(&m);
92	memset(&t, 0, sizeof t);
93
94	t.tx_buf = &msg[0];
95	t.len = len;
96
97	spi_message_add_tail(&t, &m);
98	spi_sync(spi, &m);
99
100	return len;
101}
102#else
103#define snd_soc_4_12_spi_write NULL
104#endif
105
106static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
107				     unsigned int reg)
108{
109	int ret;
110	unsigned int val;
111
112	if (reg >= codec->driver->reg_cache_size ||
113		snd_soc_codec_volatile_register(codec, reg) ||
114		codec->cache_bypass) {
115			if (codec->cache_only)
116				return -1;
117
118			BUG_ON(!codec->hw_read);
119			return codec->hw_read(codec, reg);
120	}
121
122	ret = snd_soc_cache_read(codec, reg, &val);
123	if (ret < 0)
124		return -1;
125	return val;
126}
127
128static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
129			     unsigned int value)
130{
131	u8 data[2];
132	int ret;
133
134	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
135	data[1] = value & 0x00ff;
136
137	if (!snd_soc_codec_volatile_register(codec, reg) &&
138		reg < codec->driver->reg_cache_size &&
139		!codec->cache_bypass) {
140		ret = snd_soc_cache_write(codec, reg, value);
141		if (ret < 0)
142			return -1;
143	}
144
145	if (codec->cache_only) {
146		codec->cache_sync = 1;
147		return 0;
148	}
149
150	ret = codec->hw_write(codec->control_data, data, 2);
151	if (ret == 2)
152		return 0;
153	if (ret < 0)
154		return ret;
155	else
156		return -EIO;
157}
158
159#if defined(CONFIG_SPI_MASTER)
160static int snd_soc_7_9_spi_write(void *control_data, const char *data,
161				 int len)
162{
163	struct spi_device *spi = control_data;
164	struct spi_transfer t;
165	struct spi_message m;
166	u8 msg[2];
167
168	if (len <= 0)
169		return 0;
170
171	msg[0] = data[0];
172	msg[1] = data[1];
173
174	spi_message_init(&m);
175	memset(&t, 0, sizeof t);
176
177	t.tx_buf = &msg[0];
178	t.len = len;
179
180	spi_message_add_tail(&t, &m);
181	spi_sync(spi, &m);
182
183	return len;
184}
185#else
186#define snd_soc_7_9_spi_write NULL
187#endif
188
189static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
190			     unsigned int value)
191{
192	u8 data[2];
193	int ret;
194
195	reg &= 0xff;
196	data[0] = reg;
197	data[1] = value & 0xff;
198
199	if (!snd_soc_codec_volatile_register(codec, reg) &&
200		reg < codec->driver->reg_cache_size &&
201		!codec->cache_bypass) {
202		ret = snd_soc_cache_write(codec, reg, value);
203		if (ret < 0)
204			return -1;
205	}
206
207	if (codec->cache_only) {
208		codec->cache_sync = 1;
209		return 0;
210	}
211
212	if (codec->hw_write(codec->control_data, data, 2) == 2)
213		return 0;
214	else
215		return -EIO;
216}
217
218static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
219				     unsigned int reg)
220{
221	int ret;
222	unsigned int val;
223
224	reg &= 0xff;
225	if (reg >= codec->driver->reg_cache_size ||
226		snd_soc_codec_volatile_register(codec, reg) ||
227		codec->cache_bypass) {
228			if (codec->cache_only)
229				return -1;
230
231			BUG_ON(!codec->hw_read);
232			return codec->hw_read(codec, reg);
233	}
234
235	ret = snd_soc_cache_read(codec, reg, &val);
236	if (ret < 0)
237		return -1;
238	return val;
239}
240
241#if defined(CONFIG_SPI_MASTER)
242static int snd_soc_8_8_spi_write(void *control_data, const char *data,
243				 int len)
244{
245	struct spi_device *spi = control_data;
246	struct spi_transfer t;
247	struct spi_message m;
248	u8 msg[2];
249
250	if (len <= 0)
251		return 0;
252
253	msg[0] = data[0];
254	msg[1] = data[1];
255
256	spi_message_init(&m);
257	memset(&t, 0, sizeof t);
258
259	t.tx_buf = &msg[0];
260	t.len = len;
261
262	spi_message_add_tail(&t, &m);
263	spi_sync(spi, &m);
264
265	return len;
266}
267#else
268#define snd_soc_8_8_spi_write NULL
269#endif
270
271static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
272			      unsigned int value)
273{
274	u8 data[3];
275	int ret;
276
277	data[0] = reg;
278	data[1] = (value >> 8) & 0xff;
279	data[2] = value & 0xff;
280
281	if (!snd_soc_codec_volatile_register(codec, reg) &&
282		reg < codec->driver->reg_cache_size &&
283		!codec->cache_bypass) {
284		ret = snd_soc_cache_write(codec, reg, value);
285		if (ret < 0)
286			return -1;
287	}
288
289	if (codec->cache_only) {
290		codec->cache_sync = 1;
291		return 0;
292	}
293
294	if (codec->hw_write(codec->control_data, data, 3) == 3)
295		return 0;
296	else
297		return -EIO;
298}
299
300static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
301				      unsigned int reg)
302{
303	int ret;
304	unsigned int val;
305
306	if (reg >= codec->driver->reg_cache_size ||
307	    snd_soc_codec_volatile_register(codec, reg) ||
308	    codec->cache_bypass) {
309		if (codec->cache_only)
310			return -1;
311
312		BUG_ON(!codec->hw_read);
313		return codec->hw_read(codec, reg);
314	}
315
316	ret = snd_soc_cache_read(codec, reg, &val);
317	if (ret < 0)
318		return -1;
319	return val;
320}
321
322#if defined(CONFIG_SPI_MASTER)
323static int snd_soc_8_16_spi_write(void *control_data, const char *data,
324				 int len)
325{
326	struct spi_device *spi = control_data;
327	struct spi_transfer t;
328	struct spi_message m;
329	u8 msg[3];
330
331	if (len <= 0)
332		return 0;
333
334	msg[0] = data[0];
335	msg[1] = data[1];
336	msg[2] = data[2];
337
338	spi_message_init(&m);
339	memset(&t, 0, sizeof t);
340
341	t.tx_buf = &msg[0];
342	t.len = len;
343
344	spi_message_add_tail(&t, &m);
345	spi_sync(spi, &m);
346
347	return len;
348}
349#else
350#define snd_soc_8_16_spi_write NULL
351#endif
352
353#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
354static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
355					  unsigned int r)
356{
357	struct i2c_msg xfer[2];
358	u8 reg = r;
359	u8 data;
360	int ret;
361	struct i2c_client *client = codec->control_data;
362
363	/* Write register */
364	xfer[0].addr = client->addr;
365	xfer[0].flags = 0;
366	xfer[0].len = 1;
367	xfer[0].buf = &reg;
368
369	/* Read data */
370	xfer[1].addr = client->addr;
371	xfer[1].flags = I2C_M_RD;
372	xfer[1].len = 1;
373	xfer[1].buf = &data;
374
375	ret = i2c_transfer(client->adapter, xfer, 2);
376	if (ret != 2) {
377		dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
378		return 0;
379	}
380
381	return data;
382}
383#else
384#define snd_soc_8_8_read_i2c NULL
385#endif
386
387#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
388static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
389					  unsigned int r)
390{
391	struct i2c_msg xfer[2];
392	u8 reg = r;
393	u16 data;
394	int ret;
395	struct i2c_client *client = codec->control_data;
396
397	/* Write register */
398	xfer[0].addr = client->addr;
399	xfer[0].flags = 0;
400	xfer[0].len = 1;
401	xfer[0].buf = &reg;
402
403	/* Read data */
404	xfer[1].addr = client->addr;
405	xfer[1].flags = I2C_M_RD;
406	xfer[1].len = 2;
407	xfer[1].buf = (u8 *)&data;
408
409	ret = i2c_transfer(client->adapter, xfer, 2);
410	if (ret != 2) {
411		dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
412		return 0;
413	}
414
415	return (data >> 8) | ((data & 0xff) << 8);
416}
417#else
418#define snd_soc_8_16_read_i2c NULL
419#endif
420
421#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
422static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
423					  unsigned int r)
424{
425	struct i2c_msg xfer[2];
426	u16 reg = r;
427	u8 data;
428	int ret;
429	struct i2c_client *client = codec->control_data;
430
431	/* Write register */
432	xfer[0].addr = client->addr;
433	xfer[0].flags = 0;
434	xfer[0].len = 2;
435	xfer[0].buf = (u8 *)&reg;
436
437	/* Read data */
438	xfer[1].addr = client->addr;
439	xfer[1].flags = I2C_M_RD;
440	xfer[1].len = 1;
441	xfer[1].buf = &data;
442
443	ret = i2c_transfer(client->adapter, xfer, 2);
444	if (ret != 2) {
445		dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
446		return 0;
447	}
448
449	return data;
450}
451#else
452#define snd_soc_16_8_read_i2c NULL
453#endif
454
455static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
456				     unsigned int reg)
457{
458	int ret;
459	unsigned int val;
460
461	reg &= 0xff;
462	if (reg >= codec->driver->reg_cache_size ||
463		snd_soc_codec_volatile_register(codec, reg) ||
464		codec->cache_bypass) {
465			if (codec->cache_only)
466				return -1;
467
468			BUG_ON(!codec->hw_read);
469			return codec->hw_read(codec, reg);
470	}
471
472	ret = snd_soc_cache_read(codec, reg, &val);
473	if (ret < 0)
474		return -1;
475	return val;
476}
477
478static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
479			     unsigned int value)
480{
481	u8 data[3];
482	int ret;
483
484	data[0] = (reg >> 8) & 0xff;
485	data[1] = reg & 0xff;
486	data[2] = value;
487
488	reg &= 0xff;
489	if (!snd_soc_codec_volatile_register(codec, reg) &&
490		reg < codec->driver->reg_cache_size &&
491		!codec->cache_bypass) {
492		ret = snd_soc_cache_write(codec, reg, value);
493		if (ret < 0)
494			return -1;
495	}
496
497	if (codec->cache_only) {
498		codec->cache_sync = 1;
499		return 0;
500	}
501
502	ret = codec->hw_write(codec->control_data, data, 3);
503	if (ret == 3)
504		return 0;
505	if (ret < 0)
506		return ret;
507	else
508		return -EIO;
509}
510
511#if defined(CONFIG_SPI_MASTER)
512static int snd_soc_16_8_spi_write(void *control_data, const char *data,
513				 int len)
514{
515	struct spi_device *spi = control_data;
516	struct spi_transfer t;
517	struct spi_message m;
518	u8 msg[3];
519
520	if (len <= 0)
521		return 0;
522
523	msg[0] = data[0];
524	msg[1] = data[1];
525	msg[2] = data[2];
526
527	spi_message_init(&m);
528	memset(&t, 0, sizeof t);
529
530	t.tx_buf = &msg[0];
531	t.len = len;
532
533	spi_message_add_tail(&t, &m);
534	spi_sync(spi, &m);
535
536	return len;
537}
538#else
539#define snd_soc_16_8_spi_write NULL
540#endif
541
542#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
543static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
544					   unsigned int r)
545{
546	struct i2c_msg xfer[2];
547	u16 reg = cpu_to_be16(r);
548	u16 data;
549	int ret;
550	struct i2c_client *client = codec->control_data;
551
552	/* Write register */
553	xfer[0].addr = client->addr;
554	xfer[0].flags = 0;
555	xfer[0].len = 2;
556	xfer[0].buf = (u8 *)&reg;
557
558	/* Read data */
559	xfer[1].addr = client->addr;
560	xfer[1].flags = I2C_M_RD;
561	xfer[1].len = 2;
562	xfer[1].buf = (u8 *)&data;
563
564	ret = i2c_transfer(client->adapter, xfer, 2);
565	if (ret != 2) {
566		dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
567		return 0;
568	}
569
570	return be16_to_cpu(data);
571}
572#else
573#define snd_soc_16_16_read_i2c NULL
574#endif
575
576static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
577				       unsigned int reg)
578{
579	int ret;
580	unsigned int val;
581
582	if (reg >= codec->driver->reg_cache_size ||
583	    snd_soc_codec_volatile_register(codec, reg) ||
584	    codec->cache_bypass) {
585		if (codec->cache_only)
586			return -1;
587
588		BUG_ON(!codec->hw_read);
589		return codec->hw_read(codec, reg);
590	}
591
592	ret = snd_soc_cache_read(codec, reg, &val);
593	if (ret < 0)
594		return -1;
595
596	return val;
597}
598
599static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
600			       unsigned int value)
601{
602	u8 data[4];
603	int ret;
604
605	data[0] = (reg >> 8) & 0xff;
606	data[1] = reg & 0xff;
607	data[2] = (value >> 8) & 0xff;
608	data[3] = value & 0xff;
609
610	if (!snd_soc_codec_volatile_register(codec, reg) &&
611		reg < codec->driver->reg_cache_size &&
612		!codec->cache_bypass) {
613		ret = snd_soc_cache_write(codec, reg, value);
614		if (ret < 0)
615			return -1;
616	}
617
618	if (codec->cache_only) {
619		codec->cache_sync = 1;
620		return 0;
621	}
622
623	ret = codec->hw_write(codec->control_data, data, 4);
624	if (ret == 4)
625		return 0;
626	if (ret < 0)
627		return ret;
628	else
629		return -EIO;
630}
631
632#if defined(CONFIG_SPI_MASTER)
633static int snd_soc_16_16_spi_write(void *control_data, const char *data,
634				 int len)
635{
636	struct spi_device *spi = control_data;
637	struct spi_transfer t;
638	struct spi_message m;
639	u8 msg[4];
640
641	if (len <= 0)
642		return 0;
643
644	msg[0] = data[0];
645	msg[1] = data[1];
646	msg[2] = data[2];
647	msg[3] = data[3];
648
649	spi_message_init(&m);
650	memset(&t, 0, sizeof t);
651
652	t.tx_buf = &msg[0];
653	t.len = len;
654
655	spi_message_add_tail(&t, &m);
656	spi_sync(spi, &m);
657
658	return len;
659}
660#else
661#define snd_soc_16_16_spi_write NULL
662#endif
663
664static struct {
665	int addr_bits;
666	int data_bits;
667	int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
668	int (*spi_write)(void *, const char *, int);
669	unsigned int (*read)(struct snd_soc_codec *, unsigned int);
670	unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
671} io_types[] = {
672	{
673		.addr_bits = 4, .data_bits = 12,
674		.write = snd_soc_4_12_write, .read = snd_soc_4_12_read,
675		.spi_write = snd_soc_4_12_spi_write,
676	},
677	{
678		.addr_bits = 7, .data_bits = 9,
679		.write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
680		.spi_write = snd_soc_7_9_spi_write,
681	},
682	{
683		.addr_bits = 8, .data_bits = 8,
684		.write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
685		.i2c_read = snd_soc_8_8_read_i2c,
686		.spi_write = snd_soc_8_8_spi_write,
687	},
688	{
689		.addr_bits = 8, .data_bits = 16,
690		.write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
691		.i2c_read = snd_soc_8_16_read_i2c,
692		.spi_write = snd_soc_8_16_spi_write,
693	},
694	{
695		.addr_bits = 16, .data_bits = 8,
696		.write = snd_soc_16_8_write, .read = snd_soc_16_8_read,
697		.i2c_read = snd_soc_16_8_read_i2c,
698		.spi_write = snd_soc_16_8_spi_write,
699	},
700	{
701		.addr_bits = 16, .data_bits = 16,
702		.write = snd_soc_16_16_write, .read = snd_soc_16_16_read,
703		.i2c_read = snd_soc_16_16_read_i2c,
704		.spi_write = snd_soc_16_16_spi_write,
705	},
706};
707
708/**
709 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
710 *
711 * @codec: CODEC to configure.
712 * @type: Type of cache.
713 * @addr_bits: Number of bits of register address data.
714 * @data_bits: Number of bits of data per register.
715 * @control: Control bus used.
716 *
717 * Register formats are frequently shared between many I2C and SPI
718 * devices.  In order to promote code reuse the ASoC core provides
719 * some standard implementations of CODEC read and write operations
720 * which can be set up using this function.
721 *
722 * The caller is responsible for allocating and initialising the
723 * actual cache.
724 *
725 * Note that at present this code cannot be used by CODECs with
726 * volatile registers.
727 */
728int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
729			       int addr_bits, int data_bits,
730			       enum snd_soc_control_type control)
731{
732	int i;
733
734	for (i = 0; i < ARRAY_SIZE(io_types); i++)
735		if (io_types[i].addr_bits == addr_bits &&
736		    io_types[i].data_bits == data_bits)
737			break;
738	if (i == ARRAY_SIZE(io_types)) {
739		printk(KERN_ERR
740		       "No I/O functions for %d bit address %d bit data\n",
741		       addr_bits, data_bits);
742		return -EINVAL;
743	}
744
745	codec->write = io_types[i].write;
746	codec->read = io_types[i].read;
747
748	switch (control) {
749	case SND_SOC_CUSTOM:
750		break;
751
752	case SND_SOC_I2C:
753#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
754		codec->hw_write = (hw_write_t)i2c_master_send;
755#endif
756		if (io_types[i].i2c_read)
757			codec->hw_read = io_types[i].i2c_read;
758
759		codec->control_data = container_of(codec->dev,
760						   struct i2c_client,
761						   dev);
762		break;
763
764	case SND_SOC_SPI:
765		if (io_types[i].spi_write)
766			codec->hw_write = io_types[i].spi_write;
767
768		codec->control_data = container_of(codec->dev,
769						   struct spi_device,
770						   dev);
771		break;
772	}
773
774	return 0;
775}
776EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
777
778static bool snd_soc_set_cache_val(void *base, unsigned int idx,
779				  unsigned int val, unsigned int word_size)
780{
781	switch (word_size) {
782	case 1: {
783		u8 *cache = base;
784		if (cache[idx] == val)
785			return true;
786		cache[idx] = val;
787		break;
788	}
789	case 2: {
790		u16 *cache = base;
791		if (cache[idx] == val)
792			return true;
793		cache[idx] = val;
794		break;
795	}
796	default:
797		BUG();
798	}
799	return false;
800}
801
802static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx,
803		unsigned int word_size)
804{
805	switch (word_size) {
806	case 1: {
807		const u8 *cache = base;
808		return cache[idx];
809	}
810	case 2: {
811		const u16 *cache = base;
812		return cache[idx];
813	}
814	default:
815		BUG();
816	}
817	/* unreachable */
818	return -1;
819}
820
821struct snd_soc_rbtree_node {
822	struct rb_node node;
823	unsigned int reg;
824	unsigned int value;
825	unsigned int defval;
826} __attribute__ ((packed));
827
828struct snd_soc_rbtree_ctx {
829	struct rb_root root;
830};
831
832static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup(
833	struct rb_root *root, unsigned int reg)
834{
835	struct rb_node *node;
836	struct snd_soc_rbtree_node *rbnode;
837
838	node = root->rb_node;
839	while (node) {
840		rbnode = container_of(node, struct snd_soc_rbtree_node, node);
841		if (rbnode->reg < reg)
842			node = node->rb_left;
843		else if (rbnode->reg > reg)
844			node = node->rb_right;
845		else
846			return rbnode;
847	}
848
849	return NULL;
850}
851
852static int snd_soc_rbtree_insert(struct rb_root *root,
853				 struct snd_soc_rbtree_node *rbnode)
854{
855	struct rb_node **new, *parent;
856	struct snd_soc_rbtree_node *rbnode_tmp;
857
858	parent = NULL;
859	new = &root->rb_node;
860	while (*new) {
861		rbnode_tmp = container_of(*new, struct snd_soc_rbtree_node,
862					  node);
863		parent = *new;
864		if (rbnode_tmp->reg < rbnode->reg)
865			new = &((*new)->rb_left);
866		else if (rbnode_tmp->reg > rbnode->reg)
867			new = &((*new)->rb_right);
868		else
869			return 0;
870	}
871
872	/* insert the node into the rbtree */
873	rb_link_node(&rbnode->node, parent, new);
874	rb_insert_color(&rbnode->node, root);
875
876	return 1;
877}
878
879static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
880{
881	struct snd_soc_rbtree_ctx *rbtree_ctx;
882	struct rb_node *node;
883	struct snd_soc_rbtree_node *rbnode;
884	unsigned int val;
885	int ret;
886
887	rbtree_ctx = codec->reg_cache;
888	for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
889		rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
890		if (rbnode->value == rbnode->defval)
891			continue;
892		ret = snd_soc_cache_read(codec, rbnode->reg, &val);
893		if (ret)
894			return ret;
895		codec->cache_bypass = 1;
896		ret = snd_soc_write(codec, rbnode->reg, val);
897		codec->cache_bypass = 0;
898		if (ret)
899			return ret;
900		dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
901			rbnode->reg, val);
902	}
903
904	return 0;
905}
906
907static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec,
908				      unsigned int reg, unsigned int value)
909{
910	struct snd_soc_rbtree_ctx *rbtree_ctx;
911	struct snd_soc_rbtree_node *rbnode;
912
913	rbtree_ctx = codec->reg_cache;
914	rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
915	if (rbnode) {
916		if (rbnode->value == value)
917			return 0;
918		rbnode->value = value;
919	} else {
920		/* bail out early, no need to create the rbnode yet */
921		if (!value)
922			return 0;
923		/*
924		 * for uninitialized registers whose value is changed
925		 * from the default zero, create an rbnode and insert
926		 * it into the tree.
927		 */
928		rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL);
929		if (!rbnode)
930			return -ENOMEM;
931		rbnode->reg = reg;
932		rbnode->value = value;
933		snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode);
934	}
935
936	return 0;
937}
938
939static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec,
940				     unsigned int reg, unsigned int *value)
941{
942	struct snd_soc_rbtree_ctx *rbtree_ctx;
943	struct snd_soc_rbtree_node *rbnode;
944
945	rbtree_ctx = codec->reg_cache;
946	rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
947	if (rbnode) {
948		*value = rbnode->value;
949	} else {
950		/* uninitialized registers default to 0 */
951		*value = 0;
952	}
953
954	return 0;
955}
956
957static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec)
958{
959	struct rb_node *next;
960	struct snd_soc_rbtree_ctx *rbtree_ctx;
961	struct snd_soc_rbtree_node *rbtree_node;
962
963	/* if we've already been called then just return */
964	rbtree_ctx = codec->reg_cache;
965	if (!rbtree_ctx)
966		return 0;
967
968	/* free up the rbtree */
969	next = rb_first(&rbtree_ctx->root);
970	while (next) {
971		rbtree_node = rb_entry(next, struct snd_soc_rbtree_node, node);
972		next = rb_next(&rbtree_node->node);
973		rb_erase(&rbtree_node->node, &rbtree_ctx->root);
974		kfree(rbtree_node);
975	}
976
977	/* release the resources */
978	kfree(codec->reg_cache);
979	codec->reg_cache = NULL;
980
981	return 0;
982}
983
984static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
985{
986	struct snd_soc_rbtree_node *rbtree_node;
987	struct snd_soc_rbtree_ctx *rbtree_ctx;
988	unsigned int val;
989	unsigned int word_size;
990	int i;
991	int ret;
992
993	codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL);
994	if (!codec->reg_cache)
995		return -ENOMEM;
996
997	rbtree_ctx = codec->reg_cache;
998	rbtree_ctx->root = RB_ROOT;
999
1000	if (!codec->reg_def_copy)
1001		return 0;
1002
1003	/*
1004	 * populate the rbtree with the initialized registers.  All other
1005	 * registers will be inserted when they are first modified.
1006	 */
1007	word_size = codec->driver->reg_word_size;
1008	for (i = 0; i < codec->driver->reg_cache_size; ++i) {
1009		val = snd_soc_get_cache_val(codec->reg_def_copy, i, word_size);
1010		if (!val)
1011			continue;
1012		rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL);
1013		if (!rbtree_node) {
1014			ret = -ENOMEM;
1015			snd_soc_cache_exit(codec);
1016			break;
1017		}
1018		rbtree_node->reg = i;
1019		rbtree_node->value = val;
1020		rbtree_node->defval = val;
1021		snd_soc_rbtree_insert(&rbtree_ctx->root, rbtree_node);
1022	}
1023
1024	return 0;
1025}
1026
1027#ifdef CONFIG_SND_SOC_CACHE_LZO
1028struct snd_soc_lzo_ctx {
1029	void *wmem;
1030	void *dst;
1031	const void *src;
1032	size_t src_len;
1033	size_t dst_len;
1034	size_t decompressed_size;
1035	unsigned long *sync_bmp;
1036	int sync_bmp_nbits;
1037};
1038
1039#define LZO_BLOCK_NUM 8
1040static int snd_soc_lzo_block_count(void)
1041{
1042	return LZO_BLOCK_NUM;
1043}
1044
1045static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx)
1046{
1047	lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
1048	if (!lzo_ctx->wmem)
1049		return -ENOMEM;
1050	return 0;
1051}
1052
1053static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx)
1054{
1055	size_t compress_size;
1056	int ret;
1057
1058	ret = lzo1x_1_compress(lzo_ctx->src, lzo_ctx->src_len,
1059			       lzo_ctx->dst, &compress_size, lzo_ctx->wmem);
1060	if (ret != LZO_E_OK || compress_size > lzo_ctx->dst_len)
1061		return -EINVAL;
1062	lzo_ctx->dst_len = compress_size;
1063	return 0;
1064}
1065
1066static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx)
1067{
1068	size_t dst_len;
1069	int ret;
1070
1071	dst_len = lzo_ctx->dst_len;
1072	ret = lzo1x_decompress_safe(lzo_ctx->src, lzo_ctx->src_len,
1073				    lzo_ctx->dst, &dst_len);
1074	if (ret != LZO_E_OK || dst_len != lzo_ctx->dst_len)
1075		return -EINVAL;
1076	return 0;
1077}
1078
1079static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec,
1080		struct snd_soc_lzo_ctx *lzo_ctx)
1081{
1082	int ret;
1083
1084	lzo_ctx->dst_len = lzo1x_worst_compress(PAGE_SIZE);
1085	lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
1086	if (!lzo_ctx->dst) {
1087		lzo_ctx->dst_len = 0;
1088		return -ENOMEM;
1089	}
1090
1091	ret = snd_soc_lzo_compress(lzo_ctx);
1092	if (ret < 0)
1093		return ret;
1094	return 0;
1095}
1096
1097static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec,
1098		struct snd_soc_lzo_ctx *lzo_ctx)
1099{
1100	int ret;
1101
1102	lzo_ctx->dst_len = lzo_ctx->decompressed_size;
1103	lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
1104	if (!lzo_ctx->dst) {
1105		lzo_ctx->dst_len = 0;
1106		return -ENOMEM;
1107	}
1108
1109	ret = snd_soc_lzo_decompress(lzo_ctx);
1110	if (ret < 0)
1111		return ret;
1112	return 0;
1113}
1114
1115static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
1116		unsigned int reg)
1117{
1118	const struct snd_soc_codec_driver *codec_drv;
1119
1120	codec_drv = codec->driver;
1121	return (reg * codec_drv->reg_word_size) /
1122	       DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
1123}
1124
1125static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
1126		unsigned int reg)
1127{
1128	const struct snd_soc_codec_driver *codec_drv;
1129
1130	codec_drv = codec->driver;
1131	return reg % (DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()) /
1132		      codec_drv->reg_word_size);
1133}
1134
1135static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
1136{
1137	const struct snd_soc_codec_driver *codec_drv;
1138
1139	codec_drv = codec->driver;
1140	return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
1141}
1142
1143static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
1144{
1145	struct snd_soc_lzo_ctx **lzo_blocks;
1146	unsigned int val;
1147	int i;
1148	int ret;
1149
1150	lzo_blocks = codec->reg_cache;
1151	for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
1152		ret = snd_soc_cache_read(codec, i, &val);
1153		if (ret)
1154			return ret;
1155		codec->cache_bypass = 1;
1156		ret = snd_soc_write(codec, i, val);
1157		codec->cache_bypass = 0;
1158		if (ret)
1159			return ret;
1160		dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
1161			i, val);
1162	}
1163
1164	return 0;
1165}
1166
1167static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec,
1168				   unsigned int reg, unsigned int value)
1169{
1170	struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
1171	int ret, blkindex, blkpos;
1172	size_t blksize, tmp_dst_len;
1173	void *tmp_dst;
1174
1175	/* index of the compressed lzo block */
1176	blkindex = snd_soc_lzo_get_blkindex(codec, reg);
1177	/* register index within the decompressed block */
1178	blkpos = snd_soc_lzo_get_blkpos(codec, reg);
1179	/* size of the compressed block */
1180	blksize = snd_soc_lzo_get_blksize(codec);
1181	lzo_blocks = codec->reg_cache;
1182	lzo_block = lzo_blocks[blkindex];
1183
1184	/* save the pointer and length of the compressed block */
1185	tmp_dst = lzo_block->dst;
1186	tmp_dst_len = lzo_block->dst_len;
1187
1188	/* prepare the source to be the compressed block */
1189	lzo_block->src = lzo_block->dst;
1190	lzo_block->src_len = lzo_block->dst_len;
1191
1192	/* decompress the block */
1193	ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
1194	if (ret < 0) {
1195		kfree(lzo_block->dst);
1196		goto out;
1197	}
1198
1199	/* write the new value to the cache */
1200	if (snd_soc_set_cache_val(lzo_block->dst, blkpos, value,
1201				  codec->driver->reg_word_size)) {
1202		kfree(lzo_block->dst);
1203		goto out;
1204	}
1205
1206	/* prepare the source to be the decompressed block */
1207	lzo_block->src = lzo_block->dst;
1208	lzo_block->src_len = lzo_block->dst_len;
1209
1210	/* compress the block */
1211	ret = snd_soc_lzo_compress_cache_block(codec, lzo_block);
1212	if (ret < 0) {
1213		kfree(lzo_block->dst);
1214		kfree(lzo_block->src);
1215		goto out;
1216	}
1217
1218	/* set the bit so we know we have to sync this register */
1219	set_bit(reg, lzo_block->sync_bmp);
1220	kfree(tmp_dst);
1221	kfree(lzo_block->src);
1222	return 0;
1223out:
1224	lzo_block->dst = tmp_dst;
1225	lzo_block->dst_len = tmp_dst_len;
1226	return ret;
1227}
1228
1229static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,
1230				  unsigned int reg, unsigned int *value)
1231{
1232	struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
1233	int ret, blkindex, blkpos;
1234	size_t blksize, tmp_dst_len;
1235	void *tmp_dst;
1236
1237	*value = 0;
1238	/* index of the compressed lzo block */
1239	blkindex = snd_soc_lzo_get_blkindex(codec, reg);
1240	/* register index within the decompressed block */
1241	blkpos = snd_soc_lzo_get_blkpos(codec, reg);
1242	/* size of the compressed block */
1243	blksize = snd_soc_lzo_get_blksize(codec);
1244	lzo_blocks = codec->reg_cache;
1245	lzo_block = lzo_blocks[blkindex];
1246
1247	/* save the pointer and length of the compressed block */
1248	tmp_dst = lzo_block->dst;
1249	tmp_dst_len = lzo_block->dst_len;
1250
1251	/* prepare the source to be the compressed block */
1252	lzo_block->src = lzo_block->dst;
1253	lzo_block->src_len = lzo_block->dst_len;
1254
1255	/* decompress the block */
1256	ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
1257	if (ret >= 0)
1258		/* fetch the value from the cache */
1259		*value = snd_soc_get_cache_val(lzo_block->dst, blkpos,
1260					       codec->driver->reg_word_size);
1261
1262	kfree(lzo_block->dst);
1263	/* restore the pointer and length of the compressed block */
1264	lzo_block->dst = tmp_dst;
1265	lzo_block->dst_len = tmp_dst_len;
1266	return 0;
1267}
1268
1269static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec)
1270{
1271	struct snd_soc_lzo_ctx **lzo_blocks;
1272	int i, blkcount;
1273
1274	lzo_blocks = codec->reg_cache;
1275	if (!lzo_blocks)
1276		return 0;
1277
1278	blkcount = snd_soc_lzo_block_count();
1279	/*
1280	 * the pointer to the bitmap used for syncing the cache
1281	 * is shared amongst all lzo_blocks.  Ensure it is freed
1282	 * only once.
1283	 */
1284	if (lzo_blocks[0])
1285		kfree(lzo_blocks[0]->sync_bmp);
1286	for (i = 0; i < blkcount; ++i) {
1287		if (lzo_blocks[i]) {
1288			kfree(lzo_blocks[i]->wmem);
1289			kfree(lzo_blocks[i]->dst);
1290		}
1291		/* each lzo_block is a pointer returned by kmalloc or NULL */
1292		kfree(lzo_blocks[i]);
1293	}
1294	kfree(lzo_blocks);
1295	codec->reg_cache = NULL;
1296	return 0;
1297}
1298
1299static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1300{
1301	struct snd_soc_lzo_ctx **lzo_blocks;
1302	size_t bmp_size;
1303	const struct snd_soc_codec_driver *codec_drv;
1304	int ret, tofree, i, blksize, blkcount;
1305	const char *p, *end;
1306	unsigned long *sync_bmp;
1307
1308	ret = 0;
1309	codec_drv = codec->driver;
1310
1311	/*
1312	 * If we have not been given a default register cache
1313	 * then allocate a dummy zero-ed out region, compress it
1314	 * and remember to free it afterwards.
1315	 */
1316	tofree = 0;
1317	if (!codec->reg_def_copy)
1318		tofree = 1;
1319
1320	if (!codec->reg_def_copy) {
1321		codec->reg_def_copy = kzalloc(codec->reg_size, GFP_KERNEL);
1322		if (!codec->reg_def_copy)
1323			return -ENOMEM;
1324	}
1325
1326	blkcount = snd_soc_lzo_block_count();
1327	codec->reg_cache = kzalloc(blkcount * sizeof *lzo_blocks,
1328				   GFP_KERNEL);
1329	if (!codec->reg_cache) {
1330		ret = -ENOMEM;
1331		goto err_tofree;
1332	}
1333	lzo_blocks = codec->reg_cache;
1334
1335	/*
1336	 * allocate a bitmap to be used when syncing the cache with
1337	 * the hardware.  Each time a register is modified, the corresponding
1338	 * bit is set in the bitmap, so we know that we have to sync
1339	 * that register.
1340	 */
1341	bmp_size = codec_drv->reg_cache_size;
1342	sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long),
1343			   GFP_KERNEL);
1344	if (!sync_bmp) {
1345		ret = -ENOMEM;
1346		goto err;
1347	}
1348	bitmap_zero(sync_bmp, bmp_size);
1349
1350	/* allocate the lzo blocks and initialize them */
1351	for (i = 0; i < blkcount; ++i) {
1352		lzo_blocks[i] = kzalloc(sizeof **lzo_blocks,
1353					GFP_KERNEL);
1354		if (!lzo_blocks[i]) {
1355			kfree(sync_bmp);
1356			ret = -ENOMEM;
1357			goto err;
1358		}
1359		lzo_blocks[i]->sync_bmp = sync_bmp;
1360		lzo_blocks[i]->sync_bmp_nbits = bmp_size;
1361		/* alloc the working space for the compressed block */
1362		ret = snd_soc_lzo_prepare(lzo_blocks[i]);
1363		if (ret < 0)
1364			goto err;
1365	}
1366
1367	blksize = snd_soc_lzo_get_blksize(codec);
1368	p = codec->reg_def_copy;
1369	end = codec->reg_def_copy + codec->reg_size;
1370	/* compress the register map and fill the lzo blocks */
1371	for (i = 0; i < blkcount; ++i, p += blksize) {
1372		lzo_blocks[i]->src = p;
1373		if (p + blksize > end)
1374			lzo_blocks[i]->src_len = end - p;
1375		else
1376			lzo_blocks[i]->src_len = blksize;
1377		ret = snd_soc_lzo_compress_cache_block(codec,
1378						       lzo_blocks[i]);
1379		if (ret < 0)
1380			goto err;
1381		lzo_blocks[i]->decompressed_size =
1382			lzo_blocks[i]->src_len;
1383	}
1384
1385	if (tofree) {
1386		kfree(codec->reg_def_copy);
1387		codec->reg_def_copy = NULL;
1388	}
1389	return 0;
1390err:
1391	snd_soc_cache_exit(codec);
1392err_tofree:
1393	if (tofree) {
1394		kfree(codec->reg_def_copy);
1395		codec->reg_def_copy = NULL;
1396	}
1397	return ret;
1398}
1399#endif
1400
1401static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
1402{
1403	int i;
1404	int ret;
1405	const struct snd_soc_codec_driver *codec_drv;
1406	unsigned int val;
1407
1408	codec_drv = codec->driver;
1409	for (i = 0; i < codec_drv->reg_cache_size; ++i) {
1410		ret = snd_soc_cache_read(codec, i, &val);
1411		if (ret)
1412			return ret;
1413		if (codec->reg_def_copy)
1414			if (snd_soc_get_cache_val(codec->reg_def_copy,
1415						  i, codec_drv->reg_word_size) == val)
1416				continue;
1417		ret = snd_soc_write(codec, i, val);
1418		if (ret)
1419			return ret;
1420		dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
1421			i, val);
1422	}
1423	return 0;
1424}
1425
1426static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
1427				    unsigned int reg, unsigned int value)
1428{
1429	snd_soc_set_cache_val(codec->reg_cache, reg, value,
1430			      codec->driver->reg_word_size);
1431	return 0;
1432}
1433
1434static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
1435				   unsigned int reg, unsigned int *value)
1436{
1437	*value = snd_soc_get_cache_val(codec->reg_cache, reg,
1438				       codec->driver->reg_word_size);
1439	return 0;
1440}
1441
1442static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
1443{
1444	if (!codec->reg_cache)
1445		return 0;
1446	kfree(codec->reg_cache);
1447	codec->reg_cache = NULL;
1448	return 0;
1449}
1450
1451static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
1452{
1453	const struct snd_soc_codec_driver *codec_drv;
1454
1455	codec_drv = codec->driver;
1456
1457	if (codec->reg_def_copy)
1458		codec->reg_cache = kmemdup(codec->reg_def_copy,
1459					   codec->reg_size, GFP_KERNEL);
1460	else
1461		codec->reg_cache = kzalloc(codec->reg_size, GFP_KERNEL);
1462	if (!codec->reg_cache)
1463		return -ENOMEM;
1464
1465	return 0;
1466}
1467
1468/* an array of all supported compression types */
1469static const struct snd_soc_cache_ops cache_types[] = {
1470	/* Flat *must* be the first entry for fallback */
1471	{
1472		.id = SND_SOC_FLAT_COMPRESSION,
1473		.name = "flat",
1474		.init = snd_soc_flat_cache_init,
1475		.exit = snd_soc_flat_cache_exit,
1476		.read = snd_soc_flat_cache_read,
1477		.write = snd_soc_flat_cache_write,
1478		.sync = snd_soc_flat_cache_sync
1479	},
1480#ifdef CONFIG_SND_SOC_CACHE_LZO
1481	{
1482		.id = SND_SOC_LZO_COMPRESSION,
1483		.name = "LZO",
1484		.init = snd_soc_lzo_cache_init,
1485		.exit = snd_soc_lzo_cache_exit,
1486		.read = snd_soc_lzo_cache_read,
1487		.write = snd_soc_lzo_cache_write,
1488		.sync = snd_soc_lzo_cache_sync
1489	},
1490#endif
1491	{
1492		.id = SND_SOC_RBTREE_COMPRESSION,
1493		.name = "rbtree",
1494		.init = snd_soc_rbtree_cache_init,
1495		.exit = snd_soc_rbtree_cache_exit,
1496		.read = snd_soc_rbtree_cache_read,
1497		.write = snd_soc_rbtree_cache_write,
1498		.sync = snd_soc_rbtree_cache_sync
1499	}
1500};
1501
1502int snd_soc_cache_init(struct snd_soc_codec *codec)
1503{
1504	int i;
1505
1506	for (i = 0; i < ARRAY_SIZE(cache_types); ++i)
1507		if (cache_types[i].id == codec->compress_type)
1508			break;
1509
1510	/* Fall back to flat compression */
1511	if (i == ARRAY_SIZE(cache_types)) {
1512		dev_warn(codec->dev, "Could not match compress type: %d\n",
1513			 codec->compress_type);
1514		i = 0;
1515	}
1516
1517	mutex_init(&codec->cache_rw_mutex);
1518	codec->cache_ops = &cache_types[i];
1519
1520	if (codec->cache_ops->init) {
1521		if (codec->cache_ops->name)
1522			dev_dbg(codec->dev, "Initializing %s cache for %s codec\n",
1523				codec->cache_ops->name, codec->name);
1524		return codec->cache_ops->init(codec);
1525	}
1526	return -EINVAL;
1527}
1528
1529/*
1530 * NOTE: keep in mind that this function might be called
1531 * multiple times.
1532 */
1533int snd_soc_cache_exit(struct snd_soc_codec *codec)
1534{
1535	if (codec->cache_ops && codec->cache_ops->exit) {
1536		if (codec->cache_ops->name)
1537			dev_dbg(codec->dev, "Destroying %s cache for %s codec\n",
1538				codec->cache_ops->name, codec->name);
1539		return codec->cache_ops->exit(codec);
1540	}
1541	return -EINVAL;
1542}
1543
1544/**
1545 * snd_soc_cache_read: Fetch the value of a given register from the cache.
1546 *
1547 * @codec: CODEC to configure.
1548 * @reg: The register index.
1549 * @value: The value to be returned.
1550 */
1551int snd_soc_cache_read(struct snd_soc_codec *codec,
1552		       unsigned int reg, unsigned int *value)
1553{
1554	int ret;
1555
1556	mutex_lock(&codec->cache_rw_mutex);
1557
1558	if (value && codec->cache_ops && codec->cache_ops->read) {
1559		ret = codec->cache_ops->read(codec, reg, value);
1560		mutex_unlock(&codec->cache_rw_mutex);
1561		return ret;
1562	}
1563
1564	mutex_unlock(&codec->cache_rw_mutex);
1565	return -EINVAL;
1566}
1567EXPORT_SYMBOL_GPL(snd_soc_cache_read);
1568
1569/**
1570 * snd_soc_cache_write: Set the value of a given register in the cache.
1571 *
1572 * @codec: CODEC to configure.
1573 * @reg: The register index.
1574 * @value: The new register value.
1575 */
1576int snd_soc_cache_write(struct snd_soc_codec *codec,
1577			unsigned int reg, unsigned int value)
1578{
1579	int ret;
1580
1581	mutex_lock(&codec->cache_rw_mutex);
1582
1583	if (codec->cache_ops && codec->cache_ops->write) {
1584		ret = codec->cache_ops->write(codec, reg, value);
1585		mutex_unlock(&codec->cache_rw_mutex);
1586		return ret;
1587	}
1588
1589	mutex_unlock(&codec->cache_rw_mutex);
1590	return -EINVAL;
1591}
1592EXPORT_SYMBOL_GPL(snd_soc_cache_write);
1593
1594/**
1595 * snd_soc_cache_sync: Sync the register cache with the hardware.
1596 *
1597 * @codec: CODEC to configure.
1598 *
1599 * Any registers that should not be synced should be marked as
1600 * volatile.  In general drivers can choose not to use the provided
1601 * syncing functionality if they so require.
1602 */
1603int snd_soc_cache_sync(struct snd_soc_codec *codec)
1604{
1605	int ret;
1606	const char *name;
1607
1608	if (!codec->cache_sync) {
1609		return 0;
1610	}
1611
1612	if (codec->cache_ops->name)
1613		name = codec->cache_ops->name;
1614	else
1615		name = "unknown";
1616
1617	if (codec->cache_ops && codec->cache_ops->sync) {
1618		if (codec->cache_ops->name)
1619			dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
1620				codec->cache_ops->name, codec->name);
1621		trace_snd_soc_cache_sync(codec, name, "start");
1622		ret = codec->cache_ops->sync(codec);
1623		if (!ret)
1624			codec->cache_sync = 0;
1625		trace_snd_soc_cache_sync(codec, name, "end");
1626		return ret;
1627	}
1628
1629	return -EINVAL;
1630}
1631EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
1632
1633static int snd_soc_get_reg_access_index(struct snd_soc_codec *codec,
1634					unsigned int reg)
1635{
1636	const struct snd_soc_codec_driver *codec_drv;
1637	unsigned int min, max, index;
1638
1639	codec_drv = codec->driver;
1640	min = 0;
1641	max = codec_drv->reg_access_size - 1;
1642	do {
1643		index = (min + max) / 2;
1644		if (codec_drv->reg_access_default[index].reg == reg)
1645			return index;
1646		if (codec_drv->reg_access_default[index].reg < reg)
1647			min = index + 1;
1648		else
1649			max = index;
1650	} while (min <= max);
1651	return -1;
1652}
1653
1654int snd_soc_default_volatile_register(struct snd_soc_codec *codec,
1655				      unsigned int reg)
1656{
1657	int index;
1658
1659	if (reg >= codec->driver->reg_cache_size)
1660		return 1;
1661	index = snd_soc_get_reg_access_index(codec, reg);
1662	if (index < 0)
1663		return 0;
1664	return codec->driver->reg_access_default[index].vol;
1665}
1666EXPORT_SYMBOL_GPL(snd_soc_default_volatile_register);
1667
1668int snd_soc_default_readable_register(struct snd_soc_codec *codec,
1669				      unsigned int reg)
1670{
1671	int index;
1672
1673	if (reg >= codec->driver->reg_cache_size)
1674		return 1;
1675	index = snd_soc_get_reg_access_index(codec, reg);
1676	if (index < 0)
1677		return 0;
1678	return codec->driver->reg_access_default[index].read;
1679}
1680EXPORT_SYMBOL_GPL(snd_soc_default_readable_register);
1681