aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2013-06-24 10:31:31 -0400
committerMark Brown <broonie@linaro.org>2013-06-25 05:32:13 -0400
commit45405d58924f49a13b924ed6db6fe47981487b4a (patch)
treeb2c0ed208ffd157a02ab1e5ccf635f582f6d20e3 /sound
parent2352d4bf43b105ec2da5f43211db4a4c9bf34d4e (diff)
ASoC: adau1701: switch to direct regmap API usage
The hardware I/O has to be open-coded due to registers of unequal sizes. Other than that, the transition is straight forward. Signed-off-by: Daniel Mack <zonque@gmail.com> Acked-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/adau1701.c118
1 files changed, 85 insertions, 33 deletions
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 770d90ee5f92..881bab4a65aa 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -16,6 +16,7 @@
16#include <linux/of.h> 16#include <linux/of.h>
17#include <linux/of_gpio.h> 17#include <linux/of_gpio.h>
18#include <linux/of_device.h> 18#include <linux/of_device.h>
19#include <linux/regmap.h>
19#include <sound/core.h> 20#include <sound/core.h>
20#include <sound/pcm.h> 21#include <sound/pcm.h>
21#include <sound/pcm_params.h> 22#include <sound/pcm_params.h>
@@ -24,16 +25,16 @@
24#include "sigmadsp.h" 25#include "sigmadsp.h"
25#include "adau1701.h" 26#include "adau1701.h"
26 27
27#define ADAU1701_DSPCTRL 0x1c 28#define ADAU1701_DSPCTRL 0x081c
28#define ADAU1701_SEROCTL 0x1e 29#define ADAU1701_SEROCTL 0x081e
29#define ADAU1701_SERICTL 0x1f 30#define ADAU1701_SERICTL 0x081f
30 31
31#define ADAU1701_AUXNPOW 0x22 32#define ADAU1701_AUXNPOW 0x0822
32 33
33#define ADAU1701_OSCIPOW 0x26 34#define ADAU1701_OSCIPOW 0x0826
34#define ADAU1701_DACSET 0x27 35#define ADAU1701_DACSET 0x0827
35 36
36#define ADAU1701_NUM_REGS 0x28 37#define ADAU1701_MAX_REGISTER 0x0828
37 38
38#define ADAU1701_DSPCTRL_CR (1 << 2) 39#define ADAU1701_DSPCTRL_CR (1 << 2)
39#define ADAU1701_DSPCTRL_DAM (1 << 3) 40#define ADAU1701_DSPCTRL_DAM (1 << 3)
@@ -97,6 +98,7 @@ struct adau1701 {
97 unsigned int dai_fmt; 98 unsigned int dai_fmt;
98 unsigned int pll_clkdiv; 99 unsigned int pll_clkdiv;
99 unsigned int sysclk; 100 unsigned int sysclk;
101 struct regmap *regmap;
100}; 102};
101 103
102static const struct snd_kcontrol_new adau1701_controls[] = { 104static const struct snd_kcontrol_new adau1701_controls[] = {
@@ -128,7 +130,7 @@ static const struct snd_soc_dapm_route adau1701_dapm_routes[] = {
128 { "ADC", NULL, "IN1" }, 130 { "ADC", NULL, "IN1" },
129}; 131};
130 132
131static unsigned int adau1701_register_size(struct snd_soc_codec *codec, 133static unsigned int adau1701_register_size(struct device *dev,
132 unsigned int reg) 134 unsigned int reg)
133{ 135{
134 switch (reg) { 136 switch (reg) {
@@ -142,33 +144,42 @@ static unsigned int adau1701_register_size(struct snd_soc_codec *codec,
142 return 1; 144 return 1;
143 } 145 }
144 146
145 dev_err(codec->dev, "Unsupported register address: %d\n", reg); 147 dev_err(dev, "Unsupported register address: %d\n", reg);
146 return 0; 148 return 0;
147} 149}
148 150
149static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg, 151static bool adau1701_volatile_reg(struct device *dev, unsigned int reg)
150 unsigned int value)
151{ 152{
153 switch (reg) {
154 case ADAU1701_DACSET:
155 return true;
156 default:
157 return false;
158 }
159}
160
161static int adau1701_reg_write(void *context, unsigned int reg,
162 unsigned int value)
163{
164 struct i2c_client *client = context;
152 unsigned int i; 165 unsigned int i;
153 unsigned int size; 166 unsigned int size;
154 uint8_t buf[4]; 167 uint8_t buf[4];
155 int ret; 168 int ret;
156 169
157 size = adau1701_register_size(codec, reg); 170 size = adau1701_register_size(&client->dev, reg);
158 if (size == 0) 171 if (size == 0)
159 return -EINVAL; 172 return -EINVAL;
160 173
161 snd_soc_cache_write(codec, reg, value); 174 buf[0] = reg >> 8;
162 175 buf[1] = reg & 0xff;
163 buf[0] = 0x08;
164 buf[1] = reg;
165 176
166 for (i = size + 1; i >= 2; --i) { 177 for (i = size + 1; i >= 2; --i) {
167 buf[i] = value; 178 buf[i] = value;
168 value >>= 8; 179 value >>= 8;
169 } 180 }
170 181
171 ret = i2c_master_send(to_i2c_client(codec->dev), buf, size + 2); 182 ret = i2c_master_send(client, buf, size + 2);
172 if (ret == size + 2) 183 if (ret == size + 2)
173 return 0; 184 return 0;
174 else if (ret < 0) 185 else if (ret < 0)
@@ -177,16 +188,45 @@ static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg,
177 return -EIO; 188 return -EIO;
178} 189}
179 190
180static unsigned int adau1701_read(struct snd_soc_codec *codec, unsigned int reg) 191static int adau1701_reg_read(void *context, unsigned int reg,
192 unsigned int *value)
181{ 193{
182 unsigned int value; 194 int ret;
183 unsigned int ret; 195 unsigned int i;
196 unsigned int size;
197 uint8_t send_buf[2], recv_buf[3];
198 struct i2c_client *client = context;
199 struct i2c_msg msgs[2];
200
201 size = adau1701_register_size(&client->dev, reg);
202 if (size == 0)
203 return -EINVAL;
184 204
185 ret = snd_soc_cache_read(codec, reg, &value); 205 send_buf[0] = reg >> 8;
186 if (ret) 206 send_buf[1] = reg & 0xff;
207
208 msgs[0].addr = client->addr;
209 msgs[0].len = sizeof(send_buf);
210 msgs[0].buf = send_buf;
211 msgs[0].flags = 0;
212
213 msgs[1].addr = client->addr;
214 msgs[1].len = size;
215 msgs[1].buf = recv_buf;
216 msgs[1].flags = I2C_M_RD;
217
218 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
219 if (ret < 0)
187 return ret; 220 return ret;
221 else if (ret != ARRAY_SIZE(msgs))
222 return -EIO;
223
224 *value = 0;
225
226 for (i = 0; i < size; i++)
227 *value |= recv_buf[i] << (i * 8);
188 228
189 return value; 229 return 0;
190} 230}
191 231
192static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv) 232static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
@@ -242,8 +282,11 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
242 } 282 }
243 } 283 }
244 284
245 snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT); 285 regmap_write(adau1701->regmap, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT);
246 snd_soc_write(codec, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR); 286 regmap_write(adau1701->regmap, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR);
287
288 regcache_mark_dirty(adau1701->regmap);
289 regcache_sync(adau1701->regmap);
247 290
248 return 0; 291 return 0;
249} 292}
@@ -429,8 +472,8 @@ static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
429 472
430 adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 473 adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
431 474
432 snd_soc_write(codec, ADAU1701_SERICTL, serictl); 475 regmap_write(adau1701->regmap, ADAU1701_SERICTL, serictl);
433 snd_soc_update_bits(codec, ADAU1701_SEROCTL, 476 regmap_update_bits(adau1701->regmap, ADAU1701_SEROCTL,
434 ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl); 477 ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl);
435 478
436 return 0; 479 return 0;
@@ -567,9 +610,6 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
567 .set_bias_level = adau1701_set_bias_level, 610 .set_bias_level = adau1701_set_bias_level,
568 .idle_bias_off = true, 611 .idle_bias_off = true,
569 612
570 .reg_cache_size = ADAU1701_NUM_REGS,
571 .reg_word_size = sizeof(u16),
572
573 .controls = adau1701_controls, 613 .controls = adau1701_controls,
574 .num_controls = ARRAY_SIZE(adau1701_controls), 614 .num_controls = ARRAY_SIZE(adau1701_controls),
575 .dapm_widgets = adau1701_dapm_widgets, 615 .dapm_widgets = adau1701_dapm_widgets,
@@ -577,12 +617,19 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
577 .dapm_routes = adau1701_dapm_routes, 617 .dapm_routes = adau1701_dapm_routes,
578 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), 618 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes),
579 619
580 .write = adau1701_write,
581 .read = adau1701_read,
582
583 .set_sysclk = adau1701_set_sysclk, 620 .set_sysclk = adau1701_set_sysclk,
584}; 621};
585 622
623static const struct regmap_config adau1701_regmap = {
624 .reg_bits = 16,
625 .val_bits = 32,
626 .max_register = ADAU1701_MAX_REGISTER,
627 .cache_type = REGCACHE_RBTREE,
628 .volatile_reg = adau1701_volatile_reg,
629 .reg_write = adau1701_reg_write,
630 .reg_read = adau1701_reg_read,
631};
632
586static int adau1701_i2c_probe(struct i2c_client *client, 633static int adau1701_i2c_probe(struct i2c_client *client,
587 const struct i2c_device_id *id) 634 const struct i2c_device_id *id)
588{ 635{
@@ -596,6 +643,11 @@ static int adau1701_i2c_probe(struct i2c_client *client,
596 if (!adau1701) 643 if (!adau1701)
597 return -ENOMEM; 644 return -ENOMEM;
598 645
646 adau1701->regmap = devm_regmap_init(dev, NULL, client,
647 &adau1701_regmap);
648 if (IS_ERR(adau1701->regmap))
649 return PTR_ERR(adau1701->regmap);
650
599 if (dev->of_node) { 651 if (dev->of_node) {
600 gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0); 652 gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0);
601 if (gpio_nreset < 0 && gpio_nreset != -ENOENT) 653 if (gpio_nreset < 0 && gpio_nreset != -ENOENT)