linux/sound/soc/codecs/arizona.c
<<
>>
Prefs
   1/*
   2 * arizona.c - Wolfson Arizona class device shared support
   3 *
   4 * Copyright 2012 Wolfson Microelectronics plc
   5 *
   6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/delay.h>
  14#include <linux/gcd.h>
  15#include <linux/module.h>
  16#include <linux/pm_runtime.h>
  17#include <sound/pcm.h>
  18#include <sound/pcm_params.h>
  19#include <sound/tlv.h>
  20
  21#include <linux/mfd/arizona/core.h>
  22#include <linux/mfd/arizona/gpio.h>
  23#include <linux/mfd/arizona/registers.h>
  24
  25#include "arizona.h"
  26
  27#define ARIZONA_AIF_BCLK_CTRL                   0x00
  28#define ARIZONA_AIF_TX_PIN_CTRL                 0x01
  29#define ARIZONA_AIF_RX_PIN_CTRL                 0x02
  30#define ARIZONA_AIF_RATE_CTRL                   0x03
  31#define ARIZONA_AIF_FORMAT                      0x04
  32#define ARIZONA_AIF_TX_BCLK_RATE                0x05
  33#define ARIZONA_AIF_RX_BCLK_RATE                0x06
  34#define ARIZONA_AIF_FRAME_CTRL_1                0x07
  35#define ARIZONA_AIF_FRAME_CTRL_2                0x08
  36#define ARIZONA_AIF_FRAME_CTRL_3                0x09
  37#define ARIZONA_AIF_FRAME_CTRL_4                0x0A
  38#define ARIZONA_AIF_FRAME_CTRL_5                0x0B
  39#define ARIZONA_AIF_FRAME_CTRL_6                0x0C
  40#define ARIZONA_AIF_FRAME_CTRL_7                0x0D
  41#define ARIZONA_AIF_FRAME_CTRL_8                0x0E
  42#define ARIZONA_AIF_FRAME_CTRL_9                0x0F
  43#define ARIZONA_AIF_FRAME_CTRL_10               0x10
  44#define ARIZONA_AIF_FRAME_CTRL_11               0x11
  45#define ARIZONA_AIF_FRAME_CTRL_12               0x12
  46#define ARIZONA_AIF_FRAME_CTRL_13               0x13
  47#define ARIZONA_AIF_FRAME_CTRL_14               0x14
  48#define ARIZONA_AIF_FRAME_CTRL_15               0x15
  49#define ARIZONA_AIF_FRAME_CTRL_16               0x16
  50#define ARIZONA_AIF_FRAME_CTRL_17               0x17
  51#define ARIZONA_AIF_FRAME_CTRL_18               0x18
  52#define ARIZONA_AIF_TX_ENABLES                  0x19
  53#define ARIZONA_AIF_RX_ENABLES                  0x1A
  54#define ARIZONA_AIF_FORCE_WRITE                 0x1B
  55
  56#define arizona_fll_err(_fll, fmt, ...) \
  57        dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  58#define arizona_fll_warn(_fll, fmt, ...) \
  59        dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  60#define arizona_fll_dbg(_fll, fmt, ...) \
  61        dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  62
  63#define arizona_aif_err(_dai, fmt, ...) \
  64        dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  65#define arizona_aif_warn(_dai, fmt, ...) \
  66        dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  67#define arizona_aif_dbg(_dai, fmt, ...) \
  68        dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  69
  70static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
  71                          struct snd_kcontrol *kcontrol,
  72                          int event)
  73{
  74        struct snd_soc_codec *codec = w->codec;
  75        struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
  76        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
  77        bool manual_ena = false;
  78        int val;
  79
  80        switch (arizona->type) {
  81        case WM5102:
  82                switch (arizona->rev) {
  83                case 0:
  84                        break;
  85                default:
  86                        manual_ena = true;
  87                        break;
  88                }
  89        default:
  90                break;
  91        }
  92
  93        switch (event) {
  94        case SND_SOC_DAPM_PRE_PMU:
  95                if (!priv->spk_ena && manual_ena) {
  96                        snd_soc_write(codec, 0x4f5, 0x25a);
  97                        priv->spk_ena_pending = true;
  98                }
  99                break;
 100        case SND_SOC_DAPM_POST_PMU:
 101                val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
 102                if (val & ARIZONA_SPK_SHUTDOWN_STS) {
 103                        dev_crit(arizona->dev,
 104                                 "Speaker not enabled due to temperature\n");
 105                        return -EBUSY;
 106                }
 107
 108                snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
 109                                    1 << w->shift, 1 << w->shift);
 110
 111                if (priv->spk_ena_pending) {
 112                        msleep(75);
 113                        snd_soc_write(codec, 0x4f5, 0xda);
 114                        priv->spk_ena_pending = false;
 115                        priv->spk_ena++;
 116                }
 117                break;
 118        case SND_SOC_DAPM_PRE_PMD:
 119                if (manual_ena) {
 120                        priv->spk_ena--;
 121                        if (!priv->spk_ena)
 122                                snd_soc_write(codec, 0x4f5, 0x25a);
 123                }
 124
 125                snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
 126                                    1 << w->shift, 0);
 127                break;
 128        case SND_SOC_DAPM_POST_PMD:
 129                if (manual_ena) {
 130                        if (!priv->spk_ena)
 131                                snd_soc_write(codec, 0x4f5, 0x0da);
 132                }
 133                break;
 134        }
 135
 136        return 0;
 137}
 138
 139static irqreturn_t arizona_thermal_warn(int irq, void *data)
 140{
 141        struct arizona *arizona = data;
 142        unsigned int val;
 143        int ret;
 144
 145        ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
 146                          &val);
 147        if (ret != 0) {
 148                dev_err(arizona->dev, "Failed to read thermal status: %d\n",
 149                        ret);
 150        } else if (val & ARIZONA_SPK_SHUTDOWN_WARN_STS) {
 151                dev_crit(arizona->dev, "Thermal warning\n");
 152        }
 153
 154        return IRQ_HANDLED;
 155}
 156
 157static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
 158{
 159        struct arizona *arizona = data;
 160        unsigned int val;
 161        int ret;
 162
 163        ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
 164                          &val);
 165        if (ret != 0) {
 166                dev_err(arizona->dev, "Failed to read thermal status: %d\n",
 167                        ret);
 168        } else if (val & ARIZONA_SPK_SHUTDOWN_STS) {
 169                dev_crit(arizona->dev, "Thermal shutdown\n");
 170                ret = regmap_update_bits(arizona->regmap,
 171                                         ARIZONA_OUTPUT_ENABLES_1,
 172                                         ARIZONA_OUT4L_ENA |
 173                                         ARIZONA_OUT4R_ENA, 0);
 174                if (ret != 0)
 175                        dev_crit(arizona->dev,
 176                                 "Failed to disable speaker outputs: %d\n",
 177                                 ret);
 178        }
 179
 180        return IRQ_HANDLED;
 181}
 182
 183static const struct snd_soc_dapm_widget arizona_spkl =
 184        SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
 185                           ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
 186                           SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
 187
 188static const struct snd_soc_dapm_widget arizona_spkr =
 189        SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
 190                           ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
 191                           SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
 192
 193int arizona_init_spk(struct snd_soc_codec *codec)
 194{
 195        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 196        struct arizona *arizona = priv->arizona;
 197        int ret;
 198
 199        ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1);
 200        if (ret != 0)
 201                return ret;
 202
 203        switch (arizona->type) {
 204        case WM8997:
 205                break;
 206        default:
 207                ret = snd_soc_dapm_new_controls(&codec->dapm,
 208                                                &arizona_spkr, 1);
 209                if (ret != 0)
 210                        return ret;
 211                break;
 212        }
 213
 214        ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN,
 215                                  "Thermal warning", arizona_thermal_warn,
 216                                  arizona);
 217        if (ret != 0)
 218                dev_err(arizona->dev,
 219                        "Failed to get thermal warning IRQ: %d\n",
 220                        ret);
 221
 222        ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN,
 223                                  "Thermal shutdown", arizona_thermal_shutdown,
 224                                  arizona);
 225        if (ret != 0)
 226                dev_err(arizona->dev,
 227                        "Failed to get thermal shutdown IRQ: %d\n",
 228                        ret);
 229
 230        return 0;
 231}
 232EXPORT_SYMBOL_GPL(arizona_init_spk);
 233
 234int arizona_init_gpio(struct snd_soc_codec *codec)
 235{
 236        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 237        struct arizona *arizona = priv->arizona;
 238        int i;
 239
 240        switch (arizona->type) {
 241        case WM5110:
 242                snd_soc_dapm_disable_pin(&codec->dapm, "DRC2 Signal Activity");
 243                break;
 244        default:
 245                break;
 246        }
 247
 248        snd_soc_dapm_disable_pin(&codec->dapm, "DRC1 Signal Activity");
 249
 250        for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
 251                switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
 252                case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
 253                        snd_soc_dapm_enable_pin(&codec->dapm,
 254                                                "DRC1 Signal Activity");
 255                        break;
 256                case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
 257                        snd_soc_dapm_enable_pin(&codec->dapm,
 258                                                "DRC2 Signal Activity");
 259                        break;
 260                default:
 261                        break;
 262                }
 263        }
 264
 265        return 0;
 266}
 267EXPORT_SYMBOL_GPL(arizona_init_gpio);
 268
 269const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
 270        "None",
 271        "Tone Generator 1",
 272        "Tone Generator 2",
 273        "Haptics",
 274        "AEC",
 275        "Mic Mute Mixer",
 276        "Noise Generator",
 277        "IN1L",
 278        "IN1R",
 279        "IN2L",
 280        "IN2R",
 281        "IN3L",
 282        "IN3R",
 283        "IN4L",
 284        "IN4R",
 285        "AIF1RX1",
 286        "AIF1RX2",
 287        "AIF1RX3",
 288        "AIF1RX4",
 289        "AIF1RX5",
 290        "AIF1RX6",
 291        "AIF1RX7",
 292        "AIF1RX8",
 293        "AIF2RX1",
 294        "AIF2RX2",
 295        "AIF3RX1",
 296        "AIF3RX2",
 297        "SLIMRX1",
 298        "SLIMRX2",
 299        "SLIMRX3",
 300        "SLIMRX4",
 301        "SLIMRX5",
 302        "SLIMRX6",
 303        "SLIMRX7",
 304        "SLIMRX8",
 305        "EQ1",
 306        "EQ2",
 307        "EQ3",
 308        "EQ4",
 309        "DRC1L",
 310        "DRC1R",
 311        "DRC2L",
 312        "DRC2R",
 313        "LHPF1",
 314        "LHPF2",
 315        "LHPF3",
 316        "LHPF4",
 317        "DSP1.1",
 318        "DSP1.2",
 319        "DSP1.3",
 320        "DSP1.4",
 321        "DSP1.5",
 322        "DSP1.6",
 323        "DSP2.1",
 324        "DSP2.2",
 325        "DSP2.3",
 326        "DSP2.4",
 327        "DSP2.5",
 328        "DSP2.6",
 329        "DSP3.1",
 330        "DSP3.2",
 331        "DSP3.3",
 332        "DSP3.4",
 333        "DSP3.5",
 334        "DSP3.6",
 335        "DSP4.1",
 336        "DSP4.2",
 337        "DSP4.3",
 338        "DSP4.4",
 339        "DSP4.5",
 340        "DSP4.6",
 341        "ASRC1L",
 342        "ASRC1R",
 343        "ASRC2L",
 344        "ASRC2R",
 345        "ISRC1INT1",
 346        "ISRC1INT2",
 347        "ISRC1INT3",
 348        "ISRC1INT4",
 349        "ISRC1DEC1",
 350        "ISRC1DEC2",
 351        "ISRC1DEC3",
 352        "ISRC1DEC4",
 353        "ISRC2INT1",
 354        "ISRC2INT2",
 355        "ISRC2INT3",
 356        "ISRC2INT4",
 357        "ISRC2DEC1",
 358        "ISRC2DEC2",
 359        "ISRC2DEC3",
 360        "ISRC2DEC4",
 361        "ISRC3INT1",
 362        "ISRC3INT2",
 363        "ISRC3INT3",
 364        "ISRC3INT4",
 365        "ISRC3DEC1",
 366        "ISRC3DEC2",
 367        "ISRC3DEC3",
 368        "ISRC3DEC4",
 369};
 370EXPORT_SYMBOL_GPL(arizona_mixer_texts);
 371
 372int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
 373        0x00,  /* None */
 374        0x04,  /* Tone */
 375        0x05,
 376        0x06,  /* Haptics */
 377        0x08,  /* AEC */
 378        0x0c,  /* Noise mixer */
 379        0x0d,  /* Comfort noise */
 380        0x10,  /* IN1L */
 381        0x11,
 382        0x12,
 383        0x13,
 384        0x14,
 385        0x15,
 386        0x16,
 387        0x17,
 388        0x20,  /* AIF1RX1 */
 389        0x21,
 390        0x22,
 391        0x23,
 392        0x24,
 393        0x25,
 394        0x26,
 395        0x27,
 396        0x28,  /* AIF2RX1 */
 397        0x29,
 398        0x30,  /* AIF3RX1 */
 399        0x31,
 400        0x38,  /* SLIMRX1 */
 401        0x39,
 402        0x3a,
 403        0x3b,
 404        0x3c,
 405        0x3d,
 406        0x3e,
 407        0x3f,
 408        0x50,  /* EQ1 */
 409        0x51,
 410        0x52,
 411        0x53,
 412        0x58,  /* DRC1L */
 413        0x59,
 414        0x5a,
 415        0x5b,
 416        0x60,  /* LHPF1 */
 417        0x61,
 418        0x62,
 419        0x63,
 420        0x68,  /* DSP1.1 */
 421        0x69,
 422        0x6a,
 423        0x6b,
 424        0x6c,
 425        0x6d,
 426        0x70,  /* DSP2.1 */
 427        0x71,
 428        0x72,
 429        0x73,
 430        0x74,
 431        0x75,
 432        0x78,  /* DSP3.1 */
 433        0x79,
 434        0x7a,
 435        0x7b,
 436        0x7c,
 437        0x7d,
 438        0x80,  /* DSP4.1 */
 439        0x81,
 440        0x82,
 441        0x83,
 442        0x84,
 443        0x85,
 444        0x90,  /* ASRC1L */
 445        0x91,
 446        0x92,
 447        0x93,
 448        0xa0,  /* ISRC1INT1 */
 449        0xa1,
 450        0xa2,
 451        0xa3,
 452        0xa4,  /* ISRC1DEC1 */
 453        0xa5,
 454        0xa6,
 455        0xa7,
 456        0xa8,  /* ISRC2DEC1 */
 457        0xa9,
 458        0xaa,
 459        0xab,
 460        0xac,  /* ISRC2INT1 */
 461        0xad,
 462        0xae,
 463        0xaf,
 464        0xb0,  /* ISRC3DEC1 */
 465        0xb1,
 466        0xb2,
 467        0xb3,
 468        0xb4,  /* ISRC3INT1 */
 469        0xb5,
 470        0xb6,
 471        0xb7,
 472};
 473EXPORT_SYMBOL_GPL(arizona_mixer_values);
 474
 475const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
 476EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
 477
 478const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
 479        "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
 480};
 481EXPORT_SYMBOL_GPL(arizona_rate_text);
 482
 483const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
 484        0, 1, 2, 8,
 485};
 486EXPORT_SYMBOL_GPL(arizona_rate_val);
 487
 488
 489const struct soc_enum arizona_isrc_fsl[] = {
 490        SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
 491                              ARIZONA_ISRC1_FSL_SHIFT, 0xf,
 492                              ARIZONA_RATE_ENUM_SIZE,
 493                              arizona_rate_text, arizona_rate_val),
 494        SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
 495                              ARIZONA_ISRC2_FSL_SHIFT, 0xf,
 496                              ARIZONA_RATE_ENUM_SIZE,
 497                              arizona_rate_text, arizona_rate_val),
 498        SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
 499                              ARIZONA_ISRC3_FSL_SHIFT, 0xf,
 500                              ARIZONA_RATE_ENUM_SIZE,
 501                              arizona_rate_text, arizona_rate_val),
 502};
 503EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
 504
 505static const char *arizona_vol_ramp_text[] = {
 506        "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
 507        "15ms/6dB", "30ms/6dB",
 508};
 509
 510const struct soc_enum arizona_in_vd_ramp =
 511        SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
 512                        ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
 513EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
 514
 515const struct soc_enum arizona_in_vi_ramp =
 516        SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
 517                        ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
 518EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
 519
 520const struct soc_enum arizona_out_vd_ramp =
 521        SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
 522                        ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
 523EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
 524
 525const struct soc_enum arizona_out_vi_ramp =
 526        SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
 527                        ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
 528EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
 529
 530static const char *arizona_lhpf_mode_text[] = {
 531        "Low-pass", "High-pass"
 532};
 533
 534const struct soc_enum arizona_lhpf1_mode =
 535        SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2,
 536                        arizona_lhpf_mode_text);
 537EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
 538
 539const struct soc_enum arizona_lhpf2_mode =
 540        SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2,
 541                        arizona_lhpf_mode_text);
 542EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
 543
 544const struct soc_enum arizona_lhpf3_mode =
 545        SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2,
 546                        arizona_lhpf_mode_text);
 547EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
 548
 549const struct soc_enum arizona_lhpf4_mode =
 550        SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2,
 551                        arizona_lhpf_mode_text);
 552EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
 553
 554static const char *arizona_ng_hold_text[] = {
 555        "30ms", "120ms", "250ms", "500ms",
 556};
 557
 558const struct soc_enum arizona_ng_hold =
 559        SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT,
 560                        4, arizona_ng_hold_text);
 561EXPORT_SYMBOL_GPL(arizona_ng_hold);
 562
 563static const char * const arizona_in_dmic_osr_text[] = {
 564        "1.536MHz", "3.072MHz", "6.144MHz",
 565};
 566
 567const struct soc_enum arizona_in_dmic_osr[] = {
 568        SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT,
 569                        ARRAY_SIZE(arizona_in_dmic_osr_text),
 570                        arizona_in_dmic_osr_text),
 571        SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT,
 572                        ARRAY_SIZE(arizona_in_dmic_osr_text),
 573                        arizona_in_dmic_osr_text),
 574        SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT,
 575                        ARRAY_SIZE(arizona_in_dmic_osr_text),
 576                        arizona_in_dmic_osr_text),
 577        SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT,
 578                        ARRAY_SIZE(arizona_in_dmic_osr_text),
 579                        arizona_in_dmic_osr_text),
 580};
 581EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
 582
 583static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
 584{
 585        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 586        unsigned int val;
 587        int i;
 588
 589        if (ena)
 590                val = ARIZONA_IN_VU;
 591        else
 592                val = 0;
 593
 594        for (i = 0; i < priv->num_inputs; i++)
 595                snd_soc_update_bits(codec,
 596                                    ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
 597                                    ARIZONA_IN_VU, val);
 598}
 599
 600int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
 601                  int event)
 602{
 603        struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
 604        unsigned int reg;
 605
 606        if (w->shift % 2)
 607                reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
 608        else
 609                reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
 610
 611        switch (event) {
 612        case SND_SOC_DAPM_PRE_PMU:
 613                priv->in_pending++;
 614                break;
 615        case SND_SOC_DAPM_POST_PMU:
 616                snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
 617
 618                /* If this is the last input pending then allow VU */
 619                priv->in_pending--;
 620                if (priv->in_pending == 0) {
 621                        msleep(1);
 622                        arizona_in_set_vu(w->codec, 1);
 623                }
 624                break;
 625        case SND_SOC_DAPM_PRE_PMD:
 626                snd_soc_update_bits(w->codec, reg,
 627                                    ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
 628                                    ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
 629                break;
 630        case SND_SOC_DAPM_POST_PMD:
 631                /* Disable volume updates if no inputs are enabled */
 632                reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
 633                if (reg == 0)
 634                        arizona_in_set_vu(w->codec, 0);
 635        }
 636
 637        return 0;
 638}
 639EXPORT_SYMBOL_GPL(arizona_in_ev);
 640
 641int arizona_out_ev(struct snd_soc_dapm_widget *w,
 642                   struct snd_kcontrol *kcontrol,
 643                   int event)
 644{
 645        switch (event) {
 646        case SND_SOC_DAPM_POST_PMU:
 647                switch (w->shift) {
 648                case ARIZONA_OUT1L_ENA_SHIFT:
 649                case ARIZONA_OUT1R_ENA_SHIFT:
 650                case ARIZONA_OUT2L_ENA_SHIFT:
 651                case ARIZONA_OUT2R_ENA_SHIFT:
 652                case ARIZONA_OUT3L_ENA_SHIFT:
 653                case ARIZONA_OUT3R_ENA_SHIFT:
 654                        msleep(17);
 655                        break;
 656
 657                default:
 658                        break;
 659                }
 660                break;
 661        }
 662
 663        return 0;
 664}
 665EXPORT_SYMBOL_GPL(arizona_out_ev);
 666
 667int arizona_hp_ev(struct snd_soc_dapm_widget *w,
 668                   struct snd_kcontrol *kcontrol,
 669                   int event)
 670{
 671        struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
 672        unsigned int mask = 1 << w->shift;
 673        unsigned int val;
 674
 675        switch (event) {
 676        case SND_SOC_DAPM_POST_PMU:
 677                val = mask;
 678                break;
 679        case SND_SOC_DAPM_PRE_PMD:
 680                val = 0;
 681                break;
 682        default:
 683                return -EINVAL;
 684        }
 685
 686        /* Store the desired state for the HP outputs */
 687        priv->arizona->hp_ena &= ~mask;
 688        priv->arizona->hp_ena |= val;
 689
 690        /* Force off if HPDET magic is active */
 691        if (priv->arizona->hpdet_magic)
 692                val = 0;
 693
 694        snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val);
 695
 696        return arizona_out_ev(w, kcontrol, event);
 697}
 698EXPORT_SYMBOL_GPL(arizona_hp_ev);
 699
 700static unsigned int arizona_sysclk_48k_rates[] = {
 701        6144000,
 702        12288000,
 703        24576000,
 704        49152000,
 705        73728000,
 706        98304000,
 707        147456000,
 708};
 709
 710static unsigned int arizona_sysclk_44k1_rates[] = {
 711        5644800,
 712        11289600,
 713        22579200,
 714        45158400,
 715        67737600,
 716        90316800,
 717        135475200,
 718};
 719
 720static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
 721                             unsigned int freq)
 722{
 723        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 724        unsigned int reg;
 725        unsigned int *rates;
 726        int ref, div, refclk;
 727
 728        switch (clk) {
 729        case ARIZONA_CLK_OPCLK:
 730                reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
 731                refclk = priv->sysclk;
 732                break;
 733        case ARIZONA_CLK_ASYNC_OPCLK:
 734                reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
 735                refclk = priv->asyncclk;
 736                break;
 737        default:
 738                return -EINVAL;
 739        }
 740
 741        if (refclk % 8000)
 742                rates = arizona_sysclk_44k1_rates;
 743        else
 744                rates = arizona_sysclk_48k_rates;
 745
 746        for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
 747                     rates[ref] <= refclk; ref++) {
 748                div = 1;
 749                while (rates[ref] / div >= freq && div < 32) {
 750                        if (rates[ref] / div == freq) {
 751                                dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
 752                                        freq);
 753                                snd_soc_update_bits(codec, reg,
 754                                                    ARIZONA_OPCLK_DIV_MASK |
 755                                                    ARIZONA_OPCLK_SEL_MASK,
 756                                                    (div <<
 757                                                     ARIZONA_OPCLK_DIV_SHIFT) |
 758                                                    ref);
 759                                return 0;
 760                        }
 761                        div++;
 762                }
 763        }
 764
 765        dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
 766        return -EINVAL;
 767}
 768
 769int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 770                       int source, unsigned int freq, int dir)
 771{
 772        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 773        struct arizona *arizona = priv->arizona;
 774        char *name;
 775        unsigned int reg;
 776        unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
 777        unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
 778        unsigned int *clk;
 779
 780        switch (clk_id) {
 781        case ARIZONA_CLK_SYSCLK:
 782                name = "SYSCLK";
 783                reg = ARIZONA_SYSTEM_CLOCK_1;
 784                clk = &priv->sysclk;
 785                mask |= ARIZONA_SYSCLK_FRAC;
 786                break;
 787        case ARIZONA_CLK_ASYNCCLK:
 788                name = "ASYNCCLK";
 789                reg = ARIZONA_ASYNC_CLOCK_1;
 790                clk = &priv->asyncclk;
 791                break;
 792        case ARIZONA_CLK_OPCLK:
 793        case ARIZONA_CLK_ASYNC_OPCLK:
 794                return arizona_set_opclk(codec, clk_id, freq);
 795        default:
 796                return -EINVAL;
 797        }
 798
 799        switch (freq) {
 800        case  5644800:
 801        case  6144000:
 802                break;
 803        case 11289600:
 804        case 12288000:
 805                val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
 806                break;
 807        case 22579200:
 808        case 24576000:
 809                val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
 810                break;
 811        case 45158400:
 812        case 49152000:
 813                val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
 814                break;
 815        case 67737600:
 816        case 73728000:
 817                val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
 818                break;
 819        case 90316800:
 820        case 98304000:
 821                val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
 822                break;
 823        case 135475200:
 824        case 147456000:
 825                val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
 826                break;
 827        case 0:
 828                dev_dbg(arizona->dev, "%s cleared\n", name);
 829                *clk = freq;
 830                return 0;
 831        default:
 832                return -EINVAL;
 833        }
 834
 835        *clk = freq;
 836
 837        if (freq % 6144000)
 838                val |= ARIZONA_SYSCLK_FRAC;
 839
 840        dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
 841
 842        return regmap_update_bits(arizona->regmap, reg, mask, val);
 843}
 844EXPORT_SYMBOL_GPL(arizona_set_sysclk);
 845
 846static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 847{
 848        struct snd_soc_codec *codec = dai->codec;
 849        int lrclk, bclk, mode, base;
 850
 851        base = dai->driver->base;
 852
 853        lrclk = 0;
 854        bclk = 0;
 855
 856        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 857        case SND_SOC_DAIFMT_DSP_A:
 858                mode = 0;
 859                break;
 860        case SND_SOC_DAIFMT_I2S:
 861                mode = 2;
 862                break;
 863        default:
 864                arizona_aif_err(dai, "Unsupported DAI format %d\n",
 865                                fmt & SND_SOC_DAIFMT_FORMAT_MASK);
 866                return -EINVAL;
 867        }
 868
 869        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 870        case SND_SOC_DAIFMT_CBS_CFS:
 871                break;
 872        case SND_SOC_DAIFMT_CBS_CFM:
 873                lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
 874                break;
 875        case SND_SOC_DAIFMT_CBM_CFS:
 876                bclk |= ARIZONA_AIF1_BCLK_MSTR;
 877                break;
 878        case SND_SOC_DAIFMT_CBM_CFM:
 879                bclk |= ARIZONA_AIF1_BCLK_MSTR;
 880                lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
 881                break;
 882        default:
 883                arizona_aif_err(dai, "Unsupported master mode %d\n",
 884                                fmt & SND_SOC_DAIFMT_MASTER_MASK);
 885                return -EINVAL;
 886        }
 887
 888        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 889        case SND_SOC_DAIFMT_NB_NF:
 890                break;
 891        case SND_SOC_DAIFMT_IB_IF:
 892                bclk |= ARIZONA_AIF1_BCLK_INV;
 893                lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
 894                break;
 895        case SND_SOC_DAIFMT_IB_NF:
 896                bclk |= ARIZONA_AIF1_BCLK_INV;
 897                break;
 898        case SND_SOC_DAIFMT_NB_IF:
 899                lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
 900                break;
 901        default:
 902                return -EINVAL;
 903        }
 904
 905        snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
 906                            ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
 907                            bclk);
 908        snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
 909                            ARIZONA_AIF1TX_LRCLK_INV |
 910                            ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
 911        snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
 912                            ARIZONA_AIF1RX_LRCLK_INV |
 913                            ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
 914        snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
 915                            ARIZONA_AIF1_FMT_MASK, mode);
 916
 917        return 0;
 918}
 919
 920static const int arizona_48k_bclk_rates[] = {
 921        -1,
 922        48000,
 923        64000,
 924        96000,
 925        128000,
 926        192000,
 927        256000,
 928        384000,
 929        512000,
 930        768000,
 931        1024000,
 932        1536000,
 933        2048000,
 934        3072000,
 935        4096000,
 936        6144000,
 937        8192000,
 938        12288000,
 939        24576000,
 940};
 941
 942static const unsigned int arizona_48k_rates[] = {
 943        12000,
 944        24000,
 945        48000,
 946        96000,
 947        192000,
 948        384000,
 949        768000,
 950        4000,
 951        8000,
 952        16000,
 953        32000,
 954        64000,
 955        128000,
 956        256000,
 957        512000,
 958};
 959
 960static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
 961        .count  = ARRAY_SIZE(arizona_48k_rates),
 962        .list   = arizona_48k_rates,
 963};
 964
 965static const int arizona_44k1_bclk_rates[] = {
 966        -1,
 967        44100,
 968        58800,
 969        88200,
 970        117600,
 971        177640,
 972        235200,
 973        352800,
 974        470400,
 975        705600,
 976        940800,
 977        1411200,
 978        1881600,
 979        2822400,
 980        3763200,
 981        5644800,
 982        7526400,
 983        11289600,
 984        22579200,
 985};
 986
 987static const unsigned int arizona_44k1_rates[] = {
 988        11025,
 989        22050,
 990        44100,
 991        88200,
 992        176400,
 993        352800,
 994        705600,
 995};
 996
 997static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
 998        .count  = ARRAY_SIZE(arizona_44k1_rates),
 999        .list   = arizona_44k1_rates,
