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