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_err(_fll, fmt, ...) \ 56 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 57 #define arizona_fll_warn(_fll, fmt, ...) \ 58 dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 59 #define arizona_fll_dbg(_fll, fmt, ...) \ 60 dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 61 62 #define arizona_aif_err(_dai, fmt, ...) \ 63 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 64 #define arizona_aif_warn(_dai, fmt, ...) \ 65 dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 66 #define arizona_aif_dbg(_dai, fmt, ...) \ 67 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 68 69 static int arizona_spk_ev(struct snd_soc_dapm_widget *w, 70 struct snd_kcontrol *kcontrol, 71 int event) 72 { 73 struct snd_soc_codec *codec = w->codec; 74 struct arizona *arizona = dev_get_drvdata(codec->dev->parent); 75 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 76 bool manual_ena = false; 77 int val; 78 79 switch (arizona->type) { 80 case WM5102: 81 switch (arizona->rev) { 82 case 0: 83 break; 84 default: 85 manual_ena = true; 86 break; 87 } 88 default: 89 break; 90 } 91 92 switch (event) { 93 case SND_SOC_DAPM_PRE_PMU: 94 if (!priv->spk_ena && manual_ena) { 95 snd_soc_write(codec, 0x4f5, 0x25a); 96 priv->spk_ena_pending = true; 97 } 98 break; 99 case SND_SOC_DAPM_POST_PMU: 100 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3); 101 if (val & ARIZONA_SPK_SHUTDOWN_STS) { 102 dev_crit(arizona->dev, 103 "Speaker not enabled due to temperature\n"); 104 return -EBUSY; 105 } 106 107 snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1, 108 1 << w->shift, 1 << w->shift); 109 110 if (priv->spk_ena_pending) { 111 msleep(75); 112 snd_soc_write(codec, 0x4f5, 0xda); 113 priv->spk_ena_pending = false; 114 priv->spk_ena++; 115 } 116 break; 117 case SND_SOC_DAPM_PRE_PMD: 118 if (manual_ena) { 119 priv->spk_ena--; 120 if (!priv->spk_ena) 121 snd_soc_write(codec, 0x4f5, 0x25a); 122 } 123 124 snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1, 125 1 << w->shift, 0); 126 break; 127 case SND_SOC_DAPM_POST_PMD: 128 if (manual_ena) { 129 if (!priv->spk_ena) 130 snd_soc_write(codec, 0x4f5, 0x0da); 131 } 132 break; 133 } 134 135 return 0; 136 } 137 138 static irqreturn_t arizona_thermal_warn(int irq, void *data) 139 { 140 struct arizona *arizona = data; 141 unsigned int val; 142 int ret; 143 144 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3, 145 &val); 146 if (ret != 0) { 147 dev_err(arizona->dev, "Failed to read thermal status: %d\n", 148 ret); 149 } else if (val & ARIZONA_SPK_SHUTDOWN_WARN_STS) { 150 dev_crit(arizona->dev, "Thermal warning\n"); 151 } 152 153 return IRQ_HANDLED; 154 } 155 156 static irqreturn_t arizona_thermal_shutdown(int irq, void *data) 157 { 158 struct arizona *arizona = data; 159 unsigned int val; 160 int ret; 161 162 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3, 163 &val); 164 if (ret != 0) { 165 dev_err(arizona->dev, "Failed to read thermal status: %d\n", 166 ret); 167 } else if (val & ARIZONA_SPK_SHUTDOWN_STS) { 168 dev_crit(arizona->dev, "Thermal shutdown\n"); 169 ret = regmap_update_bits(arizona->regmap, 170 ARIZONA_OUTPUT_ENABLES_1, 171 ARIZONA_OUT4L_ENA | 172 ARIZONA_OUT4R_ENA, 0); 173 if (ret != 0) 174 dev_crit(arizona->dev, 175 "Failed to disable speaker outputs: %d\n", 176 ret); 177 } 178 179 return IRQ_HANDLED; 180 } 181 182 static const struct snd_soc_dapm_widget arizona_spkl = 183 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM, 184 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, 185 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); 186 187 static const struct snd_soc_dapm_widget arizona_spkr = 188 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM, 189 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, 190 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); 191 192 int arizona_init_spk(struct snd_soc_codec *codec) 193 { 194 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 195 struct arizona *arizona = priv->arizona; 196 int ret; 197 198 ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1); 199 if (ret != 0) 200 return ret; 201 202 ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkr, 1); 203 if (ret != 0) 204 return ret; 205 206 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN, 207 "Thermal warning", arizona_thermal_warn, 208 arizona); 209 if (ret != 0) 210 dev_err(arizona->dev, 211 "Failed to get thermal warning IRQ: %d\n", 212 ret); 213 214 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN, 215 "Thermal shutdown", arizona_thermal_shutdown, 216 arizona); 217 if (ret != 0) 218 dev_err(arizona->dev, 219 "Failed to get thermal shutdown IRQ: %d\n", 220 ret); 221 222 return 0; 223 } 224 EXPORT_SYMBOL_GPL(arizona_init_spk); 225 226 const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { 227 "None", 228 "Tone Generator 1", 229 "Tone Generator 2", 230 "Haptics", 231 "AEC", 232 "Mic Mute Mixer", 233 "Noise Generator", 234 "IN1L", 235 "IN1R", 236 "IN2L", 237 "IN2R", 238 "IN3L", 239 "IN3R", 240 "IN4L", 241 "IN4R", 242 "AIF1RX1", 243 "AIF1RX2", 244 "AIF1RX3", 245 "AIF1RX4", 246 "AIF1RX5", 247 "AIF1RX6", 248 "AIF1RX7", 249 "AIF1RX8", 250 "AIF2RX1", 251 "AIF2RX2", 252 "AIF3RX1", 253 "AIF3RX2", 254 "SLIMRX1", 255 "SLIMRX2", 256 "SLIMRX3", 257 "SLIMRX4", 258 "SLIMRX5", 259 "SLIMRX6", 260 "SLIMRX7", 261 "SLIMRX8", 262 "EQ1", 263 "EQ2", 264 "EQ3", 265 "EQ4", 266 "DRC1L", 267 "DRC1R", 268 "DRC2L", 269 "DRC2R", 270 "LHPF1", 271 "LHPF2", 272 "LHPF3", 273 "LHPF4", 274 "DSP1.1", 275 "DSP1.2", 276 "DSP1.3", 277 "DSP1.4", 278 "DSP1.5", 279 "DSP1.6", 280 "DSP2.1", 281 "DSP2.2", 282 "DSP2.3", 283 "DSP2.4", 284 "DSP2.5", 285 "DSP2.6", 286 "DSP3.1", 287 "DSP3.2", 288 "DSP3.3", 289 "DSP3.4", 290 "DSP3.5", 291 "DSP3.6", 292 "DSP4.1", 293 "DSP4.2", 294 "DSP4.3", 295 "DSP4.4", 296 "DSP4.5", 297 "DSP4.6", 298 "ASRC1L", 299 "ASRC1R", 300 "ASRC2L", 301 "ASRC2R", 302 "ISRC1INT1", 303 "ISRC1INT2", 304 "ISRC1INT3", 305 "ISRC1INT4", 306 "ISRC1DEC1", 307 "ISRC1DEC2", 308 "ISRC1DEC3", 309 "ISRC1DEC4", 310 "ISRC2INT1", 311 "ISRC2INT2", 312 "ISRC2INT3", 313 "ISRC2INT4", 314 "ISRC2DEC1", 315 "ISRC2DEC2", 316 "ISRC2DEC3", 317 "ISRC2DEC4", 318 "ISRC3INT1", 319 "ISRC3INT2", 320 "ISRC3INT3", 321 "ISRC3INT4", 322 "ISRC3DEC1", 323 "ISRC3DEC2", 324 "ISRC3DEC3", 325 "ISRC3DEC4", 326 }; 327 EXPORT_SYMBOL_GPL(arizona_mixer_texts); 328 329 int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = { 330 0x00, /* None */ 331 0x04, /* Tone */ 332 0x05, 333 0x06, /* Haptics */ 334 0x08, /* AEC */ 335 0x0c, /* Noise mixer */ 336 0x0d, /* Comfort noise */ 337 0x10, /* IN1L */ 338 0x11, 339 0x12, 340 0x13, 341 0x14, 342 0x15, 343 0x16, 344 0x17, 345 0x20, /* AIF1RX1 */ 346 0x21, 347 0x22, 348 0x23, 349 0x24, 350 0x25, 351 0x26, 352 0x27, 353 0x28, /* AIF2RX1 */ 354 0x29, 355 0x30, /* AIF3RX1 */ 356 0x31, 357 0x38, /* SLIMRX1 */ 358 0x39, 359 0x3a, 360 0x3b, 361 0x3c, 362 0x3d, 363 0x3e, 364 0x3f, 365 0x50, /* EQ1 */ 366 0x51, 367 0x52, 368 0x53, 369 0x58, /* DRC1L */ 370 0x59, 371 0x5a, 372 0x5b, 373 0x60, /* LHPF1 */ 374 0x61, 375 0x62, 376 0x63, 377 0x68, /* DSP1.1 */ 378 0x69, 379 0x6a, 380 0x6b, 381 0x6c, 382 0x6d, 383 0x70, /* DSP2.1 */ 384 0x71, 385 0x72, 386 0x73, 387 0x74, 388 0x75, 389 0x78, /* DSP3.1 */ 390 0x79, 391 0x7a, 392 0x7b, 393 0x7c, 394 0x7d, 395 0x80, /* DSP4.1 */ 396 0x81, 397 0x82, 398 0x83, 399 0x84, 400 0x85, 401 0x90, /* ASRC1L */ 402 0x91, 403 0x92, 404 0x93, 405 0xa0, /* ISRC1INT1 */ 406 0xa1, 407 0xa2, 408 0xa3, 409 0xa4, /* ISRC1DEC1 */ 410 0xa5, 411 0xa6, 412 0xa7, 413 0xa8, /* ISRC2DEC1 */ 414 0xa9, 415 0xaa, 416 0xab, 417 0xac, /* ISRC2INT1 */ 418 0xad, 419 0xae, 420 0xaf, 421 0xb0, /* ISRC3DEC1 */ 422 0xb1, 423 0xb2, 424 0xb3, 425 0xb4, /* ISRC3INT1 */ 426 0xb5, 427 0xb6, 428 0xb7, 429 }; 430 EXPORT_SYMBOL_GPL(arizona_mixer_values); 431 432 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); 433 EXPORT_SYMBOL_GPL(arizona_mixer_tlv); 434 435 const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = { 436 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate", 437 }; 438 EXPORT_SYMBOL_GPL(arizona_rate_text); 439 440 const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = { 441 0, 1, 2, 8, 442 }; 443 EXPORT_SYMBOL_GPL(arizona_rate_val); 444 445 446 const struct soc_enum arizona_isrc_fsl[] = { 447 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2, 448 ARIZONA_ISRC1_FSL_SHIFT, 0xf, 449 ARIZONA_RATE_ENUM_SIZE, 450 arizona_rate_text, arizona_rate_val), 451 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2, 452 ARIZONA_ISRC2_FSL_SHIFT, 0xf, 453 ARIZONA_RATE_ENUM_SIZE, 454 arizona_rate_text, arizona_rate_val), 455 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2, 456 ARIZONA_ISRC3_FSL_SHIFT, 0xf, 457 ARIZONA_RATE_ENUM_SIZE, 458 arizona_rate_text, arizona_rate_val), 459 }; 460 EXPORT_SYMBOL_GPL(arizona_isrc_fsl); 461 462 static const char *arizona_vol_ramp_text[] = { 463 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", 464 "15ms/6dB", "30ms/6dB", 465 }; 466 467 const struct soc_enum arizona_in_vd_ramp = 468 SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, 469 ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); 470 EXPORT_SYMBOL_GPL(arizona_in_vd_ramp); 471 472 const struct soc_enum arizona_in_vi_ramp = 473 SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP, 474 ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); 475 EXPORT_SYMBOL_GPL(arizona_in_vi_ramp); 476 477 const struct soc_enum arizona_out_vd_ramp = 478 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, 479 ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text); 480 EXPORT_SYMBOL_GPL(arizona_out_vd_ramp); 481 482 const struct soc_enum arizona_out_vi_ramp = 483 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP, 484 ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text); 485 EXPORT_SYMBOL_GPL(arizona_out_vi_ramp); 486 487 static const char *arizona_lhpf_mode_text[] = { 488 "Low-pass", "High-pass" 489 }; 490 491 const struct soc_enum arizona_lhpf1_mode = 492 SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2, 493 arizona_lhpf_mode_text); 494 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode); 495 496 const struct soc_enum arizona_lhpf2_mode = 497 SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2, 498 arizona_lhpf_mode_text); 499 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode); 500 501 const struct soc_enum arizona_lhpf3_mode = 502 SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2, 503 arizona_lhpf_mode_text); 504 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode); 505 506 const struct soc_enum arizona_lhpf4_mode = 507 SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2, 508 arizona_lhpf_mode_text); 509 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); 510 511 static const char *arizona_ng_hold_text[] = { 512 "30ms", "120ms", "250ms", "500ms", 513 }; 514 515 const struct soc_enum arizona_ng_hold = 516 SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT, 517 4, arizona_ng_hold_text); 518 EXPORT_SYMBOL_GPL(arizona_ng_hold); 519 520 static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena) 521 { 522 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 523 unsigned int val; 524 int i; 525 526 if (ena) 527 val = ARIZONA_IN_VU; 528 else 529 val = 0; 530 531 for (i = 0; i < priv->num_inputs; i++) 532 snd_soc_update_bits(codec, 533 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4), 534 ARIZONA_IN_VU, val); 535 } 536 537 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 538 int event) 539 { 540 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); 541 unsigned int reg; 542 543 if (w->shift % 2) 544 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8); 545 else 546 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8); 547 548 switch (event) { 549 case SND_SOC_DAPM_PRE_PMU: 550 priv->in_pending++; 551 break; 552 case SND_SOC_DAPM_POST_PMU: 553 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); 554 555 /* If this is the last input pending then allow VU */ 556 priv->in_pending--; 557 if (priv->in_pending == 0) { 558 msleep(1); 559 arizona_in_set_vu(w->codec, 1); 560 } 561 break; 562 case SND_SOC_DAPM_PRE_PMD: 563 snd_soc_update_bits(w->codec, reg, 564 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU, 565 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU); 566 break; 567 case SND_SOC_DAPM_POST_PMD: 568 /* Disable volume updates if no inputs are enabled */ 569 reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES); 570 if (reg == 0) 571 arizona_in_set_vu(w->codec, 0); 572 } 573 574 return 0; 575 } 576 EXPORT_SYMBOL_GPL(arizona_in_ev); 577 578 int arizona_out_ev(struct snd_soc_dapm_widget *w, 579 struct snd_kcontrol *kcontrol, 580 int event) 581 { 582 switch (event) { 583 case SND_SOC_DAPM_POST_PMU: 584 switch (w->shift) { 585 case ARIZONA_OUT1L_ENA_SHIFT: 586 case ARIZONA_OUT1R_ENA_SHIFT: 587 case ARIZONA_OUT2L_ENA_SHIFT: 588 case ARIZONA_OUT2R_ENA_SHIFT: 589 case ARIZONA_OUT3L_ENA_SHIFT: 590 case ARIZONA_OUT3R_ENA_SHIFT: 591 msleep(17); 592 break; 593 594 default: 595 break; 596 } 597 break; 598 } 599 600 return 0; 601 } 602 EXPORT_SYMBOL_GPL(arizona_out_ev); 603 604 int arizona_hp_ev(struct snd_soc_dapm_widget *w, 605 struct snd_kcontrol *kcontrol, 606 int event) 607 { 608 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); 609 unsigned int mask = 1 << w->shift; 610 unsigned int val; 611 612 switch (event) { 613 case SND_SOC_DAPM_POST_PMU: 614 val = mask; 615 break; 616 case SND_SOC_DAPM_PRE_PMD: 617 val = 0; 618 break; 619 default: 620 return -EINVAL; 621 } 622 623 /* Store the desired state for the HP outputs */ 624 priv->arizona->hp_ena &= ~mask; 625 priv->arizona->hp_ena |= val; 626 627 /* Force off if HPDET magic is active */ 628 if (priv->arizona->hpdet_magic) 629 val = 0; 630 631 snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val); 632 633 return arizona_out_ev(w, kcontrol, event); 634 } 635 EXPORT_SYMBOL_GPL(arizona_hp_ev); 636 637 static unsigned int arizona_sysclk_48k_rates[] = { 638 6144000, 639 12288000, 640 24576000, 641 49152000, 642 73728000, 643 98304000, 644 147456000, 645 }; 646 647 static unsigned int arizona_sysclk_44k1_rates[] = { 648 5644800, 649 11289600, 650 22579200, 651 45158400, 652 67737600, 653 90316800, 654 135475200, 655 }; 656 657 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk, 658 unsigned int freq) 659 { 660 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 661 unsigned int reg; 662 unsigned int *rates; 663 int ref, div, refclk; 664 665 switch (clk) { 666 case ARIZONA_CLK_OPCLK: 667 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK; 668 refclk = priv->sysclk; 669 break; 670 case ARIZONA_CLK_ASYNC_OPCLK: 671 reg = ARIZONA_OUTPUT_ASYNC_CLOCK; 672 refclk = priv->asyncclk; 673 break; 674 default: 675 return -EINVAL; 676 } 677 678 if (refclk % 8000) 679 rates = arizona_sysclk_44k1_rates; 680 else 681 rates = arizona_sysclk_48k_rates; 682 683 for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) && 684 rates[ref] <= refclk; ref++) { 685 div = 1; 686 while (rates[ref] / div >= freq && div < 32) { 687 if (rates[ref] / div == freq) { 688 dev_dbg(codec->dev, "Configured %dHz OPCLK\n", 689 freq); 690 snd_soc_update_bits(codec, reg, 691 ARIZONA_OPCLK_DIV_MASK | 692 ARIZONA_OPCLK_SEL_MASK, 693 (div << 694 ARIZONA_OPCLK_DIV_SHIFT) | 695 ref); 696 return 0; 697 } 698 div++; 699 } 700 } 701 702 dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq); 703 return -EINVAL; 704 } 705 706 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, 707 int source, unsigned int freq, int dir) 708 { 709 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 710 struct arizona *arizona = priv->arizona; 711 char *name; 712 unsigned int reg; 713 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK; 714 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT; 715 unsigned int *clk; 716 717 switch (clk_id) { 718 case ARIZONA_CLK_SYSCLK: 719 name = "SYSCLK"; 720 reg = ARIZONA_SYSTEM_CLOCK_1; 721 clk = &priv->sysclk; 722 mask |= ARIZONA_SYSCLK_FRAC; 723 break; 724 case ARIZONA_CLK_ASYNCCLK: 725 name = "ASYNCCLK"; 726 reg = ARIZONA_ASYNC_CLOCK_1; 727 clk = &priv->asyncclk; 728 break; 729 case ARIZONA_CLK_OPCLK: 730 case ARIZONA_CLK_ASYNC_OPCLK: 731 return arizona_set_opclk(codec, clk_id, freq); 732 default: 733 return -EINVAL; 734 } 735 736 switch (freq) { 737 case 5644800: 738 case 6144000: 739 break; 740 case 11289600: 741 case 12288000: 742 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; 743 break; 744 case 22579200: 745 case 24576000: 746 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; 747 break; 748 case 45158400: 749 case 49152000: 750 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; 751 break; 752 case 67737600: 753 case 73728000: 754 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; 755 break; 756 case 90316800: 757 case 98304000: 758 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; 759 break; 760 case 135475200: 761 case 147456000: 762 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; 763 break; 764 case 0: 765 dev_dbg(arizona->dev, "%s cleared\n", name); 766 *clk = freq; 767 return 0; 768 default: 769 return -EINVAL; 770 } 771 772 *clk = freq; 773 774 if (freq % 6144000) 775 val |= ARIZONA_SYSCLK_FRAC; 776 777 dev_dbg(arizona->dev, "%s set to %uHz", name, freq); 778 779 return regmap_update_bits(arizona->regmap, reg, mask, val); 780 } 781 EXPORT_SYMBOL_GPL(arizona_set_sysclk); 782 783 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 784 { 785 struct snd_soc_codec *codec = dai->codec; 786 int lrclk, bclk, mode, base; 787 788 base = dai->driver->base; 789 790 lrclk = 0; 791 bclk = 0; 792 793 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 794 case SND_SOC_DAIFMT_DSP_A: 795 mode = 0; 796 break; 797 case SND_SOC_DAIFMT_I2S: 798 mode = 2; 799 break; 800 default: 801 arizona_aif_err(dai, "Unsupported DAI format %d\n", 802 fmt & SND_SOC_DAIFMT_FORMAT_MASK); 803 return -EINVAL; 804 } 805 806 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 807 case SND_SOC_DAIFMT_CBS_CFS: 808 break; 809 case SND_SOC_DAIFMT_CBS_CFM: 810 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR; 811 break; 812 case SND_SOC_DAIFMT_CBM_CFS: 813 bclk |= ARIZONA_AIF1_BCLK_MSTR; 814 break; 815 case SND_SOC_DAIFMT_CBM_CFM: 816 bclk |= ARIZONA_AIF1_BCLK_MSTR; 817 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR; 818 break; 819 default: 820 arizona_aif_err(dai, "Unsupported master mode %d\n", 821 fmt & SND_SOC_DAIFMT_MASTER_MASK); 822 return -EINVAL; 823 } 824 825 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 826 case SND_SOC_DAIFMT_NB_NF: 827 break; 828 case SND_SOC_DAIFMT_IB_IF: 829 bclk |= ARIZONA_AIF1_BCLK_INV; 830 lrclk |= ARIZONA_AIF1TX_LRCLK_INV; 831 break; 832 case SND_SOC_DAIFMT_IB_NF: 833 bclk |= ARIZONA_AIF1_BCLK_INV; 834 break; 835 case SND_SOC_DAIFMT_NB_IF: 836 lrclk |= ARIZONA_AIF1TX_LRCLK_INV; 837 break; 838 default: 839 return -EINVAL; 840 } 841 842 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL, 843 ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR, 844 bclk); 845 snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL, 846 ARIZONA_AIF1TX_LRCLK_INV | 847 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk); 848 snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL, 849 ARIZONA_AIF1RX_LRCLK_INV | 850 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk); 851 snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT, 852 ARIZONA_AIF1_FMT_MASK, mode); 853 854 return 0; 855 } 856 857 static const int arizona_48k_bclk_rates[] = { 858 -1, 859 48000, 860 64000, 861 96000, 862 128000, 863 192000, 864 256000, 865 384000, 866 512000, 867 768000, 868 1024000, 869 1536000, 870 2048000, 871 3072000, 872 4096000, 873 6144000, 874 8192000, 875 12288000, 876 24576000, 877 }; 878 879 static const unsigned int arizona_48k_rates[] = { 880 12000, 881 24000, 882 48000, 883 96000, 884 192000, 885 384000, 886 768000, 887 4000, 888 8000, 889 16000, 890 32000, 891 64000, 892 128000, 893 256000, 894 512000, 895 }; 896 897 static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = { 898 .count = ARRAY_SIZE(arizona_48k_rates), 899 .list = arizona_48k_rates, 900 }; 901 902 static const int arizona_44k1_bclk_rates[] = { 903 -1, 904 44100, 905 58800, 906 88200, 907 117600, 908 177640, 909 235200, 910 352800, 911 470400, 912 705600, 913 940800, 914 1411200, 915 1881600, 916 2822400, 917 3763200, 918 5644800, 919 7526400, 920 11289600, 921 22579200, 922 }; 923 924 static const unsigned int arizona_44k1_rates[] = { 925 11025, 926 22050, 927 44100, 928 88200, 929 176400, 930 352800, 931 705600, 932 }; 933 934 static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = { 935 .count = ARRAY_SIZE(arizona_44k1_rates), 936 .list = arizona_44k1_rates, 937 }; 938 939 static int arizona_sr_vals[] = { 940 0, 941 12000, 942 24000, 943 48000, 944 96000, 945 192000, 946 384000, 947 768000, 948 0, 949 11025, 950 22050, 951 44100, 952 88200, 953 176400, 954 352800, 955 705600, 956 4000, 957 8000, 958 16000, 959 32000, 960 64000, 961 128000, 962 256000, 963 512000, 964 }; 965 966 static int arizona_startup(struct snd_pcm_substream *substream, 967 struct snd_soc_dai *dai) 968 { 969 struct snd_soc_codec *codec = dai->codec; 970 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 971 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; 972 const struct snd_pcm_hw_constraint_list *constraint; 973 unsigned int base_rate; 974 975 switch (dai_priv->clk) { 976 case ARIZONA_CLK_SYSCLK: 977 base_rate = priv->sysclk; 978 break; 979 case ARIZONA_CLK_ASYNCCLK: 980 base_rate = priv->asyncclk; 981 break; 982 default: 983 return 0; 984 } 985 986 if (base_rate == 0) 987 return 0; 988 989 if (base_rate % 8000) 990 constraint = &arizona_44k1_constraint; 991 else 992 constraint = &arizona_48k_constraint; 993 994 return snd_pcm_hw_constraint_list(substream->runtime, 0, 995 SNDRV_PCM_HW_PARAM_RATE, 996 constraint); 997 } 998 999 static int arizona_hw_params_rate(struct snd_pcm_substream *substream, 1000 struct snd_pcm_hw_params *params, 1001 struct snd_soc_dai *dai) 1002 { 1003 struct snd_soc_codec *codec = dai->codec; 1004 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1005 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; 1006 int base = dai->driver->base; 1007 int i, sr_val; 1008 1009 /* 1010 * We will need to be more flexible than this in future, 1011 * currently we use a single sample rate for SYSCLK. 1012 */ 1013 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++) 1014 if (arizona_sr_vals[i] == params_rate(params)) 1015 break; 1016 if (i == ARRAY_SIZE(arizona_sr_vals)) { 1017 arizona_aif_err(dai, "Unsupported sample rate %dHz\n", 1018 params_rate(params)); 1019 return -EINVAL; 1020 } 1021 sr_val = i; 1022 1023 switch (dai_priv->clk) { 1024 case ARIZONA_CLK_SYSCLK: 1025 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1, 1026 ARIZONA_SAMPLE_RATE_1_MASK, sr_val); 1027 if (base) 1028 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, 1029 ARIZONA_AIF1_RATE_MASK, 0); 1030 break; 1031 case ARIZONA_CLK_ASYNCCLK: 1032 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1, 1033 ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val); 1034 if (base) 1035 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, 1036 ARIZONA_AIF1_RATE_MASK, 1037 8 << ARIZONA_AIF1_RATE_SHIFT); 1038 break; 1039 default: 1040 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk); 1041 return -EINVAL; 1042 } 1043 1044 return 0; 1045 } 1046 1047 static int arizona_hw_params(struct snd_pcm_substream *substream, 1048 struct snd_pcm_hw_params *params, 1049 struct snd_soc_dai *dai) 1050 { 1051 struct snd_soc_codec *codec = dai->codec; 1052 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1053 struct arizona *arizona = priv->arizona; 1054 int base = dai->driver->base; 1055 const int *rates; 1056 int i, ret, val; 1057 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; 1058 int bclk, lrclk, wl, frame, bclk_target; 1059 1060 if (params_rate(params) % 8000) 1061 rates = &arizona_44k1_bclk_rates[0]; 1062 else 1063 rates = &arizona_48k_bclk_rates[0]; 1064 1065 bclk_target = snd_soc_params_to_bclk(params); 1066 if (chan_limit && chan_limit < params_channels(params)) { 1067 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit); 1068 bclk_target /= params_channels(params); 1069 bclk_target *= chan_limit; 1070 } 1071 1072 /* Force stereo for I2S mode */ 1073 val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT); 1074 if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) { 1075 arizona_aif_dbg(dai, "Forcing stereo mode\n"); 1076 bclk_target *= 2; 1077 } 1078 1079 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { 1080 if (rates[i] >= bclk_target && 1081 rates[i] % params_rate(params) == 0) { 1082 bclk = i; 1083 break; 1084 } 1085 } 1086 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) { 1087 arizona_aif_err(dai, "Unsupported sample rate %dHz\n", 1088 params_rate(params)); 1089 return -EINVAL; 1090 } 1091 1092 lrclk = rates[bclk] / params_rate(params); 1093 1094 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n", 1095 rates[bclk], rates[bclk] / lrclk); 1096 1097 wl = snd_pcm_format_width(params_format(params)); 1098 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl; 1099 1100 ret = arizona_hw_params_rate(substream, params, dai); 1101 if (ret != 0) 1102 return ret; 1103 1104 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL, 1105 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk); 1106 snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE, 1107 ARIZONA_AIF1TX_BCPF_MASK, lrclk); 1108 snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE, 1109 ARIZONA_AIF1RX_BCPF_MASK, lrclk); 1110 snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1, 1111 ARIZONA_AIF1TX_WL_MASK | 1112 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame); 1113 snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2, 1114 ARIZONA_AIF1RX_WL_MASK | 1115 ARIZONA_AIF1RX_SLOT_LEN_MASK, frame); 1116 1117 return 0; 1118 } 1119 1120 static const char *arizona_dai_clk_str(int clk_id) 1121 { 1122 switch (clk_id) { 1123 case ARIZONA_CLK_SYSCLK: 1124 return "SYSCLK"; 1125 case ARIZONA_CLK_ASYNCCLK: 1126 return "ASYNCCLK"; 1127 default: 1128 return "Unknown clock"; 1129 } 1130 } 1131 1132 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, 1133 int clk_id, unsigned int freq, int dir) 1134 { 1135 struct snd_soc_codec *codec = dai->codec; 1136 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 1137 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; 1138 struct snd_soc_dapm_route routes[2]; 1139 1140 switch (clk_id) { 1141 case ARIZONA_CLK_SYSCLK: 1142 case ARIZONA_CLK_ASYNCCLK: 1143 break; 1144 default: 1145 return -EINVAL; 1146 } 1147 1148 if (clk_id == dai_priv->clk) 1149 return 0; 1150 1151 if (dai->active) { 1152 dev_err(codec->dev, "Can't change clock on active DAI %d\n", 1153 dai->id); 1154 return -EBUSY; 1155 } 1156 1157 dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1, 1158 arizona_dai_clk_str(clk_id)); 1159 1160 memset(&routes, 0, sizeof(routes)); 1161 routes[0].sink = dai->driver->capture.stream_name; 1162 routes[1].sink = dai->driver->playback.stream_name; 1163 1164 routes[0].source = arizona_dai_clk_str(dai_priv->clk); 1165 routes[1].source = arizona_dai_clk_str(dai_priv->clk); 1166 snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); 1167 1168 routes[0].source = arizona_dai_clk_str(clk_id); 1169 routes[1].source = arizona_dai_clk_str(clk_id); 1170 snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); 1171 1172 dai_priv->clk = clk_id; 1173 1174 return snd_soc_dapm_sync(&codec->dapm); 1175 } 1176 1177 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate) 1178 { 1179 struct snd_soc_codec *codec = dai->codec; 1180 int base = dai->driver->base; 1181 unsigned int reg; 1182 1183 if (tristate) 1184 reg = ARIZONA_AIF1_TRI; 1185 else 1186 reg = 0; 1187 1188 return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL, 1189 ARIZONA_AIF1_TRI, reg); 1190 } 1191 1192 const struct snd_soc_dai_ops arizona_dai_ops = { 1193 .startup = arizona_startup, 1194 .set_fmt = arizona_set_fmt, 1195 .hw_params = arizona_hw_params, 1196 .set_sysclk = arizona_dai_set_sysclk, 1197 .set_tristate = arizona_set_tristate, 1198 }; 1199 EXPORT_SYMBOL_GPL(arizona_dai_ops); 1200 1201 int arizona_init_dai(struct arizona_priv *priv, int id) 1202 { 1203 struct arizona_dai_priv *dai_priv = &priv->dai[id]; 1204 1205 dai_priv->clk = ARIZONA_CLK_SYSCLK; 1206 1207 return 0; 1208 } 1209 EXPORT_SYMBOL_GPL(arizona_init_dai); 1210 1211 static irqreturn_t arizona_fll_clock_ok(int irq, void *data) 1212 { 1213 struct arizona_fll *fll = data; 1214 1215 arizona_fll_dbg(fll, "clock OK\n"); 1216 1217 complete(&fll->ok); 1218 1219 return IRQ_HANDLED; 1220 } 1221 1222 static struct { 1223 unsigned int min; 1224 unsigned int max; 1225 u16 fratio; 1226 int ratio; 1227 } fll_fratios[] = { 1228 { 0, 64000, 4, 16 }, 1229 { 64000, 128000, 3, 8 }, 1230 { 128000, 256000, 2, 4 }, 1231 { 256000, 1000000, 1, 2 }, 1232 { 1000000, 13500000, 0, 1 }, 1233 }; 1234 1235 static struct { 1236 unsigned int min; 1237 unsigned int max; 1238 u16 gain; 1239 } fll_gains[] = { 1240 { 0, 256000, 0 }, 1241 { 256000, 1000000, 2 }, 1242 { 1000000, 13500000, 4 }, 1243 }; 1244 1245 struct arizona_fll_cfg { 1246 int n; 1247 int theta; 1248 int lambda; 1249 int refdiv; 1250 int outdiv; 1251 int fratio; 1252 int gain; 1253 }; 1254 1255 static int arizona_calc_fll(struct arizona_fll *fll, 1256 struct arizona_fll_cfg *cfg, 1257 unsigned int Fref, 1258 unsigned int Fout) 1259 { 1260 unsigned int target, div, gcd_fll; 1261 int i, ratio; 1262 1263 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout); 1264 1265 /* Fref must be <=13.5MHz */ 1266 div = 1; 1267 cfg->refdiv = 0; 1268 while ((Fref / div) > 13500000) { 1269 div *= 2; 1270 cfg->refdiv++; 1271 1272 if (div > 8) { 1273 arizona_fll_err(fll, 1274 "Can't scale %dMHz in to <=13.5MHz\n", 1275 Fref); 1276 return -EINVAL; 1277 } 1278 } 1279 1280 /* Apply the division for our remaining calculations */ 1281 Fref /= div; 1282 1283 /* Fvco should be over the targt; don't check the upper bound */ 1284 div = 1; 1285 while (Fout * div < 90000000 * fll->vco_mult) { 1286 div++; 1287 if (div > 7) { 1288 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n", 1289 Fout); 1290 return -EINVAL; 1291 } 1292 } 1293 target = Fout * div / fll->vco_mult; 1294 cfg->outdiv = div; 1295 1296 arizona_fll_dbg(fll, "Fvco=%dHz\n", target); 1297 1298 /* Find an appropraite FLL_FRATIO and factor it out of the target */ 1299 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { 1300 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { 1301 cfg->fratio = fll_fratios[i].fratio; 1302 ratio = fll_fratios[i].ratio; 1303 break; 1304 } 1305 } 1306 if (i == ARRAY_SIZE(fll_fratios)) { 1307 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n", 1308 Fref); 1309 return -EINVAL; 1310 } 1311 1312 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) { 1313 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) { 1314 cfg->gain = fll_gains[i].gain; 1315 break; 1316 } 1317 } 1318 if (i == ARRAY_SIZE(fll_gains)) { 1319 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n", 1320 Fref); 1321 return -EINVAL; 1322 } 1323 1324 cfg->n = target / (ratio * Fref); 1325 1326 if (target % (ratio * Fref)) { 1327 gcd_fll = gcd(target, ratio * Fref); 1328 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll); 1329 1330 cfg->theta = (target - (cfg->n * ratio * Fref)) 1331 / gcd_fll; 1332 cfg->lambda = (ratio * Fref) / gcd_fll; 1333 } else { 1334 cfg->theta = 0; 1335 cfg->lambda = 0; 1336 } 1337 1338 /* Round down to 16bit range with cost of accuracy lost. 1339 * Denominator must be bigger than numerator so we only 1340 * take care of it. 1341 */ 1342 while (cfg->lambda >= (1 << 16)) { 1343 cfg->theta >>= 1; 1344 cfg->lambda >>= 1; 1345 } 1346 1347 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n", 1348 cfg->n, cfg->theta, cfg->lambda); 1349 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", 1350 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); 1351 arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain); 1352 1353 return 0; 1354 1355 } 1356 1357 static void arizona_apply_fll(struct arizona *arizona, unsigned int base, 1358 struct arizona_fll_cfg *cfg, int source, 1359 bool sync) 1360 { 1361 regmap_update_bits(arizona->regmap, base + 3, 1362 ARIZONA_FLL1_THETA_MASK, cfg->theta); 1363 regmap_update_bits(arizona->regmap, base + 4, 1364 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda); 1365 regmap_update_bits(arizona->regmap, base + 5, 1366 ARIZONA_FLL1_FRATIO_MASK, 1367 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT); 1368 regmap_update_bits(arizona->regmap, base + 6, 1369 ARIZONA_FLL1_CLK_REF_DIV_MASK | 1370 ARIZONA_FLL1_CLK_REF_SRC_MASK, 1371 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | 1372 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); 1373 1374 if (sync) 1375 regmap_update_bits(arizona->regmap, base + 0x7, 1376 ARIZONA_FLL1_GAIN_MASK, 1377 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); 1378 else 1379 regmap_update_bits(arizona->regmap, base + 0x9, 1380 ARIZONA_FLL1_GAIN_MASK, 1381 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); 1382 1383 regmap_update_bits(arizona->regmap, base + 2, 1384 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, 1385 ARIZONA_FLL1_CTRL_UPD | cfg->n); 1386 } 1387 1388 static bool arizona_is_enabled_fll(struct arizona_fll *fll) 1389 { 1390 struct arizona *arizona = fll->arizona; 1391 unsigned int reg; 1392 int ret; 1393 1394 ret = regmap_read(arizona->regmap, fll->base + 1, ®); 1395 if (ret != 0) { 1396 arizona_fll_err(fll, "Failed to read current state: %d\n", 1397 ret); 1398 return ret; 1399 } 1400 1401 return reg & ARIZONA_FLL1_ENA; 1402 } 1403 1404 static void arizona_enable_fll(struct arizona_fll *fll, 1405 struct arizona_fll_cfg *ref, 1406 struct arizona_fll_cfg *sync) 1407 { 1408 struct arizona *arizona = fll->arizona; 1409 int ret; 1410 1411 /* 1412 * If we have both REFCLK and SYNCCLK then enable both, 1413 * otherwise apply the SYNCCLK settings to REFCLK. 1414 */ 1415 if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) { 1416 regmap_update_bits(arizona->regmap, fll->base + 5, 1417 ARIZONA_FLL1_OUTDIV_MASK, 1418 ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); 1419 1420 arizona_apply_fll(arizona, fll->base, ref, fll->ref_src, 1421 false); 1422 if (fll->sync_src >= 0) 1423 arizona_apply_fll(arizona, fll->base + 0x10, sync, 1424 fll->sync_src, true); 1425 } else if (fll->sync_src >= 0) { 1426 regmap_update_bits(arizona->regmap, fll->base + 5, 1427 ARIZONA_FLL1_OUTDIV_MASK, 1428 sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); 1429 1430 arizona_apply_fll(arizona, fll->base, sync, 1431 fll->sync_src, false); 1432 1433 regmap_update_bits(arizona->regmap, fll->base + 0x11, 1434 ARIZONA_FLL1_SYNC_ENA, 0); 1435 } else { 1436 arizona_fll_err(fll, "No clocks provided\n"); 1437 return; 1438 } 1439 1440 /* 1441 * Increase the bandwidth if we're not using a low frequency 1442 * sync source. 1443 */ 1444 if (fll->sync_src >= 0 && fll->sync_freq > 100000) 1445 regmap_update_bits(arizona->regmap, fll->base + 0x17, 1446 ARIZONA_FLL1_SYNC_BW, 0); 1447 else 1448 regmap_update_bits(arizona->regmap, fll->base + 0x17, 1449 ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW); 1450 1451 if (!arizona_is_enabled_fll(fll)) 1452 pm_runtime_get(arizona->dev); 1453 1454 /* Clear any pending completions */ 1455 try_wait_for_completion(&fll->ok); 1456 1457 regmap_update_bits(arizona->regmap, fll->base + 1, 1458 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); 1459 if (fll->ref_src >= 0 && fll->sync_src >= 0 && 1460 fll->ref_src != fll->sync_src) 1461 regmap_update_bits(arizona->regmap, fll->base + 0x11, 1462 ARIZONA_FLL1_SYNC_ENA, 1463 ARIZONA_FLL1_SYNC_ENA); 1464 1465 ret = wait_for_completion_timeout(&fll->ok, 1466 msecs_to_jiffies(250)); 1467 if (ret == 0) 1468 arizona_fll_warn(fll, "Timed out waiting for lock\n"); 1469 } 1470 1471 static void arizona_disable_fll(struct arizona_fll *fll) 1472 { 1473 struct arizona *arizona = fll->arizona; 1474 bool change; 1475 1476 regmap_update_bits_check(arizona->regmap, fll->base + 1, 1477 ARIZONA_FLL1_ENA, 0, &change); 1478 regmap_update_bits(arizona->regmap, fll->base + 0x11, 1479 ARIZONA_FLL1_SYNC_ENA, 0); 1480 1481 if (change) 1482 pm_runtime_put_autosuspend(arizona->dev); 1483 } 1484 1485 int arizona_set_fll_refclk(struct arizona_fll *fll, int source, 1486 unsigned int Fref, unsigned int Fout) 1487 { 1488 struct arizona_fll_cfg ref, sync; 1489 int ret; 1490 1491 if (fll->ref_src == source && fll->ref_freq == Fref) 1492 return 0; 1493 1494 if (fll->fout && Fref > 0) { 1495 ret = arizona_calc_fll(fll, &ref, Fref, fll->fout); 1496 if (ret != 0) 1497 return ret; 1498 1499 if (fll->sync_src >= 0) { 1500 ret = arizona_calc_fll(fll, &sync, fll->sync_freq, 1501 fll->fout); 1502 if (ret != 0) 1503 return ret; 1504 } 1505 } 1506 1507 fll->ref_src = source; 1508 fll->ref_freq = Fref; 1509 1510 if (fll->fout && Fref > 0) { 1511 arizona_enable_fll(fll, &ref, &sync); 1512 } 1513 1514 return 0; 1515 } 1516 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk); 1517 1518 int arizona_set_fll(struct arizona_fll *fll, int source, 1519 unsigned int Fref, unsigned int Fout) 1520 { 1521 struct arizona_fll_cfg ref, sync; 1522 int ret; 1523 1524 if (fll->sync_src == source && 1525 fll->sync_freq == Fref && fll->fout == Fout) 1526 return 0; 1527 1528 if (Fout) { 1529 if (fll->ref_src >= 0) { 1530 ret = arizona_calc_fll(fll, &ref, fll->ref_freq, 1531 Fout); 1532 if (ret != 0) 1533 return ret; 1534 } 1535 1536 ret = arizona_calc_fll(fll, &sync, Fref, Fout); 1537 if (ret != 0) 1538 return ret; 1539 } 1540 1541 fll->sync_src = source; 1542 fll->sync_freq = Fref; 1543 fll->fout = Fout; 1544 1545 if (Fout) { 1546 arizona_enable_fll(fll, &ref, &sync); 1547 } else { 1548 arizona_disable_fll(fll); 1549 } 1550 1551 return 0; 1552 } 1553 EXPORT_SYMBOL_GPL(arizona_set_fll); 1554 1555 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, 1556 int ok_irq, struct arizona_fll *fll) 1557 { 1558 int ret; 1559 unsigned int val; 1560 1561 init_completion(&fll->ok); 1562 1563 fll->id = id; 1564 fll->base = base; 1565 fll->arizona = arizona; 1566 fll->sync_src = ARIZONA_FLL_SRC_NONE; 1567 1568 /* Configure default refclk to 32kHz if we have one */ 1569 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); 1570 switch (val & ARIZONA_CLK_32K_SRC_MASK) { 1571 case ARIZONA_CLK_SRC_MCLK1: 1572 case ARIZONA_CLK_SRC_MCLK2: 1573 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK; 1574 break; 1575 default: 1576 fll->ref_src = ARIZONA_FLL_SRC_NONE; 1577 } 1578 fll->ref_freq = 32768; 1579 1580 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); 1581 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), 1582 "FLL%d clock OK", id); 1583 1584 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name, 1585 arizona_fll_clock_ok, fll); 1586 if (ret != 0) { 1587 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n", 1588 id, ret); 1589 } 1590 1591 regmap_update_bits(arizona->regmap, fll->base + 1, 1592 ARIZONA_FLL1_FREERUN, 0); 1593 1594 return 0; 1595 } 1596 EXPORT_SYMBOL_GPL(arizona_init_fll); 1597 1598 /** 1599 * arizona_set_output_mode - Set the mode of the specified output 1600 * 1601 * @codec: Device to configure 1602 * @output: Output number 1603 * @diff: True to set the output to differential mode 1604 * 1605 * Some systems use external analogue switches to connect more 1606 * analogue devices to the CODEC than are supported by the device. In 1607 * some systems this requires changing the switched output from single 1608 * ended to differential mode dynamically at runtime, an operation 1609 * supported using this function. 1610 * 1611 * Most systems have a single static configuration and should use 1612 * platform data instead. 1613 */ 1614 int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff) 1615 { 1616 unsigned int reg, val; 1617 1618 if (output < 1 || output > 6) 1619 return -EINVAL; 1620 1621 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8; 1622 1623 if (diff) 1624 val = ARIZONA_OUT1_MONO; 1625 else 1626 val = 0; 1627 1628 return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val); 1629 } 1630 EXPORT_SYMBOL_GPL(arizona_set_output_mode); 1631 1632 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support"); 1633 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1634 MODULE_LICENSE("GPL"); 1635