diff options
| -rw-r--r-- | Documentation/devicetree/bindings/sound/adi,adau1701.txt | 35 | ||||
| -rw-r--r-- | sound/soc/codecs/adau1701.c | 321 |
2 files changed, 307 insertions, 49 deletions
diff --git a/Documentation/devicetree/bindings/sound/adi,adau1701.txt b/Documentation/devicetree/bindings/sound/adi,adau1701.txt new file mode 100644 index 000000000000..547a49b56a62 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/adi,adau1701.txt | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | Analog Devices ADAU1701 | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | |||
| 5 | - compatible: Should contain "adi,adau1701" | ||
| 6 | - reg: The i2c address. Value depends on the state of ADDR0 | ||
| 7 | and ADDR1, as wired in hardware. | ||
| 8 | |||
| 9 | Optional properties: | ||
| 10 | |||
| 11 | - reset-gpio: A GPIO spec to define which pin is connected to the | ||
| 12 | chip's !RESET pin. If specified, the driver will | ||
| 13 | assert a hardware reset at probe time. | ||
| 14 | - adi,pll-mode-gpios: An array of two GPIO specs to describe the GPIOs | ||
| 15 | the ADAU's PLL config pins are connected to. | ||
| 16 | The state of the pins are set according to the | ||
| 17 | configured clock divider on ASoC side before the | ||
| 18 | firmware is loaded. | ||
| 19 | - adi,pin-config: An array of 12 numerical values selecting one of the | ||
| 20 | pin configurations as described in the datasheet, | ||
| 21 | table 53. Note that the value of this property has | ||
| 22 | to be prefixed with '/bits/ 8'. | ||
| 23 | |||
| 24 | Examples: | ||
| 25 | |||
| 26 | i2c_bus { | ||
| 27 | adau1701@34 { | ||
| 28 | compatible = "adi,adau1701"; | ||
| 29 | reg = <0x34>; | ||
| 30 | reset-gpio = <&gpio 23 0>; | ||
| 31 | adi,pll-mode-gpios = <&gpio 24 0 &gpio 25 0>; | ||
| 32 | adi,pin-config = /bits/ 8 <0x4 0x7 0x5 0x5 0x4 0x4 | ||
| 33 | 0x4 0x4 0x4 0x4 0x4 0x4>; | ||
| 34 | }; | ||
| 35 | }; | ||
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, |
