1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * wm8523.c -- WM8523 ALSA SoC Audio driver 4 * 5 * Copyright 2009 Wolfson Microelectronics plc 6 * 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 8 */ 9 10 #include <linux/mod_devicetable.h> 11 #include <linux/module.h> 12 #include <linux/moduleparam.h> 13 #include <linux/init.h> 14 #include <linux/delay.h> 15 #include <linux/pm.h> 16 #include <linux/i2c.h> 17 #include <linux/regmap.h> 18 #include <linux/regulator/consumer.h> 19 #include <linux/slab.h> 20 #include <sound/core.h> 21 #include <sound/pcm.h> 22 #include <sound/pcm_params.h> 23 #include <sound/soc.h> 24 #include <sound/initval.h> 25 #include <sound/tlv.h> 26 27 #include "wm8523.h" 28 29 #define WM8523_NUM_SUPPLIES 2 30 static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = { 31 "AVDD", 32 "LINEVDD", 33 }; 34 35 #define WM8523_NUM_RATES 7 36 37 /* codec private data */ 38 struct wm8523_priv { 39 struct regmap *regmap; 40 struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES]; 41 unsigned int sysclk; 42 unsigned int rate_constraint_list[WM8523_NUM_RATES]; 43 struct snd_pcm_hw_constraint_list rate_constraint; 44 }; 45 46 static const struct reg_default wm8523_reg_defaults[] = { 47 { 2, 0x0000 }, /* R2 - PSCTRL1 */ 48 { 3, 0x1812 }, /* R3 - AIF_CTRL1 */ 49 { 4, 0x0000 }, /* R4 - AIF_CTRL2 */ 50 { 5, 0x0001 }, /* R5 - DAC_CTRL3 */ 51 { 6, 0x0190 }, /* R6 - DAC_GAINL */ 52 { 7, 0x0190 }, /* R7 - DAC_GAINR */ 53 { 8, 0x0000 }, /* R8 - ZERO_DETECT */ 54 }; 55 56 static bool wm8523_volatile_register(struct device *dev, unsigned int reg) 57 { 58 switch (reg) { 59 case WM8523_DEVICE_ID: 60 case WM8523_REVISION: 61 return true; 62 default: 63 return false; 64 } 65 } 66 67 static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0); 68 69 static const char *wm8523_zd_count_text[] = { 70 "1024", 71 "2048", 72 }; 73 74 static SOC_ENUM_SINGLE_DECL(wm8523_zc_count, WM8523_ZERO_DETECT, 0, 75 wm8523_zd_count_text); 76 77 static const struct snd_kcontrol_new wm8523_controls[] = { 78 SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR, 79 0, 448, 0, dac_tlv), 80 SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0), 81 SOC_SINGLE("Playback Deemphasis Switch", WM8523_AIF_CTRL1, 8, 1, 0), 82 SOC_DOUBLE("Playback Switch", WM8523_DAC_CTRL3, 2, 3, 1, 1), 83 SOC_SINGLE("Volume Ramp Up Switch", WM8523_DAC_CTRL3, 1, 1, 0), 84 SOC_SINGLE("Volume Ramp Down Switch", WM8523_DAC_CTRL3, 0, 1, 0), 85 SOC_ENUM("Zero Detect Count", wm8523_zc_count), 86 }; 87 88 static const struct snd_soc_dapm_widget wm8523_dapm_widgets[] = { 89 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0), 90 SND_SOC_DAPM_OUTPUT("LINEVOUTL"), 91 SND_SOC_DAPM_OUTPUT("LINEVOUTR"), 92 }; 93 94 static const struct snd_soc_dapm_route wm8523_dapm_routes[] = { 95 { "LINEVOUTL", NULL, "DAC" }, 96 { "LINEVOUTR", NULL, "DAC" }, 97 }; 98 99 static const struct { 100 int value; 101 int ratio; 102 } lrclk_ratios[WM8523_NUM_RATES] = { 103 { 1, 128 }, 104 { 2, 192 }, 105 { 3, 256 }, 106 { 4, 384 }, 107 { 5, 512 }, 108 { 6, 768 }, 109 { 7, 1152 }, 110 }; 111 112 static const struct { 113 int value; 114 int ratio; 115 } bclk_ratios[] = { 116 { 2, 32 }, 117 { 3, 64 }, 118 { 4, 128 }, 119 }; 120 121 static int wm8523_startup(struct snd_pcm_substream *substream, 122 struct snd_soc_dai *dai) 123 { 124 struct snd_soc_component *component = dai->component; 125 struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component); 126 127 /* The set of sample rates that can be supported depends on the 128 * MCLK supplied to the CODEC - enforce this. 129 */ 130 if (!wm8523->sysclk) { 131 dev_err(component->dev, 132 "No MCLK configured, call set_sysclk() on init\n"); 133 return -EINVAL; 134 } 135 136 snd_pcm_hw_constraint_list(substream->runtime, 0, 137 SNDRV_PCM_HW_PARAM_RATE, 138 &wm8523->rate_constraint); 139 140 return 0; 141 } 142 143 static int wm8523_hw_params(struct snd_pcm_substream *substream, 144 struct snd_pcm_hw_params *params, 145 struct snd_soc_dai *dai) 146 { 147 struct snd_soc_component *component = dai->component; 148 struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component); 149 int i; 150 u16 aifctrl1 = snd_soc_component_read(component, WM8523_AIF_CTRL1); 151 u16 aifctrl2 = snd_soc_component_read(component, WM8523_AIF_CTRL2); 152 153 /* Find a supported LRCLK ratio */ 154 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { 155 if (wm8523->sysclk / params_rate(params) == 156 lrclk_ratios[i].ratio) 157 break; 158 } 159 160 /* Should never happen, should be handled by constraints */ 161 if (i == ARRAY_SIZE(lrclk_ratios)) { 162 dev_err(component->dev, "MCLK/fs ratio %d unsupported\n", 163 wm8523->sysclk / params_rate(params)); 164 return -EINVAL; 165 } 166 167 aifctrl2 &= ~WM8523_SR_MASK; 168 aifctrl2 |= lrclk_ratios[i].value; 169 170 if (aifctrl1 & WM8523_AIF_MSTR) { 171 /* Find a fs->bclk ratio */ 172 for (i = 0; i < ARRAY_SIZE(bclk_ratios); i++) 173 if (params_width(params) * 2 <= bclk_ratios[i].ratio) 174 break; 175 176 if (i == ARRAY_SIZE(bclk_ratios)) { 177 dev_err(component->dev, 178 "No matching BCLK/fs ratio for word length %d\n", 179 params_width(params)); 180 return -EINVAL; 181 } 182 183 aifctrl2 &= ~WM8523_BCLKDIV_MASK; 184 aifctrl2 |= bclk_ratios[i].value << WM8523_BCLKDIV_SHIFT; 185 } 186 187 aifctrl1 &= ~WM8523_WL_MASK; 188 switch (params_width(params)) { 189 case 16: 190 break; 191 case 20: 192 aifctrl1 |= 0x8; 193 break; 194 case 24: 195 aifctrl1 |= 0x10; 196 break; 197 case 32: 198 aifctrl1 |= 0x18; 199 break; 200 } 201 202 snd_soc_component_write(component, WM8523_AIF_CTRL1, aifctrl1); 203 snd_soc_component_write(component, WM8523_AIF_CTRL2, aifctrl2); 204 205 return 0; 206 } 207 208 static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai, 209 int clk_id, unsigned int freq, int dir) 210 { 211 struct snd_soc_component *component = codec_dai->component; 212 struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component); 213 unsigned int val; 214 int i; 215 216 wm8523->sysclk = freq; 217 218 wm8523->rate_constraint.count = 0; 219 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { 220 val = freq / lrclk_ratios[i].ratio; 221 /* Check that it's a standard rate since core can't 222 * cope with others and having the odd rates confuses 223 * constraint matching. 224 */ 225 switch (val) { 226 case 8000: 227 case 11025: 228 case 16000: 229 case 22050: 230 case 32000: 231 case 44100: 232 case 48000: 233 case 64000: 234 case 88200: 235 case 96000: 236 case 176400: 237 case 192000: 238 dev_dbg(component->dev, "Supported sample rate: %dHz\n", 239 val); 240 wm8523->rate_constraint_list[i] = val; 241 wm8523->rate_constraint.count++; 242 break; 243 default: 244 dev_dbg(component->dev, "Skipping sample rate: %dHz\n", 245 val); 246 } 247 } 248 249 /* Need at least one supported rate... */ 250 if (wm8523->rate_constraint.count == 0) 251 return -EINVAL; 252 253 return 0; 254 } 255 256 257 static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai, 258 unsigned int fmt) 259 { 260 struct snd_soc_component *component = codec_dai->component; 261 u16 aifctrl1 = snd_soc_component_read(component, WM8523_AIF_CTRL1); 262 263 aifctrl1 &= ~(WM8523_BCLK_INV_MASK | WM8523_LRCLK_INV_MASK | 264 WM8523_FMT_MASK | WM8523_AIF_MSTR_MASK); 265 266 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 267 case SND_SOC_DAIFMT_CBM_CFM: 268 aifctrl1 |= WM8523_AIF_MSTR; 269 break; 270 case SND_SOC_DAIFMT_CBS_CFS: 271 break; 272 default: 273 return -EINVAL; 274 } 275 276 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 277 case SND_SOC_DAIFMT_I2S: 278 aifctrl1 |= 0x0002; 279 break; 280 case SND_SOC_DAIFMT_RIGHT_J: 281 break; 282 case SND_SOC_DAIFMT_LEFT_J: 283 aifctrl1 |= 0x0001; 284 break; 285 case SND_SOC_DAIFMT_DSP_A: 286 aifctrl1 |= 0x0003; 287 break; 288 case SND_SOC_DAIFMT_DSP_B: 289 aifctrl1 |= 0x0023; 290 break; 291 default: 292 return -EINVAL; 293 } 294 295 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 296 case SND_SOC_DAIFMT_NB_NF: 297 break; 298 case SND_SOC_DAIFMT_IB_IF: 299 aifctrl1 |= WM8523_BCLK_INV | WM8523_LRCLK_INV; 300 break; 301 case SND_SOC_DAIFMT_IB_NF: 302 aifctrl1 |= WM8523_BCLK_INV; 303 break; 304 case SND_SOC_DAIFMT_NB_IF: 305 aifctrl1 |= WM8523_LRCLK_INV; 306 break; 307 default: 308 return -EINVAL; 309 } 310 311 snd_soc_component_write(component, WM8523_AIF_CTRL1, aifctrl1); 312 313 return 0; 314 } 315 316 static int wm8523_set_bias_level(struct snd_soc_component *component, 317 enum snd_soc_bias_level level) 318 { 319 struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component); 320 int ret; 321 322 switch (level) { 323 case SND_SOC_BIAS_ON: 324 break; 325 326 case SND_SOC_BIAS_PREPARE: 327 /* Full power on */ 328 snd_soc_component_update_bits(component, WM8523_PSCTRL1, 329 WM8523_SYS_ENA_MASK, 3); 330 break; 331 332 case SND_SOC_BIAS_STANDBY: 333 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { 334 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies), 335 wm8523->supplies); 336 if (ret != 0) { 337 dev_err(component->dev, 338 "Failed to enable supplies: %d\n", 339 ret); 340 return ret; 341 } 342 343 /* Sync back default/cached values */ 344 regcache_sync(wm8523->regmap); 345 346 /* Initial power up */ 347 snd_soc_component_update_bits(component, WM8523_PSCTRL1, 348 WM8523_SYS_ENA_MASK, 1); 349 350 msleep(100); 351 } 352 353 /* Power up to mute */ 354 snd_soc_component_update_bits(component, WM8523_PSCTRL1, 355 WM8523_SYS_ENA_MASK, 2); 356 357 break; 358 359 case SND_SOC_BIAS_OFF: 360 /* The chip runs through the power down sequence for us. */ 361 snd_soc_component_update_bits(component, WM8523_PSCTRL1, 362 WM8523_SYS_ENA_MASK, 0); 363 msleep(100); 364 365 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), 366 wm8523->supplies); 367 break; 368 } 369 return 0; 370 } 371 372 #define WM8523_RATES SNDRV_PCM_RATE_8000_192000 373 374 #define WM8523_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 375 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 376 377 static const struct snd_soc_dai_ops wm8523_dai_ops = { 378 .startup = wm8523_startup, 379 .hw_params = wm8523_hw_params, 380 .set_sysclk = wm8523_set_dai_sysclk, 381 .set_fmt = wm8523_set_dai_fmt, 382 }; 383 384 static struct snd_soc_dai_driver wm8523_dai = { 385 .name = "wm8523-hifi", 386 .playback = { 387 .stream_name = "Playback", 388 .channels_min = 2, /* Mono modes not yet supported */ 389 .channels_max = 2, 390 .rates = WM8523_RATES, 391 .formats = WM8523_FORMATS, 392 }, 393 .ops = &wm8523_dai_ops, 394 }; 395 396 static int wm8523_probe(struct snd_soc_component *component) 397 { 398 struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component); 399 400 wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; 401 wm8523->rate_constraint.count = 402 ARRAY_SIZE(wm8523->rate_constraint_list); 403 404 /* Change some default settings - latch VU and enable ZC */ 405 snd_soc_component_update_bits(component, WM8523_DAC_GAINR, 406 WM8523_DACR_VU, WM8523_DACR_VU); 407 snd_soc_component_update_bits(component, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC); 408 409 return 0; 410 } 411 412 static const struct snd_soc_component_driver soc_component_dev_wm8523 = { 413 .probe = wm8523_probe, 414 .set_bias_level = wm8523_set_bias_level, 415 .controls = wm8523_controls, 416 .num_controls = ARRAY_SIZE(wm8523_controls), 417 .dapm_widgets = wm8523_dapm_widgets, 418 .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets), 419 .dapm_routes = wm8523_dapm_routes, 420 .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes), 421 .suspend_bias_off = 1, 422 .idle_bias_on = 1, 423 .use_pmdown_time = 1, 424 .endianness = 1, 425 }; 426 427 static const struct of_device_id wm8523_of_match[] = { 428 { .compatible = "wlf,wm8523" }, 429 { }, 430 }; 431 MODULE_DEVICE_TABLE(of, wm8523_of_match); 432 433 static const struct regmap_config wm8523_regmap = { 434 .reg_bits = 8, 435 .val_bits = 16, 436 .max_register = WM8523_ZERO_DETECT, 437 438 .reg_defaults = wm8523_reg_defaults, 439 .num_reg_defaults = ARRAY_SIZE(wm8523_reg_defaults), 440 .cache_type = REGCACHE_MAPLE, 441 442 .volatile_reg = wm8523_volatile_register, 443 }; 444 445 static int wm8523_i2c_probe(struct i2c_client *i2c) 446 { 447 struct wm8523_priv *wm8523; 448 unsigned int val; 449 int ret, i; 450 451 wm8523 = devm_kzalloc(&i2c->dev, sizeof(struct wm8523_priv), 452 GFP_KERNEL); 453 if (wm8523 == NULL) 454 return -ENOMEM; 455 456 wm8523->regmap = devm_regmap_init_i2c(i2c, &wm8523_regmap); 457 if (IS_ERR(wm8523->regmap)) { 458 ret = PTR_ERR(wm8523->regmap); 459 dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); 460 return ret; 461 } 462 463 for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++) 464 wm8523->supplies[i].supply = wm8523_supply_names[i]; 465 466 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8523->supplies), 467 wm8523->supplies); 468 if (ret != 0) { 469 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); 470 return ret; 471 } 472 473 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies), 474 wm8523->supplies); 475 if (ret != 0) { 476 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); 477 return ret; 478 } 479 480 ret = regmap_read(wm8523->regmap, WM8523_DEVICE_ID, &val); 481 if (ret < 0) { 482 dev_err(&i2c->dev, "Failed to read ID register\n"); 483 goto err_enable; 484 } 485 if (val != 0x8523) { 486 dev_err(&i2c->dev, "Device is not a WM8523, ID is %x\n", ret); 487 ret = -EINVAL; 488 goto err_enable; 489 } 490 491 ret = regmap_read(wm8523->regmap, WM8523_REVISION, &val); 492 if (ret < 0) { 493 dev_err(&i2c->dev, "Failed to read revision register\n"); 494 goto err_enable; 495 } 496 dev_info(&i2c->dev, "revision %c\n", 497 (val & WM8523_CHIP_REV_MASK) + 'A'); 498 499 ret = regmap_write(wm8523->regmap, WM8523_DEVICE_ID, 0x8523); 500 if (ret != 0) { 501 dev_err(&i2c->dev, "Failed to reset device: %d\n", ret); 502 goto err_enable; 503 } 504 505 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 506 507 i2c_set_clientdata(i2c, wm8523); 508 509 ret = devm_snd_soc_register_component(&i2c->dev, 510 &soc_component_dev_wm8523, &wm8523_dai, 1); 511 512 return ret; 513 514 err_enable: 515 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 516 return ret; 517 } 518 519 static const struct i2c_device_id wm8523_i2c_id[] = { 520 { "wm8523" }, 521 { } 522 }; 523 MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id); 524 525 static struct i2c_driver wm8523_i2c_driver = { 526 .driver = { 527 .name = "wm8523", 528 .of_match_table = wm8523_of_match, 529 }, 530 .probe = wm8523_i2c_probe, 531 .id_table = wm8523_i2c_id, 532 }; 533 534 module_i2c_driver(wm8523_i2c_driver); 535 536 MODULE_DESCRIPTION("ASoC WM8523 driver"); 537 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 538 MODULE_LICENSE("GPL"); 539
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.