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