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