1 /* 2 * arizona.c - Wolfson Arizona class device shared support 3 * 4 * Copyright 2012 Wolfson Microelectronics plc 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13 #include <linux/delay.h> 14 #include <linux/gcd.h> 15 #include <linux/module.h> 16 #include <linux/pm_runtime.h> 17 #include <sound/pcm.h> 18 #include <sound/pcm_params.h> 19 #include <sound/tlv.h> 20 21 #include <linux/mfd/arizona/core.h> 22 #include <linux/mfd/arizona/registers.h> 23 24 #include "arizona.h" 25 26 #define ARIZONA_AIF_BCLK_CTRL 0x00 27 #define ARIZONA_AIF_TX_PIN_CTRL 0x01 28 #define ARIZONA_AIF_RX_PIN_CTRL 0x02 29 #define ARIZONA_AIF_RATE_CTRL 0x03 30 #define ARIZONA_AIF_FORMAT 0x04 31 #define ARIZONA_AIF_TX_BCLK_RATE 0x05 32 #define ARIZONA_AIF_RX_BCLK_RATE 0x06 33 #define ARIZONA_AIF_FRAME_CTRL_1 0x07 34 #define ARIZONA_AIF_FRAME_CTRL_2 0x08 35 #define ARIZONA_AIF_FRAME_CTRL_3 0x09 36 #define ARIZONA_AIF_FRAME_CTRL_4 0x0A 37 #define ARIZONA_AIF_FRAME_CTRL_5 0x0B 38 #define ARIZONA_AIF_FRAME_CTRL_6 0x0C 39 #define ARIZONA_AIF_FRAME_CTRL_7 0x0D 40 #define ARIZONA_AIF_FRAME_CTRL_8 0x0E 41 #define ARIZONA_AIF_FRAME_CTRL_9 0x0F 42 #define ARIZONA_AIF_FRAME_CTRL_10 0x10 43 #define ARIZONA_AIF_FRAME_CTRL_11 0x11 44 #define ARIZONA_AIF_FRAME_CTRL_12 0x12 45 #define ARIZONA_AIF_FRAME_CTRL_13 0x13 46 #define ARIZONA_AIF_FRAME_CTRL_14 0x14 47 #define ARIZONA_AIF_FRAME_CTRL_15 0x15 48 #define ARIZONA_AIF_FRAME_CTRL_16 0x16 49 #define ARIZONA_AIF_FRAME_CTRL_17 0x17 50 #define ARIZONA_AIF_FRAME_CTRL_18 0x18 51 #define ARIZONA_AIF_TX_ENABLES 0x19 52 #define ARIZONA_AIF_RX_ENABLES 0x1A 53 #define ARIZONA_AIF_FORCE_WRITE 0x1B 54 55 #define ARIZONA_FLL_VCO_CORNER 141900000 56 #define ARIZONA_FLL_MAX_FREF 13500000 57 #define ARIZONA_FLL_MIN_FVCO 90000000 58 #define ARIZONA_FLL_MAX_FRATIO 16 59 #define ARIZONA_FLL_MAX_REFDIV 8 60 #define ARIZONA_FLL_MIN_OUTDIV 2 61 #define ARIZONA_FLL_MAX_OUTDIV 7 62 63 #define ARIZONA_FMT_DSP_MODE_A 0 64 #define ARIZONA_FMT_DSP_MODE_B 1 65 #define ARIZONA_FMT_I2S_MODE 2 66 #define ARIZONA_FMT_LEFT_JUSTIFIED_MODE 3 67 68 #define arizona_fll_err(_fll, fmt, ...) \ 69 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 70 #define arizona_fll_warn(_fll, fmt, ...) \ 71 dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 72 #define arizona_fll_dbg(_fll, fmt, ...) \ 73 dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 74 75 #define arizona_aif_err(_dai, fmt, ...) \ 76 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 77 #define arizona_aif_warn(_dai, fmt, ...) \ 78 dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 79 #define arizona_aif_dbg(_dai, fmt, ...) \ 80 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 81 82 static int arizona_spk_ev(struct snd_soc_dapm_widget *w, 83 struct snd_kcontrol *kcontrol, 84 int event) 85 { 86 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 87 struct arizona *arizona = dev_get_drvdata(codec->dev->parent); 88 int val; 89 90 switch (event) { 91 case SND_SOC_DAPM_POST_PMU: 92 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3); 93 if (val & ARIZONA_SPK_OVERHEAT_STS) { 94 dev_crit(arizona->dev, 95 "Speaker not enabled due to temperature\n"); 96 return -EBUSY; 97 } 98 99 regmap_update_bits_async(arizona->regmap, 100 ARIZONA_OUTPUT_ENABLES_1, 101 1 << w->shift, 1 << w->shift); 102 break; 103 case SND_SOC_DAPM_PRE_PMD: 104 regmap_update_bits_async(arizona->regmap, 105 ARIZONA_OUTPUT_ENABLES_1, 106 1 << w->shift, 0); 107 break; 108 default: 109 break; 110 } 111 112 return arizona_out_ev(w, kcontrol, event); 113 } 114 115 static irqreturn_t arizona_thermal_warn(int irq, void *data) 116 { 117 struct arizona *arizona = data; 118 unsigned int val; 119 int ret; 120 121 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3, 122 &val); 123 if (ret != 0) { 124 dev_err(arizona->dev, "Failed to read thermal status: %d\n", 125 ret); 126 } else if (val & ARIZONA_SPK_OVERHEAT_WARN_STS) { 127 dev_crit(arizona->dev, "Thermal warning\n"); 128 } 129 130 return IRQ_HANDLED; 131 } 132 133 static irqreturn_t arizona_thermal_shutdown(int irq, void *data) 134 { 135 struct arizona *arizona = data; 136 unsigned int val; 137 int ret; 138 139 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3, 140 &val); 141 if (ret != 0) { 142 dev_err(arizona->dev, "Failed to read thermal status: %d\n", 143 ret); 144 } else if (val & ARIZONA_SPK_OVERHEAT_STS) { 145 dev_crit(arizona->dev, "Thermal shutdown\n"); 146 ret = regmap_update_bits(arizona->regmap, 147 ARIZONA_OUTPUT_ENABLES_1, 148 ARIZONA_OUT4L_ENA | 149 ARIZONA_OUT4R_ENA, 0); 150 if (ret != 0) 151 dev_crit(arizona->dev, 152 "Failed to disable speaker outputs: %d\n", 153 ret); 154 } 155 156 return IRQ_HANDLED; 157 } 158 159 static const struct snd_soc_dapm_widget arizona_spkl = 160 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM, 161 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, 162 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 163 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD); 164 165 static const struct snd_soc_dapm_widget arizona_spkr = 166 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM, 167 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, 168 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 169 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD); 170 171 int arizona_init_spk(struct snd_soc_codec *codec) 172 { 173 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 174 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 175 struct arizona *arizona = priv->arizona; 176 int ret; 177 178 ret = snd_soc_dapm_new_controls(dapm, &arizona_spkl, 1); 179 if (ret != 0) 180 return ret; 181 182 switch (arizona->type) { 183 case WM8997: 184 case CS47L24: 185 case WM1831: 186 break; 187 default: 188 ret = snd_soc_dapm_new_controls(dapm, &arizona_spkr, 1); 189 if (ret != 0) 190 return ret; 191 break; 192 } 193 194 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN, 195 "Thermal warning", arizona_thermal_warn, 196 arizona); 197 if (ret != 0) 198 dev_err(arizona->dev, 199 "Failed to get thermal warning IRQ: %d\n", 200 ret); 201 202 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT, 203 "Thermal shutdown", arizona_thermal_shutdown, 204 arizona); 205 if (ret != 0) 206 dev_err(arizona->dev, 207 "Failed to get thermal shutdown IRQ: %d\n", 208 ret); 209 210 return 0; 211 } 212 EXPORT_SYMBOL_GPL(arizona_init_spk); 213 214 int arizona_free_spk(struct snd_soc_codec *codec) 215 { 216 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 217 struct arizona *arizona = priv->arizona; 218 219 arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN, arizona); 220 arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT, arizona); 221 222 return 0; 223 } 224 EXPORT_SYMBOL_GPL(arizona_free_spk); 225 226 static const struct snd_soc_dapm_route arizona_mono_routes[] = { 227 { "OUT1R", NULL, "OUT1L" }, 228 { "OUT2R", NULL, "OUT2L" }, 229 { "OUT3R", NULL, "OUT3L" }, 230 { "OUT4R", NULL, "OUT4L" }, 231 { "OUT5R", NULL, "OUT5L" }, 232 { "OUT6R", NULL, "OUT6L" }, 233 }; 234 235 int arizona_init_mono(struct snd_soc_codec *codec) 236 { 237 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 238 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 239 struct arizona *arizona = priv->arizona; 240 int i; 241 242 for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) { 243 if (arizona->pdata.out_mono[i]) 244 snd_soc_dapm_add_routes(dapm, 245 &arizona_mono_routes[i], 1); 246 } 247 248 return 0; 249 } 250 EXPORT_SYMBOL_GPL(arizona_init_mono); 251 252 int arizona_init_gpio(struct snd_soc_codec *codec) 253 { 254 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 255 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 256 struct arizona *arizona = priv->arizona; 257 int i; 258 259 switch (arizona->type) { 260 case WM5110: 261 case WM8280: 262 snd_soc_dapm_disable_pin(dapm, "DRC2 Signal Activity"); 263 break; 264 default: 265 break; 266 } 267 268 snd_soc_dapm_disable_pin(dapm, "DRC1 Signal Activity"); 269 270 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) { 271 switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) { 272 case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT: 273 snd_soc_dapm_enable_pin(dapm, "DRC1 Signal Activity"); 274 break; 275 case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT: 276 snd_soc_dapm_enable_pin(dapm, "DRC2 Signal Activity"); 277 break; 278 default: 279 break; 280 } 281 } 282 283 return 0; 284 } 285 EXPORT_SYMBOL_GPL(arizona_init_gpio); 286 287 int arizona_init_notifiers(struct snd_soc_codec *codec) 288 { 289 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 290 struct arizona *arizona = priv->arizona; 291 292 BLOCKING_INIT_NOTIFIER_HEAD(&arizona->notifier); 293 294 return 0; 295 } 296 EXPORT_SYMBOL_GPL(arizona_init_notifiers); 297 298 const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { 299 "None", 300 "Tone Generator 1", 301 "Tone Generator 2", 302 "Haptics", 303 "AEC", 304 "AEC2", 305 "Mic Mute Mixer", 306 "Noise Generator", 307 "IN1L", 308 "IN1R", 309 "IN2L", 310 "IN2R", 311 "IN3L", 312 "IN3R", 313 "IN4L", 314 "IN4R", 315 "AIF1RX1", 316 "AIF1RX2", 317 "AIF1RX3", 318 "AIF1RX4", 319 "AIF1RX5", 320 "AIF1RX6", 321 "AIF1RX7", 322 "AIF1RX8", 323 "AIF2RX1", 324 "AIF2RX2", 325 "AIF2RX3", 326 "AIF2RX4", 327 "AIF2RX5", 328 "AIF2RX6", 329 "AIF3RX1", 330 "AIF3RX2", 331 "SLIMRX1", 332 "SLIMRX2", 333 "SLIMRX3", 334 "SLIMRX4", 335 "SLIMRX5", 336 "SLIMRX6", 337 "SLIMRX7", 338 "SLIMRX8", 339 "EQ1", 340 "EQ2", 341 "EQ3", 342 "EQ4", 343 "DRC1L", 344 "DRC1R", 345 "DRC2L", 346 "DRC2R", 347 "LHPF1", 348 "LHPF2", 349 "LHPF3", 350 "LHPF4", 351 "DSP1.1", 352 "DSP1.2", 353 "DSP1.3", 354 "DSP1.4", 355 "DSP1.5", 356 "DSP1.6", 357 "DSP2.1", 358 "DSP2.2", 359 "DSP2.3", 360 "DSP2.4", 361 "DSP2.5", 362 "DSP2.6", 363 "DSP3.1", 364 "DSP3.2", 365 "DSP3.3", 366 "DSP3.4", 367 "DSP3.5", 368 "DSP3.6", 369 "DSP4.1", 370 "DSP4.2", 371 "DSP4.3", 372 "DSP4.4", 373 "DSP4.5", 374 "DSP4.6", 375 "ASRC1L", 376 "ASRC1R", 377 "ASRC2L", 378 "ASRC2R", 379 "ISRC1INT1", 380 "ISRC1INT2", 381 "ISRC1INT3", 382 "ISRC1INT4", 383 "ISRC1DEC1", 384 "ISRC1DEC2", 385 "ISRC1DEC3", 386 "ISRC1DEC4", 387 "ISRC2INT1", 388 "ISRC2INT2", 389 "ISRC2INT3", 390 "ISRC2INT4", 391 "ISRC2DEC1", 392 "ISRC2DEC2", 393 "ISRC2DEC3", 394 "ISRC2DEC4", 395 "ISRC3INT1", 396 "ISRC3INT2", 397 "ISRC3INT3", 398 "ISRC3INT4", 399 "ISRC3DEC1", 400 "ISRC3DEC2", 401 "ISRC3DEC3", 402 "ISRC3DEC4", 403 }; 404 EXPORT_SYMBOL_GPL(arizona_mixer_texts); 405 406 unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = { 407 0x00, /* None */ 408 0x04, /* Tone */ 409 0x05, 410 0x06, /* Haptics */ 411 0x08, /* AEC */ 412 0x09, /* AEC2 */ 413 0x0c, /* Noise mixer */ 414 0x0d, /* Comfort noise */ 415 0x10, /* IN1L */ 416 0x11, 417 0x12, 418 0x13, 419 0x14, 420 0x15, 421 0x16, 422 0x17, 423 0x20, /* AIF1RX1 */ 424 0x21, 425 0x22, 426 0x23, 427 0x24, 428 0x25, 429 0x26, 430 0x27, 431 0x28, /* AIF2RX1 */ 432 0x29, 433 0x2a, 434 0x2b, 435 0x2c, 436 0x2d, 437 0x30, /* AIF3RX1 */ 438 0x31, 439 0x38, /* SLIMRX1 */ 440 0x39, 441 0x3a, 442 0x3b, 443 0x3c, 444 0x3d, 445 0x3e, 446 0x3f, 447 0x50, /* EQ1 */ 448 0x51, 449 0x52, 450 0x53, 451 0x58, /* DRC1L */ 452 0x59, 453 0x5a, 454 0x5b, 455 0x60, /* LHPF1 */ 456 0x61, 457 0x62, 458 0x63, 459 0x68, /* DSP1.1 */ 460 0x69, 461 0x6a, 462 0x6b, 463 0x6c, 464 0x6d, 465 0x70, /* DSP2.1 */ 466 0x71, 467 0x72, 468 0x73, 469 0x74, 470 0x75, 471 0x78, /* DSP3.1 */ 472 0x79, 473 0x7a, 474 0x7b, 475 0x7c, 476 0x7d, 477 0x80, /* DSP4.1 */ 478 0x81, 479 0x82, 480 0x83, 481 0x84, 482 0x85, 483 0x90, /* ASRC1L */ 484 0x91, 485 0x92, 486 0x93, 487 0xa0, /* ISRC1INT1 */ 488 0xa1, 489 0xa2, 490 0xa3, 491 0xa4, /* ISRC1DEC1 */ 492 0xa5, 493 0xa6, 494 0xa7, 495 0xa8, /* ISRC2DEC1 */ 496 0xa9, 497 0xaa, 498 0xab, 499 0xac, /* ISRC2INT1 */ 500 0xad, 501 0xae, 502 0xaf, 503 0xb0, /* ISRC3DEC1 */ 504 0xb1, 505 0xb2, 506 0xb3, 507 0xb4, /* ISRC3INT1 */ 508 0xb5, 509 0xb6, 510 0xb7, 511 }; 512 EXPORT_SYMBOL_GPL(arizona_mixer_values); 513 514 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); 515 EXPORT_SYMBOL_GPL(arizona_mixer_tlv); 516 517 const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = { 518 "12kHz", "24kHz", "48kHz", "96kHz", "192kHz", 519 "11.025kHz", "22.05kHz", "44.1kHz", "88.2kHz", "176.4kHz", 520 "4kHz", "8kHz", "16kHz", "32kHz", 521 }; 522 EXPORT_SYMBOL_GPL(arizona_sample_rate_text); 523 524 const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = { 525 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 526 0x10, 0x11, 0x12, 0x13, 527 }; 528 EXPORT_SYMBOL_GPL(arizona_sample_rate_val); 529 530 const char *arizona_sample_rate_val_to_name(unsigned int rate_val) 531 { 532 int i; 533 534 for (i = 0; i < ARRAY_SIZE(arizona_sample_rate_val); ++i) { 535 if (arizona_sample_rate_val[i] == rate_val) 536 return arizona_sample_rate_text[i]; 537 } 538 539 return "Illegal"; 540 } 541 EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name); 542 543 const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = { 544 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate", 545 }; 546 EXPORT_SYMBOL_GPL(arizona_rate_text); 547 548 const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = { 549 0, 1, 2, 8, 550 }; 551 EXPORT_SYMBOL_GPL(arizona_rate_val); 552 553 554 const struct soc_enum arizona_isrc_fsh[] = { 555 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1, 556 ARIZONA_ISRC1_FSH_SHIFT, 0xf, 557 ARIZONA_RATE_ENUM_SIZE, 558 arizona_rate_text, arizona_rate_val), 559 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_1, 560 ARIZONA_ISRC2_FSH_SHIFT, 0xf, 561 ARIZONA_RATE_ENUM_SIZE, 562 arizona_rate_text, arizona_rate_val), 563 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_1, 564 ARIZONA_ISRC3_FSH_SHIFT, 0xf, 565 ARIZONA_RATE_ENUM_SIZE, 566 arizona_rate_text, arizona_rate_val), 567 }; 568 EXPORT_SYMBOL_GPL(arizona_isrc_fsh); 569 570 const struct soc_enum arizona_isrc_fsl[] = { 571 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2, 572 ARIZONA_ISRC1_FSL_SHIFT, 0xf, 573 ARIZONA_RATE_ENUM_SIZE, 574 arizona_rate_text, arizona_rate_val), 575 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2, 576 ARIZONA_ISRC2_FSL_SHIFT, 0xf, 577 ARIZONA_RATE_ENUM_SIZE, 578 arizona_rate_text, arizona_rate_val), 579 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2, 580 ARIZONA_ISRC3_FSL_SHIFT, 0xf, 581 ARIZONA_RATE_ENUM_SIZE, 582 arizona_rate_text, arizona_rate_val), 583 }; 584 EXPORT_SYMBOL_GPL(arizona_isrc_fsl); 585 586 const struct soc_enum arizona_asrc_rate1 = 587 SOC_VALUE_ENUM_SINGLE(ARIZONA_ASRC_RATE1, 588 ARIZONA_ASRC_RATE1_SHIFT, 0xf, 589 ARIZONA_RATE_ENUM_SIZE - 1, 590 arizona_rate_text, arizona_rate_val); 591 EXPORT_SYMBOL_GPL(arizona_asrc_rate1); 592 593 static const char * const arizona_vol_ramp_text[] = { 594 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", 595 "15ms/6dB", "30ms/6dB", 596 }; 597 598 SOC_ENUM_SINGLE_DECL(arizona_in_vd_ramp, 599 ARIZONA_INPUT_VOLUME_RAMP, 600 ARIZONA_IN_VD_RAMP_SHIFT, 601 arizona_vol_ramp_text); 602 EXPORT_SYMBOL_GPL(arizona_in_vd_ramp); 603 604 SOC_ENUM_SINGLE_DECL(arizona_in_vi_ramp, 605 ARIZONA_INPUT_VOLUME_RAMP, 606 ARIZONA_IN_VI_RAMP_SHIFT, 607 arizona_vol_ramp_text); 608 EXPORT_SYMBOL_GPL(arizona_in_vi_ramp); 609 610 SOC_ENUM_SINGLE_DECL(arizona_out_vd_ramp, 611 ARIZONA_OUTPUT_VOLUME_RAMP, 612 ARIZONA_OUT_VD_RAMP_SHIFT, 613 arizona_vol_ramp_text); 614 EXPORT_SYMBOL_GPL(arizona_out_vd_ramp); 615 616 SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp, 617 ARIZONA_OUTPUT_VOLUME_RAMP, 618 ARIZONA_OUT_VI_RAMP_SHIFT, 619 arizona_vol_ramp_text); 620 EXPORT_SYMBOL_GPL(arizona_out_vi_ramp); 621 622 static const char * const arizona_lhpf_mode_text[] = { 623 "Low-pass", "High-pass" 624 }; 625 626 SOC_ENUM_SINGLE_DECL(arizona_lhpf1_mode, 627 ARIZONA_HPLPF1_1, 628 ARIZONA_LHPF1_MODE_SHIFT, 629 arizona_lhpf_mode_text); 630 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode); 631 632 SOC_ENUM_SINGLE_DECL(arizona_lhpf2_mode, 633 ARIZONA_HPLPF2_1, 634 ARIZONA_LHPF2_MODE_SHIFT, 635 arizona_lhpf_mode_text); 636 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode); 637 638 SOC_ENUM_SINGLE_DECL(arizona_lhpf3_mode, 639 ARIZONA_HPLPF3_1, 640 ARIZONA_LHPF3_MODE_SHIFT, 641 arizona_lhpf_mode_text); 642 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode); 643 644 SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode, 645 ARIZONA_HPLPF4_1, 646 ARIZONA_LHPF4_MODE_SHIFT, 647 arizona_lhpf_mode_text); 648 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); 649 650 static const char * const arizona_ng_hold_text[] = { 651 "30ms", "120ms", "250ms", "500ms", 652 }; 653 654 SOC_ENUM_SINGLE_DECL(arizona_ng_hold, 655 ARIZONA_NOISE_GATE_CONTROL, 656 ARIZONA_NGATE_HOLD_SHIFT, 657 arizona_ng_hold_text); 658 EXPORT_SYMBOL_GPL(arizona_ng_hold); 659 660 static const char * const arizona_in_hpf_cut_text[] = { 661 "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz" 662 }; 663 664 SOC_ENUM_SINGLE_DECL(arizona_in_hpf_cut_enum, 665 ARIZONA_HPF_CONTROL, 666 ARIZONA_IN_HPF_CUT_SHIFT, 667 arizona_in_hpf_cut_text); 668 EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum); 669 670 static const char * const arizona_in_dmic_osr_text[] = { 671 "1.536MHz", "3.072MHz", "6.144MHz", "768kHz", 672 }; 673 674 const struct soc_enum arizona_in_dmic_osr[] = { 675 SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT, 676 ARRAY_SIZE(arizona_in_dmic_osr_text), 677 arizona_in_dmic_osr_text), 678 SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT, 679 ARRAY_SIZE(arizona_in_dmic_osr_text), 680 arizona_in_dmic_osr_text), 681 SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT, 682 ARRAY_SIZE(arizona_in_dmic_osr_text), 683 arizona_in_dmic_osr_text), 684 SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT, 685 ARRAY_SIZE(arizona_in_dmic_osr_text), 686 arizona_in_dmic_osr_text), 687 }; 688 EXPORT_SYMBOL_GPL(arizona_in_dmic_osr); 689 690 static const char * const arizona_anc_input_src_text[] = { 691 "None", "IN1", "IN2", "IN3", "IN4", 692 }; 693 694 static const char * const arizona_anc_channel_src_text[] = { 695 "None", "Left", "Right", "Combine", 696 }; 697 698 const struct soc_enum arizona_anc_input_src[] = { 699 SOC_ENUM_SINGLE(ARIZONA_ANC_SRC, 700 ARIZONA_IN_RXANCL_SEL_SHIFT, 701 ARRAY_SIZE(arizona_anc_input_src_text), 702 arizona_anc_input_src_text), 703 SOC_ENUM_SINGLE(ARIZONA_FCL_ADC_REFORMATTER_CONTROL, 704 ARIZONA_FCL_MIC_MODE_SEL, 705 ARRAY_SIZE(arizona_anc_channel_src_text), 706 arizona_anc_channel_src_text), 707 SOC_ENUM_SINGLE(ARIZONA_ANC_SRC, 708 ARIZONA_IN_RXANCR_SEL_SHIFT, 709 ARRAY_SIZE(arizona_anc_input_src_text), 710 arizona_anc_input_src_text), 711 SOC_ENUM_SINGLE(ARIZONA_FCR_ADC_REFORMATTER_CONTROL, 712 ARIZONA_FCR_MIC_MODE_SEL, 713 ARRAY_SIZE(arizona_anc_channel_src_text), 714 arizona_anc_channel_src_text), 715 }; 716 EXPORT_SYMBOL_GPL(arizona_anc_input_src); 717 718 static const char * const arizona_anc_ng_texts[] = { 719 "None", 720 "Internal", 721 "External", 722 }; 723 724 SOC_ENUM_SINGLE_DECL(arizona_anc_ng_enum, SND_SOC_NOPM, 0, 725 arizona_anc_ng_texts); 726 EXPORT_SYMBOL_GPL(arizona_anc_ng_enum); 727 728 static const char * const arizona_output_anc_src_text[] = { 729 "None", "RXANCL", "RXANCR", 730 }; 731 732 const struct soc_enum arizona_output_anc_src[] = { 733 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, 734 ARIZONA_OUT1L_ANC_SRC_SHIFT, 735 ARRAY_SIZE(arizona_output_anc_src_text), 736 arizona_output_anc_src_text), 737 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1R, 738 ARIZONA_OUT1R_ANC_SRC_SHIFT, 739 ARRAY_SIZE(arizona_output_anc_src_text), 740 arizona_output_anc_src_text), 741 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L, 742 ARIZONA_OUT2L_ANC_SRC_SHIFT, 743 ARRAY_SIZE(arizona_output_anc_src_text), 744 arizona_output_anc_src_text), 745 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2R, 746 ARIZONA_OUT2R_ANC_SRC_SHIFT, 747 ARRAY_SIZE(arizona_output_anc_src_text), 748 arizona_output_anc_src_text), 749 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, 750 ARIZONA_OUT3L_ANC_SRC_SHIFT, 751 ARRAY_SIZE(arizona_output_anc_src_text), 752 arizona_output_anc_src_text), 753 SOC_ENUM_SINGLE(ARIZONA_DAC_VOLUME_LIMIT_3R, 754 ARIZONA_OUT3R_ANC_SRC_SHIFT, 755 ARRAY_SIZE(arizona_output_anc_src_text), 756 arizona_output_anc_src_text), 757 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4L, 758 ARIZONA_OUT4L_ANC_SRC_SHIFT, 759 ARRAY_SIZE(arizona_output_anc_src_text), 760 arizona_output_anc_src_text), 761 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4R, 762 ARIZONA_OUT4R_ANC_SRC_SHIFT, 763 ARRAY_SIZE(arizona_output_anc_src_text), 764 arizona_output_anc_src_text), 765 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5L, 766 ARIZONA_OUT5L_ANC_SRC_SHIFT, 767 ARRAY_SIZE(arizona_output_anc_src_text), 768 arizona_output_anc_src_text), 769 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5R, 770 ARIZONA_OUT5R_ANC_SRC_SHIFT, 771 ARRAY_SIZE(arizona_output_anc_src_text), 772 arizona_output_anc_src_text), 773 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6L, 774 ARIZONA_OUT6L_ANC_SRC_SHIFT, 775 ARRAY_SIZE(arizona_output_anc_src_text), 776 arizona_output_anc_src_text), 777 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6R, 778 ARIZONA_OUT6R_ANC_SRC_SHIFT, 779 ARRAY_SIZE(arizona_output_anc_src_text), 780 arizona_output_anc_src_text), 781 }; 782 EXPORT_SYMBOL_GPL(arizona_output_anc_src); 783 784 const struct snd_kcontrol_new arizona_voice_trigger_switch[] = { 785 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0), 786 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 1, 1, 0), 787 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 2, 1, 0), 788 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 3, 1, 0), 789 }; 790 EXPORT_SYMBOL_GPL(arizona_voice_trigger_switch); 791 792 static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena) 793 { 794 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 795 unsigned int val; 796 int i; 797 798 if (ena) 799 val = ARIZONA_IN_VU; 800 else 801 val = 0; 802 803 for (i = 0; i < priv->num_inputs; i++) 804 snd_soc_update_bits(codec, 805 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4), 806 ARIZONA_IN_VU, val); 807 } 808 809 bool arizona_input_analog(struct snd_soc_codec *codec, int shift) 810 { 811 unsigned int reg = ARIZONA_IN1L_CONTROL + ((shift / 2) * 8); 812 unsigned int val = snd_soc_read(codec, reg); 813 814 return !(val & ARIZONA_IN1_MODE_MASK); 815 } 816 EXPORT_SYMBOL_GPL(arizona_input_analog); 817 818 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 819 int event) 820 { 821 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 822 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 823 unsigned int reg; 824 825 if (w->shift % 2) 826 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8); 827 else 828 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8); 829 830 switch (event) { 831 case SND_SOC_DAPM_PRE_PMU: 832 priv->in_pending++; 833 break; 834 case SND_SOC_DAPM_POST_PMU: 835 snd_soc_update_bits(codec, reg, ARIZONA_IN1L_MUTE, 0); 836 837 /* If this is the last input pending then allow VU */ 838 priv->in_pending--; 839 if (priv->in_pending == 0) { 840 msleep(1); 841 arizona_in_set_vu(codec, 1); 842 } 843 break; 844 case SND_SOC_DAPM_PRE_PMD: 845 snd_soc_update_bits(codec, reg, 846 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU, 847 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU); 848 break; 849 case SND_SOC_DAPM_POST_PMD: 850 /* Disable volume updates if no inputs are enabled */ 851 reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES); 852 if (reg == 0) 853 arizona_in_set_vu(codec, 0); 854 break; 855 default: 856 break; 857 } 858 859 return 0; 860 } 861 EXPORT_SYMBOL_GPL(arizona_in_ev); 862 863 int arizona_out_ev(struct snd_soc_dapm_widget *w, 864 struct snd_kcontrol *kcontrol, 865 int event) 866 { 867 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 868 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 869 struct arizona *arizona = priv->arizona; 870 871 switch (event) { 872 case SND_SOC_DAPM_PRE_PMU: 873 switch (w->shift) { 874 case ARIZONA_OUT1L_ENA_SHIFT: 875 case ARIZONA_OUT1R_ENA_SHIFT: 876 case ARIZONA_OUT2L_ENA_SHIFT: 877 case ARIZONA_OUT2R_ENA_SHIFT: 878 case ARIZONA_OUT3L_ENA_SHIFT: 879 case ARIZONA_OUT3R_ENA_SHIFT: 880 priv->out_up_pending++; 881 priv->out_up_delay += 17; 882 break; 883 case ARIZONA_OUT4L_ENA_SHIFT: 884 case ARIZONA_OUT4R_ENA_SHIFT: 885 priv->out_up_pending++; 886 switch (arizona->type) { 887 case WM5102: 888 case WM8997: 889 break; 890 default: 891 priv->out_up_delay += 10; 892 break; 893 } 894 break; 895 default: 896 break; 897 } 898 break; 899 case SND_SOC_DAPM_POST_PMU: 900 switch (w->shift) { 901 case ARIZONA_OUT1L_ENA_SHIFT: 902 case ARIZONA_OUT1R_ENA_SHIFT: 903 case ARIZONA_OUT2L_ENA_SHIFT: 904 case ARIZONA_OUT2R_ENA_SHIFT: 905 case ARIZONA_OUT3L_ENA_SHIFT: 906 case ARIZONA_OUT3R_ENA_SHIFT: 907 case ARIZONA_OUT4L_ENA_SHIFT: 908 case ARIZONA_OUT4R_ENA_SHIFT: 909 priv->out_up_pending--; 910 if (!priv->out_up_pending && priv->out_up_delay) { 911 dev_dbg(codec->dev, "Power up delay: %d\n", 912 priv->out_up_delay); 913 msleep(priv->out_up_delay); 914 priv->out_up_delay = 0; 915 } 916 break; 917 918 default: 919 break; 920 } 921 break; 922 case SND_SOC_DAPM_PRE_PMD: 923 switch (w->shift) { 924 case ARIZONA_OUT1L_ENA_SHIFT: 925 case ARIZONA_OUT1R_ENA_SHIFT: 926 case ARIZONA_OUT2L_ENA_SHIFT: 927 case ARIZONA_OUT2R_ENA_SHIFT: 928 case ARIZONA_OUT3L_ENA_SHIFT: 929 case ARIZONA_OUT3R_ENA_SHIFT: 930 priv->out_down_pending++; 931 priv->out_down_delay++; 932 break; 933 case ARIZONA_OUT4L_ENA_SHIFT: 934 case ARIZONA_OUT4R_ENA_SHIFT: 935 priv->out_down_pending++; 936 switch (arizona->type) { 937 case WM5102: 938 case WM8997: 939 break; 940 case WM8998: 941 case WM1814: 942 priv->out_down_delay += 5; 943 break; 944 default: 945 priv->out_down_delay++; 946 break; 947 } 948 default: 949 break; 950 } 951 break; 952 case SND_SOC_DAPM_POST_PMD: 953 switch (w->shift) { 954 case ARIZONA_OUT1L_ENA_SHIFT: 955 case ARIZONA_OUT1R_ENA_SHIFT: 956 case ARIZONA_OUT2L_ENA_SHIFT: 957 case ARIZONA_OUT2R_ENA_SHIFT: 958 case ARIZONA_OUT3L_ENA_SHIFT: 959 case ARIZONA_OUT3R_ENA_SHIFT: 960 case ARIZONA_OUT4L_ENA_SHIFT: 961 case ARIZONA_OUT4R_ENA_SHIFT: 962 priv->out_down_pending--; 963 if (!priv->out_down_pending && priv->out_down_delay) { 964 dev_dbg(codec->dev, "Power down delay: %d\n", 965 priv->out_down_delay); 966 msleep(priv->out_down_delay); 967 priv->out_down_delay = 0; 968 } 969 break; 970 default: 971 break; 972 } 973 break; 974 default: 975 break; 976 } 977 978 return 0; 979 } 980 EXPORT_SYMBOL_GPL(arizona_out_ev); 981 982 int arizona_hp_ev(struct snd_soc_dapm_widget *w, 983 struct snd_kcontrol *kcontrol, 984 int event) 985 { 986 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 987 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 988 struct arizona *arizona = priv->arizona; 989 unsigned int mask = 1 << w->shift; 990 unsigned int val; 991 992 switch (event) { 993 case SND_SOC_DAPM_POST_PMU: 994 val = mask; 995 break; 996 case SND_SOC_DAPM_PRE_PMD: 997 val = 0; 998 break; 999 case SND_SOC_DAPM_PRE_PMU: 1000 case SND_SOC_DAPM_POST_PMD: 1001 return arizona_out_ev(w, kcontrol, event); 1002 default: 1003 return -EINVAL; 1004 } 1005 1006 /* Store the desired state for the HP outputs */ 1007 priv->arizona->hp_ena &= ~mask; 1008 priv->arizona->hp_ena |= val; 1009 1010 /* Force off if HPDET clamp is active */ 1011 if (priv->arizona->hpdet_clamp) 1012 val = 0; 1013 1014 regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, 1015 mask, val); 1016 1017 return arizona_out_ev(w, kcontrol, event); 1018 } 1019 EXPORT_SYMBOL_GPL(arizona_hp_ev); 1020 1021 static int arizona_dvfs_enable(struct snd_soc_codec *codec) 1022 { 1023 const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1024 struct arizona *arizona = priv->arizona; 1025 int ret; 1026 1027 ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000); 1028 if (ret) { 1029 dev_err(codec->dev, "Failed to boost DCVDD: %d\n", ret); 1030 return ret; 1031 } 1032 1033 ret = regmap_update_bits(arizona->regmap, 1034 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1, 1035 ARIZONA_SUBSYS_MAX_FREQ, 1036 ARIZONA_SUBSYS_MAX_FREQ); 1037 if (ret) { 1038 dev_err(codec->dev, "Failed to enable subsys max: %d\n", ret); 1039 regulator_set_voltage(arizona->dcvdd, 1200000, 1800000); 1040 return ret; 1041 } 1042 1043 return 0; 1044 } 1045 1046 static int arizona_dvfs_disable(struct snd_soc_codec *codec) 1047 { 1048 const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1049 struct arizona *arizona = priv->arizona; 1050 int ret; 1051 1052 ret = regmap_update_bits(arizona->regmap, 1053 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1, 1054 ARIZONA_SUBSYS_MAX_FREQ, 0); 1055 if (ret) { 1056 dev_err(codec->dev, "Failed to disable subsys max: %d\n", ret); 1057 return ret; 1058 } 1059 1060 ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000); 1061 if (ret) { 1062 dev_err(codec->dev, "Failed to unboost DCVDD: %d\n", ret); 1063 return ret; 1064 } 1065 1066 return 0; 1067 } 1068 1069 int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags) 1070 { 1071 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1072 int ret = 0; 1073 1074 mutex_lock(&priv->dvfs_lock); 1075 1076 if (!priv->dvfs_cached && !priv->dvfs_reqs) { 1077 ret = arizona_dvfs_enable(codec); 1078 if (ret) 1079 goto err; 1080 } 1081 1082 priv->dvfs_reqs |= flags; 1083 err: 1084 mutex_unlock(&priv->dvfs_lock); 1085 return ret; 1086 } 1087 EXPORT_SYMBOL_GPL(arizona_dvfs_up); 1088 1089 int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags) 1090 { 1091 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1092 unsigned int old_reqs; 1093 int ret = 0; 1094 1095 mutex_lock(&priv->dvfs_lock); 1096 1097 old_reqs = priv->dvfs_reqs; 1098 priv->dvfs_reqs &= ~flags; 1099 1100 if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs) 1101 ret = arizona_dvfs_disable(codec); 1102 1103 mutex_unlock(&priv->dvfs_lock); 1104 return ret; 1105 } 1106 EXPORT_SYMBOL_GPL(arizona_dvfs_down); 1107 1108 int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w, 1109 struct snd_kcontrol *kcontrol, int event) 1110 { 1111 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 1112 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1113 int ret = 0; 1114 1115 mutex_lock(&priv->dvfs_lock); 1116 1117 switch (event) { 1118 case SND_SOC_DAPM_POST_PMU: 1119 if (priv->dvfs_reqs) 1120 ret = arizona_dvfs_enable(codec); 1121 1122 priv->dvfs_cached = false; 1123 break; 1124 case SND_SOC_DAPM_PRE_PMD: 1125 /* We must ensure DVFS is disabled before the codec goes into 1126 * suspend so that we are never in an illegal state of DVFS 1127 * enabled without enough DCVDD 1128 */ 1129 priv->dvfs_cached = true; 1130 1131 if (priv->dvfs_reqs) 1132 ret = arizona_dvfs_disable(codec); 1133 break; 1134 default: 1135 break; 1136 } 1137 1138 mutex_unlock(&priv->dvfs_lock); 1139 return ret; 1140 } 1141 EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev); 1142 1143 void arizona_init_dvfs(struct arizona_priv *priv) 1144 { 1145 mutex_init(&priv->dvfs_lock); 1146 } 1147 EXPORT_SYMBOL_GPL(arizona_init_dvfs); 1148 1149 int arizona_anc_ev(struct snd_soc_dapm_widget *w, 1150 struct snd_kcontrol *kcontrol, 1151 int event) 1152 { 1153 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 1154 unsigned int val; 1155 1156 switch (event) { 1157 case SND_SOC_DAPM_POST_PMU: 1158 val = 1 << w->shift; 1159 break; 1160 case SND_SOC_DAPM_PRE_PMD: 1161 val = 1 << (w->shift + 1); 1162 break; 1163 default: 1164 return 0; 1165 } 1166 1167 snd_soc_write(codec, ARIZONA_CLOCK_CONTROL, val); 1168 1169 return 0; 1170 } 1171 EXPORT_SYMBOL_GPL(arizona_anc_ev); 1172 1173 static unsigned int arizona_opclk_ref_48k_rates[] = { 1174 6144000, 1175 12288000, 1176 24576000, 1177 49152000, 1178 }; 1179 1180 static unsigned int arizona_opclk_ref_44k1_rates[] = { 1181 5644800, 1182 11289600, 1183 22579200, 1184 45158400, 1185 }; 1186 1187 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk, 1188 unsigned int freq) 1189 { 1190 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1191 unsigned int reg; 1192 unsigned int *rates; 1193 int ref, div, refclk; 1194 1195 switch (clk) { 1196 case ARIZONA_CLK_OPCLK: 1197 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK; 1198 refclk = priv->sysclk; 1199 break; 1200 case ARIZONA_CLK_ASYNC_OPCLK: 1201 reg = ARIZONA_OUTPUT_ASYNC_CLOCK; 1202 refclk = priv->asyncclk; 1203 break; 1204 default: 1205 return -EINVAL; 1206 } 1207 1208 if (refclk % 8000) 1209 rates = arizona_opclk_ref_44k1_rates; 1210 else 1211 rates = arizona_opclk_ref_48k_rates; 1212 1213 for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) && 1214 rates[ref] <= refclk; ref++) { 1215 div = 1; 1216 while (rates[ref] / div >= freq && div < 32) { 1217 if (rates[ref] / div == freq) { 1218 dev_dbg(codec->dev, "Configured %dHz OPCLK\n", 1219 freq); 1220 snd_soc_update_bits(codec, reg, 1221 ARIZONA_OPCLK_DIV_MASK | 1222 ARIZONA_OPCLK_SEL_MASK, 1223 (div << 1224 ARIZONA_OPCLK_DIV_SHIFT) | 1225 ref); 1226 return 0; 1227 } 1228 div++; 1229 } 1230 } 1231 1232 dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq); 1233 return -EINVAL; 1234 } 1235 1236 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, 1237 int source, unsigned int freq, int dir) 1238 { 1239 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1240 struct arizona *arizona = priv->arizona; 1241 char *name; 1242 unsigned int reg; 1243 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK; 1244 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT; 1245 int *clk; 1246 1247 switch (clk_id) { 1248 case ARIZONA_CLK_SYSCLK: 1249 name = "SYSCLK"; 1250 reg = ARIZONA_SYSTEM_CLOCK_1; 1251 clk = &priv->sysclk; 1252 mask |= ARIZONA_SYSCLK_FRAC; 1253 break; 1254 case ARIZONA_CLK_ASYNCCLK: 1255 name = "ASYNCCLK"; 1256 reg = ARIZONA_ASYNC_CLOCK_1; 1257 clk = &priv->asyncclk; 1258 break; 1259 case ARIZONA_CLK_OPCLK: 1260 case ARIZONA_CLK_ASYNC_OPCLK: 1261 return arizona_set_opclk(codec, clk_id, freq); 1262 default: 1263 return -EINVAL; 1264 } 1265 1266 switch (freq) { 1267 case 5644800: 1268 case 6144000: 1269 break; 1270 case 11289600: 1271 case 12288000: 1272 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; 1273 break; 1274 case 22579200: 1275 case 24576000: 1276 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; 1277 break; 1278 case 45158400: 1279 case 49152000: 1280 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; 1281 break; 1282 case 67737600: 1283 case 73728000: 1284 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; 1285 break; 1286 case 90316800: 1287 case 98304000: 1288 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; 1289 break; 1290 case 135475200: 1291 case 147456000: 1292 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; 1293 break; 1294 case 0: 1295 dev_dbg(arizona->dev, "%s cleared\n", name); 1296 *clk = freq; 1297 return 0; 1298 default: 1299 return -EINVAL; 1300 } 1301 1302 *clk = freq; 1303 1304 if (freq % 6144000) 1305 val |= ARIZONA_SYSCLK_FRAC; 1306 1307 dev_dbg(arizona->dev, "%s set to %uHz", name, freq); 1308 1309 return regmap_update_bits(arizona->regmap, reg, mask, val); 1310 } 1311 EXPORT_SYMBOL_GPL(arizona_set_sysclk); 1312 1313 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 1314 { 1315 struct snd_soc_codec *codec = dai->codec; 1316 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1317 struct arizona *arizona = priv->arizona; 1318 int lrclk, bclk, mode, base; 1319 1320 base = dai->driver->base; 1321 1322 lrclk = 0; 1323 bclk = 0; 1324 1325 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1326 case SND_SOC_DAIFMT_DSP_A: 1327 mode = ARIZONA_FMT_DSP_MODE_A; 1328 break; 1329 case SND_SOC_DAIFMT_DSP_B: 1330 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) 1331 != SND_SOC_DAIFMT_CBM_CFM) { 1332 arizona_aif_err(dai, "DSP_B not valid in slave mode\n"); 1333 return -EINVAL; 1334 } 1335 mode = ARIZONA_FMT_DSP_MODE_B; 1336 break; 1337 case SND_SOC_DAIFMT_I2S: 1338 mode = ARIZONA_FMT_I2S_MODE; 1339 break; 1340 case SND_SOC_DAIFMT_LEFT_J: 1341 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) 1342 != SND_SOC_DAIFMT_CBM_CFM) { 1343 arizona_aif_err(dai, "LEFT_J not valid in slave mode\n"); 1344 return -EINVAL; 1345 } 1346 mode = ARIZONA_FMT_LEFT_JUSTIFIED_MODE; 1347 break; 1348 default: 1349 arizona_aif_err(dai, "Unsupported DAI format %d\n", 1350 fmt & SND_SOC_DAIFMT_FORMAT_MASK); 1351 return -EINVAL; 1352 } 1353 1354 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1355 case SND_SOC_DAIFMT_CBS_CFS: 1356 break; 1357 case SND_SOC_DAIFMT_CBS_CFM: 1358 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR; 1359 break; 1360 case SND_SOC_DAIFMT_CBM_CFS: 1361 bclk |= ARIZONA_AIF1_BCLK_MSTR; 1362 break; 1363 case SND_SOC_DAIFMT_CBM_CFM: 1364 bclk |= ARIZONA_AIF1_BCLK_MSTR; 1365 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR; 1366 break; 1367 default: 1368 arizona_aif_err(dai, "Unsupported master mode %d\n", 1369 fmt & SND_SOC_DAIFMT_MASTER_MASK); 1370 return -EINVAL; 1371 } 1372 1373 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 1374 case SND_SOC_DAIFMT_NB_NF: 1375 break; 1376 case SND_SOC_DAIFMT_IB_IF: 1377 bclk |= ARIZONA_AIF1_BCLK_INV; 1378 lrclk |= ARIZONA_AIF1TX_LRCLK_INV; 1379 break; 1380 case SND_SOC_DAIFMT_IB_NF: 1381 bclk |= ARIZONA_AIF1_BCLK_INV; 1382 break; 1383 case SND_SOC_DAIFMT_NB_IF: 1384 lrclk |= ARIZONA_AIF1TX_LRCLK_INV; 1385 break; 1386 default: 1387 return -EINVAL; 1388 } 1389 1390 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL, 1391 ARIZONA_AIF1_BCLK_INV | 1392 ARIZONA_AIF1_BCLK_MSTR, 1393 bclk); 1394 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL, 1395 ARIZONA_AIF1TX_LRCLK_INV | 1396 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk); 1397 regmap_update_bits_async(arizona->regmap, 1398 base + ARIZONA_AIF_RX_PIN_CTRL, 1399 ARIZONA_AIF1RX_LRCLK_INV | 1400 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk); 1401 regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT, 1402 ARIZONA_AIF1_FMT_MASK, mode); 1403 1404 return 0; 1405 } 1406 1407 static const int arizona_48k_bclk_rates[] = { 1408 -1, 1409 48000, 1410 64000, 1411 96000, 1412 128000, 1413 192000, 1414 256000, 1415 384000, 1416 512000, 1417 768000, 1418 1024000, 1419 1536000, 1420 2048000, 1421 3072000, 1422 4096000, 1423 6144000, 1424 8192000, 1425 12288000, 1426 24576000, 1427 }; 1428 1429 static const int arizona_44k1_bclk_rates[] = { 1430 -1, 1431 44100, 1432 58800, 1433 88200, 1434 117600, 1435 177640, 1436 235200, 1437 352800, 1438 470400, 1439 705600, 1440 940800, 1441 1411200, 1442 1881600, 1443 2822400, 1444 3763200, 1445 5644800, 1446 7526400, 1447 11289600, 1448 22579200, 1449 }; 1450 1451 static const unsigned int arizona_sr_vals[] = { 1452 0, 1453 12000, 1454 24000, 1455 48000, 1456 96000, 1457 192000, 1458 384000, 1459 768000, 1460 0, 1461 11025, 1462 22050, 1463 44100, 1464 88200, 1465 176400, 1466 352800, 1467 705600, 1468 4000, 1469 8000, 1470 16000, 1471 32000, 1472 64000, 1473 128000, 1474 256000, 1475 512000, 1476 }; 1477 1478 #define ARIZONA_48K_RATE_MASK 0x0F003E 1479 #define ARIZONA_44K1_RATE_MASK 0x003E00 1480 #define ARIZONA_RATE_MASK (ARIZONA_48K_RATE_MASK | ARIZONA_44K1_RATE_MASK) 1481 1482 static const struct snd_pcm_hw_constraint_list arizona_constraint = { 1483 .count = ARRAY_SIZE(arizona_sr_vals), 1484 .list = arizona_sr_vals, 1485 }; 1486 1487 static int arizona_startup(struct snd_pcm_substream *substream, 1488 struct snd_soc_dai *dai) 1489 { 1490 struct snd_soc_codec *codec = dai->codec; 1491 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1492 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; 1493 unsigned int base_rate; 1494 1495 if (!substream->runtime) 1496 return 0; 1497 1498 switch (dai_priv->clk) { 1499 case ARIZONA_CLK_SYSCLK: 1500 base_rate = priv->sysclk; 1501 break; 1502 case ARIZONA_CLK_ASYNCCLK: 1503 base_rate = priv->asyncclk; 1504 break; 1505 default: 1506 return 0; 1507 } 1508 1509 if (base_rate == 0) 1510 dai_priv->constraint.mask = ARIZONA_RATE_MASK; 1511 else if (base_rate % 8000) 1512 dai_priv->constraint.mask = ARIZONA_44K1_RATE_MASK; 1513 else 1514 dai_priv->constraint.mask = ARIZONA_48K_RATE_MASK; 1515 1516 return snd_pcm_hw_constraint_list(substream->runtime, 0, 1517 SNDRV_PCM_HW_PARAM_RATE, 1518 &dai_priv->constraint); 1519 } 1520 1521 static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec, 1522 unsigned int rate) 1523 { 1524 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1525 struct arizona *arizona = priv->arizona; 1526 struct reg_sequence dac_comp[] = { 1527 { 0x80, 0x3 }, 1528 { ARIZONA_DAC_COMP_1, 0 }, 1529 { ARIZONA_DAC_COMP_2, 0 }, 1530 { 0x80, 0x0 }, 1531 }; 1532 1533 mutex_lock(&arizona->dac_comp_lock); 1534 1535 dac_comp[1].def = arizona->dac_comp_coeff; 1536 if (rate >= 176400) 1537 dac_comp[2].def = arizona->dac_comp_enabled; 1538 1539 mutex_unlock(&arizona->dac_comp_lock); 1540 1541 regmap_multi_reg_write(arizona->regmap, 1542 dac_comp, 1543 ARRAY_SIZE(dac_comp)); 1544 } 1545 1546 static int arizona_hw_params_rate(struct snd_pcm_substream *substream, 1547 struct snd_pcm_hw_params *params, 1548 struct snd_soc_dai *dai) 1549 { 1550 struct snd_soc_codec *codec = dai->codec; 1551 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1552 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; 1553 int base = dai->driver->base; 1554 int i, sr_val, ret; 1555 1556 /* 1557 * We will need to be more flexible than this in future, 1558 * currently we use a single sample rate for SYSCLK. 1559 */ 1560 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++) 1561 if (arizona_sr_vals[i] == params_rate(params)) 1562 break; 1563 if (i == ARRAY_SIZE(arizona_sr_vals)) { 1564 arizona_aif_err(dai, "Unsupported sample rate %dHz\n", 1565 params_rate(params)); 1566 return -EINVAL; 1567 } 1568 sr_val = i; 1569 1570 switch (priv->arizona->type) { 1571 case WM5102: 1572 case WM8997: 1573 if (arizona_sr_vals[sr_val] >= 88200) 1574 ret = arizona_dvfs_up(codec, ARIZONA_DVFS_SR1_RQ); 1575 else 1576 ret = arizona_dvfs_down(codec, ARIZONA_DVFS_SR1_RQ); 1577 1578 if (ret) { 1579 arizona_aif_err(dai, "Failed to change DVFS %d\n", ret); 1580 return ret; 1581 } 1582 break; 1583 default: 1584 break; 1585 } 1586 1587 switch (dai_priv->clk) { 1588 case ARIZONA_CLK_SYSCLK: 1589 switch (priv->arizona->type) { 1590 case WM5102: 1591 arizona_wm5102_set_dac_comp(codec, 1592 params_rate(params)); 1593 break; 1594 default: 1595 break; 1596 } 1597 1598 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1, 1599 ARIZONA_SAMPLE_RATE_1_MASK, sr_val); 1600 if (base) 1601 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, 1602 ARIZONA_AIF1_RATE_MASK, 0); 1603 break; 1604 case ARIZONA_CLK_ASYNCCLK: 1605 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1, 1606 ARIZONA_ASYNC_SAMPLE_RATE_1_MASK, sr_val); 1607 if (base) 1608 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, 1609 ARIZONA_AIF1_RATE_MASK, 1610 8 << ARIZONA_AIF1_RATE_SHIFT); 1611 break; 1612 default: 1613 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk); 1614 return -EINVAL; 1615 } 1616 1617 return 0; 1618 } 1619 1620 static bool arizona_aif_cfg_changed(struct snd_soc_codec *codec, 1621 int base, int bclk, int lrclk, int frame) 1622 { 1623 int val; 1624 1625 val = snd_soc_read(codec, base + ARIZONA_AIF_BCLK_CTRL); 1626 if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK)) 1627 return true; 1628 1629 val = snd_soc_read(codec, base + ARIZONA_AIF_TX_BCLK_RATE); 1630 if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK)) 1631 return true; 1632 1633 val = snd_soc_read(codec, base + ARIZONA_AIF_FRAME_CTRL_1); 1634 if (frame != (val & (ARIZONA_AIF1TX_WL_MASK | 1635 ARIZONA_AIF1TX_SLOT_LEN_MASK))) 1636 return true; 1637 1638 return false; 1639 } 1640 1641 static int arizona_hw_params(struct snd_pcm_substream *substream, 1642 struct snd_pcm_hw_params *params, 1643 struct snd_soc_dai *dai) 1644 { 1645 struct snd_soc_codec *codec = dai->codec; 1646 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1647 struct arizona *arizona = priv->arizona; 1648 int base = dai->driver->base; 1649 const int *rates; 1650 int i, ret, val; 1651 int channels = params_channels(params); 1652 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; 1653 int tdm_width = arizona->tdm_width[dai->id - 1]; 1654 int tdm_slots = arizona->tdm_slots[dai->id - 1]; 1655 int bclk, lrclk, wl, frame, bclk_target; 1656 bool reconfig; 1657 unsigned int aif_tx_state, aif_rx_state; 1658 1659 if (params_rate(params) % 4000) 1660 rates = &arizona_44k1_bclk_rates[0]; 1661 else 1662 rates = &arizona_48k_bclk_rates[0]; 1663 1664 wl = params_width(params); 1665 1666 if (tdm_slots) { 1667 arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n", 1668 tdm_slots, tdm_width); 1669 bclk_target = tdm_slots * tdm_width * params_rate(params); 1670 channels = tdm_slots; 1671 } else { 1672 bclk_target = snd_soc_params_to_bclk(params); 1673 tdm_width = wl; 1674 } 1675 1676 if (chan_limit && chan_limit < channels) { 1677 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit); 1678 bclk_target /= channels; 1679 bclk_target *= chan_limit; 1680 } 1681 1682 /* Force multiple of 2 channels for I2S mode */ 1683 val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT); 1684 val &= ARIZONA_AIF1_FMT_MASK; 1685 if ((channels & 1) && (val == ARIZONA_FMT_I2S_MODE)) { 1686 arizona_aif_dbg(dai, "Forcing stereo mode\n"); 1687 bclk_target /= channels; 1688 bclk_target *= channels + 1; 1689 } 1690 1691 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { 1692 if (rates[i] >= bclk_target && 1693 rates[i] % params_rate(params) == 0) { 1694 bclk = i; 1695 break; 1696 } 1697 } 1698 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) { 1699 arizona_aif_err(dai, "Unsupported sample rate %dHz\n", 1700 params_rate(params)); 1701 return -EINVAL; 1702 } 1703 1704 lrclk = rates[bclk] / params_rate(params); 1705 1706 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n", 1707 rates[bclk], rates[bclk] / lrclk); 1708 1709 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width; 1710 1711 reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame); 1712 1713 if (reconfig) { 1714 /* Save AIF TX/RX state */ 1715 aif_tx_state = snd_soc_read(codec, 1716 base + ARIZONA_AIF_TX_ENABLES); 1717 aif_rx_state = snd_soc_read(codec, 1718 base + ARIZONA_AIF_RX_ENABLES); 1719 /* Disable AIF TX/RX before reconfiguring it */ 1720 regmap_update_bits_async(arizona->regmap, 1721 base + ARIZONA_AIF_TX_ENABLES, 0xff, 0x0); 1722 regmap_update_bits(arizona->regmap, 1723 base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0); 1724 } 1725 1726 ret = arizona_hw_params_rate(substream, params, dai); 1727 if (ret != 0) 1728 goto restore_aif; 1729 1730 if (reconfig) { 1731 regmap_update_bits_async(arizona->regmap, 1732 base + ARIZONA_AIF_BCLK_CTRL, 1733 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk); 1734 regmap_update_bits_async(arizona->regmap, 1735 base + ARIZONA_AIF_TX_BCLK_RATE, 1736 ARIZONA_AIF1TX_BCPF_MASK, lrclk); 1737 regmap_update_bits_async(arizona->regmap, 1738 base + ARIZONA_AIF_RX_BCLK_RATE, 1739 ARIZONA_AIF1RX_BCPF_MASK, lrclk); 1740 regmap_update_bits_async(arizona->regmap, 1741 base + ARIZONA_AIF_FRAME_CTRL_1, 1742 ARIZONA_AIF1TX_WL_MASK | 1743 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame); 1744 regmap_update_bits(arizona->regmap, 1745 base + ARIZONA_AIF_FRAME_CTRL_2, 1746 ARIZONA_AIF1RX_WL_MASK | 1747 ARIZONA_AIF1RX_SLOT_LEN_MASK, frame); 1748 } 1749 1750 restore_aif: 1751 if (reconfig) { 1752 /* Restore AIF TX/RX state */ 1753 regmap_update_bits_async(arizona->regmap, 1754 base + ARIZONA_AIF_TX_ENABLES, 1755 0xff, aif_tx_state); 1756 regmap_update_bits(arizona->regmap, 1757 base + ARIZONA_AIF_RX_ENABLES, 1758 0xff, aif_rx_state); 1759 } 1760 return ret; 1761 } 1762 1763 static const char *arizona_dai_clk_str(int clk_id) 1764 { 1765 switch (clk_id) { 1766 case ARIZONA_CLK_SYSCLK: 1767 return "SYSCLK"; 1768 case ARIZONA_CLK_ASYNCCLK: 1769 return "ASYNCCLK"; 1770 default: 1771 return "Unknown clock"; 1772 } 1773 } 1774 1775 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, 1776 int clk_id, unsigned int freq, int dir) 1777 { 1778 struct snd_soc_codec *codec = dai->codec; 1779 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 1780 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1781 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; 1782 struct snd_soc_dapm_route routes[2]; 1783 1784 switch (clk_id) { 1785 case ARIZONA_CLK_SYSCLK: 1786 case ARIZONA_CLK_ASYNCCLK: 1787 break; 1788 default: 1789 return -EINVAL; 1790 } 1791 1792 if (clk_id == dai_priv->clk) 1793 return 0; 1794 1795 if (dai->active) { 1796 dev_err(codec->dev, "Can't change clock on active DAI %d\n", 1797 dai->id); 1798 return -EBUSY; 1799 } 1800 1801 dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1, 1802 arizona_dai_clk_str(clk_id)); 1803 1804 memset(&routes, 0, sizeof(routes)); 1805 routes[0].sink = dai->driver->capture.stream_name; 1806 routes[1].sink = dai->driver->playback.stream_name; 1807 1808 routes[0].source = arizona_dai_clk_str(dai_priv->clk); 1809 routes[1].source = arizona_dai_clk_str(dai_priv->clk); 1810 snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes)); 1811 1812 routes[0].source = arizona_dai_clk_str(clk_id); 1813 routes[1].source = arizona_dai_clk_str(clk_id); 1814 snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes)); 1815 1816 dai_priv->clk = clk_id; 1817 1818 return snd_soc_dapm_sync(dapm); 1819 } 1820 1821 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate) 1822 { 1823 struct snd_soc_codec *codec = dai->codec; 1824 int base = dai->driver->base; 1825 unsigned int reg; 1826 1827 if (tristate) 1828 reg = ARIZONA_AIF1_TRI; 1829 else 1830 reg = 0; 1831 1832 return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, 1833 ARIZONA_AIF1_TRI, reg); 1834 } 1835 1836 static void arizona_set_channels_to_mask(struct snd_soc_dai *dai, 1837 unsigned int base, 1838 int channels, unsigned int mask) 1839 { 1840 struct snd_soc_codec *codec = dai->codec; 1841 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1842 struct arizona *arizona = priv->arizona; 1843 int slot, i; 1844 1845 for (i = 0; i < channels; ++i) { 1846 slot = ffs(mask) - 1; 1847 if (slot < 0) 1848 return; 1849 1850 regmap_write(arizona->regmap, base + i, slot); 1851 1852 mask &= ~(1 << slot); 1853 } 1854 1855 if (mask) 1856 arizona_aif_warn(dai, "Too many channels in TDM mask\n"); 1857 } 1858 1859 static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 1860 unsigned int rx_mask, int slots, int slot_width) 1861 { 1862 struct snd_soc_codec *codec = dai->codec; 1863 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1864 struct arizona *arizona = priv->arizona; 1865 int base = dai->driver->base; 1866 int rx_max_chan = dai->driver->playback.channels_max; 1867 int tx_max_chan = dai->driver->capture.channels_max; 1868 1869 /* Only support TDM for the physical AIFs */ 1870 if (dai->id > ARIZONA_MAX_AIF) 1871 return -ENOTSUPP; 1872 1873 if (slots == 0) { 1874 tx_mask = (1 << tx_max_chan) - 1; 1875 rx_mask = (1 << rx_max_chan) - 1; 1876 } 1877 1878 arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_3, 1879 tx_max_chan, tx_mask); 1880 arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_11, 1881 rx_max_chan, rx_mask); 1882 1883 arizona->tdm_width[dai->id - 1] = slot_width; 1884 arizona->tdm_slots[dai->id - 1] = slots; 1885 1886 return 0; 1887 } 1888 1889 const struct snd_soc_dai_ops arizona_dai_ops = { 1890 .startup = arizona_startup, 1891 .set_fmt = arizona_set_fmt, 1892 .set_tdm_slot = arizona_set_tdm_slot, 1893 .hw_params = arizona_hw_params, 1894 .set_sysclk = arizona_dai_set_sysclk, 1895 .set_tristate = arizona_set_tristate, 1896 }; 1897 EXPORT_SYMBOL_GPL(arizona_dai_ops); 1898 1899 const struct snd_soc_dai_ops arizona_simple_dai_ops = { 1900 .startup = arizona_startup, 1901 .hw_params = arizona_hw_params_rate, 1902 .set_sysclk = arizona_dai_set_sysclk, 1903 }; 1904 EXPORT_SYMBOL_GPL(arizona_simple_dai_ops); 1905 1906 int arizona_init_dai(struct arizona_priv *priv, int id) 1907 { 1908 struct arizona_dai_priv *dai_priv = &priv->dai[id]; 1909 1910 dai_priv->clk = ARIZONA_CLK_SYSCLK; 1911 dai_priv->constraint = arizona_constraint; 1912 1913 return 0; 1914 } 1915 EXPORT_SYMBOL_GPL(arizona_init_dai); 1916 1917 static struct { 1918 unsigned int min; 1919 unsigned int max; 1920 u16 fratio; 1921 int ratio; 1922 } fll_fratios[] = { 1923 { 0, 64000, 4, 16 }, 1924 { 64000, 128000, 3, 8 }, 1925 { 128000, 256000, 2, 4 }, 1926 { 256000, 1000000, 1, 2 }, 1927 { 1000000, 13500000, 0, 1 }, 1928 }; 1929 1930 static const unsigned int pseudo_fref_max[ARIZONA_FLL_MAX_FRATIO] = { 1931 13500000, 1932 6144000, 1933 6144000, 1934 3072000, 1935 3072000, 1936 2822400, 1937 2822400, 1938 1536000, 1939 1536000, 1940 1536000, 1941 1536000, 1942 1536000, 1943 1536000, 1944 1536000, 1945 1536000, 1946 768000, 1947 }; 1948 1949 static struct { 1950 unsigned int min; 1951 unsigned int max; 1952 u16 gain; 1953 } fll_gains[] = { 1954 { 0, 256000, 0 }, 1955 { 256000, 1000000, 2 }, 1956 { 1000000, 13500000, 4 }, 1957 }; 1958 1959 struct arizona_fll_cfg { 1960 int n; 1961 unsigned int theta; 1962 unsigned int lambda; 1963 int refdiv; 1964 int outdiv; 1965 int fratio; 1966 int gain; 1967 }; 1968 1969 static int arizona_validate_fll(struct arizona_fll *fll, 1970 unsigned int Fref, 1971 unsigned int Fout) 1972 { 1973 unsigned int Fvco_min; 1974 1975 if (fll->fout && Fout != fll->fout) { 1976 arizona_fll_err(fll, 1977 "Can't change output on active FLL\n"); 1978 return -EINVAL; 1979 } 1980 1981 if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) { 1982 arizona_fll_err(fll, 1983 "Can't scale %dMHz in to <=13.5MHz\n", 1984 Fref); 1985 return -EINVAL; 1986 } 1987 1988 Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult; 1989 if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) { 1990 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n", 1991 Fout); 1992 return -EINVAL; 1993 } 1994 1995 return 0; 1996 } 1997 1998 static int arizona_find_fratio(unsigned int Fref, int *fratio) 1999 { 2000 int i; 2001 2002 /* Find an appropriate FLL_FRATIO */ 2003 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { 2004 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { 2005 if (fratio) 2006 *fratio = fll_fratios[i].fratio; 2007 return fll_fratios[i].ratio; 2008 } 2009 } 2010 2011 return -EINVAL; 2012 } 2013 2014 static int arizona_calc_fratio(struct arizona_fll *fll, 2015 struct arizona_fll_cfg *cfg, 2016 unsigned int target, 2017 unsigned int Fref, bool sync) 2018 { 2019 int init_ratio, ratio; 2020 int refdiv, div; 2021 2022 /* Fref must be <=13.5MHz, find initial refdiv */ 2023 div = 1; 2024 cfg->refdiv = 0; 2025 while (Fref > ARIZONA_FLL_MAX_FREF) { 2026 div *= 2; 2027 Fref /= 2; 2028 cfg->refdiv++; 2029 2030 if (div > ARIZONA_FLL_MAX_REFDIV) 2031 return -EINVAL; 2032 } 2033 2034 /* Find an appropriate FLL_FRATIO */ 2035 init_ratio = arizona_find_fratio(Fref, &cfg->fratio); 2036 if (init_ratio < 0) { 2037 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n", 2038 Fref); 2039 return init_ratio; 2040 } 2041 2042 switch (fll->arizona->type) { 2043 case WM5102: 2044 case WM8997: 2045 return init_ratio; 2046 case WM5110: 2047 case WM8280: 2048 if (fll->arizona->rev < 3 || sync) 2049 return init_ratio; 2050 break; 2051 default: 2052 if (sync) 2053 return init_ratio; 2054 break; 2055 } 2056 2057 cfg->fratio = init_ratio - 1; 2058 2059 /* Adjust FRATIO/refdiv to avoid integer mode if possible */ 2060 refdiv = cfg->refdiv; 2061 2062 arizona_fll_dbg(fll, "pseudo: initial ratio=%u fref=%u refdiv=%u\n", 2063 init_ratio, Fref, refdiv); 2064 2065 while (div <= ARIZONA_FLL_MAX_REFDIV) { 2066 /* start from init_ratio because this may already give a 2067 * fractional N.K 2068 */ 2069 for (ratio = init_ratio; ratio > 0; ratio--) { 2070 if (target % (ratio * Fref)) { 2071 cfg->refdiv = refdiv; 2072 cfg->fratio = ratio - 1; 2073 arizona_fll_dbg(fll, 2074 "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n", 2075 Fref, refdiv, div, ratio); 2076 return ratio; 2077 } 2078 } 2079 2080 for (ratio = init_ratio + 1; ratio <= ARIZONA_FLL_MAX_FRATIO; 2081 ratio++) { 2082 if ((ARIZONA_FLL_VCO_CORNER / 2) / 2083 (fll->vco_mult * ratio) < Fref) { 2084 arizona_fll_dbg(fll, "pseudo: hit VCO corner\n"); 2085 break; 2086 } 2087 2088 if (Fref > pseudo_fref_max[ratio - 1]) { 2089 arizona_fll_dbg(fll, 2090 "pseudo: exceeded max fref(%u) for ratio=%u\n", 2091 pseudo_fref_max[ratio - 1], 2092 ratio); 2093 break; 2094 } 2095 2096 if (target % (ratio * Fref)) { 2097 cfg->refdiv = refdiv; 2098 cfg->fratio = ratio - 1; 2099 arizona_fll_dbg(fll, 2100 "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n", 2101 Fref, refdiv, div, ratio); 2102 return ratio; 2103 } 2104 } 2105 2106 div *= 2; 2107 Fref /= 2; 2108 refdiv++; 2109 init_ratio = arizona_find_fratio(Fref, NULL); 2110 arizona_fll_dbg(fll, 2111 "pseudo: change fref=%u refdiv=%d(%d) ratio=%u\n", 2112 Fref, refdiv, div, init_ratio); 2113 } 2114 2115 arizona_fll_warn(fll, "Falling back to integer mode operation\n"); 2116 return cfg->fratio + 1; 2117 } 2118 2119 static int arizona_calc_fll(struct arizona_fll *fll, 2120 struct arizona_fll_cfg *cfg, 2121 unsigned int Fref, bool sync) 2122 { 2123 unsigned int target, div, gcd_fll; 2124 int i, ratio; 2125 2126 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout); 2127 2128 /* Fvco should be over the targt; don't check the upper bound */ 2129 div = ARIZONA_FLL_MIN_OUTDIV; 2130 while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) { 2131 div++; 2132 if (div > ARIZONA_FLL_MAX_OUTDIV) 2133 return -EINVAL; 2134 } 2135 target = fll->fout * div / fll->vco_mult; 2136 cfg->outdiv = div; 2137 2138 arizona_fll_dbg(fll, "Fvco=%dHz\n", target); 2139 2140 /* Find an appropriate FLL_FRATIO and refdiv */ 2141 ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync); 2142 if (ratio < 0) 2143 return ratio; 2144 2145 /* Apply the division for our remaining calculations */ 2146 Fref = Fref / (1 << cfg->refdiv); 2147 2148 cfg->n = target / (ratio * Fref); 2149 2150 if (target % (ratio * Fref)) { 2151 gcd_fll = gcd(target, ratio * Fref); 2152 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll); 2153 2154 cfg->theta = (target - (cfg->n * ratio * Fref)) 2155 / gcd_fll; 2156 cfg->lambda = (ratio * Fref) / gcd_fll; 2157 } else { 2158 cfg->theta = 0; 2159 cfg->lambda = 0; 2160 } 2161 2162 /* Round down to 16bit range with cost of accuracy lost. 2163 * Denominator must be bigger than numerator so we only 2164 * take care of it. 2165 */ 2166 while (cfg->lambda >= (1 << 16)) { 2167 cfg->theta >>= 1; 2168 cfg->lambda >>= 1; 2169 } 2170 2171 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) { 2172 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) { 2173 cfg->gain = fll_gains[i].gain; 2174 break; 2175 } 2176 } 2177 if (i == ARRAY_SIZE(fll_gains)) { 2178 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n", 2179 Fref); 2180 return -EINVAL; 2181 } 2182 2183 arizona_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n", 2184 cfg->n, cfg->theta, cfg->lambda); 2185 arizona_fll_dbg(fll, "FRATIO=0x%x(%d) OUTDIV=%d REFCLK_DIV=0x%x(%d)\n", 2186 cfg->fratio, ratio, cfg->outdiv, 2187 cfg->refdiv, 1 << cfg->refdiv); 2188 arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain); 2189 2190 return 0; 2191 2192 } 2193 2194 static void arizona_apply_fll(struct arizona *arizona, unsigned int base, 2195 struct arizona_fll_cfg *cfg, int source, 2196 bool sync) 2197 { 2198 regmap_update_bits_async(arizona->regmap, base + 3, 2199 ARIZONA_FLL1_THETA_MASK, cfg->theta); 2200 regmap_update_bits_async(arizona->regmap, base + 4, 2201 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda); 2202 regmap_update_bits_async(arizona->regmap, base + 5, 2203 ARIZONA_FLL1_FRATIO_MASK, 2204 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT); 2205 regmap_update_bits_async(arizona->regmap, base + 6, 2206 ARIZONA_FLL1_CLK_REF_DIV_MASK | 2207 ARIZONA_FLL1_CLK_REF_SRC_MASK, 2208 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | 2209 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); 2210 2211 if (sync) { 2212 regmap_update_bits(arizona->regmap, base + 0x7, 2213 ARIZONA_FLL1_GAIN_MASK, 2214 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); 2215 } else { 2216 regmap_update_bits(arizona->regmap, base + 0x5, 2217 ARIZONA_FLL1_OUTDIV_MASK, 2218 cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); 2219 regmap_update_bits(arizona->regmap, base + 0x9, 2220 ARIZONA_FLL1_GAIN_MASK, 2221 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); 2222 } 2223 2224 regmap_update_bits_async(arizona->regmap, base + 2, 2225 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, 2226 ARIZONA_FLL1_CTRL_UPD | cfg->n); 2227 } 2228 2229 static int arizona_is_enabled_fll(struct arizona_fll *fll, int base) 2230 { 2231 struct arizona *arizona = fll->arizona; 2232 unsigned int reg; 2233 int ret; 2234 2235 ret = regmap_read(arizona->regmap, base + 1, ®); 2236 if (ret != 0) { 2237 arizona_fll_err(fll, "Failed to read current state: %d\n", 2238 ret); 2239 return ret; 2240 } 2241 2242 return reg & ARIZONA_FLL1_ENA; 2243 } 2244 2245 static int arizona_enable_fll(struct arizona_fll *fll) 2246 { 2247 struct arizona *arizona = fll->arizona; 2248 bool use_sync = false; 2249 int already_enabled = arizona_is_enabled_fll(fll, fll->base); 2250 int sync_enabled = arizona_is_enabled_fll(fll, fll->base + 0x10); 2251 struct arizona_fll_cfg cfg; 2252 int i; 2253 unsigned int val; 2254 2255 if (already_enabled < 0) 2256 return already_enabled; 2257 if (sync_enabled < 0) 2258 return sync_enabled; 2259 2260 if (already_enabled) { 2261 /* Facilitate smooth refclk across the transition */ 2262 regmap_update_bits(fll->arizona->regmap, fll->base + 1, 2263 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN); 2264 udelay(32); 2265 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9, 2266 ARIZONA_FLL1_GAIN_MASK, 0); 2267 } 2268 2269 /* 2270 * If we have both REFCLK and SYNCCLK then enable both, 2271 * otherwise apply the SYNCCLK settings to REFCLK. 2272 */ 2273 if (fll->ref_src >= 0 && fll->ref_freq && 2274 fll->ref_src != fll->sync_src) { 2275 arizona_calc_fll(fll, &cfg, fll->ref_freq, false); 2276 2277 /* Ref path hardcodes lambda to 65536 when sync is on */ 2278 if (fll->sync_src >= 0 && cfg.lambda) 2279 cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda; 2280 2281 arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src, 2282 false); 2283 if (fll->sync_src >= 0) { 2284 arizona_calc_fll(fll, &cfg, fll->sync_freq, true); 2285 2286 arizona_apply_fll(arizona, fll->base + 0x10, &cfg, 2287 fll->sync_src, true); 2288 use_sync = true; 2289 } 2290 } else if (fll->sync_src >= 0) { 2291 arizona_calc_fll(fll, &cfg, fll->sync_freq, false); 2292 2293 arizona_apply_fll(arizona, fll->base, &cfg, 2294 fll->sync_src, false); 2295 2296 regmap_update_bits_async(arizona->regmap, fll->base + 0x11, 2297 ARIZONA_FLL1_SYNC_ENA, 0); 2298 } else { 2299 arizona_fll_err(fll, "No clocks provided\n"); 2300 return -EINVAL; 2301 } 2302 2303 if (already_enabled && !!sync_enabled != use_sync) 2304 arizona_fll_warn(fll, "Synchroniser changed on active FLL\n"); 2305 2306 /* 2307 * Increase the bandwidth if we're not using a low frequency 2308 * sync source. 2309 */ 2310 if (use_sync && fll->sync_freq > 100000) 2311 regmap_update_bits_async(arizona->regmap, fll->base + 0x17, 2312 ARIZONA_FLL1_SYNC_BW, 0); 2313 else 2314 regmap_update_bits_async(arizona->regmap, fll->base + 0x17, 2315 ARIZONA_FLL1_SYNC_BW, 2316 ARIZONA_FLL1_SYNC_BW); 2317 2318 if (!already_enabled) 2319 pm_runtime_get_sync(arizona->dev); 2320 2321 if (use_sync) 2322 regmap_update_bits_async(arizona->regmap, fll->base + 0x11, 2323 ARIZONA_FLL1_SYNC_ENA, 2324 ARIZONA_FLL1_SYNC_ENA); 2325 regmap_update_bits_async(arizona->regmap, fll->base + 1, 2326 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); 2327 2328 if (already_enabled) 2329 regmap_update_bits_async(arizona->regmap, fll->base + 1, 2330 ARIZONA_FLL1_FREERUN, 0); 2331 2332 arizona_fll_dbg(fll, "Waiting for FLL lock...\n"); 2333 val = 0; 2334 for (i = 0; i < 15; i++) { 2335 if (i < 5) 2336 usleep_range(200, 400); 2337 else 2338 msleep(20); 2339 2340 regmap_read(arizona->regmap, 2341 ARIZONA_INTERRUPT_RAW_STATUS_5, 2342 &val); 2343 if (val & (ARIZONA_FLL1_CLOCK_OK_STS << (fll->id - 1))) 2344 break; 2345 } 2346 if (i == 15) 2347 arizona_fll_warn(fll, "Timed out waiting for lock\n"); 2348 else 2349 arizona_fll_dbg(fll, "FLL locked (%d polls)\n", i); 2350 2351 return 0; 2352 } 2353 2354 static void arizona_disable_fll(struct arizona_fll *fll) 2355 { 2356 struct arizona *arizona = fll->arizona; 2357 bool change; 2358 2359 regmap_update_bits_async(arizona->regmap, fll->base + 1, 2360 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN); 2361 regmap_update_bits_check(arizona->regmap, fll->base + 1, 2362 ARIZONA_FLL1_ENA, 0, &change); 2363 regmap_update_bits(arizona->regmap, fll->base + 0x11, 2364 ARIZONA_FLL1_SYNC_ENA, 0); 2365 regmap_update_bits_async(arizona->regmap, fll->base + 1, 2366 ARIZONA_FLL1_FREERUN, 0); 2367 2368 if (change) 2369 pm_runtime_put_autosuspend(arizona->dev); 2370 } 2371 2372 int arizona_set_fll_refclk(struct arizona_fll *fll, int source, 2373 unsigned int Fref, unsigned int Fout) 2374 { 2375 int ret = 0; 2376 2377 if (fll->ref_src == source && fll->ref_freq == Fref) 2378 return 0; 2379 2380 if (fll->fout && Fref > 0) { 2381 ret = arizona_validate_fll(fll, Fref, fll->fout); 2382 if (ret != 0) 2383 return ret; 2384 } 2385 2386 fll->ref_src = source; 2387 fll->ref_freq = Fref; 2388 2389 if (fll->fout && Fref > 0) { 2390 ret = arizona_enable_fll(fll); 2391 } 2392 2393 return ret; 2394 } 2395 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk); 2396 2397 int arizona_set_fll(struct arizona_fll *fll, int source, 2398 unsigned int Fref, unsigned int Fout) 2399 { 2400 int ret = 0; 2401 2402 if (fll->sync_src == source && 2403 fll->sync_freq == Fref && fll->fout == Fout) 2404 return 0; 2405 2406 if (Fout) { 2407 if (fll->ref_src >= 0) { 2408 ret = arizona_validate_fll(fll, fll->ref_freq, Fout); 2409 if (ret != 0) 2410 return ret; 2411 } 2412 2413 ret = arizona_validate_fll(fll, Fref, Fout); 2414 if (ret != 0) 2415 return ret; 2416 } 2417 2418 fll->sync_src = source; 2419 fll->sync_freq = Fref; 2420 fll->fout = Fout; 2421 2422 if (Fout) 2423 ret = arizona_enable_fll(fll); 2424 else 2425 arizona_disable_fll(fll); 2426 2427 return ret; 2428 } 2429 EXPORT_SYMBOL_GPL(arizona_set_fll); 2430 2431 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, 2432 int ok_irq, struct arizona_fll *fll) 2433 { 2434 unsigned int val; 2435 2436 fll->id = id; 2437 fll->base = base; 2438 fll->arizona = arizona; 2439 fll->sync_src = ARIZONA_FLL_SRC_NONE; 2440 2441 /* Configure default refclk to 32kHz if we have one */ 2442 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); 2443 switch (val & ARIZONA_CLK_32K_SRC_MASK) { 2444 case ARIZONA_CLK_SRC_MCLK1: 2445 case ARIZONA_CLK_SRC_MCLK2: 2446 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK; 2447 break; 2448 default: 2449 fll->ref_src = ARIZONA_FLL_SRC_NONE; 2450 } 2451 fll->ref_freq = 32768; 2452 2453 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); 2454 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), 2455 "FLL%d clock OK", id); 2456 2457 regmap_update_bits(arizona->regmap, fll->base + 1, 2458 ARIZONA_FLL1_FREERUN, 0); 2459 2460 return 0; 2461 } 2462 EXPORT_SYMBOL_GPL(arizona_init_fll); 2463 2464 /** 2465 * arizona_set_output_mode - Set the mode of the specified output 2466 * 2467 * @codec: Device to configure 2468 * @output: Output number 2469 * @diff: True to set the output to differential mode 2470 * 2471 * Some systems use external analogue switches to connect more 2472 * analogue devices to the CODEC than are supported by the device. In 2473 * some systems this requires changing the switched output from single 2474 * ended to differential mode dynamically at runtime, an operation 2475 * supported using this function. 2476 * 2477 * Most systems have a single static configuration and should use 2478 * platform data instead. 2479 */ 2480 int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff) 2481 { 2482 unsigned int reg, val; 2483 2484 if (output < 1 || output > 6) 2485 return -EINVAL; 2486 2487 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8; 2488 2489 if (diff) 2490 val = ARIZONA_OUT1_MONO; 2491 else 2492 val = 0; 2493 2494 return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val); 2495 } 2496 EXPORT_SYMBOL_GPL(arizona_set_output_mode); 2497 2498 static const struct soc_enum arizona_adsp2_rate_enum[] = { 2499 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1, 2500 ARIZONA_DSP1_RATE_SHIFT, 0xf, 2501 ARIZONA_RATE_ENUM_SIZE, 2502 arizona_rate_text, arizona_rate_val), 2503 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1, 2504 ARIZONA_DSP1_RATE_SHIFT, 0xf, 2505 ARIZONA_RATE_ENUM_SIZE, 2506 arizona_rate_text, arizona_rate_val), 2507 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1, 2508 ARIZONA_DSP1_RATE_SHIFT, 0xf, 2509 ARIZONA_RATE_ENUM_SIZE, 2510 arizona_rate_text, arizona_rate_val), 2511 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1, 2512 ARIZONA_DSP1_RATE_SHIFT, 0xf, 2513 ARIZONA_RATE_ENUM_SIZE, 2514 arizona_rate_text, arizona_rate_val), 2515 }; 2516 2517 const struct snd_kcontrol_new arizona_adsp2_rate_controls[] = { 2518 SOC_ENUM("DSP1 Rate", arizona_adsp2_rate_enum[0]), 2519 SOC_ENUM("DSP2 Rate", arizona_adsp2_rate_enum[1]), 2520 SOC_ENUM("DSP3 Rate", arizona_adsp2_rate_enum[2]), 2521 SOC_ENUM("DSP4 Rate", arizona_adsp2_rate_enum[3]), 2522 }; 2523 EXPORT_SYMBOL_GPL(arizona_adsp2_rate_controls); 2524 2525 static bool arizona_eq_filter_unstable(bool mode, __be16 _a, __be16 _b) 2526 { 2527 s16 a = be16_to_cpu(_a); 2528 s16 b = be16_to_cpu(_b); 2529 2530 if (!mode) { 2531 return abs(a) >= 4096; 2532 } else { 2533 if (abs(b) >= 4096) 2534 return true; 2535 2536 return (abs((a << 16) / (4096 - b)) >= 4096 << 4); 2537 } 2538 } 2539 2540 int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol, 2541 struct snd_ctl_elem_value *ucontrol) 2542 { 2543 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 2544 struct arizona *arizona = dev_get_drvdata(codec->dev->parent); 2545 struct soc_bytes *params = (void *)kcontrol->private_value; 2546 unsigned int val; 2547 __be16 *data; 2548 int len; 2549 int ret; 2550 2551 len = params->num_regs * regmap_get_val_bytes(arizona->regmap); 2552 2553 data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA); 2554 if (!data) 2555 return -ENOMEM; 2556 2557 data[0] &= cpu_to_be16(ARIZONA_EQ1_B1_MODE); 2558 2559 if (arizona_eq_filter_unstable(!!data[0], data[1], data[2]) || 2560 arizona_eq_filter_unstable(true, data[4], data[5]) || 2561 arizona_eq_filter_unstable(true, data[8], data[9]) || 2562 arizona_eq_filter_unstable(true, data[12], data[13]) || 2563 arizona_eq_filter_unstable(false, data[16], data[17])) { 2564 dev_err(arizona->dev, "Rejecting unstable EQ coefficients\n"); 2565 ret = -EINVAL; 2566 goto out; 2567 } 2568 2569 ret = regmap_read(arizona->regmap, params->base, &val); 2570 if (ret != 0) 2571 goto out; 2572 2573 val &= ~ARIZONA_EQ1_B1_MODE; 2574 data[0] |= cpu_to_be16(val); 2575 2576 ret = regmap_raw_write(arizona->regmap, params->base, data, len); 2577 2578 out: 2579 kfree(data); 2580 return ret; 2581 } 2582 EXPORT_SYMBOL_GPL(arizona_eq_coeff_put); 2583 2584 int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol, 2585 struct snd_ctl_elem_value *ucontrol) 2586 { 2587 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 2588 struct arizona *arizona = dev_get_drvdata(codec->dev->parent); 2589 __be16 *data = (__be16 *)ucontrol->value.bytes.data; 2590 s16 val = be16_to_cpu(*data); 2591 2592 if (abs(val) >= 4096) { 2593 dev_err(arizona->dev, "Rejecting unstable LHPF coefficients\n"); 2594 return -EINVAL; 2595 } 2596 2597 return snd_soc_bytes_put(kcontrol, ucontrol); 2598 } 2599 EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put); 2600 2601 int arizona_register_notifier(struct snd_soc_codec *codec, 2602 struct notifier_block *nb, 2603 int (*notify)(struct notifier_block *nb, 2604 unsigned long action, void *data)) 2605 { 2606 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 2607 struct arizona *arizona = priv->arizona; 2608 2609 nb->notifier_call = notify; 2610 2611 return blocking_notifier_chain_register(&arizona->notifier, nb); 2612 } 2613 EXPORT_SYMBOL_GPL(arizona_register_notifier); 2614 2615 int arizona_unregister_notifier(struct snd_soc_codec *codec, 2616 struct notifier_block *nb) 2617 { 2618 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 2619 struct arizona *arizona = priv->arizona; 2620 2621 return blocking_notifier_chain_unregister(&arizona->notifier, nb); 2622 } 2623 EXPORT_SYMBOL_GPL(arizona_unregister_notifier); 2624 2625 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support"); 2626 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 2627 MODULE_LICENSE("GPL"); 2628