aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-09-25 08:29:44 -0400
committerMark Brown <broonie@linaro.org>2013-09-25 08:30:59 -0400
commit7fbdeb809050cb958f3baa83dcc643f9a2f287f2 (patch)
treeb7e9f3973279ba2a4af4d3f3cd631abe7d2ef128 /sound/soc
parent5b0959d472c215e6d712ac47e64110bd125ddd07 (diff)
ASoC: tlv320aic26: Convert to direct regmap API usage
This moves us towards being able to remove the duplicated register I/O code in ASoC. The datasheet and the driver document the device as having a register map divided into pages but since the paging is actually done by sending the page address and the register address with each transaction this is no different to having a simple register address. The datasheet does also document the low five bits of the 16 bit "command" as unused which we could represent as padding but it seems simpler and less confusing to things that use block transfers or autoincrement to represent these as part of the register address. Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/tlv320aic26.c80
-rw-r--r--sound/soc/codecs/tlv320aic26.h5
2 files changed, 13 insertions, 72 deletions
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 4d8244750f23..94a658fa6d97 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -29,6 +29,7 @@ MODULE_LICENSE("GPL");
29/* AIC26 driver private data */ 29/* AIC26 driver private data */
30struct aic26 { 30struct aic26 {
31 struct spi_device *spi; 31 struct spi_device *spi;
32 struct regmap *regmap;
32 struct snd_soc_codec *codec; 33 struct snd_soc_codec *codec;
33 int master; 34 int master;
34 int datfm; 35 int datfm;
@@ -40,72 +41,6 @@ struct aic26 {
40 int keyclick_len; 41 int keyclick_len;
41}; 42};
42 43
43/* ---------------------------------------------------------------------
44 * Register access routines
45 */
46static unsigned int aic26_reg_read(struct snd_soc_codec *codec,
47 unsigned int reg)
48{
49 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
50 u16 *cache = codec->reg_cache;
51 u16 cmd, value;
52 u8 buffer[2];
53 int rc;
54
55 if (reg >= AIC26_NUM_REGS) {
56 WARN_ON_ONCE(1);
57 return 0;
58 }
59
60 /* Do SPI transfer; first 16bits are command; remaining is
61 * register contents */
62 cmd = AIC26_READ_COMMAND_WORD(reg);
63 buffer[0] = (cmd >> 8) & 0xff;
64 buffer[1] = cmd & 0xff;
65 rc = spi_write_then_read(aic26->spi, buffer, 2, buffer, 2);
66 if (rc) {
67 dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
68 return -EIO;
69 }
70 value = (buffer[0] << 8) | buffer[1];
71
72 /* Update the cache before returning with the value */
73 cache[reg] = value;
74 return value;
75}
76
77static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
78 unsigned int value)
79{
80 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
81 u16 *cache = codec->reg_cache;
82 u16 cmd;
83 u8 buffer[4];
84 int rc;
85
86 if (reg >= AIC26_NUM_REGS) {
87 WARN_ON_ONCE(1);
88 return -EINVAL;
89 }
90
91 /* Do SPI transfer; first 16bits are command; remaining is data
92 * to write into register */
93 cmd = AIC26_WRITE_COMMAND_WORD(reg);
94 buffer[0] = (cmd >> 8) & 0xff;
95 buffer[1] = cmd & 0xff;
96 buffer[2] = value >> 8;
97 buffer[3] = value;
98 rc = spi_write(aic26->spi, buffer, 4);
99 if (rc) {
100 dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
101 return -EIO;
102 }
103
104 /* update cache before returning */
105 cache[reg] = value;
106 return 0;
107}
108
109static const struct snd_soc_dapm_widget tlv320aic26_dapm_widgets[] = { 44static const struct snd_soc_dapm_widget tlv320aic26_dapm_widgets[] = {
110SND_SOC_DAPM_INPUT("MICIN"), 45SND_SOC_DAPM_INPUT("MICIN"),
111SND_SOC_DAPM_INPUT("AUX"), 46SND_SOC_DAPM_INPUT("AUX"),
@@ -360,6 +295,8 @@ static int aic26_probe(struct snd_soc_codec *codec)
360 struct aic26 *aic26 = dev_get_drvdata(codec->dev); 295 struct aic26 *aic26 = dev_get_drvdata(codec->dev);
361 int ret, reg; 296 int ret, reg;
362 297
298 snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
299
363 aic26->codec = codec; 300 aic26->codec = codec;
364 301
365 /* Reset the codec to power on defaults */ 302 /* Reset the codec to power on defaults */
@@ -385,8 +322,6 @@ static int aic26_probe(struct snd_soc_codec *codec)
385 322
386static struct snd_soc_codec_driver aic26_soc_codec_dev = { 323static struct snd_soc_codec_driver aic26_soc_codec_dev = {
387 .probe = aic26_probe, 324 .probe = aic26_probe,
388 .read = aic26_reg_read,
389 .write = aic26_reg_write,
390 .controls = aic26_snd_controls, 325 .controls = aic26_snd_controls,
391 .num_controls = ARRAY_SIZE(aic26_snd_controls), 326 .num_controls = ARRAY_SIZE(aic26_snd_controls),
392 .dapm_widgets = tlv320aic26_dapm_widgets, 327 .dapm_widgets = tlv320aic26_dapm_widgets,
@@ -395,6 +330,11 @@ static struct snd_soc_codec_driver aic26_soc_codec_dev = {
395 .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes), 330 .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes),
396}; 331};
397 332
333static const struct regmap_config aic26_regmap = {
334 .reg_bits = 16,
335 .val_bits = 16,
336};
337
398/* --------------------------------------------------------------------- 338/* ---------------------------------------------------------------------
399 * SPI device portion of driver: probe and release routines and SPI 339 * SPI device portion of driver: probe and release routines and SPI
400 * driver registration. 340 * driver registration.
@@ -411,6 +351,10 @@ static int aic26_spi_probe(struct spi_device *spi)
411 if (!aic26) 351 if (!aic26)
412 return -ENOMEM; 352 return -ENOMEM;
413 353
354 aic26->regmap = devm_regmap_init_spi(spi, &aic26_regmap);
355 if (IS_ERR(aic26->regmap))
356 return PTR_ERR(aic26->regmap);
357
414 /* Initialize the driver data */ 358 /* Initialize the driver data */
415 aic26->spi = spi; 359 aic26->spi = spi;
416 dev_set_drvdata(&spi->dev, aic26); 360 dev_set_drvdata(&spi->dev, aic26);
diff --git a/sound/soc/codecs/tlv320aic26.h b/sound/soc/codecs/tlv320aic26.h
index 67f19c3bebe6..629b85e75409 100644
--- a/sound/soc/codecs/tlv320aic26.h
+++ b/sound/soc/codecs/tlv320aic26.h
@@ -9,10 +9,7 @@
9#define _TLV320AIC16_H_ 9#define _TLV320AIC16_H_
10 10
11/* AIC26 Registers */ 11/* AIC26 Registers */
12#define AIC26_READ_COMMAND_WORD(addr) ((1 << 15) | (addr << 5)) 12#define AIC26_PAGE_ADDR(page, offset) ((page << 11) | offset << 5)
13#define AIC26_WRITE_COMMAND_WORD(addr) ((0 << 15) | (addr << 5))
14#define AIC26_PAGE_ADDR(page, offset) ((page << 6) | offset)
15#define AIC26_NUM_REGS AIC26_PAGE_ADDR(3, 0)
16 13
17/* Page 0: Auxiliary data registers */ 14/* Page 0: Auxiliary data registers */
18#define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05) 15#define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05)