aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-cache.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-07-05 12:24:50 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-07-05 12:24:50 -0400
commit17a52fd60a0a0e617ed94aadb1b19751a8fa219e (patch)
tree2c2fd4526ae219ec9435a0a4b0fc281a5ca62b7c /sound/soc/soc-cache.c
parent5420f30723122012c7bb868a55ff21c7d383b68e (diff)
ASoC: Begin to factor out register cache I/O functions
A lot of CODECs share the same register data formats and therefore replicate the code to manage access to and caching of the register map. In order to reduce code duplication centralised versions of this code will be introduced with drivers able to configure the use of the common code by calling the new snd_soc_codec_set_cache_io() API call during startup. As an initial user the 7 bit address/9 bit data format used by many Wolfson devices is supported for write only CODECs and the drivers with straightforward register cache implementations are converted to use it. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-cache.c')
-rw-r--r--sound/soc/soc-cache.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
new file mode 100644
index 000000000000..4eb4333a0efb
--- /dev/null
+++ b/sound/soc/soc-cache.c
@@ -0,0 +1,105 @@
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 <sound/soc.h>
15
16static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
17 unsigned int reg)
18{
19 u16 *cache = codec->reg_cache;
20 if (reg >= codec->reg_cache_size)
21 return -1;
22 return cache[reg];
23}
24
25static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
26 unsigned int value)
27{
28 u16 *cache = codec->reg_cache;
29 u8 data[2];
30 int ret;
31
32 BUG_ON(codec->volatile_register);
33
34 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
35 data[1] = value & 0x00ff;
36
37 if (reg < codec->reg_cache_size)
38 cache[reg] = value;
39 ret = codec->hw_write(codec->control_data, data, 2);
40 if (ret == 2)
41 return 0;
42 if (ret < 0)
43 return ret;
44 else
45 return -EIO;
46}
47
48
49static struct {
50 int addr_bits;
51 int data_bits;
52 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
53 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
54} io_types[] = {
55 { 7, 9, snd_soc_7_9_write, snd_soc_7_9_read },
56};
57
58/**
59 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
60 *
61 * @codec: CODEC to configure.
62 * @type: Type of cache.
63 * @addr_bits: Number of bits of register address data.
64 * @data_bits: Number of bits of data per register.
65 *
66 * Register formats are frequently shared between many I2C and SPI
67 * devices. In order to promote code reuse the ASoC core provides
68 * some standard implementations of CODEC read and write operations
69 * which can be set up using this function.
70 *
71 * The caller is responsible for allocating and initialising the
72 * actual cache.
73 *
74 * Note that at present this code cannot be used by CODECs with
75 * volatile registers.
76 */
77int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
78 int addr_bits, int data_bits)
79{
80 int i;
81
82 /* We don't support volatile registers yet - refactoring of
83 * the hw_read operation will be required to do so. */
84 if (codec->volatile_register) {
85 printk(KERN_ERR "Volatile registers not yet supported\n");
86 return -EINVAL;
87 }
88
89 for (i = 0; i < ARRAY_SIZE(io_types); i++)
90 if (io_types[i].addr_bits == addr_bits &&
91 io_types[i].data_bits == data_bits)
92 break;
93 if (i == ARRAY_SIZE(io_types)) {
94 printk(KERN_ERR
95 "No I/O functions for %d bit address %d bit data\n",
96 addr_bits, data_bits);
97 return -EINVAL;
98 }
99
100 codec->write = io_types[i].write;
101 codec->read = io_types[i].read;
102
103 return 0;
104}
105EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);