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