1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * wm8804.c -- WM8804 S/PDIF transceiver driver 4 * 5 * Copyright 2010-11 Wolfson Microelectronics plc 6 * 7 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> 8 */ 9 10 #include <linux/module.h> 11 #include <linux/moduleparam.h> 12 #include <linux/init.h> 13 #include <linux/gpio/consumer.h> 14 #include <linux/delay.h> 15 #include <linux/pm.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/regulator/consumer.h> 18 #include <linux/slab.h> 19 #include <sound/core.h> 20 #include <sound/pcm.h> 21 #include <sound/pcm_params.h> 22 #include <sound/soc.h> 23 #include <sound/initval.h> 24 #include <sound/tlv.h> 25 #include <sound/soc-dapm.h> 26 27 #include "wm8804.h" 28 29 #define WM8804_NUM_SUPPLIES 2 30 static const char *wm8804_supply_names[WM8804_NUM_SUPPLIES] = { 31 "PVDD", 32 "DVDD" 33 }; 34 35 static const struct reg_default wm8804_reg_defaults[] = { 36 { 3, 0x21 }, /* R3 - PLL1 */ 37 { 4, 0xFD }, /* R4 - PLL2 */ 38 { 5, 0x36 }, /* R5 - PLL3 */ 39 { 6, 0x07 }, /* R6 - PLL4 */ 40 { 7, 0x16 }, /* R7 - PLL5 */ 41 { 8, 0x18 }, /* R8 - PLL6 */ 42 { 9, 0xFF }, /* R9 - SPDMODE */ 43 { 10, 0x00 }, /* R10 - INTMASK */ 44 { 18, 0x00 }, /* R18 - SPDTX1 */ 45 { 19, 0x00 }, /* R19 - SPDTX2 */ 46 { 20, 0x00 }, /* R20 - SPDTX3 */ 47 { 21, 0x71 }, /* R21 - SPDTX4 */ 48 { 22, 0x0B }, /* R22 - SPDTX5 */ 49 { 23, 0x70 }, /* R23 - GPO0 */ 50 { 24, 0x57 }, /* R24 - GPO1 */ 51 { 26, 0x42 }, /* R26 - GPO2 */ 52 { 27, 0x06 }, /* R27 - AIFTX */ 53 { 28, 0x06 }, /* R28 - AIFRX */ 54 { 29, 0x80 }, /* R29 - SPDRX1 */ 55 { 30, 0x07 }, /* R30 - PWRDN */ 56 }; 57 58 struct wm8804_priv { 59 struct device *dev; 60 struct regmap *regmap; 61 struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES]; 62 struct notifier_block disable_nb[WM8804_NUM_SUPPLIES]; 63 int mclk_div; 64 65 struct gpio_desc *reset; 66 67 int aif_pwr; 68 }; 69 70 static int txsrc_put(struct snd_kcontrol *kcontrol, 71 struct snd_ctl_elem_value *ucontrol); 72 73 static int wm8804_aif_event(struct snd_soc_dapm_widget *w, 74 struct snd_kcontrol *kcontrol, int event); 75 76 /* 77 * We can't use the same notifier block for more than one supply and 78 * there's no way I can see to get from a callback to the caller 79 * except container_of(). 80 */ 81 #define WM8804_REGULATOR_EVENT(n) \ 82 static int wm8804_regulator_event_##n(struct notifier_block *nb, \ 83 unsigned long event, void *data) \ 84 { \ 85 struct wm8804_priv *wm8804 = container_of(nb, struct wm8804_priv, \ 86 disable_nb[n]); \ 87 if (event & REGULATOR_EVENT_DISABLE) { \ 88 regcache_mark_dirty(wm8804->regmap); \ 89 } \ 90 return 0; \ 91 } 92 93 WM8804_REGULATOR_EVENT(0) 94 WM8804_REGULATOR_EVENT(1) 95 96 static const char *txsrc_text[] = { "S/PDIF RX", "AIF" }; 97 static SOC_ENUM_SINGLE_DECL(txsrc, WM8804_SPDTX4, 6, txsrc_text); 98 99 static const struct snd_kcontrol_new wm8804_tx_source_mux[] = { 100 SOC_DAPM_ENUM_EXT("Input Source", txsrc, 101 snd_soc_dapm_get_enum_double, txsrc_put), 102 }; 103 104 static const struct snd_soc_dapm_widget wm8804_dapm_widgets[] = { 105 SND_SOC_DAPM_OUTPUT("SPDIF Out"), 106 SND_SOC_DAPM_INPUT("SPDIF In"), 107 108 SND_SOC_DAPM_PGA("SPDIFTX", WM8804_PWRDN, 2, 1, NULL, 0), 109 SND_SOC_DAPM_PGA("SPDIFRX", WM8804_PWRDN, 1, 1, NULL, 0), 110 111 SND_SOC_DAPM_MUX("Tx Source", SND_SOC_NOPM, 6, 0, wm8804_tx_source_mux), 112 113 SND_SOC_DAPM_AIF_OUT_E("AIFTX", NULL, 0, SND_SOC_NOPM, 0, 0, wm8804_aif_event, 114 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 115 SND_SOC_DAPM_AIF_IN_E("AIFRX", NULL, 0, SND_SOC_NOPM, 0, 0, wm8804_aif_event, 116 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 117 }; 118 119 static const struct snd_soc_dapm_route wm8804_dapm_routes[] = { 120 { "AIFRX", NULL, "Playback" }, 121 { "Tx Source", "AIF", "AIFRX" }, 122 123 { "SPDIFRX", NULL, "SPDIF In" }, 124 { "Tx Source", "S/PDIF RX", "SPDIFRX" }, 125 126 { "SPDIFTX", NULL, "Tx Source" }, 127 { "SPDIF Out", NULL, "SPDIFTX" }, 128 129 { "AIFTX", NULL, "SPDIFRX" }, 130 { "Capture", NULL, "AIFTX" }, 131 }; 132 133 static int wm8804_aif_event(struct snd_soc_dapm_widget *w, 134 struct snd_kcontrol *kcontrol, int event) 135 { 136 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 137 struct wm8804_priv *wm8804 = snd_soc_component_get_drvdata(component); 138 139 switch (event) { 140 case SND_SOC_DAPM_POST_PMU: 141 /* power up the aif */ 142 if (!wm8804->aif_pwr) 143 snd_soc_component_update_bits(component, WM8804_PWRDN, 0x10, 0x0); 144 wm8804->aif_pwr++; 145 break; 146 case SND_SOC_DAPM_POST_PMD: 147 /* power down only both paths are disabled */ 148 wm8804->aif_pwr--; 149 if (!wm8804->aif_pwr) 150 snd_soc_component_update_bits(component, WM8804_PWRDN, 0x10, 0x10); 151 break; 152 } 153 154 return 0; 155 } 156 157 static int txsrc_put(struct snd_kcontrol *kcontrol, 158 struct snd_ctl_elem_value *ucontrol) 159 { 160 struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); 161 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 162 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 163 unsigned int val = ucontrol->value.enumerated.item[0] << e->shift_l; 164 unsigned int mask = 1 << e->shift_l; 165 unsigned int txpwr; 166 167 if (val != 0 && val != mask) 168 return -EINVAL; 169 170 snd_soc_dapm_mutex_lock(dapm); 171 172 if (snd_soc_component_test_bits(component, e->reg, mask, val)) { 173 /* save the current power state of the transmitter */ 174 txpwr = snd_soc_component_read(component, WM8804_PWRDN) & 0x4; 175 176 /* power down the transmitter */ 177 snd_soc_component_update_bits(component, WM8804_PWRDN, 0x4, 0x4); 178 179 /* set the tx source */ 180 snd_soc_component_update_bits(component, e->reg, mask, val); 181 182 /* restore the transmitter's configuration */ 183 snd_soc_component_update_bits(component, WM8804_PWRDN, 0x4, txpwr); 184 } 185 186 snd_soc_dapm_mutex_unlock(dapm); 187 188 return 0; 189 } 190 191 static bool wm8804_volatile(struct device *dev, unsigned int reg) 192 { 193 switch (reg) { 194 case WM8804_RST_DEVID1: 195 case WM8804_DEVID2: 196 case WM8804_DEVREV: 197 case WM8804_INTSTAT: 198 case WM8804_SPDSTAT: 199 case WM8804_RXCHAN1: 200 case WM8804_RXCHAN2: 201 case WM8804_RXCHAN3: 202 case WM8804_RXCHAN4: 203 case WM8804_RXCHAN5: 204 return true; 205 default: 206 return false; 207 } 208 } 209 210 static int wm8804_soft_reset(struct wm8804_priv *wm8804) 211 { 212 return regmap_write(wm8804->regmap, WM8804_RST_DEVID1, 0x0); 213 } 214 215 static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 216 { 217 struct snd_soc_component *component; 218 u16 format, master, bcp, lrp; 219 220 component = dai->component; 221 222 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 223 case SND_SOC_DAIFMT_I2S: 224 format = 0x2; 225 break; 226 case SND_SOC_DAIFMT_RIGHT_J: 227 format = 0x0; 228 break; 229 case SND_SOC_DAIFMT_LEFT_J: 230 format = 0x1; 231 break; 232 case SND_SOC_DAIFMT_DSP_A: 233 case SND_SOC_DAIFMT_DSP_B: 234 format = 0x3; 235 break; 236 default: 237 dev_err(dai->dev, "Unknown dai format\n"); 238 return -EINVAL; 239 } 240 241 /* set data format */ 242 snd_soc_component_update_bits(component, WM8804_AIFTX, 0x3, format); 243 snd_soc_component_update_bits(component, WM8804_AIFRX, 0x3, format); 244 245 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 246 case SND_SOC_DAIFMT_CBM_CFM: 247 master = 1; 248 break; 249 case SND_SOC_DAIFMT_CBS_CFS: 250 master = 0; 251 break; 252 default: 253 dev_err(dai->dev, "Unknown master/slave configuration\n"); 254 return -EINVAL; 255 } 256 257 /* set master/slave mode */ 258 snd_soc_component_update_bits(component, WM8804_AIFRX, 0x40, master << 6); 259 260 bcp = lrp = 0; 261 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 262 case SND_SOC_DAIFMT_NB_NF: 263 break; 264 case SND_SOC_DAIFMT_IB_IF: 265 bcp = lrp = 1; 266 break; 267 case SND_SOC_DAIFMT_IB_NF: 268 bcp = 1; 269 break; 270 case SND_SOC_DAIFMT_NB_IF: 271 lrp = 1; 272 break; 273 default: 274 dev_err(dai->dev, "Unknown polarity configuration\n"); 275 return -EINVAL; 276 } 277 278 /* set frame inversion */ 279 snd_soc_component_update_bits(component, WM8804_AIFTX, 0x10 | 0x20, 280 (bcp << 4) | (lrp << 5)); 281 snd_soc_component_update_bits(component, WM8804_AIFRX, 0x10 | 0x20, 282 (bcp << 4) | (lrp << 5)); 283 return 0; 284 } 285 286 static int wm8804_hw_params(struct snd_pcm_substream *substream, 287 struct snd_pcm_hw_params *params, 288 struct snd_soc_dai *dai) 289 { 290 struct snd_soc_component *component; 291 u16 blen; 292 293 component = dai->component; 294 295 switch (params_width(params)) { 296 case 16: 297 blen = 0x0; 298 break; 299 case 20: 300 blen = 0x1; 301 break; 302 case 24: 303 blen = 0x2; 304 break; 305 default: 306 dev_err(dai->dev, "Unsupported word length: %u\n", 307 params_width(params)); 308 return -EINVAL; 309 } 310 311 /* set word length */ 312 snd_soc_component_update_bits(component, WM8804_AIFTX, 0xc, blen << 2); 313 snd_soc_component_update_bits(component, WM8804_AIFRX, 0xc, blen << 2); 314 315 return 0; 316 } 317 318 struct pll_div { 319 u32 prescale:1; 320 u32 mclkdiv:1; 321 u32 freqmode:2; 322 u32 n:4; 323 u32 k:22; 324 }; 325 326 /* PLL rate to output rate divisions */ 327 static struct { 328 unsigned int div; 329 unsigned int freqmode; 330 unsigned int mclkdiv; 331 } post_table[] = { 332 { 2, 0, 0 }, 333 { 4, 0, 1 }, 334 { 4, 1, 0 }, 335 { 8, 1, 1 }, 336 { 8, 2, 0 }, 337 { 16, 2, 1 }, 338 { 12, 3, 0 }, 339 { 24, 3, 1 } 340 }; 341 342 #define FIXED_PLL_SIZE ((1ULL << 22) * 10) 343 static int pll_factors(struct pll_div *pll_div, unsigned int target, 344 unsigned int source, unsigned int mclk_div) 345 { 346 u64 Kpart; 347 unsigned long int K, Ndiv, Nmod, tmp; 348 int i; 349 350 /* 351 * Scale the output frequency up; the PLL should run in the 352 * region of 90-100MHz. 353 */ 354 for (i = 0; i < ARRAY_SIZE(post_table); i++) { 355 tmp = target * post_table[i].div; 356 if ((tmp >= 90000000 && tmp <= 100000000) && 357 (mclk_div == post_table[i].mclkdiv)) { 358 pll_div->freqmode = post_table[i].freqmode; 359 pll_div->mclkdiv = post_table[i].mclkdiv; 360 target *= post_table[i].div; 361 break; 362 } 363 } 364 365 if (i == ARRAY_SIZE(post_table)) { 366 pr_err("%s: Unable to scale output frequency: %uHz\n", 367 __func__, target); 368 return -EINVAL; 369 } 370 371 pll_div->prescale = 0; 372 Ndiv = target / source; 373 if (Ndiv < 5) { 374 source >>= 1; 375 pll_div->prescale = 1; 376 Ndiv = target / source; 377 } 378 379 if (Ndiv < 5 || Ndiv > 13) { 380 pr_err("%s: WM8804 N value is not within the recommended range: %lu\n", 381 __func__, Ndiv); 382 return -EINVAL; 383 } 384 pll_div->n = Ndiv; 385 386 Nmod = target % source; 387 Kpart = FIXED_PLL_SIZE * (u64)Nmod; 388 389 do_div(Kpart, source); 390 391 K = Kpart & 0xffffffff; 392 if ((K % 10) >= 5) 393 K += 5; 394 K /= 10; 395 pll_div->k = K; 396 397 return 0; 398 } 399 400 static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id, 401 int source, unsigned int freq_in, 402 unsigned int freq_out) 403 { 404 struct snd_soc_component *component = dai->component; 405 struct wm8804_priv *wm8804 = snd_soc_component_get_drvdata(component); 406 bool change; 407 408 if (!freq_in || !freq_out) { 409 /* disable the PLL */ 410 regmap_update_bits_check(wm8804->regmap, WM8804_PWRDN, 411 0x1, 0x1, &change); 412 if (change) 413 pm_runtime_put(wm8804->dev); 414 } else { 415 int ret; 416 struct pll_div pll_div; 417 418 ret = pll_factors(&pll_div, freq_out, freq_in, 419 wm8804->mclk_div); 420 if (ret) 421 return ret; 422 423 /* power down the PLL before reprogramming it */ 424 regmap_update_bits_check(wm8804->regmap, WM8804_PWRDN, 425 0x1, 0x1, &change); 426 if (!change) 427 pm_runtime_get_sync(wm8804->dev); 428 429 /* set PLLN and PRESCALE */ 430 snd_soc_component_update_bits(component, WM8804_PLL4, 0xf | 0x10, 431 pll_div.n | (pll_div.prescale << 4)); 432 /* set mclkdiv and freqmode */ 433 snd_soc_component_update_bits(component, WM8804_PLL5, 0x3 | 0x8, 434 pll_div.freqmode | (pll_div.mclkdiv << 3)); 435 /* set PLLK */ 436 snd_soc_component_write(component, WM8804_PLL1, pll_div.k & 0xff); 437 snd_soc_component_write(component, WM8804_PLL2, (pll_div.k >> 8) & 0xff); 438 snd_soc_component_write(component, WM8804_PLL3, pll_div.k >> 16); 439 440 /* power up the PLL */ 441 snd_soc_component_update_bits(component, WM8804_PWRDN, 0x1, 0); 442 } 443 444 return 0; 445 } 446 447 static int wm8804_set_sysclk(struct snd_soc_dai *dai, 448 int clk_id, unsigned int freq, int dir) 449 { 450 struct snd_soc_component *component; 451 452 component = dai->component; 453 454 switch (clk_id) { 455 case WM8804_TX_CLKSRC_MCLK: 456 if ((freq >= 10000000 && freq <= 14400000) 457 || (freq >= 16280000 && freq <= 27000000)) 458 snd_soc_component_update_bits(component, WM8804_PLL6, 0x80, 0x80); 459 else { 460 dev_err(dai->dev, "OSCCLOCK is not within the " 461 "recommended range: %uHz\n", freq); 462 return -EINVAL; 463 } 464 break; 465 case WM8804_TX_CLKSRC_PLL: 466 snd_soc_component_update_bits(component, WM8804_PLL6, 0x80, 0); 467 break; 468 case WM8804_CLKOUT_SRC_CLK1: 469 snd_soc_component_update_bits(component, WM8804_PLL6, 0x8, 0); 470 break; 471 case WM8804_CLKOUT_SRC_OSCCLK: 472 snd_soc_component_update_bits(component, WM8804_PLL6, 0x8, 0x8); 473 break; 474 default: 475 dev_err(dai->dev, "Unknown clock source: %d\n", clk_id); 476 return -EINVAL; 477 } 478 479 return 0; 480 } 481 482 static int wm8804_set_clkdiv(struct snd_soc_dai *dai, 483 int div_id, int div) 484 { 485 struct snd_soc_component *component; 486 struct wm8804_priv *wm8804; 487 488 component = dai->component; 489 switch (div_id) { 490 case WM8804_CLKOUT_DIV: 491 snd_soc_component_update_bits(component, WM8804_PLL5, 0x30, 492 (div & 0x3) << 4); 493 break; 494 case WM8804_MCLK_DIV: 495 wm8804 = snd_soc_component_get_drvdata(component); 496 wm8804->mclk_div = div; 497 break; 498 default: 499 dev_err(dai->dev, "Unknown clock divider: %d\n", div_id); 500 return -EINVAL; 501 } 502 return 0; 503 } 504 505 static const struct snd_soc_dai_ops wm8804_dai_ops = { 506 .hw_params = wm8804_hw_params, 507 .set_fmt = wm8804_set_fmt, 508 .set_sysclk = wm8804_set_sysclk, 509 .set_clkdiv = wm8804_set_clkdiv, 510 .set_pll = wm8804_set_pll 511 }; 512 513 #define WM8804_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 514 SNDRV_PCM_FMTBIT_S24_LE) 515 516 #define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 517 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ 518 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \ 519 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000) 520 521 static struct snd_soc_dai_driver wm8804_dai = { 522 .name = "wm8804-spdif", 523 .playback = { 524 .stream_name = "Playback", 525 .channels_min = 2, 526 .channels_max = 2, 527 .rates = WM8804_RATES, 528 .formats = WM8804_FORMATS, 529 }, 530 .capture = { 531 .stream_name = "Capture", 532 .channels_min = 2, 533 .channels_max = 2, 534 .rates = WM8804_RATES, 535 .formats = WM8804_FORMATS, 536 }, 537 .ops = &wm8804_dai_ops, 538 .symmetric_rate = 1 539 }; 540 541 static const struct snd_soc_component_driver soc_component_dev_wm8804 = { 542 .dapm_widgets = wm8804_dapm_widgets, 543 .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets), 544 .dapm_routes = wm8804_dapm_routes, 545 .num_dapm_routes = ARRAY_SIZE(wm8804_dapm_routes), 546 .use_pmdown_time = 1, 547 .endianness = 1, 548 }; 549 550 const struct regmap_config wm8804_regmap_config = { 551 .reg_bits = 8, 552 .val_bits = 8, 553 554 .max_register = WM8804_MAX_REGISTER, 555 .volatile_reg = wm8804_volatile, 556 557 .cache_type = REGCACHE_MAPLE, 558 .reg_defaults = wm8804_reg_defaults, 559 .num_reg_defaults = ARRAY_SIZE(wm8804_reg_defaults), 560 }; 561 EXPORT_SYMBOL_GPL(wm8804_regmap_config); 562 563 int wm8804_probe(struct device *dev, struct regmap *regmap) 564 { 565 struct wm8804_priv *wm8804; 566 unsigned int id1, id2; 567 int i, ret; 568 569 wm8804 = devm_kzalloc(dev, sizeof(*wm8804), GFP_KERNEL); 570 if (!wm8804) 571 return -ENOMEM; 572 573 dev_set_drvdata(dev, wm8804); 574 575 wm8804->dev = dev; 576 wm8804->regmap = regmap; 577 578 wm8804->reset = devm_gpiod_get_optional(dev, "wlf,reset", 579 GPIOD_OUT_LOW); 580 if (IS_ERR(wm8804->reset)) { 581 ret = PTR_ERR(wm8804->reset); 582 dev_err(dev, "Failed to get reset line: %d\n", ret); 583 return ret; 584 } 585 586 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) 587 wm8804->supplies[i].supply = wm8804_supply_names[i]; 588 589 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(wm8804->supplies), 590 wm8804->supplies); 591 if (ret) { 592 dev_err(dev, "Failed to request supplies: %d\n", ret); 593 return ret; 594 } 595 596 wm8804->disable_nb[0].notifier_call = wm8804_regulator_event_0; 597 wm8804->disable_nb[1].notifier_call = wm8804_regulator_event_1; 598 599 /* This should really be moved into the regulator core */ 600 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) { 601 struct regulator *regulator = wm8804->supplies[i].consumer; 602 603 ret = devm_regulator_register_notifier(regulator, 604 &wm8804->disable_nb[i]); 605 if (ret != 0) { 606 dev_err(dev, 607 "Failed to register regulator notifier: %d\n", 608 ret); 609 return ret; 610 } 611 } 612 613 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies), 614 wm8804->supplies); 615 if (ret) { 616 dev_err(dev, "Failed to enable supplies: %d\n", ret); 617 return ret; 618 } 619 620 gpiod_set_value_cansleep(wm8804->reset, 1); 621 622 ret = regmap_read(regmap, WM8804_RST_DEVID1, &id1); 623 if (ret < 0) { 624 dev_err(dev, "Failed to read device ID: %d\n", ret); 625 goto err_reg_enable; 626 } 627 628 ret = regmap_read(regmap, WM8804_DEVID2, &id2); 629 if (ret < 0) { 630 dev_err(dev, "Failed to read device ID: %d\n", ret); 631 goto err_reg_enable; 632 } 633 634 id2 = (id2 << 8) | id1; 635 636 if (id2 != 0x8805) { 637 dev_err(dev, "Invalid device ID: %#x\n", id2); 638 ret = -EINVAL; 639 goto err_reg_enable; 640 } 641 642 ret = regmap_read(regmap, WM8804_DEVREV, &id1); 643 if (ret < 0) { 644 dev_err(dev, "Failed to read device revision: %d\n", 645 ret); 646 goto err_reg_enable; 647 } 648 dev_info(dev, "revision %c\n", id1 + 'A'); 649 650 if (!wm8804->reset) { 651 ret = wm8804_soft_reset(wm8804); 652 if (ret < 0) { 653 dev_err(dev, "Failed to issue reset: %d\n", ret); 654 goto err_reg_enable; 655 } 656 } 657 658 ret = devm_snd_soc_register_component(dev, &soc_component_dev_wm8804, 659 &wm8804_dai, 1); 660 if (ret < 0) { 661 dev_err(dev, "Failed to register CODEC: %d\n", ret); 662 goto err_reg_enable; 663 } 664 665 pm_runtime_set_active(dev); 666 pm_runtime_enable(dev); 667 pm_runtime_idle(dev); 668 669 return 0; 670 671 err_reg_enable: 672 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); 673 return ret; 674 } 675 EXPORT_SYMBOL_GPL(wm8804_probe); 676 677 void wm8804_remove(struct device *dev) 678 { 679 pm_runtime_disable(dev); 680 } 681 EXPORT_SYMBOL_GPL(wm8804_remove); 682 683 #if IS_ENABLED(CONFIG_PM) 684 static int wm8804_runtime_resume(struct device *dev) 685 { 686 struct wm8804_priv *wm8804 = dev_get_drvdata(dev); 687 int ret; 688 689 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies), 690 wm8804->supplies); 691 if (ret) { 692 dev_err(wm8804->dev, "Failed to enable supplies: %d\n", ret); 693 return ret; 694 } 695 696 regcache_sync(wm8804->regmap); 697 698 /* Power up OSCCLK */ 699 regmap_update_bits(wm8804->regmap, WM8804_PWRDN, 0x8, 0x0); 700 701 return 0; 702 } 703 704 static int wm8804_runtime_suspend(struct device *dev) 705 { 706 struct wm8804_priv *wm8804 = dev_get_drvdata(dev); 707 708 /* Power down OSCCLK */ 709 regmap_update_bits(wm8804->regmap, WM8804_PWRDN, 0x8, 0x8); 710 711 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), 712 wm8804->supplies); 713 714 return 0; 715 } 716 #endif 717 718 const struct dev_pm_ops wm8804_pm = { 719 SET_RUNTIME_PM_OPS(wm8804_runtime_suspend, wm8804_runtime_resume, NULL) 720 }; 721 EXPORT_SYMBOL_GPL(wm8804_pm); 722 723 MODULE_DESCRIPTION("ASoC WM8804 driver"); 724 MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>"); 725 MODULE_LICENSE("GPL"); 726