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/gcd.h>
  14#include <linux/module.h>
  15#include <linux/pm_runtime.h>
  16#include <sound/pcm.h>
  17#include <sound/pcm_params.h>
  18#include <sound/tlv.h>
  19
  20#include <linux/mfd/arizona/core.h>
  21#include <linux/mfd/arizona/registers.h>
  22
  23#include "arizona.h"
  24
  25#define ARIZONA_AIF_BCLK_CTRL                   0x00
  26#define ARIZONA_AIF_TX_PIN_CTRL                 0x01
  27#define ARIZONA_AIF_RX_PIN_CTRL                 0x02
  28#define ARIZONA_AIF_RATE_CTRL                   0x03
  29#define ARIZONA_AIF_FORMAT                      0x04
  30#define ARIZONA_AIF_TX_BCLK_RATE                0x05
  31#define ARIZONA_AIF_RX_BCLK_RATE                0x06
  32#define ARIZONA_AIF_FRAME_CTRL_1                0x07
  33#define ARIZONA_AIF_FRAME_CTRL_2                0x08
  34#define ARIZONA_AIF_FRAME_CTRL_3                0x09
  35#define ARIZONA_AIF_FRAME_CTRL_4                0x0A
  36#define ARIZONA_AIF_FRAME_CTRL_5                0x0B
  37#define ARIZONA_AIF_FRAME_CTRL_6                0x0C
  38#define ARIZONA_AIF_FRAME_CTRL_7                0x0D
  39#define ARIZONA_AIF_FRAME_CTRL_8                0x0E
  40#define ARIZONA_AIF_FRAME_CTRL_9                0x0F
  41#define ARIZONA_AIF_FRAME_CTRL_10               0x10
  42#define ARIZONA_AIF_FRAME_CTRL_11               0x11
  43#define ARIZONA_AIF_FRAME_CTRL_12               0x12
  44#define ARIZONA_AIF_FRAME_CTRL_13               0x13
  45#define ARIZONA_AIF_FRAME_CTRL_14               0x14
  46#define ARIZONA_AIF_FRAME_CTRL_15               0x15
  47#define ARIZONA_AIF_FRAME_CTRL_16               0x16
  48#define ARIZONA_AIF_FRAME_CTRL_17               0x17
  49#define ARIZONA_AIF_FRAME_CTRL_18               0x18
  50#define ARIZONA_AIF_TX_ENABLES                  0x19
  51#define ARIZONA_AIF_RX_ENABLES                  0x1A
  52#define ARIZONA_AIF_FORCE_WRITE                 0x1B
  53
  54#define arizona_fll_err(_fll, fmt, ...) \
  55        dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  56#define arizona_fll_warn(_fll, fmt, ...) \
  57        dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  58#define arizona_fll_dbg(_fll, fmt, ...) \
  59        dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
  60
  61#define arizona_aif_err(_dai, fmt, ...) \
  62        dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  63#define arizona_aif_warn(_dai, fmt, ...) \
  64        dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  65#define arizona_aif_dbg(_dai, fmt, ...) \
  66        dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
  67
  68const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
  69        "None",
  70        "Tone Generator 1",
  71        "Tone Generator 2",
  72        "Haptics",
  73        "AEC",
  74        "Mic Mute Mixer",
  75        "Noise Generator",
  76        "IN1L",
  77        "IN1R",
  78        "IN2L",
  79        "IN2R",
  80        "IN3L",
  81        "IN3R",
  82        "IN4L",
  83        "IN4R",
  84        "AIF1RX1",
  85        "AIF1RX2",
  86        "AIF1RX3",
  87        "AIF1RX4",
  88        "AIF1RX5",
  89        "AIF1RX6",
  90        "AIF1RX7",
  91        "AIF1RX8",
  92        "AIF2RX1",
  93        "AIF2RX2",
  94        "AIF3RX1",
  95        "AIF3RX2",
  96        "SLIMRX1",
  97        "SLIMRX2",
  98        "SLIMRX3",
  99        "SLIMRX4",
 100        "SLIMRX5",
 101        "SLIMRX6",
 102        "SLIMRX7",
 103        "SLIMRX8",
 104        "EQ1",
 105        "EQ2",
 106        "EQ3",
 107        "EQ4",
 108        "DRC1L",
 109        "DRC1R",
 110        "DRC2L",
 111        "DRC2R",
 112        "LHPF1",
 113        "LHPF2",
 114        "LHPF3",
 115        "LHPF4",
 116        "DSP1.1",
 117        "DSP1.2",
 118        "DSP1.3",
 119        "DSP1.4",
 120        "DSP1.5",
 121        "DSP1.6",
 122        "ASRC1L",
 123        "ASRC1R",
 124        "ASRC2L",
 125        "ASRC2R",
 126};
 127EXPORT_SYMBOL_GPL(arizona_mixer_texts);
 128
 129int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
 130        0x00,  /* None */
 131        0x04,  /* Tone */
 132        0x05,
 133        0x06,  /* Haptics */
 134        0x08,  /* AEC */
 135        0x0c,  /* Noise mixer */
 136        0x0d,  /* Comfort noise */
 137        0x10,  /* IN1L */
 138        0x11,
 139        0x12,
 140        0x13,
 141        0x14,
 142        0x15,
 143        0x16,
 144        0x17,
 145        0x20,  /* AIF1RX1 */
 146        0x21,
 147        0x22,
 148        0x23,
 149        0x24,
 150        0x25,
 151        0x26,
 152        0x27,
 153        0x28,  /* AIF2RX1 */
 154        0x29,
 155        0x30,  /* AIF3RX1 */
 156        0x31,
 157        0x38,  /* SLIMRX1 */
 158        0x39,
 159        0x3a,
 160        0x3b,
 161        0x3c,
 162        0x3d,
 163        0x3e,
 164        0x3f,
 165        0x50,  /* EQ1 */
 166        0x51,
 167        0x52,
 168        0x53,
 169        0x58,  /* DRC1L */
 170        0x59,
 171        0x5a,
 172        0x5b,
 173        0x60,  /* LHPF1 */
 174        0x61,
 175        0x62,
 176        0x63,
 177        0x68,  /* DSP1.1 */
 178        0x69,
 179        0x6a,
 180        0x6b,
 181        0x6c,
 182        0x6d,
 183        0x90,  /* ASRC1L */
 184        0x91,
 185        0x92,
 186        0x93,
 187};
 188EXPORT_SYMBOL_GPL(arizona_mixer_values);
 189
 190const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
 191EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
 192
 193static const char *arizona_lhpf_mode_text[] = {
 194        "Low-pass", "High-pass"
 195};
 196
 197const struct soc_enum arizona_lhpf1_mode =
 198        SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2,
 199                        arizona_lhpf_mode_text);
 200EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
 201
 202const struct soc_enum arizona_lhpf2_mode =
 203        SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2,
 204                        arizona_lhpf_mode_text);
 205EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
 206
 207const struct soc_enum arizona_lhpf3_mode =
 208        SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2,
 209                        arizona_lhpf_mode_text);
 210EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
 211
 212const struct soc_enum arizona_lhpf4_mode =
 213        SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2,
 214                        arizona_lhpf_mode_text);
 215EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
 216
 217int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
 218                  int event)
 219{
 220        return 0;
 221}
 222EXPORT_SYMBOL_GPL(arizona_in_ev);
 223
 224int arizona_out_ev(struct snd_soc_dapm_widget *w,
 225                   struct snd_kcontrol *kcontrol,
 226                   int event)
 227{
 228        return 0;
 229}
 230EXPORT_SYMBOL_GPL(arizona_out_ev);
 231
 232int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 233                       int source, unsigned int freq, int dir)
 234{
 235        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 236        struct arizona *arizona = priv->arizona;
 237        char *name;
 238        unsigned int reg;
 239        unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
 240        unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
 241        unsigned int *clk;
 242
 243        switch (clk_id) {
 244        case ARIZONA_CLK_SYSCLK:
 245                name = "SYSCLK";
 246                reg = ARIZONA_SYSTEM_CLOCK_1;
 247                clk = &priv->sysclk;
 248                mask |= ARIZONA_SYSCLK_FRAC;
 249                break;
 250        case ARIZONA_CLK_ASYNCCLK:
 251                name = "ASYNCCLK";
 252                reg = ARIZONA_ASYNC_CLOCK_1;
 253                clk = &priv->asyncclk;
 254                break;
 255        default:
 256                return -EINVAL;
 257        }
 258
 259        switch (freq) {
 260        case  5644800:
 261        case  6144000:
 262                break;
 263        case 11289600:
 264        case 12288000:
 265                val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT;
 266                break;
 267        case 22579200:
 268        case 24576000:
 269                val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT;
 270                break;
 271        case 45158400:
 272        case 49152000:
 273                val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT;
 274                break;
 275        default:
 276                return -EINVAL;
 277        }
 278
 279        *clk = freq;
 280
 281        if (freq % 6144000)
 282                val |= ARIZONA_SYSCLK_FRAC;
 283
 284        dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
 285
 286        return regmap_update_bits(arizona->regmap, reg, mask, val);
 287}
 288EXPORT_SYMBOL_GPL(arizona_set_sysclk);
 289
 290static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 291{
 292        struct snd_soc_codec *codec = dai->codec;
 293        int lrclk, bclk, mode, base;
 294
 295        base = dai->driver->base;
 296
 297        lrclk = 0;
 298        bclk = 0;
 299
 300        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 301        case SND_SOC_DAIFMT_DSP_A:
 302                mode = 0;
 303                break;
 304        case SND_SOC_DAIFMT_DSP_B:
 305                mode = 1;
 306                break;
 307        case SND_SOC_DAIFMT_I2S:
 308                mode = 2;
 309                break;
 310        case SND_SOC_DAIFMT_LEFT_J:
 311                mode = 3;
 312                break;
 313        default:
 314                arizona_aif_err(dai, "Unsupported DAI format %d\n",
 315                                fmt & SND_SOC_DAIFMT_FORMAT_MASK);
 316                return -EINVAL;
 317        }
 318
 319        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 320        case SND_SOC_DAIFMT_CBS_CFS:
 321                break;
 322        case SND_SOC_DAIFMT_CBS_CFM:
 323                lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
 324                break;
 325        case SND_SOC_DAIFMT_CBM_CFS:
 326                bclk |= ARIZONA_AIF1_BCLK_MSTR;
 327                break;
 328        case SND_SOC_DAIFMT_CBM_CFM:
 329                bclk |= ARIZONA_AIF1_BCLK_MSTR;
 330                lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
 331                break;
 332        default:
 333                arizona_aif_err(dai, "Unsupported master mode %d\n",
 334                                fmt & SND_SOC_DAIFMT_MASTER_MASK);
 335                return -EINVAL;
 336        }
 337
 338        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 339        case SND_SOC_DAIFMT_NB_NF:
 340                break;
 341        case SND_SOC_DAIFMT_IB_IF:
 342                bclk |= ARIZONA_AIF1_BCLK_INV;
 343                lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
 344                break;
 345        case SND_SOC_DAIFMT_IB_NF:
 346                bclk |= ARIZONA_AIF1_BCLK_INV;
 347                break;
 348        case SND_SOC_DAIFMT_NB_IF:
 349                lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
 350                break;
 351        default:
 352                return -EINVAL;
 353        }
 354
 355        snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
 356                            ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
 357                            bclk);
 358        snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
 359                            ARIZONA_AIF1TX_LRCLK_INV |
 360                            ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
 361        snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
 362                            ARIZONA_AIF1RX_LRCLK_INV |
 363                            ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
 364        snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
 365                            ARIZONA_AIF1_FMT_MASK, mode);
 366
 367        return 0;
 368}
 369
 370static const int arizona_48k_bclk_rates[] = {
 371        -1,
 372        48000,
 373        64000,
 374        96000,
 375        128000,
 376        192000,
 377        256000,
 378        384000,
 379        512000,
 380        768000,
 381        1024000,
 382        1536000,
 383        2048000,
 384        3072000,
 385        4096000,
 386        6144000,
 387        8192000,
 388        12288000,
 389        24576000,
 390};
 391
 392static const unsigned int arizona_48k_rates[] = {
 393        12000,
 394        24000,
 395        48000,
 396        96000,
 397        192000,
 398        384000,
 399        768000,
 400        4000,
 401        8000,
 402        16000,
 403        32000,
 404        64000,
 405        128000,
 406        256000,
 407        512000,
 408};
 409
 410static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
 411        .count  = ARRAY_SIZE(arizona_48k_rates),
 412        .list   = arizona_48k_rates,
 413};
 414
 415static const int arizona_44k1_bclk_rates[] = {
 416        -1,
 417        44100,
 418        58800,
 419        88200,
 420        117600,
 421        177640,
 422        235200,
 423        352800,
 424        470400,
 425        705600,
 426        940800,
 427        1411200,
 428        1881600,
 429        2822400,
 430        3763200,
 431        5644800,
 432        7526400,
 433        11289600,
 434        22579200,
 435};
 436
 437static const unsigned int arizona_44k1_rates[] = {
 438        11025,
 439        22050,
 440        44100,
 441        88200,
 442        176400,
 443        352800,
 444        705600,
 445};
 446
 447static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
 448        .count  = ARRAY_SIZE(arizona_44k1_rates),
 449        .list   = arizona_44k1_rates,
 450};
 451
 452static int arizona_sr_vals[] = {
 453        0,
 454        12000,
 455        24000,
 456        48000,
 457        96000,
 458        192000,
 459        384000,
 460        768000,
 461        0,
 462        11025,
 463        22050,
 464        44100,
 465        88200,
 466        176400,
 467        352800,
 468        705600,
 469        4000,
 470        8000,
 471        16000,
 472        32000,
 473        64000,
 474        128000,
 475        256000,
 476        512000,
 477};
 478
 479static int arizona_startup(struct snd_pcm_substream *substream,
 480                           struct snd_soc_dai *dai)
 481{
 482        struct snd_soc_codec *codec = dai->codec;
 483        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 484        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
 485        const struct snd_pcm_hw_constraint_list *constraint;
 486        unsigned int base_rate;
 487
 488        switch (dai_priv->clk) {
 489        case ARIZONA_CLK_SYSCLK:
 490                base_rate = priv->sysclk;
 491                break;
 492        case ARIZONA_CLK_ASYNCCLK:
 493                base_rate = priv->asyncclk;
 494                break;
 495        default:
 496                return 0;
 497        }
 498
 499        if (base_rate % 8000)
 500                constraint = &arizona_44k1_constraint;
 501        else
 502                constraint = &arizona_48k_constraint;
 503
 504        return snd_pcm_hw_constraint_list(substream->runtime, 0,
 505                                          SNDRV_PCM_HW_PARAM_RATE,
 506                                          constraint);
 507}
 508
 509static int arizona_hw_params(struct snd_pcm_substream *substream,
 510                             struct snd_pcm_hw_params *params,
 511                             struct snd_soc_dai *dai)
 512{
 513        struct snd_soc_codec *codec = dai->codec;
 514        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 515        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
 516        int base = dai->driver->base;
 517        const int *rates;
 518        int i;
 519        int bclk, lrclk, wl, frame, sr_val;
 520
 521        if (params_rate(params) % 8000)
 522                rates = &arizona_44k1_bclk_rates[0];
 523        else
 524                rates = &arizona_48k_bclk_rates[0];
 525
 526        for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
 527                if (rates[i] >= snd_soc_params_to_bclk(params) &&
 528                    rates[i] % params_rate(params) == 0) {
 529                        bclk = i;
 530                        break;
 531                }
 532        }
 533        if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
 534                arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
 535                                params_rate(params));
 536                return -EINVAL;
 537        }
 538
 539        for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
 540                if (arizona_sr_vals[i] == params_rate(params))
 541                        break;
 542        if (i == ARRAY_SIZE(arizona_sr_vals)) {
 543                arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
 544                                params_rate(params));
 545                return -EINVAL;
 546        }
 547        sr_val = i;
 548
 549        lrclk = snd_soc_params_to_bclk(params) / params_rate(params);
 550
 551        arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
 552                        rates[bclk], rates[bclk] / lrclk);
 553
 554        wl = snd_pcm_format_width(params_format(params));
 555        frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
 556
 557        /*
 558         * We will need to be more flexible than this in future,
 559         * currently we use a single sample rate for SYSCLK.
 560         */
 561        switch (dai_priv->clk) {
 562        case ARIZONA_CLK_SYSCLK:
 563                snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
 564                                    ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
 565                snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
 566                                    ARIZONA_AIF1_RATE_MASK, 0);
 567                break;
 568        case ARIZONA_CLK_ASYNCCLK:
 569                snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
 570                                    ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
 571                snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
 572                                    ARIZONA_AIF1_RATE_MASK, 8);
 573                break;
 574        default:
 575                arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
 576                return -EINVAL;
 577        }
 578
 579        snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
 580                            ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
 581        snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
 582                            ARIZONA_AIF1TX_BCPF_MASK, lrclk);
 583        snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
 584                            ARIZONA_AIF1RX_BCPF_MASK, lrclk);
 585        snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
 586                            ARIZONA_AIF1TX_WL_MASK |
 587                            ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
 588        snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
 589                            ARIZONA_AIF1RX_WL_MASK |
 590                            ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
 591
 592        return 0;
 593}
 594
 595static const char *arizona_dai_clk_str(int clk_id)
 596{
 597        switch (clk_id) {
 598        case ARIZONA_CLK_SYSCLK:
 599                return "SYSCLK";
 600        case ARIZONA_CLK_ASYNCCLK:
 601                return "ASYNCCLK";
 602        default:
 603                return "Unknown clock";
 604        }
 605}
 606
 607static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
 608                                  int clk_id, unsigned int freq, int dir)
 609{
 610        struct snd_soc_codec *codec = dai->codec;
 611        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 612        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
 613        struct snd_soc_dapm_route routes[2];
 614
 615        switch (clk_id) {
 616        case ARIZONA_CLK_SYSCLK:
 617        case ARIZONA_CLK_ASYNCCLK:
 618                break;
 619        default:
 620                return -EINVAL;
 621        }
 622
 623        if (clk_id == dai_priv->clk)
 624                return 0;
 625
 626        if (dai->active) {
 627                dev_err(codec->dev, "Can't change clock on active DAI %d\n",
 628                        dai->id);
 629                return -EBUSY;
 630        }
 631
 632        memset(&routes, 0, sizeof(routes));
 633        routes[0].sink = dai->driver->capture.stream_name;
 634        routes[1].sink = dai->driver->playback.stream_name;
 635
 636        routes[0].source = arizona_dai_clk_str(dai_priv->clk);
 637        routes[1].source = arizona_dai_clk_str(dai_priv->clk);
 638        snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
 639
 640        routes[0].source = arizona_dai_clk_str(clk_id);
 641        routes[1].source = arizona_dai_clk_str(clk_id);
 642        snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
 643
 644        return snd_soc_dapm_sync(&codec->dapm);
 645}
 646
 647const struct snd_soc_dai_ops arizona_dai_ops = {
 648        .startup = arizona_startup,
 649        .set_fmt = arizona_set_fmt,
 650        .hw_params = arizona_hw_params,
 651        .set_sysclk = arizona_dai_set_sysclk,
 652};
 653EXPORT_SYMBOL_GPL(arizona_dai_ops);
 654
 655int arizona_init_dai(struct arizona_priv *priv, int id)
 656{
 657        struct arizona_dai_priv *dai_priv = &priv->dai[id];
 658
 659        dai_priv->clk = ARIZONA_CLK_SYSCLK;
 660
 661        return 0;
 662}
 663EXPORT_SYMBOL_GPL(arizona_init_dai);
 664
 665static irqreturn_t arizona_fll_lock(int irq, void *data)
 666{
 667        struct arizona_fll *fll = data;
 668
 669        arizona_fll_dbg(fll, "Locked\n");
 670
 671        complete(&fll->lock);
 672
 673        return IRQ_HANDLED;
 674}
 675
 676static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
 677{
 678        struct arizona_fll *fll = data;
 679
 680        arizona_fll_dbg(fll, "clock OK\n");
 681
 682        complete(&fll->ok);
 683
 684        return IRQ_HANDLED;
 685}
 686
 687static struct {
 688        unsigned int min;
 689        unsigned int max;
 690        u16 fratio;
 691        int ratio;
 692} fll_fratios[] = {
 693        {       0,    64000, 4, 16 },
 694        {   64000,   128000, 3,  8 },
 695        {  128000,   256000, 2,  4 },
 696        {  256000,  1000000, 1,  2 },
 697        { 1000000, 13500000, 0,  1 },
 698};
 699
 700struct arizona_fll_cfg {
 701        int n;
 702        int theta;
 703        int lambda;
 704        int refdiv;
 705        int outdiv;
 706        int fratio;
 707};
 708
 709static int arizona_calc_fll(struct arizona_fll *fll,
 710                            struct arizona_fll_cfg *cfg,
 711                            unsigned int Fref,
 712                            unsigned int Fout)
 713{
 714        unsigned int target, div, gcd_fll;
 715        int i, ratio;
 716
 717        arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
 718
 719        /* Fref must be <=13.5MHz */
 720        div = 1;
 721        cfg->refdiv = 0;
 722        while ((Fref / div) > 13500000) {
 723                div *= 2;
 724                cfg->refdiv++;
 725
 726                if (div > 8) {
 727                        arizona_fll_err(fll,
 728                                        "Can't scale %dMHz in to <=13.5MHz\n",
 729                                        Fref);
 730                        return -EINVAL;
 731                }
 732        }
 733
 734        /* Apply the division for our remaining calculations */
 735        Fref /= div;
 736
 737        /* Fvco should be over the targt; don't check the upper bound */
 738        div = 1;
 739        while (Fout * div < 90000000 * fll->vco_mult) {
 740                div++;
 741                if (div > 7) {
 742                        arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
 743                                        Fout);
 744                        return -EINVAL;
 745                }
 746        }
 747        target = Fout * div / fll->vco_mult;
 748        cfg->outdiv = div;
 749
 750        arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
 751
 752        /* Find an appropraite FLL_FRATIO and factor it out of the target */
 753        for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
 754                if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
 755                        cfg->fratio = fll_fratios[i].fratio;
 756                        ratio = fll_fratios[i].ratio;
 757                        break;
 758                }
 759        }
 760        if (i == ARRAY_SIZE(fll_fratios)) {
 761                arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
 762                                Fref);
 763                return -EINVAL;
 764        }
 765
 766        cfg->n = target / (ratio * Fref);
 767
 768        if (target % Fref) {
 769                gcd_fll = gcd(target, ratio * Fref);
 770                arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
 771
 772                cfg->theta = (target - (cfg->n * ratio * Fref))
 773                        / gcd_fll;
 774                cfg->lambda = (ratio * Fref) / gcd_fll;
 775        } else {
 776                cfg->theta = 0;
 777                cfg->lambda = 0;
 778        }
 779
 780        arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
 781                        cfg->n, cfg->theta, cfg->lambda);
 782        arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
 783                        cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
 784
 785        return 0;
 786
 787}
 788
 789static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
 790                              struct arizona_fll_cfg *cfg, int source)
 791{
 792        regmap_update_bits(arizona->regmap, base + 3,
 793                           ARIZONA_FLL1_THETA_MASK, cfg->theta);
 794        regmap_update_bits(arizona->regmap, base + 4,
 795                           ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
 796        regmap_update_bits(arizona->regmap, base + 5,
 797                           ARIZONA_FLL1_FRATIO_MASK,
 798                           cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
 799        regmap_update_bits(arizona->regmap, base + 6,
 800                           ARIZONA_FLL1_CLK_REF_DIV_MASK |
 801                           ARIZONA_FLL1_CLK_REF_SRC_MASK,
 802                           cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
 803                           source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
 804
 805        regmap_update_bits(arizona->regmap, base + 2,
 806                           ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
 807                           ARIZONA_FLL1_CTRL_UPD | cfg->n);
 808}
 809
 810int arizona_set_fll(struct arizona_fll *fll, int source,
 811                    unsigned int Fref, unsigned int Fout)
 812{
 813        struct arizona *arizona = fll->arizona;
 814        struct arizona_fll_cfg cfg, sync;
 815        unsigned int reg, val;
 816        int syncsrc;
 817        bool ena;
 818        int ret;
 819
 820        ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
 821        if (ret != 0) {
 822                arizona_fll_err(fll, "Failed to read current state: %d\n",
 823                                ret);
 824                return ret;
 825        }
 826        ena = reg & ARIZONA_FLL1_ENA;
 827
 828        if (Fout) {
 829                /* Do we have a 32kHz reference? */
 830                regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
 831                switch (val & ARIZONA_CLK_32K_SRC_MASK) {
 832                case ARIZONA_CLK_SRC_MCLK1:
 833                case ARIZONA_CLK_SRC_MCLK2:
 834                        syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
 835                        break;
 836                default:
 837                        syncsrc = -1;
 838                }
 839
 840                if (source == syncsrc)
 841                        syncsrc = -1;
 842
 843                if (syncsrc >= 0) {
 844                        ret = arizona_calc_fll(fll, &sync, Fref, Fout);
 845                        if (ret != 0)
 846                                return ret;
 847
 848                        ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
 849                        if (ret != 0)
 850                                return ret;
 851                } else {
 852                        ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
 853                        if (ret != 0)
 854                                return ret;
 855                }
 856        } else {
 857                regmap_update_bits(arizona->regmap, fll->base + 1,
 858                                   ARIZONA_FLL1_ENA, 0);
 859                regmap_update_bits(arizona->regmap, fll->base + 0x11,
 860                                   ARIZONA_FLL1_SYNC_ENA, 0);
 861
 862                if (ena)
 863                        pm_runtime_put_autosuspend(arizona->dev);
 864
 865                return 0;
 866        }
 867
 868        regmap_update_bits(arizona->regmap, fll->base + 5,
 869                           ARIZONA_FLL1_OUTDIV_MASK,
 870                           cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
 871
 872        if (syncsrc >= 0) {
 873                arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
 874                arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
 875        } else {
 876                arizona_apply_fll(arizona, fll->base, &cfg, source);
 877        }
 878
 879        if (!ena)
 880                pm_runtime_get(arizona->dev);
 881
 882        /* Clear any pending completions */
 883        try_wait_for_completion(&fll->ok);
 884
 885        regmap_update_bits(arizona->regmap, fll->base + 1,
 886                           ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
 887        if (syncsrc >= 0)
 888                regmap_update_bits(arizona->regmap, fll->base + 0x11,
 889                                   ARIZONA_FLL1_SYNC_ENA,
 890                                   ARIZONA_FLL1_SYNC_ENA);
 891
 892        ret = wait_for_completion_timeout(&fll->ok,
 893                                          msecs_to_jiffies(25));
 894        if (ret == 0)
 895                arizona_fll_warn(fll, "Timed out waiting for lock\n");
 896
 897        return 0;
 898}
 899EXPORT_SYMBOL_GPL(arizona_set_fll);
 900
 901int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
 902                     int ok_irq, struct arizona_fll *fll)
 903{
 904        int ret;
 905
 906        init_completion(&fll->lock);
 907        init_completion(&fll->ok);
 908
 909        fll->id = id;
 910        fll->base = base;
 911        fll->arizona = arizona;
 912
 913        snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
 914        snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
 915                 "FLL%d clock OK", id);
 916
 917        ret = arizona_request_irq(arizona, lock_irq, fll->lock_name,
 918                                  arizona_fll_lock, fll);
 919        if (ret != 0) {
 920                dev_err(arizona->dev, "Failed to get FLL%d lock IRQ: %d\n",
 921                        id, ret);
 922        }
 923
 924        ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
 925                                  arizona_fll_clock_ok, fll);
 926        if (ret != 0) {
 927                dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
 928                        id, ret);
 929        }
 930
 931        return 0;
 932}
 933EXPORT_SYMBOL_GPL(arizona_init_fll);
 934
 935MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
 936MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 937MODULE_LICENSE("GPL");
 938