1000};
1001
1002static int arizona_sr_vals[] = {
1003        0,
1004        12000,
1005        24000,
1006        48000,
1007        96000,
1008        192000,
1009        384000,
1010        768000,
1011        0,
1012        11025,
1013        22050,
1014        44100,
1015        88200,
1016        176400,
1017        352800,
1018        705600,
1019        4000,
1020        8000,
1021        16000,
1022        32000,
1023        64000,
1024        128000,
1025        256000,
1026        512000,
1027};
1028
1029static int arizona_startup(struct snd_pcm_substream *substream,
1030                           struct snd_soc_dai *dai)
1031{
1032        struct snd_soc_codec *codec = dai->codec;
1033        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1034        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1035        const struct snd_pcm_hw_constraint_list *constraint;
1036        unsigned int base_rate;
1037
1038        switch (dai_priv->clk) {
1039        case ARIZONA_CLK_SYSCLK:
1040                base_rate = priv->sysclk;
1041                break;
1042        case ARIZONA_CLK_ASYNCCLK:
1043                base_rate = priv->asyncclk;
1044                break;
1045        default:
1046                return 0;
1047        }
1048
1049        if (base_rate == 0)
1050                return 0;
1051
1052        if (base_rate % 8000)
1053                constraint = &arizona_44k1_constraint;
1054        else
1055                constraint = &arizona_48k_constraint;
1056
1057        return snd_pcm_hw_constraint_list(substream->runtime, 0,
1058                                          SNDRV_PCM_HW_PARAM_RATE,
1059                                          constraint);
1060}
1061
1062static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1063                                  struct snd_pcm_hw_params *params,
1064                                  struct snd_soc_dai *dai)
1065{
1066        struct snd_soc_codec *codec = dai->codec;
1067        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1068        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1069        int base = dai->driver->base;
1070        int i, sr_val;
1071
1072        /*
1073         * We will need to be more flexible than this in future,
1074         * currently we use a single sample rate for SYSCLK.
1075         */
1076        for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1077                if (arizona_sr_vals[i] == params_rate(params))
1078                        break;
1079        if (i == ARRAY_SIZE(arizona_sr_vals)) {
1080                arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1081                                params_rate(params));
1082                return -EINVAL;
1083        }
1084        sr_val = i;
1085
1086        switch (dai_priv->clk) {
1087        case ARIZONA_CLK_SYSCLK:
1088                snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
1089                                    ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
1090                if (base)
1091                        snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1092                                            ARIZONA_AIF1_RATE_MASK, 0);
1093                break;
1094        case ARIZONA_CLK_ASYNCCLK:
1095                snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
1096                                    ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
1097                if (base)
1098                        snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1099                                            ARIZONA_AIF1_RATE_MASK,
1100                                            8 << ARIZONA_AIF1_RATE_SHIFT);
1101                break;
1102        default:
1103                arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1104                return -EINVAL;
1105        }
1106
1107        return 0;
1108}
1109
1110static int arizona_hw_params(struct snd_pcm_substream *substream,
1111                             struct snd_pcm_hw_params *params,
1112                             struct snd_soc_dai *dai)
1113{
1114        struct snd_soc_codec *codec = dai->codec;
1115        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1116        struct arizona *arizona = priv->arizona;
1117        int base = dai->driver->base;
1118        const int *rates;
1119        int i, ret, val;
1120        int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1121        int bclk, lrclk, wl, frame, bclk_target;
1122
1123        if (params_rate(params) % 8000)
1124                rates = &arizona_44k1_bclk_rates[0];
1125        else
1126                rates = &arizona_48k_bclk_rates[0];
1127
1128        bclk_target = snd_soc_params_to_bclk(params);
1129        if (chan_limit && chan_limit < params_channels(params)) {
1130                arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1131                bclk_target /= params_channels(params);
1132                bclk_target *= chan_limit;
1133        }
1134
1135        /* Force stereo for I2S mode */
1136        val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
1137        if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) {
1138                arizona_aif_dbg(dai, "Forcing stereo mode\n");
1139                bclk_target *= 2;
1140        }
1141
1142        for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1143                if (rates[i] >= bclk_target &&
1144                    rates[i] % params_rate(params) == 0) {
1145                        bclk = i;
1146                        break;
1147                }
1148        }
1149        if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1150                arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1151                                params_rate(params));
1152                return -EINVAL;
1153        }
1154
1155        lrclk = rates[bclk] / params_rate(params);
1156
1157        arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1158                        rates[bclk], rates[bclk] / lrclk);
1159
1160        wl = snd_pcm_format_width(params_format(params));
1161        frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
1162
1163        ret = arizona_hw_params_rate(substream, params, dai);
1164        if (ret != 0)
1165                return ret;
1166
1167        snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
1168                            ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1169        snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
1170                            ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1171        snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
1172                            ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1173        snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
1174                            ARIZONA_AIF1TX_WL_MASK |
1175                            ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1176        snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
1177                            ARIZONA_AIF1RX_WL_MASK |
1178                            ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1179
1180        return 0;
1181}
1182
1183static const char *arizona_dai_clk_str(int clk_id)
1184{
1185        switch (clk_id) {
1186        case ARIZONA_CLK_SYSCLK:
1187                return "SYSCLK";
1188        case ARIZONA_CLK_ASYNCCLK:
1189                return "ASYNCCLK";
1190        default:
1191                return "Unknown clock";
1192        }
1193}
1194
1195static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1196                                  int clk_id, unsigned int freq, int dir)
1197{
1198        struct snd_soc_codec *codec = dai->codec;
1199        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1200        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1201        struct snd_soc_dapm_route routes[2];
1202
1203        switch (clk_id) {
1204        case ARIZONA_CLK_SYSCLK:
1205        case ARIZONA_CLK_ASYNCCLK:
1206                break;
1207        default:
1208                return -EINVAL;
1209        }
1210
1211        if (clk_id == dai_priv->clk)
1212                return 0;
1213
1214        if (dai->active) {
1215                dev_err(codec->dev, "Can't change clock on active DAI %d\n",
1216                        dai->id);
1217                return -EBUSY;
1218        }
1219
1220        dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
1221                arizona_dai_clk_str(clk_id));
1222
1223        memset(&routes, 0, sizeof(routes));
1224        routes[0].sink = dai->driver->capture.stream_name;
1225        routes[1].sink = dai->driver->playback.stream_name;
1226
1227        routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1228        routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1229        snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
1230
1231        routes[0].source = arizona_dai_clk_str(clk_id);
1232        routes[1].source = arizona_dai_clk_str(clk_id);
1233        snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
1234
1235        dai_priv->clk = clk_id;
1236
1237        return snd_soc_dapm_sync(&codec->dapm);
1238}
1239
1240static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1241{
1242        struct snd_soc_codec *codec = dai->codec;
1243        int base = dai->driver->base;
1244        unsigned int reg;
1245
1246        if (tristate)
1247                reg = ARIZONA_AIF1_TRI;
1248        else
1249                reg = 0;
1250
1251        return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1252                                   ARIZONA_AIF1_TRI, reg);
1253}
1254
1255const struct snd_soc_dai_ops arizona_dai_ops = {
1256        .startup = arizona_startup,
1257        .set_fmt = arizona_set_fmt,
1258        .hw_params = arizona_hw_params,
1259        .set_sysclk = arizona_dai_set_sysclk,
1260        .set_tristate = arizona_set_tristate,
1261};
1262EXPORT_SYMBOL_GPL(arizona_dai_ops);
1263
1264const struct snd_soc_dai_ops arizona_simple_dai_ops = {
1265        .startup = arizona_startup,
1266        .hw_params = arizona_hw_params_rate,
1267        .set_sysclk = arizona_dai_set_sysclk,
1268};
1269EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
1270
1271int arizona_init_dai(struct arizona_priv *priv, int id)
1272{
1273        struct arizona_dai_priv *dai_priv = &priv->dai[id];
1274
1275        dai_priv->clk = ARIZONA_CLK_SYSCLK;
1276
1277        return 0;
1278}
1279EXPORT_SYMBOL_GPL(arizona_init_dai);
1280
1281static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
1282{
1283        struct arizona_fll *fll = data;
1284
1285        arizona_fll_dbg(fll, "clock OK\n");
1286
1287        complete(&fll->ok);
1288
1289        return IRQ_HANDLED;
1290}
1291
1292static struct {
1293        unsigned int min;
1294        unsigned int max;
1295        u16 fratio;
1296        int ratio;
1297} fll_fratios[] = {
1298        {       0,    64000, 4, 16 },
1299        {   64000,   128000, 3,  8 },
1300        {  128000,   256000, 2,  4 },
1301        {  256000,  1000000, 1,  2 },
1302        { 1000000, 13500000, 0,  1 },
1303};
1304
1305static struct {
1306        unsigned int min;
1307        unsigned int max;
1308        u16 gain;
1309} fll_gains[] = {
1310        {       0,   256000, 0 },
1311        {  256000,  1000000, 2 },
1312        { 1000000, 13500000, 4 },
1313};
1314
1315struct arizona_fll_cfg {
1316        int n;
1317        int theta;
1318        int lambda;
1319        int refdiv;
1320        int outdiv;
1321        int fratio;
1322        int gain;
1323};
1324
1325static int arizona_calc_fll(struct arizona_fll *fll,
1326                            struct arizona_fll_cfg *cfg,
1327                            unsigned int Fref,
1328                            unsigned int Fout)
1329{
1330        unsigned int target, div, gcd_fll;
1331        int i, ratio;
1332
1333        arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
1334
1335        /* Fref must be <=13.5MHz */
1336        div = 1;
1337        cfg->refdiv = 0;
1338        while ((Fref / div) > 13500000) {
1339                div *= 2;
1340                cfg->refdiv++;
1341
1342                if (div > 8) {
1343                        arizona_fll_err(fll,
1344                                        "Can't scale %dMHz in to <=13.5MHz\n",
1345                                        Fref);
1346                        return -EINVAL;
1347                }
1348        }
1349
1350        /* Apply the division for our remaining calculations */
1351        Fref /= div;
1352
1353        /* Fvco should be over the targt; don't check the upper bound */
1354        div = 1;
1355        while (Fout * div < 90000000 * fll->vco_mult) {
1356                div++;
1357                if (div > 7) {
1358                        arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1359                                        Fout);
1360                        return -EINVAL;
1361                }
1362        }
1363        target = Fout * div / fll->vco_mult;
1364        cfg->outdiv = div;
1365
1366        arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
1367
1368        /* Find an appropraite FLL_FRATIO and factor it out of the target */
1369        for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1370                if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1371                        cfg->fratio = fll_fratios[i].fratio;
1372                        ratio = fll_fratios[i].ratio;
1373                        break;
1374                }
1375        }
1376        if (i == ARRAY_SIZE(fll_fratios)) {
1377                arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1378                                Fref);
1379                return -EINVAL;
1380        }
1381
1382        for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
1383                if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
1384                        cfg->gain = fll_gains[i].gain;
1385                        break;
1386                }
1387        }
1388        if (i == ARRAY_SIZE(fll_gains)) {
1389                arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1390                                Fref);
1391                return -EINVAL;
1392        }
1393
1394        cfg->n = target / (ratio * Fref);
1395
1396        if (target % (ratio * Fref)) {
1397                gcd_fll = gcd(target, ratio * Fref);
1398                arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
1399
1400                cfg->theta = (target - (cfg->n * ratio * Fref))
1401                        / gcd_fll;
1402                cfg->lambda = (ratio * Fref) / gcd_fll;
1403        } else {
1404                cfg->theta = 0;
1405                cfg->lambda = 0;
1406        }
1407
1408        /* Round down to 16bit range with cost of accuracy lost.
1409         * Denominator must be bigger than numerator so we only
1410         * take care of it.
1411         */
1412        while (cfg->lambda >= (1 << 16)) {
1413                cfg->theta >>= 1;
1414                cfg->lambda >>= 1;
1415        }
1416
1417        arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
1418                        cfg->n, cfg->theta, cfg->lambda);
1419        arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
1420                        cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
1421        arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);
1422
1423        return 0;
1424
1425}
1426
1427static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1428                              struct arizona_fll_cfg *cfg, int source,
1429                              bool sync)
1430{
1431        regmap_update_bits(arizona->regmap, base + 3,
1432                           ARIZONA_FLL1_THETA_MASK, cfg->theta);
1433        regmap_update_bits(arizona->regmap, base + 4,
1434                           ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
1435        regmap_update_bits(arizona->regmap, base + 5,
1436                           ARIZONA_FLL1_FRATIO_MASK,
1437                           cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
1438        regmap_update_bits(arizona->regmap, base + 6,
1439                           ARIZONA_FLL1_CLK_REF_DIV_MASK |
1440                           ARIZONA_FLL1_CLK_REF_SRC_MASK,
1441                           cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1442                           source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1443
1444        if (sync)
1445                regmap_update_bits(arizona->regmap, base + 0x7,
1446                                   ARIZONA_FLL1_GAIN_MASK,
1447                                   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1448        else
1449                regmap_update_bits(arizona->regmap, base + 0x9,
1450                                   ARIZONA_FLL1_GAIN_MASK,
1451                                   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1452
1453        regmap_update_bits(arizona->regmap, base + 2,
1454                           ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
1455                           ARIZONA_FLL1_CTRL_UPD | cfg->n);
1456}
1457
1458static bool arizona_is_enabled_fll(struct arizona_fll *fll)
1459{
1460        struct arizona *arizona = fll->arizona;
1461        unsigned int reg;
1462        int ret;
1463
1464        ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1465        if (ret != 0) {
1466                arizona_fll_err(fll, "Failed to read current state: %d\n",
1467                                ret);
1468                return ret;
1469        }
1470
1471        return reg & ARIZONA_FLL1_ENA;
1472}
1473
1474static void arizona_enable_fll(struct arizona_fll *fll,
1475                              struct arizona_fll_cfg *ref,
1476                              struct arizona_fll_cfg *sync)
1477{
1478        struct arizona *arizona = fll->arizona;
1479        int ret;
1480
1481        /*
1482         * If we have both REFCLK and SYNCCLK then enable both,
1483         * otherwise apply the SYNCCLK settings to REFCLK.
1484         */
1485        if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) {
1486                regmap_update_bits(arizona->regmap, fll->base + 5,
1487                                   ARIZONA_FLL1_OUTDIV_MASK,
1488                                   ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1489
1490                arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
1491                                  false);
1492                if (fll->sync_src >= 0)
1493                        arizona_apply_fll(arizona, fll->base + 0x10, sync,
1494                                          fll->sync_src, true);
1495        } else if (fll->sync_src >= 0) {
1496                regmap_update_bits(arizona->regmap, fll->base + 5,
1497                                   ARIZONA_FLL1_OUTDIV_MASK,
1498                                   sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1499
1500                arizona_apply_fll(arizona, fll->base, sync,
1501                                  fll->sync_src, false);
1502
1503                regmap_update_bits(arizona->regmap, fll->base + 0x11,
1504                                   ARIZONA_FLL1_SYNC_ENA, 0);
1505        } else {
1506                arizona_fll_err(fll, "No clocks provided\n");
1507                return;
1508        }
1509
1510        /*
1511         * Increase the bandwidth if we're not using a low frequency
1512         * sync source.
1513         */
1514        if (fll->sync_src >= 0 && fll->sync_freq > 100000)
1515                regmap_update_bits(arizona->regmap, fll->base + 0x17,
1516                                   ARIZONA_FLL1_SYNC_BW, 0);
1517        else
1518                regmap_update_bits(arizona->regmap, fll->base + 0x17,
1519                                   ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW);
1520
1521        if (!arizona_is_enabled_fll(fll))
1522                pm_runtime_get(arizona->dev);
1523
1524        /* Clear any pending completions */
1525        try_wait_for_completion(&fll->ok);
1526
1527        regmap_update_bits(arizona->regmap, fll->base + 1,
1528                           ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1529        if (fll->ref_src >= 0 && fll->sync_src >= 0 &&
1530            fll->ref_src != fll->sync_src)
1531                regmap_update_bits(arizona->regmap, fll->base + 0x11,
1532                                   ARIZONA_FLL1_SYNC_ENA,
1533                                   ARIZONA_FLL1_SYNC_ENA);
1534
1535        ret = wait_for_completion_timeout(&fll->ok,
1536                                          msecs_to_jiffies(250));
1537        if (ret == 0)
1538                arizona_fll_warn(fll, "Timed out waiting for lock\n");
1539}
1540
1541static void arizona_disable_fll(struct arizona_fll *fll)
1542{
1543        struct arizona *arizona = fll->arizona;
1544        bool change;
1545
1546        regmap_update_bits_check(arizona->regmap, fll->base + 1,
1547                                 ARIZONA_FLL1_ENA, 0, &change);
1548        regmap_update_bits(arizona->regmap, fll->base + 0x11,
1549                           ARIZONA_FLL1_SYNC_ENA, 0);
1550
1551        if (change)
1552                pm_runtime_put_autosuspend(arizona->dev);
1553}
1554
1555int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1556                           unsigned int Fref, unsigned int Fout)
1557{
1558        struct arizona_fll_cfg ref, sync;
1559        int ret;
1560
1561        if (fll->ref_src == source && fll->ref_freq == Fref)
1562                return 0;
1563
1564        if (fll->fout && Fref > 0) {
1565                ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
1566                if (ret != 0)
1567                        return ret;
1568
1569                if (fll->sync_src >= 0) {
1570                        ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
1571                                               fll->fout);
1572                        if (ret != 0)
1573                                return ret;
1574                }
1575        }
1576
1577        fll->ref_src = source;
1578        fll->ref_freq = Fref;
1579
1580        if (fll->fout && Fref > 0) {
1581                arizona_enable_fll(fll, &ref, &sync);
1582        }
1583
1584        return 0;
1585}
1586EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1587
1588int arizona_set_fll(struct arizona_fll *fll, int source,
1589                    unsigned int Fref, unsigned int Fout)
1590{
1591        struct arizona_fll_cfg ref, sync;
1592        int ret;
1593
1594        if (fll->sync_src == source &&
1595            fll->sync_freq == Fref && fll->fout == Fout)
1596                return 0;
1597
1598        if (Fout) {
1599                if (fll->ref_src >= 0) {
1600                        ret = arizona_calc_fll(fll, &ref, fll->ref_freq,
1601                                               Fout);
1602                        if (ret != 0)
1603                                return ret;
1604                }
1605
1606                ret = arizona_calc_fll(fll, &sync, Fref, Fout);
1607                if (ret != 0)
1608                        return ret;
1609        }
1610
1611        fll->sync_src = source;
1612        fll->sync_freq = Fref;
1613        fll->fout = Fout;
1614
1615        if (Fout) {
1616                arizona_enable_fll(fll, &ref, &sync);
1617        } else {
1618                arizona_disable_fll(fll);
1619        }
1620
1621        return 0;
1622}
1623EXPORT_SYMBOL_GPL(arizona_set_fll);
1624
1625int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1626                     int ok_irq, struct arizona_fll *fll)
1627{
1628        int ret;
1629        unsigned int val;
1630
1631        init_completion(&fll->ok);
1632
1633        fll->id = id;
1634        fll->base = base;
1635        fll->arizona = arizona;
1636        fll->sync_src = ARIZONA_FLL_SRC_NONE;
1637
1638        /* Configure default refclk to 32kHz if we have one */
1639        regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1640        switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1641        case ARIZONA_CLK_SRC_MCLK1:
1642        case ARIZONA_CLK_SRC_MCLK2:
1643                fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
1644                break;
1645        default:
1646                fll->ref_src = ARIZONA_FLL_SRC_NONE;
1647        }
1648        fll->ref_freq = 32768;
1649
1650        snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1651        snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
1652                 "FLL%d clock OK", id);
1653
1654        ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
1655                                  arizona_fll_clock_ok, fll);
1656        if (ret != 0) {
1657                dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
1658                        id, ret);
1659        }
1660
1661        regmap_update_bits(arizona->regmap, fll->base + 1,
1662                           ARIZONA_FLL1_FREERUN, 0);
1663
1664        return 0;
1665}
1666EXPORT_SYMBOL_GPL(arizona_init_fll);
1667
1668/**
1669 * arizona_set_output_mode - Set the mode of the specified output
1670 *
1671 * @codec: Device to configure
1672 * @output: Output number
1673 * @diff: True to set the output to differential mode
1674 *
1675 * Some systems use external analogue switches to connect more
1676 * analogue devices to the CODEC than are supported by the device.  In
1677 * some systems this requires changing the switched output from single
1678 * ended to differential mode dynamically at runtime, an operation
1679 * supported using this function.
1680 *
1681 * Most systems have a single static configuration and should use
1682 * platform data instead.
1683 */
1684int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
1685{
1686        unsigned int reg, val;
1687
1688        if (output < 1 || output > 6)
1689                return -EINVAL;
1690
1691        reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
1692
1693        if (diff)
1694                val = ARIZONA_OUT1_MONO;
1695        else
1696                val = 0;
1697
1698        return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
1699}
1700EXPORT_SYMBOL_GPL(arizona_set_output_mode);
1701
1702MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
1703MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1704MODULE_LICENSE("GPL");
1705