wm8523.c (13529B)
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/module.h> 11#include <linux/moduleparam.h> 12#include <linux/init.h> 13#include <linux/delay.h> 14#include <linux/pm.h> 15#include <linux/i2c.h> 16#include <linux/regmap.h> 17#include <linux/regulator/consumer.h> 18#include <linux/slab.h> 19#include <linux/of_device.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 30static 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 */ 38struct 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 46static 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 56static 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 67static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0); 68 69static const char *wm8523_zd_count_text[] = { 70 "1024", 71 "2048", 72}; 73 74static SOC_ENUM_SINGLE_DECL(wm8523_zc_count, WM8523_ZERO_DETECT, 0, 75 wm8523_zd_count_text); 76 77static const struct snd_kcontrol_new wm8523_controls[] = { 78SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR, 79 0, 448, 0, dac_tlv), 80SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0), 81SOC_SINGLE("Playback Deemphasis Switch", WM8523_AIF_CTRL1, 8, 1, 0), 82SOC_DOUBLE("Playback Switch", WM8523_DAC_CTRL3, 2, 3, 1, 1), 83SOC_SINGLE("Volume Ramp Up Switch", WM8523_DAC_CTRL3, 1, 1, 0), 84SOC_SINGLE("Volume Ramp Down Switch", WM8523_DAC_CTRL3, 0, 1, 0), 85SOC_ENUM("Zero Detect Count", wm8523_zc_count), 86}; 87 88static const struct snd_soc_dapm_widget wm8523_dapm_widgets[] = { 89SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0), 90SND_SOC_DAPM_OUTPUT("LINEVOUTL"), 91SND_SOC_DAPM_OUTPUT("LINEVOUTR"), 92}; 93 94static const struct snd_soc_dapm_route wm8523_dapm_routes[] = { 95 { "LINEVOUTL", NULL, "DAC" }, 96 { "LINEVOUTR", NULL, "DAC" }, 97}; 98 99static 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 112static const struct { 113 int value; 114 int ratio; 115} bclk_ratios[] = { 116 { 2, 32 }, 117 { 3, 64 }, 118 { 4, 128 }, 119}; 120 121static 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 143static 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 208static 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 257static 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 316static 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 377static 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 384static 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 396static 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 412static 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 .non_legacy_dai_naming = 1, 426}; 427 428static const struct of_device_id wm8523_of_match[] = { 429 { .compatible = "wlf,wm8523" }, 430 { }, 431}; 432MODULE_DEVICE_TABLE(of, wm8523_of_match); 433 434static const struct regmap_config wm8523_regmap = { 435 .reg_bits = 8, 436 .val_bits = 16, 437 .max_register = WM8523_ZERO_DETECT, 438 439 .reg_defaults = wm8523_reg_defaults, 440 .num_reg_defaults = ARRAY_SIZE(wm8523_reg_defaults), 441 .cache_type = REGCACHE_RBTREE, 442 443 .volatile_reg = wm8523_volatile_register, 444}; 445 446static int wm8523_i2c_probe(struct i2c_client *i2c) 447{ 448 struct wm8523_priv *wm8523; 449 unsigned int val; 450 int ret, i; 451 452 wm8523 = devm_kzalloc(&i2c->dev, sizeof(struct wm8523_priv), 453 GFP_KERNEL); 454 if (wm8523 == NULL) 455 return -ENOMEM; 456 457 wm8523->regmap = devm_regmap_init_i2c(i2c, &wm8523_regmap); 458 if (IS_ERR(wm8523->regmap)) { 459 ret = PTR_ERR(wm8523->regmap); 460 dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); 461 return ret; 462 } 463 464 for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++) 465 wm8523->supplies[i].supply = wm8523_supply_names[i]; 466 467 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8523->supplies), 468 wm8523->supplies); 469 if (ret != 0) { 470 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); 471 return ret; 472 } 473 474 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies), 475 wm8523->supplies); 476 if (ret != 0) { 477 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); 478 return ret; 479 } 480 481 ret = regmap_read(wm8523->regmap, WM8523_DEVICE_ID, &val); 482 if (ret < 0) { 483 dev_err(&i2c->dev, "Failed to read ID register\n"); 484 goto err_enable; 485 } 486 if (val != 0x8523) { 487 dev_err(&i2c->dev, "Device is not a WM8523, ID is %x\n", ret); 488 ret = -EINVAL; 489 goto err_enable; 490 } 491 492 ret = regmap_read(wm8523->regmap, WM8523_REVISION, &val); 493 if (ret < 0) { 494 dev_err(&i2c->dev, "Failed to read revision register\n"); 495 goto err_enable; 496 } 497 dev_info(&i2c->dev, "revision %c\n", 498 (val & WM8523_CHIP_REV_MASK) + 'A'); 499 500 ret = regmap_write(wm8523->regmap, WM8523_DEVICE_ID, 0x8523); 501 if (ret != 0) { 502 dev_err(&i2c->dev, "Failed to reset device: %d\n", ret); 503 goto err_enable; 504 } 505 506 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 507 508 i2c_set_clientdata(i2c, wm8523); 509 510 ret = devm_snd_soc_register_component(&i2c->dev, 511 &soc_component_dev_wm8523, &wm8523_dai, 1); 512 513 return ret; 514 515err_enable: 516 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 517 return ret; 518} 519 520static const struct i2c_device_id wm8523_i2c_id[] = { 521 { "wm8523", 0 }, 522 { } 523}; 524MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id); 525 526static struct i2c_driver wm8523_i2c_driver = { 527 .driver = { 528 .name = "wm8523", 529 .of_match_table = wm8523_of_match, 530 }, 531 .probe_new = wm8523_i2c_probe, 532 .id_table = wm8523_i2c_id, 533}; 534 535module_i2c_driver(wm8523_i2c_driver); 536 537MODULE_DESCRIPTION("ASoC WM8523 driver"); 538MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 539MODULE_LICENSE("GPL");