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