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                        break;
1038                default:
1039                        break;
1040                }
1041                break;
1042        case SND_SOC_DAPM_POST_PMD:
1043                switch (w->shift) {
1044                case ARIZONA_OUT1L_ENA_SHIFT:
1045                case ARIZONA_OUT1R_ENA_SHIFT:
1046                case ARIZONA_OUT2L_ENA_SHIFT:
1047                case ARIZONA_OUT2R_ENA_SHIFT:
1048                case ARIZONA_OUT3L_ENA_SHIFT:
1049                case ARIZONA_OUT3R_ENA_SHIFT:
1050                case ARIZONA_OUT4L_ENA_SHIFT:
1051                case ARIZONA_OUT4R_ENA_SHIFT:
1052                        priv->out_down_pending--;
1053                        if (!priv->out_down_pending && priv->out_down_delay) {
1054                                dev_dbg(component->dev, "Power down delay: %d\n",
1055                                        priv->out_down_delay);
1056                                msleep(priv->out_down_delay);
1057                                priv->out_down_delay = 0;
1058                        }
1059                        break;
1060                default:
1061                        break;
1062                }
1063                break;
1064        default:
1065                break;
1066        }
1067
1068        return 0;
1069}
1070EXPORT_SYMBOL_GPL(arizona_out_ev);
1071
1072int arizona_hp_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
1073                  int event)
1074{
1075        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1076        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1077        struct arizona *arizona = priv->arizona;
1078        unsigned int mask = 1 << w->shift;
1079        unsigned int val;
1080
1081        switch (event) {
1082        case SND_SOC_DAPM_POST_PMU:
1083                val = mask;
1084                break;
1085        case SND_SOC_DAPM_PRE_PMD:
1086                val = 0;
1087                break;
1088        case SND_SOC_DAPM_PRE_PMU:
1089        case SND_SOC_DAPM_POST_PMD:
1090                return arizona_out_ev(w, kcontrol, event);
1091        default:
1092                return -EINVAL;
1093        }
1094
1095        /* Store the desired state for the HP outputs */
1096        priv->arizona->hp_ena &= ~mask;
1097        priv->arizona->hp_ena |= val;
1098
1099        /* Force off if HPDET clamp is active */
1100        if (priv->arizona->hpdet_clamp)
1101                val = 0;
1102
1103        regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
1104                                 mask, val);
1105
1106        return arizona_out_ev(w, kcontrol, event);
1107}
1108EXPORT_SYMBOL_GPL(arizona_hp_ev);
1109
1110static int arizona_dvfs_enable(struct snd_soc_component *component)
1111{
1112        const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1113        struct arizona *arizona = priv->arizona;
1114        int ret;
1115
1116        ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
1117        if (ret) {
1118                dev_err(component->dev, "Failed to boost DCVDD: %d\n", ret);
1119                return ret;
1120        }
1121
1122        ret = regmap_update_bits(arizona->regmap,
1123                                 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1124                                 ARIZONA_SUBSYS_MAX_FREQ,
1125                                 ARIZONA_SUBSYS_MAX_FREQ);
1126        if (ret) {
1127                dev_err(component->dev, "Failed to enable subsys max: %d\n", ret);
1128                regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1129                return ret;
1130        }
1131
1132        return 0;
1133}
1134
1135static int arizona_dvfs_disable(struct snd_soc_component *component)
1136{
1137        const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1138        struct arizona *arizona = priv->arizona;
1139        int ret;
1140
1141        ret = regmap_update_bits(arizona->regmap,
1142                                 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1143                                 ARIZONA_SUBSYS_MAX_FREQ, 0);
1144        if (ret) {
1145                dev_err(component->dev, "Failed to disable subsys max: %d\n", ret);
1146                return ret;
1147        }
1148
1149        ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1150        if (ret) {
1151                dev_err(component->dev, "Failed to unboost DCVDD: %d\n", ret);
1152                return ret;
1153        }
1154
1155        return 0;
1156}
1157
1158int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags)
1159{
1160        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1161        int ret = 0;
1162
1163        mutex_lock(&priv->dvfs_lock);
1164
1165        if (!priv->dvfs_cached && !priv->dvfs_reqs) {
1166                ret = arizona_dvfs_enable(component);
1167                if (ret)
1168                        goto err;
1169        }
1170
1171        priv->dvfs_reqs |= flags;
1172err:
1173        mutex_unlock(&priv->dvfs_lock);
1174        return ret;
1175}
1176EXPORT_SYMBOL_GPL(arizona_dvfs_up);
1177
1178int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags)
1179{
1180        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1181        unsigned int old_reqs;
1182        int ret = 0;
1183
1184        mutex_lock(&priv->dvfs_lock);
1185
1186        old_reqs = priv->dvfs_reqs;
1187        priv->dvfs_reqs &= ~flags;
1188
1189        if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
1190                ret = arizona_dvfs_disable(component);
1191
1192        mutex_unlock(&priv->dvfs_lock);
1193        return ret;
1194}
1195EXPORT_SYMBOL_GPL(arizona_dvfs_down);
1196
1197int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
1198                           struct snd_kcontrol *kcontrol, int event)
1199{
1200        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1201        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1202        int ret = 0;
1203
1204        mutex_lock(&priv->dvfs_lock);
1205
1206        switch (event) {
1207        case SND_SOC_DAPM_POST_PMU:
1208                if (priv->dvfs_reqs)
1209                        ret = arizona_dvfs_enable(component);
1210
1211                priv->dvfs_cached = false;
1212                break;
1213        case SND_SOC_DAPM_PRE_PMD:
1214                /* We must ensure DVFS is disabled before the codec goes into
1215                 * suspend so that we are never in an illegal state of DVFS
1216                 * enabled without enough DCVDD
1217                 */
1218                priv->dvfs_cached = true;
1219
1220                if (priv->dvfs_reqs)
1221                        ret = arizona_dvfs_disable(component);
1222                break;
1223        default:
1224                break;
1225        }
1226
1227        mutex_unlock(&priv->dvfs_lock);
1228        return ret;
1229}
1230EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev);
1231
1232void arizona_init_dvfs(struct arizona_priv *priv)
1233{
1234        mutex_init(&priv->dvfs_lock);
1235}
1236EXPORT_SYMBOL_GPL(arizona_init_dvfs);
1237
1238int arizona_anc_ev(struct snd_soc_dapm_widget *w,
1239                   struct snd_kcontrol *kcontrol,
1240                   int event)
1241{
1242        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1243        unsigned int val;
1244
1245        switch (event) {
1246        case SND_SOC_DAPM_POST_PMU:
1247                val = 1 << w->shift;
1248                break;
1249        case SND_SOC_DAPM_PRE_PMD:
1250                val = 1 << (w->shift + 1);
1251                break;
1252        default:
1253                return 0;
1254        }
1255
1256        snd_soc_component_write(component, ARIZONA_CLOCK_CONTROL, val);
1257
1258        return 0;
1259}
1260EXPORT_SYMBOL_GPL(arizona_anc_ev);
1261
1262static unsigned int arizona_opclk_ref_48k_rates[] = {
1263        6144000,
1264        12288000,
1265        24576000,
1266        49152000,
1267};
1268
1269static unsigned int arizona_opclk_ref_44k1_rates[] = {
1270        5644800,
1271        11289600,
1272        22579200,
1273        45158400,
1274};
1275
1276static int arizona_set_opclk(struct snd_soc_component *component,
1277                             unsigned int clk, unsigned int freq)
1278{
1279        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1280        unsigned int reg;
1281        unsigned int *rates;
1282        int ref, div, refclk;
1283
1284        switch (clk) {
1285        case ARIZONA_CLK_OPCLK:
1286                reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
1287                refclk = priv->sysclk;
1288                break;
1289        case ARIZONA_CLK_ASYNC_OPCLK:
1290                reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
1291                refclk = priv->asyncclk;
1292                break;
1293        default:
1294                return -EINVAL;
1295        }
1296
1297        if (refclk % 8000)
1298                rates = arizona_opclk_ref_44k1_rates;
1299        else
1300                rates = arizona_opclk_ref_48k_rates;
1301
1302        for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) &&
1303             rates[ref] <= refclk; ref++) {
1304                div = 1;
1305                while (rates[ref] / div >= freq && div < 32) {
1306                        if (rates[ref] / div == freq) {
1307                                dev_dbg(component->dev, "Configured %dHz OPCLK\n",
1308                                        freq);
1309                                snd_soc_component_update_bits(component, reg,
1310                                                    ARIZONA_OPCLK_DIV_MASK |
1311                                                    ARIZONA_OPCLK_SEL_MASK,
1312                                                    (div <<
1313                                                     ARIZONA_OPCLK_DIV_SHIFT) |
1314                                                    ref);
1315                                return 0;
1316                        }
1317                        div++;
1318                }
1319        }
1320
1321        dev_err(component->dev, "Unable to generate %dHz OPCLK\n", freq);
1322        return -EINVAL;
1323}
1324
1325int arizona_clk_ev(struct snd_soc_dapm_widget *w,
1326                   struct snd_kcontrol *kcontrol, int event)
1327{
1328        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1329        struct arizona *arizona = dev_get_drvdata(component->dev->parent);
1330        unsigned int val;
1331        int clk_idx;
1332        int ret;
1333
1334        ret = regmap_read(arizona->regmap, w->reg, &val);
1335        if (ret) {
1336                dev_err(component->dev, "Failed to check clock source: %d\n", ret);
1337                return ret;
1338        }
1339
1340        val = (val & ARIZONA_SYSCLK_SRC_MASK) >> ARIZONA_SYSCLK_SRC_SHIFT;
1341
1342        switch (val) {
1343        case ARIZONA_CLK_SRC_MCLK1:
1344                clk_idx = ARIZONA_MCLK1;
1345                break;
1346        case ARIZONA_CLK_SRC_MCLK2:
1347                clk_idx = ARIZONA_MCLK2;
1348                break;
1349        default:
1350                return 0;
1351        }
1352
1353        switch (event) {
1354        case SND_SOC_DAPM_PRE_PMU:
1355                return clk_prepare_enable(arizona->mclk[clk_idx]);
1356        case SND_SOC_DAPM_POST_PMD:
1357                clk_disable_unprepare(arizona->mclk[clk_idx]);
1358                return 0;
1359        default:
1360                return 0;
1361        }
1362}
1363EXPORT_SYMBOL_GPL(arizona_clk_ev);
1364
1365int arizona_set_sysclk(struct snd_soc_component *component, int clk_id,
1366                       int source, unsigned int freq, int dir)
1367{
1368        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1369        struct arizona *arizona = priv->arizona;
1370        char *name;
1371        unsigned int reg;
1372        unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
1373        unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
1374        int *clk;
1375
1376        switch (clk_id) {
1377        case ARIZONA_CLK_SYSCLK:
1378                name = "SYSCLK";
1379                reg = ARIZONA_SYSTEM_CLOCK_1;
1380                clk = &priv->sysclk;
1381                mask |= ARIZONA_SYSCLK_FRAC;
1382                break;
1383        case ARIZONA_CLK_ASYNCCLK:
1384                name = "ASYNCCLK";
1385                reg = ARIZONA_ASYNC_CLOCK_1;
1386                clk = &priv->asyncclk;
1387                break;
1388        case ARIZONA_CLK_OPCLK:
1389        case ARIZONA_CLK_ASYNC_OPCLK:
1390                return arizona_set_opclk(component, clk_id, freq);
1391        default:
1392                return -EINVAL;
1393        }
1394
1395        switch (freq) {
1396        case  5644800:
1397        case  6144000:
1398                break;
1399        case 11289600:
1400        case 12288000:
1401                val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1402                break;
1403        case 22579200:
1404        case 24576000:
1405                val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1406                break;
1407        case 45158400:
1408        case 49152000:
1409                val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1410                break;
1411        case 67737600:
1412        case 73728000:
1413                val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1414                break;
1415        case 90316800:
1416        case 98304000:
1417                val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1418                break;
1419        case 135475200:
1420        case 147456000:
1421                val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1422                break;
1423        case 0:
1424                dev_dbg(arizona->dev, "%s cleared\n", name);
1425                *clk = freq;
1426                return 0;
1427        default:
1428                return -EINVAL;
1429        }
1430
1431        *clk = freq;
1432
1433        if (freq % 6144000)
1434                val |= ARIZONA_SYSCLK_FRAC;
1435
1436        dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
1437
1438        return regmap_update_bits(arizona->regmap, reg, mask, val);
1439}
1440EXPORT_SYMBOL_GPL(arizona_set_sysclk);
1441
1442static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1443{
1444        struct snd_soc_component *component = dai->component;
1445        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1446        struct arizona *arizona = priv->arizona;
1447        int lrclk, bclk, mode, base;
1448
1449        base = dai->driver->base;
1450
1451        lrclk = 0;
1452        bclk = 0;
1453
1454        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1455        case SND_SOC_DAIFMT_DSP_A:
1456                mode = ARIZONA_FMT_DSP_MODE_A;
1457                break;
1458        case SND_SOC_DAIFMT_DSP_B:
1459                if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1460                                != SND_SOC_DAIFMT_CBM_CFM) {
1461                        arizona_aif_err(dai, "DSP_B not valid in slave mode\n");
1462                        return -EINVAL;
1463                }
1464                mode = ARIZONA_FMT_DSP_MODE_B;
1465                break;
1466        case SND_SOC_DAIFMT_I2S:
1467                mode = ARIZONA_FMT_I2S_MODE;
1468                break;
1469        case SND_SOC_DAIFMT_LEFT_J:
1470                if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1471                                != SND_SOC_DAIFMT_CBM_CFM) {
1472                        arizona_aif_err(dai, "LEFT_J not valid in slave mode\n");
1473                        return -EINVAL;
1474                }
1475                mode = ARIZONA_FMT_LEFT_JUSTIFIED_MODE;
1476                break;
1477        default:
1478                arizona_aif_err(dai, "Unsupported DAI format %d\n",
1479                                fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1480                return -EINVAL;
1481        }
1482
1483        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1484        case SND_SOC_DAIFMT_CBS_CFS:
1485                break;
1486        case SND_SOC_DAIFMT_CBS_CFM:
1487                lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1488                break;
1489        case SND_SOC_DAIFMT_CBM_CFS:
1490                bclk |= ARIZONA_AIF1_BCLK_MSTR;
1491                break;
1492        case SND_SOC_DAIFMT_CBM_CFM:
1493                bclk |= ARIZONA_AIF1_BCLK_MSTR;
1494                lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1495                break;
1496        default:
1497                arizona_aif_err(dai, "Unsupported master mode %d\n",
1498                                fmt & SND_SOC_DAIFMT_MASTER_MASK);
1499                return -EINVAL;
1500        }
1501
1502        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1503        case SND_SOC_DAIFMT_NB_NF:
1504                break;
1505        case SND_SOC_DAIFMT_IB_IF:
1506                bclk |= ARIZONA_AIF1_BCLK_INV;
1507                lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1508                break;
1509        case SND_SOC_DAIFMT_IB_NF:
1510                bclk |= ARIZONA_AIF1_BCLK_INV;
1511                break;
1512        case SND_SOC_DAIFMT_NB_IF:
1513                lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1514                break;
1515        default:
1516                return -EINVAL;
1517        }
1518
1519        regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
1520                                 ARIZONA_AIF1_BCLK_INV |
1521                                 ARIZONA_AIF1_BCLK_MSTR,
1522                                 bclk);
1523        regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL,
1524                                 ARIZONA_AIF1TX_LRCLK_INV |
1525                                 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
1526        regmap_update_bits_async(arizona->regmap,
1527                                 base + ARIZONA_AIF_RX_PIN_CTRL,
1528                                 ARIZONA_AIF1RX_LRCLK_INV |
1529                                 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
1530        regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT,
1531                           ARIZONA_AIF1_FMT_MASK, mode);
1532
1533        return 0;
1534}
1535
1536static const int arizona_48k_bclk_rates[] = {
1537        -1,
1538        48000,
1539        64000,
1540        96000,
1541        128000,
1542        192000,
1543        256000,
1544        384000,
1545        512000,
1546        768000,
1547        1024000,
1548        1536000,
1549        2048000,
1550        3072000,
1551        4096000,
1552        6144000,
1553        8192000,
1554        12288000,
1555        24576000,
1556};
1557
1558static const int arizona_44k1_bclk_rates[] = {
1559        -1,
1560        44100,
1561        58800,
1562        88200,
1563        117600,
1564        177640,
1565        235200,
1566        352800,
1567        470400,
1568        705600,
1569        940800,
1570        1411200,
1571        1881600,
1572        2822400,
1573        3763200,
1574        5644800,
1575        7526400,
1576        11289600,
1577        22579200,
1578};
1579
1580static const unsigned int arizona_sr_vals[] = {
1581        0,
1582        12000,
1583        24000,
1584        48000,
1585        96000,
1586        192000,
1587        384000,
1588        768000,
1589        0,
1590        11025,
1591        22050,
1592        44100,
1593        88200,
1594        176400,
1595        352800,
1596        705600,
1597        4000,
1598        8000,
1599        16000,
1600        32000,
1601        64000,
1602        128000,
1603        256000,
1604        512000,
1605};
1606
1607#define ARIZONA_48K_RATE_MASK   0x0F003E
1608#define ARIZONA_44K1_RATE_MASK  0x003E00
1609#define ARIZONA_RATE_MASK       (ARIZONA_48K_RATE_MASK | ARIZONA_44K1_RATE_MASK)
1610
1611static const struct snd_pcm_hw_constraint_list arizona_constraint = {
1612        .count  = ARRAY_SIZE(arizona_sr_vals),
1613        .list   = arizona_sr_vals,
1614};
1615
1616static int arizona_startup(struct snd_pcm_substream *substream,
1617                           struct snd_soc_dai *dai)
1618{
1619        struct snd_soc_component *component = dai->component;
1620        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1621        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1622        unsigned int base_rate;
1623
1624        if (!substream->runtime)
1625                return 0;
1626
1627        switch (dai_priv->clk) {
1628        case ARIZONA_CLK_SYSCLK:
1629                base_rate = priv->sysclk;
1630                break;
1631        case ARIZONA_CLK_ASYNCCLK:
1632                base_rate = priv->asyncclk;
1633                break;
1634        default:
1635                return 0;
1636        }
1637
1638        if (base_rate == 0)
1639                dai_priv->constraint.mask = ARIZONA_RATE_MASK;
1640        else if (base_rate % 8000)
1641                dai_priv->constraint.mask = ARIZONA_44K1_RATE_MASK;
1642        else
1643                dai_priv->constraint.mask = ARIZONA_48K_RATE_MASK;
1644
1645        return snd_pcm_hw_constraint_list(substream->runtime, 0,
1646                                          SNDRV_PCM_HW_PARAM_RATE,
1647                                          &dai_priv->constraint);
1648}
1649
1650static void arizona_wm5102_set_dac_comp(struct snd_soc_component *component,
1651                                        unsigned int rate)
1652{
1653        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1654        struct arizona *arizona = priv->arizona;
1655        struct reg_sequence dac_comp[] = {
1656                { 0x80, 0x3 },
1657                { ARIZONA_DAC_COMP_1, 0 },
1658                { ARIZONA_DAC_COMP_2, 0 },
1659                { 0x80, 0x0 },
1660        };
1661
1662        mutex_lock(&arizona->dac_comp_lock);
1663
1664        dac_comp[1].def = arizona->dac_comp_coeff;
1665        if (rate >= 176400)
1666                dac_comp[2].def = arizona->dac_comp_enabled;
1667
1668        mutex_unlock(&arizona->dac_comp_lock);
1669
1670        regmap_multi_reg_write(arizona->regmap,
1671                               dac_comp,
1672                               ARRAY_SIZE(dac_comp));
1673}
1674
1675static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1676                                  struct snd_pcm_hw_params *params,
1677                                  struct snd_soc_dai *dai)
1678{
1679        struct snd_soc_component *component = dai->component;
1680        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1681        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1682        int base = dai->driver->base;
1683        int i, sr_val, ret;
1684
1685        /*
1686         * We will need to be more flexible than this in future,
1687         * currently we use a single sample rate for SYSCLK.
1688         */
1689        for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1690                if (arizona_sr_vals[i] == params_rate(params))
1691                        break;
1692        if (i == ARRAY_SIZE(arizona_sr_vals)) {
1693                arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1694                                params_rate(params));
1695                return -EINVAL;
1696        }
1697        sr_val = i;
1698
1699        switch (priv->arizona->type) {
1700        case WM5102:
1701        case WM8997:
1702                if (arizona_sr_vals[sr_val] >= 88200)
1703                        ret = arizona_dvfs_up(component, ARIZONA_DVFS_SR1_RQ);
1704                else
1705                        ret = arizona_dvfs_down(component, ARIZONA_DVFS_SR1_RQ);
1706
1707                if (ret) {
1708                        arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
1709                        return ret;
1710                }
1711                break;
1712        default:
1713                break;
1714        }
1715
1716        switch (dai_priv->clk) {
1717        case ARIZONA_CLK_SYSCLK:
1718                switch (priv->arizona->type) {
1719                case WM5102:
1720                        arizona_wm5102_set_dac_comp(component,
1721                                                    params_rate(params));
1722                        break;
1723                default:
1724                        break;
1725                }
1726
1727                snd_soc_component_update_bits(component, ARIZONA_SAMPLE_RATE_1,
1728                                              ARIZONA_SAMPLE_RATE_1_MASK,
1729                                              sr_val);
1730                if (base)
1731                        snd_soc_component_update_bits(component,
1732                                        base + ARIZONA_AIF_RATE_CTRL,
1733                                        ARIZONA_AIF1_RATE_MASK, 0);
1734                break;
1735        case ARIZONA_CLK_ASYNCCLK:
1736                snd_soc_component_update_bits(component,
1737                                              ARIZONA_ASYNC_SAMPLE_RATE_1,
1738                                              ARIZONA_ASYNC_SAMPLE_RATE_1_MASK,
1739                                              sr_val);
1740                if (base)
1741                        snd_soc_component_update_bits(component,
1742                                        base + ARIZONA_AIF_RATE_CTRL,
1743                                        ARIZONA_AIF1_RATE_MASK,
1744                                        8 << ARIZONA_AIF1_RATE_SHIFT);
1745                break;
1746        default:
1747                arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1748                return -EINVAL;
1749        }
1750
1751        return 0;
1752}
1753
1754static bool arizona_aif_cfg_changed(struct snd_soc_component *component,
1755                                    int base, int bclk, int lrclk, int frame)
1756{
1757        int val;
1758
1759        val = snd_soc_component_read(component, base + ARIZONA_AIF_BCLK_CTRL);
1760        if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
1761                return true;
1762
1763        val = snd_soc_component_read(component, base + ARIZONA_AIF_TX_BCLK_RATE);
1764        if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK))
1765                return true;
1766
1767        val = snd_soc_component_read(component, base + ARIZONA_AIF_FRAME_CTRL_1);
1768        if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
1769                             ARIZONA_AIF1TX_SLOT_LEN_MASK)))
1770                return true;
1771
1772        return false;
1773}
1774
1775static int arizona_hw_params(struct snd_pcm_substream *substream,
1776                             struct snd_pcm_hw_params *params,
1777                             struct snd_soc_dai *dai)
1778{
1779        struct snd_soc_component *component = dai->component;
1780        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1781        struct arizona *arizona = priv->arizona;
1782        int base = dai->driver->base;
1783        const int *rates;
1784        int i, ret, val;
1785        int channels = params_channels(params);
1786        int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1787        int tdm_width = arizona->tdm_width[dai->id - 1];
1788        int tdm_slots = arizona->tdm_slots[dai->id - 1];
1789        int bclk, lrclk, wl, frame, bclk_target;
1790        bool reconfig;
1791        unsigned int aif_tx_state, aif_rx_state;
1792
1793        if (params_rate(params) % 4000)
1794                rates = &arizona_44k1_bclk_rates[0];
1795        else
1796                rates = &arizona_48k_bclk_rates[0];
1797
1798        wl = params_width(params);
1799
1800        if (tdm_slots) {
1801                arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
1802                                tdm_slots, tdm_width);
1803                bclk_target = tdm_slots * tdm_width * params_rate(params);
1804                channels = tdm_slots;
1805        } else {
1806                bclk_target = snd_soc_params_to_bclk(params);
1807                tdm_width = wl;
1808        }
1809
1810        if (chan_limit && chan_limit < channels) {
1811                arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1812                bclk_target /= channels;
1813                bclk_target *= chan_limit;
1814        }
1815
1816        /* Force multiple of 2 channels for I2S mode */
1817        val = snd_soc_component_read(component, base + ARIZONA_AIF_FORMAT);
1818        val &= ARIZONA_AIF1_FMT_MASK;
1819        if ((channels & 1) && (val == ARIZONA_FMT_I2S_MODE)) {
1820                arizona_aif_dbg(dai, "Forcing stereo mode\n");
1821                bclk_target /= channels;
1822                bclk_target *= channels + 1;
1823        }
1824
1825        for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1826                if (rates[i] >= bclk_target &&
1827                    rates[i] % params_rate(params) == 0) {
1828                        bclk = i;
1829                        break;
1830                }
1831        }
1832        if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1833                arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1834                                params_rate(params));
1835                return -EINVAL;
1836        }
1837
1838        lrclk = rates[bclk] / params_rate(params);
1839
1840        arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1841                        rates[bclk], rates[bclk] / lrclk);
1842
1843        frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width;
1844
1845        reconfig = arizona_aif_cfg_changed(component, base, bclk, lrclk, frame);
1846
1847        if (reconfig) {
1848                /* Save AIF TX/RX state */
1849                aif_tx_state = snd_soc_component_read(component,
1850                                            base + ARIZONA_AIF_TX_ENABLES);
1851                aif_rx_state = snd_soc_component_read(component,
1852                                            base + ARIZONA_AIF_RX_ENABLES);
1853                /* Disable AIF TX/RX before reconfiguring it */
1854                regmap_update_bits_async(arizona->regmap,
1855                                         base + ARIZONA_AIF_TX_ENABLES,
1856                                         0xff, 0x0);
1857                regmap_update_bits(arizona->regmap,
1858                                   base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
1859        }
1860
1861        ret = arizona_hw_params_rate(substream, params, dai);
1862        if (ret != 0)
1863                goto restore_aif;
1864
1865        if (reconfig) {
1866                regmap_update_bits_async(arizona->regmap,
1867                                         base + ARIZONA_AIF_BCLK_CTRL,
1868                                         ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1869                regmap_update_bits_async(arizona->regmap,
1870                                         base + ARIZONA_AIF_TX_BCLK_RATE,
1871                                         ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1872                regmap_update_bits_async(arizona->regmap,
1873                                         base + ARIZONA_AIF_RX_BCLK_RATE,
1874                                         ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1875                regmap_update_bits_async(arizona->regmap,
1876                                         base + ARIZONA_AIF_FRAME_CTRL_1,
1877                                         ARIZONA_AIF1TX_WL_MASK |
1878                                         ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1879                regmap_update_bits(arizona->regmap,
1880                                   base + ARIZONA_AIF_FRAME_CTRL_2,
1881                                   ARIZONA_AIF1RX_WL_MASK |
1882                                   ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1883        }
1884
1885restore_aif:
1886        if (reconfig) {
1887                /* Restore AIF TX/RX state */
1888                regmap_update_bits_async(arizona->regmap,
1889                                         base + ARIZONA_AIF_TX_ENABLES,
1890                                         0xff, aif_tx_state);
1891                regmap_update_bits(arizona->regmap,
1892                                   base + ARIZONA_AIF_RX_ENABLES,
1893                                   0xff, aif_rx_state);
1894        }
1895        return ret;
1896}
1897
1898static const char *arizona_dai_clk_str(int clk_id)
1899{
1900        switch (clk_id) {
1901        case ARIZONA_CLK_SYSCLK:
1902                return "SYSCLK";
1903        case ARIZONA_CLK_ASYNCCLK:
1904                return "ASYNCCLK";
1905        default:
1906                return "Unknown clock";
1907        }
1908}
1909
1910static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1911                                  int clk_id, unsigned int freq, int dir)
1912{
1913        struct snd_soc_component *component = dai->component;
1914        struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1915        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1916        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1917        struct snd_soc_dapm_route routes[2];
1918
1919        switch (clk_id) {
1920        case ARIZONA_CLK_SYSCLK:
1921        case ARIZONA_CLK_ASYNCCLK:
1922                break;
1923        default:
1924                return -EINVAL;
1925        }
1926
1927        if (clk_id == dai_priv->clk)
1928                return 0;
1929
1930        if (snd_soc_dai_active(dai)) {
1931                dev_err(component->dev, "Can't change clock on active DAI %d\n",
1932                        dai->id);
1933                return -EBUSY;
1934        }
1935
1936        dev_dbg(component->dev, "Setting AIF%d to %s\n", dai->id + 1,
1937                arizona_dai_clk_str(clk_id));
1938
1939        memset(&routes, 0, sizeof(routes));
1940        routes[0].sink = dai->driver->capture.stream_name;
1941        routes[1].sink = dai->driver->playback.stream_name;
1942
1943        routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1944        routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1945        snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
1946
1947        routes[0].source = arizona_dai_clk_str(clk_id);
1948        routes[1].source = arizona_dai_clk_str(clk_id);
1949        snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
1950
1951        dai_priv->clk = clk_id;
1952
1953        return snd_soc_dapm_sync(dapm);
1954}
1955
1956static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1957{
1958        struct snd_soc_component *component = dai->component;
1959        int base = dai->driver->base;
1960        unsigned int reg;
1961
1962        if (tristate)
1963                reg = ARIZONA_AIF1_TRI;
1964        else
1965                reg = 0;
1966
1967        return snd_soc_component_update_bits(component,
1968                                             base + ARIZONA_AIF_RATE_CTRL,
1969                                             ARIZONA_AIF1_TRI, reg);
1970}
1971
1972static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
1973                                         unsigned int base,
1974                                         int channels, unsigned int mask)
1975{
1976        struct snd_soc_component *component = dai->component;
1977        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1978        struct arizona *arizona = priv->arizona;
1979        int slot, i;
1980
1981        for (i = 0; i < channels; ++i) {
1982                slot = ffs(mask) - 1;
1983                if (slot < 0)
1984                        return;
1985
1986                regmap_write(arizona->regmap, base + i, slot);
1987
1988                mask &= ~(1 << slot);
1989        }
1990
1991        if (mask)
1992                arizona_aif_warn(dai, "Too many channels in TDM mask\n");
1993}
1994
1995static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1996                                unsigned int rx_mask, int slots, int slot_width)
1997{
1998        struct snd_soc_component *component = dai->component;
1999        struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
2000        struct arizona *arizona = priv->arizona;
2001        int base = dai->driver->base;
2002        int rx_max_chan = dai->driver->playback.channels_max;
2003        int tx_max_chan = dai->driver->capture.channels_max;
2004
2005        /* Only support TDM for the physical AIFs */
2006        if (dai->id > ARIZONA_MAX_AIF)
2007                return -ENOTSUPP;
2008
2009        if (slots == 0) {
2010                tx_mask = (1 << tx_max_chan) - 1;
2011                rx_mask = (1 << rx_max_chan) - 1;
2012        }
2013
2014        arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_3,
2015                                     tx_max_chan, tx_mask);
2016        arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_11,
2017                                     rx_max_chan, rx_mask);
2018
2019        arizona->tdm_width[dai->id - 1] = slot_width;
2020        arizona->tdm_slots[dai->id - 1] = slots;
2021
2022        return 0;
2023}
2024
2025const struct snd_soc_dai_ops arizona_dai_ops = {
2026        .startup = arizona_startup,
2027        .set_fmt = arizona_set_fmt,
2028        .set_tdm_slot = arizona_set_tdm_slot,
2029        .hw_params = arizona_hw_params,
2030        .set_sysclk = arizona_dai_set_sysclk,
2031        .set_tristate = arizona_set_tristate,
2032};
2033EXPORT_SYMBOL_GPL(arizona_dai_ops);
2034
2035const struct snd_soc_dai_ops arizona_simple_dai_ops = {
2036        .startup = arizona_startup,
2037        .hw_params = arizona_hw_params_rate,
2038        .set_sysclk = arizona_dai_set_sysclk,
2039};
2040EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
2041
2042int arizona_init_dai(struct arizona_priv *priv, int id)
2043{
2044        struct arizona_dai_priv *dai_priv = &priv->dai[id];
2045
2046        dai_priv->clk = ARIZONA_CLK_SYSCLK;
2047        dai_priv->constraint = arizona_constraint;
2048
2049        return 0;
2050}
2051EXPORT_SYMBOL_GPL(arizona_init_dai);
2052
2053static struct {
2054        unsigned int min;
2055        unsigned int max;
2056        u16 fratio;
2057        int ratio;
2058} fll_fratios[] = {
2059        {       0,    64000, 4, 16 },
2060        {   64000,   128000, 3,  8 },
2061        {  128000,   256000, 2,  4 },
2062        {  256000,  1000000, 1,  2 },
2063        { 1000000, 13500000, 0,  1 },
2064};
2065
2066static const unsigned int pseudo_fref_max[ARIZONA_FLL_MAX_FRATIO] = {
2067        13500000,
2068         6144000,
2069         6144000,
2070         3072000,
2071         3072000,
2072         2822400,
2073         2822400,
2074         1536000,
2075         1536000,
2076         1536000,
2077         1536000,
2078         1536000,
2079         1536000,
2080         1536000,
2081         1536000,
2082          768000,
2083};
2084
2085static struct {
2086        unsigned int min;
2087        unsigned int max;
2088        u16 gain;
2089} fll_gains[] = {
2090        {       0,   256000, 0 },
2091        {  256000,  1000000, 2 },
2092        { 1000000, 13500000, 4 },
2093};
2094
2095struct arizona_fll_cfg {
2096        int n;
2097        unsigned int theta;
2098        unsigned int lambda;
2099        int refdiv;
2100        int outdiv;
2101        int fratio;
2102        int gain;
2103};
2104
2105static int arizona_validate_fll(struct arizona_fll *fll,
2106                                unsigned int Fref,
2107                                unsigned int Fout)
2108{
2109        unsigned int Fvco_min;
2110
2111        if (fll->fout && Fout != fll->fout) {
2112                arizona_fll_err(fll,
2113                                "Can't change output on active FLL\n");
2114                return -EINVAL;
2115        }
2116
2117        if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
2118                arizona_fll_err(fll,
2119                                "Can't scale %dMHz in to <=13.5MHz\n",
2120                                Fref);
2121                return -EINVAL;
2122        }
2123
2124        Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
2125        if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
2126                arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
2127                                Fout);
2128                return -EINVAL;
2129        }
2130
2131        return 0;
2132}
2133
2134static int arizona_find_fratio(unsigned int Fref, int *fratio)
2135{
2136        int i;
2137
2138        /* Find an appropriate FLL_FRATIO */
2139        for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
2140                if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
2141                        if (fratio)
2142                                *fratio = fll_fratios[i].fratio;
2143                        return fll_fratios[i].ratio;
2144                }
2145        }
2146
2147        return -EINVAL;
2148}
2149
2150static int arizona_calc_fratio(struct arizona_fll *fll,
2151                               struct arizona_fll_cfg *cfg,
2152                               unsigned int target,
2153                               unsigned int Fref, bool sync)
2154{
2155        int init_ratio, ratio;
2156        int refdiv, div;
2157
2158        /* Fref must be <=13.5MHz, find initial refdiv */
2159        div = 1;
2160        cfg->refdiv = 0;
2161        while (Fref > ARIZONA_FLL_MAX_FREF) {
2162                div *= 2;
2163                Fref /= 2;
2164                cfg->refdiv++;
2165
2166                if (div > ARIZONA_FLL_MAX_REFDIV)
2167                        return -EINVAL;
2168        }
2169
2170        /* Find an appropriate FLL_FRATIO */
2171        init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
2172        if (init_ratio < 0) {
2173                arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
2174                                Fref);
2175                return init_ratio;
2176        }
2177
2178        switch (fll->arizona->type) {
2179        case WM5102:
2180        case WM8997:
2181                return init_ratio;
2182        case WM5110:
2183        case WM8280:
2184                if (fll->arizona->rev < 3 || sync)
2185                        return init_ratio;
2186                break;
2187        default:
2188                if (sync)
2189                        return init_ratio;
2190                break;
2191        }
2192
2193        cfg->fratio = init_ratio - 1;
2194
2195        /* Adjust FRATIO/refdiv to avoid integer mode if possible */
2196        refdiv = cfg->refdiv;
2197
2198        arizona_fll_dbg(fll, "pseudo: initial ratio=%u fref=%u refdiv=%u\n",
2199                        init_ratio, Fref, refdiv);
2200
2201        while (div <= ARIZONA_FLL_MAX_REFDIV) {
2202                /* start from init_ratio because this may already give a
2203                 * fractional N.K
2204                 */
2205                for (ratio = init_ratio; ratio > 0; ratio--) {
2206                        if (target % (ratio * Fref)) {
2207                                cfg->refdiv = refdiv;
2208                                cfg->fratio = ratio - 1;
2209                                arizona_fll_dbg(fll,
2210                                        "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2211                                        Fref, refdiv, div, ratio);
2212                                return ratio;
2213                        }
2214                }
2215
2216                for (ratio = init_ratio + 1; ratio <= ARIZONA_FLL_MAX_FRATIO;
2217                     ratio++) {
2218                        if ((ARIZONA_FLL_VCO_CORNER / 2) /
2219                            (fll->vco_mult * ratio) < Fref) {
2220                                arizona_fll_dbg(fll, "pseudo: hit VCO corner\n");
2221                                break;
2222                        }
2223
2224                        if (Fref > pseudo_fref_max[ratio - 1]) {
2225                                arizona_fll_dbg(fll,
2226                                        "pseudo: exceeded max fref(%u) for ratio=%u\n",
2227                                        pseudo_fref_max[ratio - 1],
2228                                        ratio);
2229                                break;
2230                        }
2231
2232                        if (target % (ratio * Fref)) {
2233                                cfg->refdiv = refdiv;
2234                                cfg->fratio = ratio - 1;
2235                                arizona_fll_dbg(fll,
2236                                        "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2237                                        Fref, refdiv, div, ratio);
2238                                return ratio;
2239                        }
2240                }
2241
2242                div *= 2;
2243                Fref /= 2;
2244                refdiv++;
2245                init_ratio = arizona_find_fratio(Fref, NULL);
2246                arizona_fll_dbg(fll,
2247                                "pseudo: change fref=%u refdiv=%d(%d) ratio=%u\n",
2248                                Fref, refdiv, div, init_ratio);
2249        }
2250
2251        arizona_fll_warn(fll, "Falling back to integer mode operation\n");
2252        return cfg->fratio + 1;
2253}
2254
2255static int arizona_calc_fll(struct arizona_fll *fll,
2256                            struct arizona_fll_cfg *cfg,
2257                            unsigned int Fref, bool sync)
2258{
2259        unsigned int target, div, gcd_fll;
2260        int i, ratio;
2261
2262        arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
2263
2264        /* Fvco should be over the targt; don't check the upper bound */
2265        div = ARIZONA_FLL_MIN_OUTDIV;
2266        while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
2267                div++;
2268                if (div > ARIZONA_FLL_MAX_OUTDIV)
2269                        return -EINVAL;
2270        }
2271        target = fll->fout * div / fll->vco_mult;
2272        cfg->outdiv = div;
2273
2274        arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
2275
2276        /* Find an appropriate FLL_FRATIO and refdiv */
2277        ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
2278        if (ratio < 0)
2279                return ratio;
2280
2281        /* Apply the division for our remaining calculations */
2282        Fref = Fref / (1 << cfg->refdiv);
2283
2284        cfg->n = target / (ratio * Fref);
2285
2286        if (target % (ratio * Fref)) {
2287                gcd_fll = gcd(target, ratio * Fref);
2288                arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
2289
2290                cfg->theta = (target - (cfg->n * ratio * Fref))
2291                        / gcd_fll;
2292                cfg->lambda = (ratio * Fref) / gcd_fll;
2293        } else {
2294                cfg->theta = 0;
2295                cfg->lambda = 0;
2296        }
2297
2298        /* Round down to 16bit range with cost of accuracy lost.
2299         * Denominator must be bigger than numerator so we only
2300         * take care of it.
2301         */
2302        while (cfg->lambda >= (1 << 16)) {
2303                cfg->theta >>= 1;
2304                cfg->lambda >>= 1;
2305        }
2306
2307        for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
2308                if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
2309                        cfg->gain = fll_gains[i].gain;
2310                        break;
2311                }
2312        }
2313        if (i == ARRAY_SIZE(fll_gains)) {
2314                arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
2315                                Fref);
2316                return -EINVAL;
2317        }
2318
2319        arizona_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
2320                        cfg->n, cfg->theta, cfg->lambda);
2321        arizona_fll_dbg(fll, "FRATIO=0x%x(%d) OUTDIV=%d REFCLK_DIV=0x%x(%d)\n",
2322                        cfg->fratio, ratio, cfg->outdiv,
2323                        cfg->refdiv, 1 << cfg->refdiv);
2324        arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
2325
2326        return 0;
2327}
2328
2329static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
2330                              struct arizona_fll_cfg *cfg, int source,
2331                              bool sync)
2332{
2333        regmap_update_bits_async(arizona->regmap, base + 3,
2334                                 ARIZONA_FLL1_THETA_MASK, cfg->theta);
2335        regmap_update_bits_async(arizona->regmap, base + 4,
2336                                 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
2337        regmap_update_bits_async(arizona->regmap, base + 5,
2338                                 ARIZONA_FLL1_FRATIO_MASK,
2339                                 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
2340        regmap_update_bits_async(arizona->regmap, base + 6,
2341                                 ARIZONA_FLL1_CLK_REF_DIV_MASK |
2342                                 ARIZONA_FLL1_CLK_REF_SRC_MASK,
2343                                 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
2344                                 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
2345
2346        if (sync) {
2347                regmap_update_bits(arizona->regmap, base + 0x7,
2348                                   ARIZONA_FLL1_GAIN_MASK,
2349                                   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2350        } else {
2351                regmap_update_bits(arizona->regmap, base + 0x5,
2352                                   ARIZONA_FLL1_OUTDIV_MASK,
2353                                   cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
2354                regmap_update_bits(arizona->regmap, base + 0x9,
2355                                   ARIZONA_FLL1_GAIN_MASK,
2356                                   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2357        }
2358
2359        regmap_update_bits_async(arizona->regmap, base + 2,
2360                                 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
2361                                 ARIZONA_FLL1_CTRL_UPD | cfg->n);
2362}
2363
2364static int arizona_is_enabled_fll(struct arizona_fll *fll, int base)
2365{
2366        struct arizona *arizona = fll->arizona;
2367        unsigned int reg;
2368        int ret;
2369
2370        ret = regmap_read(arizona->regmap, base + 1, &reg);
2371        if (ret != 0) {
2372                arizona_fll_err(fll, "Failed to read current state: %d\n",
2373                                ret);
2374                return ret;
2375        }
2376
2377        return reg & ARIZONA_FLL1_ENA;
2378}
2379
2380static int arizona_set_fll_clks(struct arizona_fll *fll, int base, bool ena)
2381{
2382        struct arizona *arizona = fll->arizona;
2383        unsigned int val;
2384        struct clk *clk;
2385        int ret;
2386
2387        ret = regmap_read(arizona->regmap, base + 6, &val);
2388        if (ret != 0) {
2389                arizona_fll_err(fll, "Failed to read current source: %d\n",
2390                                ret);
2391                return ret;
2392        }
2393
2394        val &= ARIZONA_FLL1_CLK_REF_SRC_MASK;
2395        val >>= ARIZONA_FLL1_CLK_REF_SRC_SHIFT;
2396
2397        switch (val) {
2398        case ARIZONA_FLL_SRC_MCLK1:
2399                clk = arizona->mclk[ARIZONA_MCLK1];
2400                break;
2401        case ARIZONA_FLL_SRC_MCLK2:
2402                clk = arizona->mclk[ARIZONA_MCLK2];
2403                break;
2404        default:
2405                return 0;
2406        }
2407
2408        if (ena) {
2409                return clk_prepare_enable(clk);
2410        } else {
2411                clk_disable_unprepare(clk);
2412                return 0;
2413        }
2414}
2415
2416static int arizona_enable_fll(struct arizona_fll *fll)
2417{
2418        struct arizona *arizona = fll->arizona;
2419        bool use_sync = false;
2420        int already_enabled = arizona_is_enabled_fll(fll, fll->base);
2421        int sync_enabled = arizona_is_enabled_fll(fll, fll->base + 0x10);
2422        struct arizona_fll_cfg cfg;
2423        int i;
2424        unsigned int val;
2425
2426        if (already_enabled < 0)
2427                return already_enabled;
2428        if (sync_enabled < 0)
2429                return sync_enabled;
2430
2431        if (already_enabled) {
2432                /* Facilitate smooth refclk across the transition */
2433                regmap_update_bits(fll->arizona->regmap, fll->base + 1,
2434                                   ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2435                udelay(32);
2436                regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2437                                         ARIZONA_FLL1_GAIN_MASK, 0);
2438
2439                if (arizona_is_enabled_fll(fll, fll->base + 0x10) > 0)
2440                        arizona_set_fll_clks(fll, fll->base + 0x10, false);
2441                arizona_set_fll_clks(fll, fll->base, false);
2442        }
2443
2444        /*
2445         * If we have both REFCLK and SYNCCLK then enable both,
2446         * otherwise apply the SYNCCLK settings to REFCLK.
2447         */
2448        if (fll->ref_src >= 0 && fll->ref_freq &&
2449            fll->ref_src != fll->sync_src) {
2450                arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
2451
2452                /* Ref path hardcodes lambda to 65536 when sync is on */
2453                if (fll->sync_src >= 0 && cfg.lambda)
2454                        cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
2455
2456                arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
2457                                  false);
2458                if (fll->sync_src >= 0) {
2459                        arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
2460
2461                        arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
2462                                          fll->sync_src, true);
2463                        use_sync = true;
2464                }
2465        } else if (fll->sync_src >= 0) {
2466                arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
2467
2468                arizona_apply_fll(arizona, fll->base, &cfg,
2469                                  fll->sync_src, false);
2470
2471                regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2472                                         ARIZONA_FLL1_SYNC_ENA, 0);
2473        } else {
2474                arizona_fll_err(fll, "No clocks provided\n");
2475                return -EINVAL;
2476        }
2477
2478        if (already_enabled && !!sync_enabled != use_sync)
2479                arizona_fll_warn(fll, "Synchroniser changed on active FLL\n");
2480
2481        /*
2482         * Increase the bandwidth if we're not using a low frequency
2483         * sync source.
2484         */
2485        if (use_sync && fll->sync_freq > 100000)
2486                regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2487                                         ARIZONA_FLL1_SYNC_BW, 0);
2488        else
2489                regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2490                                         ARIZONA_FLL1_SYNC_BW,
2491                                         ARIZONA_FLL1_SYNC_BW);
2492
2493        if (!already_enabled)
2494                pm_runtime_get_sync(arizona->dev);
2495
2496        if (use_sync) {
2497                arizona_set_fll_clks(fll, fll->base + 0x10, true);
2498                regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2499                                         ARIZONA_FLL1_SYNC_ENA,
2500                                         ARIZONA_FLL1_SYNC_ENA);
2501        }
2502        arizona_set_fll_clks(fll, fll->base, true);
2503        regmap_update_bits_async(arizona->regmap, fll->base + 1,
2504                                 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
2505
2506        if (already_enabled)
2507                regmap_update_bits_async(arizona->regmap, fll->base + 1,
2508                                         ARIZONA_FLL1_FREERUN, 0);
2509
2510        arizona_fll_dbg(fll, "Waiting for FLL lock...\n");
2511        val = 0;
2512        for (i = 0; i < 15; i++) {
2513                if (i < 5)
2514                        usleep_range(200, 400);
2515                else
2516                        msleep(20);
2517
2518                regmap_read(arizona->regmap,
2519                            ARIZONA_INTERRUPT_RAW_STATUS_5,
2520                            &val);
2521                if (val & (ARIZONA_FLL1_CLOCK_OK_STS << (fll->id - 1)))
2522                        break;
2523        }
2524        if (i == 15)
2525                arizona_fll_warn(fll, "Timed out waiting for lock\n");
2526        else
2527                arizona_fll_dbg(fll, "FLL locked (%d polls)\n", i);
2528
2529        return 0;
2530}
2531
2532static void arizona_disable_fll(struct arizona_fll *fll)
2533{
2534        struct arizona *arizona = fll->arizona;
2535        bool ref_change, sync_change;
2536
2537        regmap_update_bits_async(arizona->regmap, fll->base + 1,
2538                                 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2539        regmap_update_bits_check(arizona->regmap, fll->base + 1,
2540                                 ARIZONA_FLL1_ENA, 0, &ref_change);
2541        regmap_update_bits_check(arizona->regmap, fll->base + 0x11,
2542                                 ARIZONA_FLL1_SYNC_ENA, 0, &sync_change);
2543        regmap_update_bits_async(arizona->regmap, fll->base + 1,
2544                                 ARIZONA_FLL1_FREERUN, 0);
2545
2546        if (sync_change)
2547                arizona_set_fll_clks(fll, fll->base + 0x10, false);
2548
2549        if (ref_change) {
2550                arizona_set_fll_clks(fll, fll->base, false);
2551                pm_runtime_put_autosuspend(arizona->dev);
2552        }
2553}
2554
2555int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
2556                           unsigned int Fref, unsigned int Fout)
2557{
2558        int ret = 0;
2559
2560        if (fll->ref_src == source && fll->ref_freq == Fref)
2561                return 0;
2562
2563        if (fll->fout && Fref > 0) {
2564                ret = arizona_validate_fll(fll, Fref, fll->fout);
2565                if (ret != 0)
2566                        return ret;
2567        }
2568
2569        fll->ref_src = source;
2570        fll->ref_freq = Fref;
2571
2572        if (fll->fout && Fref > 0)
2573                ret = arizona_enable_fll(fll);
2574
2575        return ret;
2576}
2577EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
2578
2579int arizona_set_fll(struct arizona_fll *fll, int source,
2580                    unsigned int Fref, unsigned int Fout)
2581{
2582        int ret = 0;
2583
2584        if (fll->sync_src == source &&
2585            fll->sync_freq == Fref && fll->fout == Fout)
2586                return 0;
2587
2588        if (Fout) {
2589                if (fll->ref_src >= 0) {
2590                        ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
2591                        if (ret != 0)
2592                                return ret;
2593                }
2594
2595                ret = arizona_validate_fll(fll, Fref, Fout);
2596                if (ret != 0)
2597                        return ret;
2598        }
2599
2600        fll->sync_src = source;
2601        fll->sync_freq = Fref;
2602        fll->fout = Fout;
2603
2604        if (Fout)
2605                ret = arizona_enable_fll(fll);
2606        else
2607                arizona_disable_fll(fll);
2608
2609        return ret;
2610}
2611EXPORT_SYMBOL_GPL(arizona_set_fll);
2612
2613int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
2614                     int ok_irq, struct arizona_fll *fll)
2615{
2616        unsigned int val;
2617
2618        fll->id = id;
2619        fll->base = base;
2620        fll->arizona = arizona;
2621        fll->sync_src = ARIZONA_FLL_SRC_NONE;
2622
2623        /* Configure default refclk to 32kHz if we have one */
2624        regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
2625        switch (val & ARIZONA_CLK_32K_SRC_MASK) {
2626        case ARIZONA_CLK_SRC_MCLK1:
2627        case ARIZONA_CLK_SRC_MCLK2:
2628                fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
2629                break;
2630        default:
2631                fll->ref_src = ARIZONA_FLL_SRC_NONE;
2632        }
2633        fll->ref_freq = 32768;
2634
2635        snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
2636        snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
2637                 "FLL%d clock OK", id);
2638
2639        regmap_update_bits(arizona->regmap, fll->base + 1,
2640                           ARIZONA_FLL1_FREERUN, 0);
2641
2642        return 0;
2643}
2644EXPORT_SYMBOL_GPL(arizona_init_fll);
2645
2646/**
2647 * arizona_set_output_mode - Set the mode of the specified output
2648 *
2649 * @component: Device to configure
2650 * @output: Output number
2651 * @diff: True to set the output to differential mode
2652 *
2653 * Some systems use external analogue switches to connect more
2654 * analogue devices to the CODEC than are supported by the device.  In
2655 * some systems this requires changing the switched output from single
2656 * ended to differential mode dynamically at runtime, an operation
2657 * supported using this function.
2658 *
2659 * Most systems have a single static configuration and should use
2660 * platform data instead.
2661 */
2662int arizona_set_output_mode(struct snd_soc_component *component, int output,
2663                            bool diff)
2664{
2665        unsigned int reg, val;
2666
2667        if (output < 1 || output > 6)
2668                return -EINVAL;
2669
2670        reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
2671
2672        if (diff)
2673                val = ARIZONA_OUT1_MONO;
2674        else
2675                val = 0;
2676
2677        return snd_soc_component_update_bits(component, reg,
2678                                             ARIZONA_OUT1_MONO, val);
2679}
2680EXPORT_SYMBOL_GPL(arizona_set_output_mode);
2681
2682static const struct soc_enum arizona_adsp2_rate_enum[] = {
2683        SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
2684                              ARIZONA_DSP1_RATE_SHIFT, 0xf,
2685                              ARIZONA_RATE_ENUM_SIZE,
2686                              arizona_rate_text, arizona_rate_val),
2687        SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
2688                              ARIZONA_DSP1_RATE_SHIFT, 0xf,
2689                              ARIZONA_RATE_ENUM_SIZE,
2690                              arizona_rate_text, arizona_rate_val),
2691        SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
2692                              ARIZONA_DSP1_RATE_SHIFT, 0xf,
2693                              ARIZONA_RATE_ENUM_SIZE,
2694                              arizona_rate_text, arizona_rate_val),
2695        SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1,
2696                              ARIZONA_DSP1_RATE_SHIFT, 0xf,
2697                              ARIZONA_RATE_ENUM_SIZE,
2698                              arizona_rate_text, arizona_rate_val),
2699};
2700
2701const struct snd_kcontrol_new arizona_adsp2_rate_controls[] = {
2702        SOC_ENUM("DSP1 Rate", arizona_adsp2_rate_enum[0]),
2703        SOC_ENUM("DSP2 Rate", arizona_adsp2_rate_enum[1]),
2704        SOC_ENUM("DSP3 Rate", arizona_adsp2_rate_enum[2]),
2705        SOC_ENUM("DSP4 Rate", arizona_adsp2_rate_enum[3]),
2706};
2707EXPORT_SYMBOL_GPL(arizona_adsp2_rate_controls);
2708
2709static bool arizona_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
2710{
2711        s16 a = be16_to_cpu(_a);
2712        s16 b = be16_to_cpu(_b);
2713
2714        if (!mode) {
2715                return abs(a) >= 4096;
2716        } else {
2717                if (abs(b) >= 4096)
2718                        return true;
2719
2720                return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
2721        }
2722}
2723
2724int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
2725                         struct snd_ctl_elem_value *ucontrol)
2726{
2727        struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2728        struct arizona *arizona = dev_get_drvdata(component->dev->parent);
2729        struct soc_bytes *params = (void *)kcontrol->private_value;
2730        unsigned int val;
2731        __be16 *data;
2732        int len;
2733        int ret;
2734
2735        len = params->num_regs * regmap_get_val_bytes(arizona->regmap);
2736
2737        data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
2738        if (!data)
2739                return -ENOMEM;
2740
2741        data[0] &= cpu_to_be16(ARIZONA_EQ1_B1_MODE);
2742
2743        if (arizona_eq_filter_unstable(!!data[0], data[1], data[2]) ||
2744            arizona_eq_filter_unstable(true, data[4], data[5]) ||
2745            arizona_eq_filter_unstable(true, data[8], data[9]) ||
2746            arizona_eq_filter_unstable(true, data[12], data[13]) ||
2747            arizona_eq_filter_unstable(false, data[16], data[17])) {
2748                dev_err(arizona->dev, "Rejecting unstable EQ coefficients\n");
2749                ret = -EINVAL;
2750                goto out;
2751        }
2752
2753        ret = regmap_read(arizona->regmap, params->base, &val);
2754        if (ret != 0)
2755                goto out;
2756
2757        val &= ~ARIZONA_EQ1_B1_MODE;
2758        data[0] |= cpu_to_be16(val);
2759
2760        ret = regmap_raw_write(arizona->regmap, params->base, data, len);
2761
2762out:
2763        kfree(data);
2764        return ret;
2765}
2766EXPORT_SYMBOL_GPL(arizona_eq_coeff_put);
2767
2768int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
2769                           struct snd_ctl_elem_value *ucontrol)
2770{
2771        struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2772        struct arizona *arizona = dev_get_drvdata(component->dev->parent);
2773        __be16 *data = (__be16 *)ucontrol->value.bytes.data;
2774        s16 val = be16_to_cpu(*data);
2775
2776        if (abs(val) >= 4096) {
2777                dev_err(arizona->dev, "Rejecting unstable LHPF coefficients\n");
2778                return -EINVAL;
2779        }
2780
2781        return snd_soc_bytes_put(kcontrol, ucontrol);
2782}
2783EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put);
2784
2785int arizona_of_get_audio_pdata(struct arizona *arizona)
2786{
2787        struct arizona_pdata *pdata = &arizona->pdata;
2788        struct device_node *np = arizona->dev->of_node;
2789        struct property *prop;
2790        const __be32 *cur;
2791        u32 val;
2792        u32 pdm_val[ARIZONA_MAX_PDM_SPK];
2793        int ret;
2794        int count = 0;
2795
2796        count = 0;
2797        of_property_for_each_u32(np, "wlf,inmode", prop, cur, val) {
2798                if (count == ARRAY_SIZE(pdata->inmode))
2799                        break;
2800
2801                pdata->inmode[count] = val;
2802                count++;
2803        }
2804
2805        count = 0;
2806        of_property_for_each_u32(np, "wlf,dmic-ref", prop, cur, val) {
2807                if (count == ARRAY_SIZE(pdata->dmic_ref))
2808                        break;
2809
2810                pdata->dmic_ref[count] = val;
2811                count++;
2812        }
2813
2814        count = 0;
2815        of_property_for_each_u32(np, "wlf,out-mono", prop, cur, val) {
2816                if (count == ARRAY_SIZE(pdata->out_mono))
2817                        break;
2818
2819                pdata->out_mono[count] = !!val;
2820                count++;
2821        }
2822
2823        count = 0;
2824        of_property_for_each_u32(np, "wlf,max-channels-clocked", prop, cur, val) {
2825                if (count == ARRAY_SIZE(pdata->max_channels_clocked))
2826                        break;
2827
2828                pdata->max_channels_clocked[count] = val;
2829                count++;
2830        }
2831
2832        count = 0;
2833        of_property_for_each_u32(np, "wlf,out-volume-limit", prop, cur, val) {
2834                if (count == ARRAY_SIZE(pdata->out_vol_limit))
2835                        break;
2836
2837                pdata->out_vol_limit[count] = val;
2838                count++;
2839        }
2840
2841        ret = of_property_read_u32_array(np, "wlf,spk-fmt",
2842                                         pdm_val, ARRAY_SIZE(pdm_val));
2843
2844        if (ret >= 0)
2845                for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
2846                        pdata->spk_fmt[count] = pdm_val[count];
2847
2848        ret = of_property_read_u32_array(np, "wlf,spk-mute",
2849                                         pdm_val, ARRAY_SIZE(pdm_val));
2850
2851        if (ret >= 0)
2852                for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
2853                        pdata->spk_mute[count] = pdm_val[count];
2854
2855        return 0;
2856}
2857EXPORT_SYMBOL_GPL(arizona_of_get_audio_pdata);
2858
2859MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
2860MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2861MODULE_LICENSE("GPL");
2862