diff options
author | Mark Brown <broonie@linaro.org> | 2013-06-30 07:42:23 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-06-30 07:42:23 -0400 |
commit | 4494783793459dc601aad574802e81592cf3173f (patch) | |
tree | f0ca70f7b389c7a151c360f031a1dbb43a2cd110 /sound | |
parent | f74b5e253a062004c1d30177f9889501423e403d (diff) | |
parent | cef929ec4e80fcfe249c800408a5f9d72ebd5933 (diff) |
Merge remote-tracking branch 'asoc/topic/adau1701' into asoc-next
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/adau1701.c | 321 |
1 files changed, 272 insertions, 49 deletions
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index dafdbe87edeb..d1124a5b3471 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c | |||
@@ -13,6 +13,10 @@ | |||
13 | #include <linux/i2c.h> | 13 | #include <linux/i2c.h> |
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/of.h> | ||
17 | #include <linux/of_gpio.h> | ||
18 | #include <linux/of_device.h> | ||
19 | #include <linux/regmap.h> | ||
16 | #include <sound/core.h> | 20 | #include <sound/core.h> |
17 | #include <sound/pcm.h> | 21 | #include <sound/pcm.h> |
18 | #include <sound/pcm_params.h> | 22 | #include <sound/pcm_params.h> |
@@ -21,16 +25,19 @@ | |||
21 | #include "sigmadsp.h" | 25 | #include "sigmadsp.h" |
22 | #include "adau1701.h" | 26 | #include "adau1701.h" |
23 | 27 | ||
24 | #define ADAU1701_DSPCTRL 0x1c | 28 | #define ADAU1701_DSPCTRL 0x081c |
25 | #define ADAU1701_SEROCTL 0x1e | 29 | #define ADAU1701_SEROCTL 0x081e |
26 | #define ADAU1701_SERICTL 0x1f | 30 | #define ADAU1701_SERICTL 0x081f |
27 | 31 | ||
28 | #define ADAU1701_AUXNPOW 0x22 | 32 | #define ADAU1701_AUXNPOW 0x0822 |
33 | #define ADAU1701_PINCONF_0 0x0820 | ||
34 | #define ADAU1701_PINCONF_1 0x0821 | ||
35 | #define ADAU1701_AUXNPOW 0x0822 | ||
29 | 36 | ||
30 | #define ADAU1701_OSCIPOW 0x26 | 37 | #define ADAU1701_OSCIPOW 0x0826 |
31 | #define ADAU1701_DACSET 0x27 | 38 | #define ADAU1701_DACSET 0x0827 |
32 | 39 | ||
33 | #define ADAU1701_NUM_REGS 0x28 | 40 | #define ADAU1701_MAX_REGISTER 0x0828 |
34 | 41 | ||
35 | #define ADAU1701_DSPCTRL_CR (1 << 2) | 42 | #define ADAU1701_DSPCTRL_CR (1 << 2) |
36 | #define ADAU1701_DSPCTRL_DAM (1 << 3) | 43 | #define ADAU1701_DSPCTRL_DAM (1 << 3) |
@@ -84,10 +91,18 @@ | |||
84 | #define ADAU1701_OSCIPOW_OPD 0x04 | 91 | #define ADAU1701_OSCIPOW_OPD 0x04 |
85 | #define ADAU1701_DACSET_DACINIT 1 | 92 | #define ADAU1701_DACSET_DACINIT 1 |
86 | 93 | ||
94 | #define ADAU1707_CLKDIV_UNSET (-1UL) | ||
95 | |||
87 | #define ADAU1701_FIRMWARE "adau1701.bin" | 96 | #define ADAU1701_FIRMWARE "adau1701.bin" |
88 | 97 | ||
89 | struct adau1701 { | 98 | struct adau1701 { |
99 | int gpio_nreset; | ||
100 | int gpio_pll_mode[2]; | ||
90 | unsigned int dai_fmt; | 101 | unsigned int dai_fmt; |
102 | unsigned int pll_clkdiv; | ||
103 | unsigned int sysclk; | ||
104 | struct regmap *regmap; | ||
105 | u8 pin_config[12]; | ||
91 | }; | 106 | }; |
92 | 107 | ||
93 | static const struct snd_kcontrol_new adau1701_controls[] = { | 108 | static const struct snd_kcontrol_new adau1701_controls[] = { |
@@ -119,10 +134,13 @@ static const struct snd_soc_dapm_route adau1701_dapm_routes[] = { | |||
119 | { "ADC", NULL, "IN1" }, | 134 | { "ADC", NULL, "IN1" }, |
120 | }; | 135 | }; |
121 | 136 | ||
122 | static unsigned int adau1701_register_size(struct snd_soc_codec *codec, | 137 | static unsigned int adau1701_register_size(struct device *dev, |
123 | unsigned int reg) | 138 | unsigned int reg) |
124 | { | 139 | { |
125 | switch (reg) { | 140 | switch (reg) { |
141 | case ADAU1701_PINCONF_0: | ||
142 | case ADAU1701_PINCONF_1: | ||
143 | return 3; | ||
126 | case ADAU1701_DSPCTRL: | 144 | case ADAU1701_DSPCTRL: |
127 | case ADAU1701_SEROCTL: | 145 | case ADAU1701_SEROCTL: |
128 | case ADAU1701_AUXNPOW: | 146 | case ADAU1701_AUXNPOW: |
@@ -133,33 +151,42 @@ static unsigned int adau1701_register_size(struct snd_soc_codec *codec, | |||
133 | return 1; | 151 | return 1; |
134 | } | 152 | } |
135 | 153 | ||
136 | dev_err(codec->dev, "Unsupported register address: %d\n", reg); | 154 | dev_err(dev, "Unsupported register address: %d\n", reg); |
137 | return 0; | 155 | return 0; |
138 | } | 156 | } |
139 | 157 | ||
140 | static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg, | 158 | static bool adau1701_volatile_reg(struct device *dev, unsigned int reg) |
141 | unsigned int value) | 159 | { |
160 | switch (reg) { | ||
161 | case ADAU1701_DACSET: | ||
162 | return true; | ||
163 | default: | ||
164 | return false; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | static int adau1701_reg_write(void *context, unsigned int reg, | ||
169 | unsigned int value) | ||
142 | { | 170 | { |
171 | struct i2c_client *client = context; | ||
143 | unsigned int i; | 172 | unsigned int i; |
144 | unsigned int size; | 173 | unsigned int size; |
145 | uint8_t buf[4]; | 174 | uint8_t buf[5]; |
146 | int ret; | 175 | int ret; |
147 | 176 | ||
148 | size = adau1701_register_size(codec, reg); | 177 | size = adau1701_register_size(&client->dev, reg); |
149 | if (size == 0) | 178 | if (size == 0) |
150 | return -EINVAL; | 179 | return -EINVAL; |
151 | 180 | ||
152 | snd_soc_cache_write(codec, reg, value); | 181 | buf[0] = reg >> 8; |
153 | 182 | buf[1] = reg & 0xff; | |
154 | buf[0] = 0x08; | ||
155 | buf[1] = reg; | ||
156 | 183 | ||
157 | for (i = size + 1; i >= 2; --i) { | 184 | for (i = size + 1; i >= 2; --i) { |
158 | buf[i] = value; | 185 | buf[i] = value; |
159 | value >>= 8; | 186 | value >>= 8; |
160 | } | 187 | } |
161 | 188 | ||
162 | ret = i2c_master_send(to_i2c_client(codec->dev), buf, size + 2); | 189 | ret = i2c_master_send(client, buf, size + 2); |
163 | if (ret == size + 2) | 190 | if (ret == size + 2) |
164 | return 0; | 191 | return 0; |
165 | else if (ret < 0) | 192 | else if (ret < 0) |
@@ -168,21 +195,107 @@ static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg, | |||
168 | return -EIO; | 195 | return -EIO; |
169 | } | 196 | } |
170 | 197 | ||
171 | static unsigned int adau1701_read(struct snd_soc_codec *codec, unsigned int reg) | 198 | static int adau1701_reg_read(void *context, unsigned int reg, |
199 | unsigned int *value) | ||
172 | { | 200 | { |
173 | unsigned int value; | 201 | int ret; |
174 | unsigned int ret; | 202 | unsigned int i; |
203 | unsigned int size; | ||
204 | uint8_t send_buf[2], recv_buf[3]; | ||
205 | struct i2c_client *client = context; | ||
206 | struct i2c_msg msgs[2]; | ||
207 | |||
208 | size = adau1701_register_size(&client->dev, reg); | ||
209 | if (size == 0) | ||
210 | return -EINVAL; | ||
175 | 211 | ||
176 | ret = snd_soc_cache_read(codec, reg, &value); | 212 | send_buf[0] = reg >> 8; |
177 | if (ret) | 213 | send_buf[1] = reg & 0xff; |
214 | |||
215 | msgs[0].addr = client->addr; | ||
216 | msgs[0].len = sizeof(send_buf); | ||
217 | msgs[0].buf = send_buf; | ||
218 | msgs[0].flags = 0; | ||
219 | |||
220 | msgs[1].addr = client->addr; | ||
221 | msgs[1].len = size; | ||
222 | msgs[1].buf = recv_buf; | ||
223 | msgs[1].flags = I2C_M_RD; | ||
224 | |||
225 | ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
226 | if (ret < 0) | ||
178 | return ret; | 227 | return ret; |
228 | else if (ret != ARRAY_SIZE(msgs)) | ||
229 | return -EIO; | ||
179 | 230 | ||
180 | return value; | 231 | *value = 0; |
232 | |||
233 | for (i = 0; i < size; i++) | ||
234 | *value |= recv_buf[i] << (i * 8); | ||
235 | |||
236 | return 0; | ||
181 | } | 237 | } |
182 | 238 | ||
183 | static int adau1701_load_firmware(struct snd_soc_codec *codec) | 239 | static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv) |
184 | { | 240 | { |
185 | return process_sigma_firmware(codec->control_data, ADAU1701_FIRMWARE); | 241 | struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); |
242 | struct i2c_client *client = to_i2c_client(codec->dev); | ||
243 | int ret; | ||
244 | |||
245 | if (clkdiv != ADAU1707_CLKDIV_UNSET && | ||
246 | gpio_is_valid(adau1701->gpio_pll_mode[0]) && | ||
247 | gpio_is_valid(adau1701->gpio_pll_mode[1])) { | ||
248 | switch (clkdiv) { | ||
249 | case 64: | ||
250 | gpio_set_value(adau1701->gpio_pll_mode[0], 0); | ||
251 | gpio_set_value(adau1701->gpio_pll_mode[1], 0); | ||
252 | break; | ||
253 | case 256: | ||
254 | gpio_set_value(adau1701->gpio_pll_mode[0], 0); | ||
255 | gpio_set_value(adau1701->gpio_pll_mode[1], 1); | ||
256 | break; | ||
257 | case 384: | ||
258 | gpio_set_value(adau1701->gpio_pll_mode[0], 1); | ||
259 | gpio_set_value(adau1701->gpio_pll_mode[1], 0); | ||
260 | break; | ||
261 | case 0: /* fallback */ | ||
262 | case 512: | ||
263 | gpio_set_value(adau1701->gpio_pll_mode[0], 1); | ||
264 | gpio_set_value(adau1701->gpio_pll_mode[1], 1); | ||
265 | break; | ||
266 | } | ||
267 | } | ||
268 | |||
269 | adau1701->pll_clkdiv = clkdiv; | ||
270 | |||
271 | if (gpio_is_valid(adau1701->gpio_nreset)) { | ||
272 | gpio_set_value(adau1701->gpio_nreset, 0); | ||
273 | /* minimum reset time is 20ns */ | ||
274 | udelay(1); | ||
275 | gpio_set_value(adau1701->gpio_nreset, 1); | ||
276 | /* power-up time may be as long as 85ms */ | ||
277 | mdelay(85); | ||
278 | } | ||
279 | |||
280 | /* | ||
281 | * Postpone the firmware download to a point in time when we | ||
282 | * know the correct PLL setup | ||
283 | */ | ||
284 | if (clkdiv != ADAU1707_CLKDIV_UNSET) { | ||
285 | ret = process_sigma_firmware(client, ADAU1701_FIRMWARE); | ||
286 | if (ret) { | ||
287 | dev_warn(codec->dev, "Failed to load firmware\n"); | ||
288 | return ret; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | regmap_write(adau1701->regmap, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT); | ||
293 | regmap_write(adau1701->regmap, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR); | ||
294 | |||
295 | regcache_mark_dirty(adau1701->regmap); | ||
296 | regcache_sync(adau1701->regmap); | ||
297 | |||
298 | return 0; | ||
186 | } | 299 | } |
187 | 300 | ||
188 | static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, | 301 | static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, |
@@ -221,7 +334,7 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, | |||
221 | mask |= ADAU1701_SEROCTL_MSB_DEALY_MASK; | 334 | mask |= ADAU1701_SEROCTL_MSB_DEALY_MASK; |
222 | } | 335 | } |
223 | 336 | ||
224 | snd_soc_update_bits(codec, ADAU1701_SEROCTL, mask, val); | 337 | regmap_update_bits(adau1701->regmap, ADAU1701_SEROCTL, mask, val); |
225 | 338 | ||
226 | return 0; | 339 | return 0; |
227 | } | 340 | } |
@@ -249,7 +362,7 @@ static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec, | |||
249 | return -EINVAL; | 362 | return -EINVAL; |
250 | } | 363 | } |
251 | 364 | ||
252 | snd_soc_update_bits(codec, ADAU1701_SERICTL, | 365 | regmap_update_bits(adau1701->regmap, ADAU1701_SERICTL, |
253 | ADAU1701_SERICTL_MODE_MASK, val); | 366 | ADAU1701_SERICTL_MODE_MASK, val); |
254 | 367 | ||
255 | return 0; | 368 | return 0; |
@@ -259,8 +372,22 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream, | |||
259 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 372 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
260 | { | 373 | { |
261 | struct snd_soc_codec *codec = dai->codec; | 374 | struct snd_soc_codec *codec = dai->codec; |
375 | struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); | ||
376 | unsigned int clkdiv = adau1701->sysclk / params_rate(params); | ||
262 | snd_pcm_format_t format; | 377 | snd_pcm_format_t format; |
263 | unsigned int val; | 378 | unsigned int val; |
379 | int ret; | ||
380 | |||
381 | /* | ||
382 | * If the mclk/lrclk ratio changes, the chip needs updated PLL | ||
383 | * mode GPIO settings, and a full reset cycle, including a new | ||
384 | * firmware upload. | ||
385 | */ | ||
386 | if (clkdiv != adau1701->pll_clkdiv) { | ||
387 | ret = adau1701_reset(codec, clkdiv); | ||
388 | if (ret < 0) | ||
389 | return ret; | ||
390 | } | ||
264 | 391 | ||
265 | switch (params_rate(params)) { | 392 | switch (params_rate(params)) { |
266 | case 192000: | 393 | case 192000: |
@@ -276,7 +403,7 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream, | |||
276 | return -EINVAL; | 403 | return -EINVAL; |
277 | } | 404 | } |
278 | 405 | ||
279 | snd_soc_update_bits(codec, ADAU1701_DSPCTRL, | 406 | regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL, |
280 | ADAU1701_DSPCTRL_SR_MASK, val); | 407 | ADAU1701_DSPCTRL_SR_MASK, val); |
281 | 408 | ||
282 | format = params_format(params); | 409 | format = params_format(params); |
@@ -352,8 +479,8 @@ static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
352 | 479 | ||
353 | adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; | 480 | adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; |
354 | 481 | ||
355 | snd_soc_write(codec, ADAU1701_SERICTL, serictl); | 482 | regmap_write(adau1701->regmap, ADAU1701_SERICTL, serictl); |
356 | snd_soc_update_bits(codec, ADAU1701_SEROCTL, | 483 | regmap_update_bits(adau1701->regmap, ADAU1701_SEROCTL, |
357 | ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl); | 484 | ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl); |
358 | 485 | ||
359 | return 0; | 486 | return 0; |
@@ -363,6 +490,7 @@ static int adau1701_set_bias_level(struct snd_soc_codec *codec, | |||
363 | enum snd_soc_bias_level level) | 490 | enum snd_soc_bias_level level) |
364 | { | 491 | { |
365 | unsigned int mask = ADAU1701_AUXNPOW_VBPD | ADAU1701_AUXNPOW_VRPD; | 492 | unsigned int mask = ADAU1701_AUXNPOW_VBPD | ADAU1701_AUXNPOW_VRPD; |
493 | struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); | ||
366 | 494 | ||
367 | switch (level) { | 495 | switch (level) { |
368 | case SND_SOC_BIAS_ON: | 496 | case SND_SOC_BIAS_ON: |
@@ -371,11 +499,13 @@ static int adau1701_set_bias_level(struct snd_soc_codec *codec, | |||
371 | break; | 499 | break; |
372 | case SND_SOC_BIAS_STANDBY: | 500 | case SND_SOC_BIAS_STANDBY: |
373 | /* Enable VREF and VREF buffer */ | 501 | /* Enable VREF and VREF buffer */ |
374 | snd_soc_update_bits(codec, ADAU1701_AUXNPOW, mask, 0x00); | 502 | regmap_update_bits(adau1701->regmap, |
503 | ADAU1701_AUXNPOW, mask, 0x00); | ||
375 | break; | 504 | break; |
376 | case SND_SOC_BIAS_OFF: | 505 | case SND_SOC_BIAS_OFF: |
377 | /* Disable VREF and VREF buffer */ | 506 | /* Disable VREF and VREF buffer */ |
378 | snd_soc_update_bits(codec, ADAU1701_AUXNPOW, mask, mask); | 507 | regmap_update_bits(adau1701->regmap, |
508 | ADAU1701_AUXNPOW, mask, mask); | ||
379 | break; | 509 | break; |
380 | } | 510 | } |
381 | 511 | ||
@@ -387,6 +517,7 @@ static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute) | |||
387 | { | 517 | { |
388 | struct snd_soc_codec *codec = dai->codec; | 518 | struct snd_soc_codec *codec = dai->codec; |
389 | unsigned int mask = ADAU1701_DSPCTRL_DAM; | 519 | unsigned int mask = ADAU1701_DSPCTRL_DAM; |
520 | struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); | ||
390 | unsigned int val; | 521 | unsigned int val; |
391 | 522 | ||
392 | if (mute) | 523 | if (mute) |
@@ -394,7 +525,7 @@ static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute) | |||
394 | else | 525 | else |
395 | val = mask; | 526 | val = mask; |
396 | 527 | ||
397 | snd_soc_update_bits(codec, ADAU1701_DSPCTRL, mask, val); | 528 | regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL, mask, val); |
398 | 529 | ||
399 | return 0; | 530 | return 0; |
400 | } | 531 | } |
@@ -403,6 +534,7 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
403 | int source, unsigned int freq, int dir) | 534 | int source, unsigned int freq, int dir) |
404 | { | 535 | { |
405 | unsigned int val; | 536 | unsigned int val; |
537 | struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); | ||
406 | 538 | ||
407 | switch (clk_id) { | 539 | switch (clk_id) { |
408 | case ADAU1701_CLK_SRC_OSC: | 540 | case ADAU1701_CLK_SRC_OSC: |
@@ -415,7 +547,9 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
415 | return -EINVAL; | 547 | return -EINVAL; |
416 | } | 548 | } |
417 | 549 | ||
418 | snd_soc_update_bits(codec, ADAU1701_OSCIPOW, ADAU1701_OSCIPOW_OPD, val); | 550 | regmap_update_bits(adau1701->regmap, ADAU1701_OSCIPOW, |
551 | ADAU1701_OSCIPOW_OPD, val); | ||
552 | adau1701->sysclk = freq; | ||
419 | 553 | ||
420 | return 0; | 554 | return 0; |
421 | } | 555 | } |
@@ -452,18 +586,45 @@ static struct snd_soc_dai_driver adau1701_dai = { | |||
452 | .symmetric_rates = 1, | 586 | .symmetric_rates = 1, |
453 | }; | 587 | }; |
454 | 588 | ||
589 | #ifdef CONFIG_OF | ||
590 | static const struct of_device_id adau1701_dt_ids[] = { | ||
591 | { .compatible = "adi,adau1701", }, | ||
592 | { } | ||
593 | }; | ||
594 | MODULE_DEVICE_TABLE(of, adau1701_dt_ids); | ||
595 | #endif | ||
596 | |||
455 | static int adau1701_probe(struct snd_soc_codec *codec) | 597 | static int adau1701_probe(struct snd_soc_codec *codec) |
456 | { | 598 | { |
457 | int ret; | 599 | int i, ret; |
600 | unsigned int val; | ||
601 | struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); | ||
602 | |||
603 | /* | ||
604 | * Let the pll_clkdiv variable default to something that won't happen | ||
605 | * at runtime. That way, we can postpone the firmware download from | ||
606 | * adau1701_reset() to a point in time when we know the correct PLL | ||
607 | * mode parameters. | ||
608 | */ | ||
609 | adau1701->pll_clkdiv = ADAU1707_CLKDIV_UNSET; | ||
610 | |||
611 | /* initalize with pre-configured pll mode settings */ | ||
612 | ret = adau1701_reset(codec, adau1701->pll_clkdiv); | ||
613 | if (ret < 0) | ||
614 | return ret; | ||
615 | |||
616 | /* set up pin config */ | ||
617 | val = 0; | ||
618 | for (i = 0; i < 6; i++) | ||
619 | val |= adau1701->pin_config[i] << (i * 4); | ||
458 | 620 | ||
459 | codec->control_data = to_i2c_client(codec->dev); | 621 | regmap_write(adau1701->regmap, ADAU1701_PINCONF_0, val); |
460 | 622 | ||
461 | ret = adau1701_load_firmware(codec); | 623 | val = 0; |
462 | if (ret) | 624 | for (i = 0; i < 6; i++) |
463 | dev_warn(codec->dev, "Failed to load firmware\n"); | 625 | val |= adau1701->pin_config[i + 6] << (i * 4); |
464 | 626 | ||
465 | snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT); | 627 | regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val); |
466 | snd_soc_write(codec, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR); | ||
467 | 628 | ||
468 | return 0; | 629 | return 0; |
469 | } | 630 | } |
@@ -473,9 +634,6 @@ static struct snd_soc_codec_driver adau1701_codec_drv = { | |||
473 | .set_bias_level = adau1701_set_bias_level, | 634 | .set_bias_level = adau1701_set_bias_level, |
474 | .idle_bias_off = true, | 635 | .idle_bias_off = true, |
475 | 636 | ||
476 | .reg_cache_size = ADAU1701_NUM_REGS, | ||
477 | .reg_word_size = sizeof(u16), | ||
478 | |||
479 | .controls = adau1701_controls, | 637 | .controls = adau1701_controls, |
480 | .num_controls = ARRAY_SIZE(adau1701_controls), | 638 | .num_controls = ARRAY_SIZE(adau1701_controls), |
481 | .dapm_widgets = adau1701_dapm_widgets, | 639 | .dapm_widgets = adau1701_dapm_widgets, |
@@ -483,22 +641,86 @@ static struct snd_soc_codec_driver adau1701_codec_drv = { | |||
483 | .dapm_routes = adau1701_dapm_routes, | 641 | .dapm_routes = adau1701_dapm_routes, |
484 | .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), | 642 | .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), |
485 | 643 | ||
486 | .write = adau1701_write, | ||
487 | .read = adau1701_read, | ||
488 | |||
489 | .set_sysclk = adau1701_set_sysclk, | 644 | .set_sysclk = adau1701_set_sysclk, |
490 | }; | 645 | }; |
491 | 646 | ||
647 | static const struct regmap_config adau1701_regmap = { | ||
648 | .reg_bits = 16, | ||
649 | .val_bits = 32, | ||
650 | .max_register = ADAU1701_MAX_REGISTER, | ||
651 | .cache_type = REGCACHE_RBTREE, | ||
652 | .volatile_reg = adau1701_volatile_reg, | ||
653 | .reg_write = adau1701_reg_write, | ||
654 | .reg_read = adau1701_reg_read, | ||
655 | }; | ||
656 | |||
492 | static int adau1701_i2c_probe(struct i2c_client *client, | 657 | static int adau1701_i2c_probe(struct i2c_client *client, |
493 | const struct i2c_device_id *id) | 658 | const struct i2c_device_id *id) |
494 | { | 659 | { |
495 | struct adau1701 *adau1701; | 660 | struct adau1701 *adau1701; |
661 | struct device *dev = &client->dev; | ||
662 | int gpio_nreset = -EINVAL; | ||
663 | int gpio_pll_mode[2] = { -EINVAL, -EINVAL }; | ||
496 | int ret; | 664 | int ret; |
497 | 665 | ||
498 | adau1701 = devm_kzalloc(&client->dev, sizeof(*adau1701), GFP_KERNEL); | 666 | adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL); |
499 | if (!adau1701) | 667 | if (!adau1701) |
500 | return -ENOMEM; | 668 | return -ENOMEM; |
501 | 669 | ||
670 | adau1701->regmap = devm_regmap_init(dev, NULL, client, | ||
671 | &adau1701_regmap); | ||
672 | if (IS_ERR(adau1701->regmap)) | ||
673 | return PTR_ERR(adau1701->regmap); | ||
674 | |||
675 | if (dev->of_node) { | ||
676 | gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0); | ||
677 | if (gpio_nreset < 0 && gpio_nreset != -ENOENT) | ||
678 | return gpio_nreset; | ||
679 | |||
680 | gpio_pll_mode[0] = of_get_named_gpio(dev->of_node, | ||
681 | "adi,pll-mode-gpios", 0); | ||
682 | if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT) | ||
683 | return gpio_pll_mode[0]; | ||
684 | |||
685 | gpio_pll_mode[1] = of_get_named_gpio(dev->of_node, | ||
686 | "adi,pll-mode-gpios", 1); | ||
687 | if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT) | ||
688 | return gpio_pll_mode[1]; | ||
689 | |||
690 | of_property_read_u32(dev->of_node, "adi,pll-clkdiv", | ||
691 | &adau1701->pll_clkdiv); | ||
692 | |||
693 | of_property_read_u8_array(dev->of_node, "adi,pin-config", | ||
694 | adau1701->pin_config, | ||
695 | ARRAY_SIZE(adau1701->pin_config)); | ||
696 | } | ||
697 | |||
698 | if (gpio_is_valid(gpio_nreset)) { | ||
699 | ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW, | ||
700 | "ADAU1701 Reset"); | ||
701 | if (ret < 0) | ||
702 | return ret; | ||
703 | } | ||
704 | |||
705 | if (gpio_is_valid(gpio_pll_mode[0]) && | ||
706 | gpio_is_valid(gpio_pll_mode[1])) { | ||
707 | ret = devm_gpio_request_one(dev, gpio_pll_mode[0], | ||
708 | GPIOF_OUT_INIT_LOW, | ||
709 | "ADAU1701 PLL mode 0"); | ||
710 | if (ret < 0) | ||
711 | return ret; | ||
712 | |||
713 | ret = devm_gpio_request_one(dev, gpio_pll_mode[1], | ||
714 | GPIOF_OUT_INIT_LOW, | ||
715 | "ADAU1701 PLL mode 1"); | ||
716 | if (ret < 0) | ||
717 | return ret; | ||
718 | } | ||
719 | |||
720 | adau1701->gpio_nreset = gpio_nreset; | ||
721 | adau1701->gpio_pll_mode[0] = gpio_pll_mode[0]; | ||
722 | adau1701->gpio_pll_mode[1] = gpio_pll_mode[1]; | ||
723 | |||
502 | i2c_set_clientdata(client, adau1701); | 724 | i2c_set_clientdata(client, adau1701); |
503 | ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, | 725 | ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, |
504 | &adau1701_dai, 1); | 726 | &adau1701_dai, 1); |
@@ -521,6 +743,7 @@ static struct i2c_driver adau1701_i2c_driver = { | |||
521 | .driver = { | 743 | .driver = { |
522 | .name = "adau1701", | 744 | .name = "adau1701", |
523 | .owner = THIS_MODULE, | 745 | .owner = THIS_MODULE, |
746 | .of_match_table = of_match_ptr(adau1701_dt_ids), | ||
524 | }, | 747 | }, |
525 | .probe = adau1701_i2c_probe, | 748 | .probe = adau1701_i2c_probe, |
526 | .remove = adau1701_i2c_remove, | 749 | .remove = adau1701_i2c_remove, |