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