linux/sound/soc/fsl/fsl_esai.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// Freescale ESAI ALSA SoC Digital Audio Interface (DAI) driver
   4//
   5// Copyright (C) 2014 Freescale Semiconductor, Inc.
   6
   7#include <linux/clk.h>
   8#include <linux/dmaengine.h>
   9#include <linux/module.h>
  10#include <linux/of_irq.h>
  11#include <linux/of_platform.h>
  12#include <linux/pm_runtime.h>
  13#include <sound/dmaengine_pcm.h>
  14#include <sound/pcm_params.h>
  15
  16#include "fsl_esai.h"
  17#include "imx-pcm.h"
  18
  19#define FSL_ESAI_FORMATS        (SNDRV_PCM_FMTBIT_S8 | \
  20                                SNDRV_PCM_FMTBIT_S16_LE | \
  21                                SNDRV_PCM_FMTBIT_S20_3LE | \
  22                                SNDRV_PCM_FMTBIT_S24_LE)
  23
  24/**
  25 * fsl_esai: ESAI private data
  26 *
  27 * @dma_params_rx: DMA parameters for receive channel
  28 * @dma_params_tx: DMA parameters for transmit channel
  29 * @pdev: platform device pointer
  30 * @regmap: regmap handler
  31 * @coreclk: clock source to access register
  32 * @extalclk: esai clock source to derive HCK, SCK and FS
  33 * @fsysclk: system clock source to derive HCK, SCK and FS
  34 * @spbaclk: SPBA clock (optional, depending on SoC design)
  35 * @fifo_depth: depth of tx/rx FIFO
  36 * @slot_width: width of each DAI slot
  37 * @slots: number of slots
  38 * @hck_rate: clock rate of desired HCKx clock
  39 * @sck_rate: clock rate of desired SCKx clock
  40 * @hck_dir: the direction of HCKx pads
  41 * @sck_div: if using PSR/PM dividers for SCKx clock
  42 * @slave_mode: if fully using DAI slave mode
  43 * @synchronous: if using tx/rx synchronous mode
  44 * @name: driver name
  45 */
  46struct fsl_esai {
  47        struct snd_dmaengine_dai_dma_data dma_params_rx;
  48        struct snd_dmaengine_dai_dma_data dma_params_tx;
  49        struct platform_device *pdev;
  50        struct regmap *regmap;
  51        struct clk *coreclk;
  52        struct clk *extalclk;
  53        struct clk *fsysclk;
  54        struct clk *spbaclk;
  55        u32 fifo_depth;
  56        u32 slot_width;
  57        u32 slots;
  58        u32 tx_mask;
  59        u32 rx_mask;
  60        u32 hck_rate[2];
  61        u32 sck_rate[2];
  62        bool hck_dir[2];
  63        bool sck_div[2];
  64        bool slave_mode;
  65        bool synchronous;
  66        char name[32];
  67};
  68
  69static irqreturn_t esai_isr(int irq, void *devid)
  70{
  71        struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
  72        struct platform_device *pdev = esai_priv->pdev;
  73        u32 esr;
  74
  75        regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr);
  76
  77        if (esr & ESAI_ESR_TINIT_MASK)
  78                dev_dbg(&pdev->dev, "isr: Transmission Initialized\n");
  79
  80        if (esr & ESAI_ESR_RFF_MASK)
  81                dev_warn(&pdev->dev, "isr: Receiving overrun\n");
  82
  83        if (esr & ESAI_ESR_TFE_MASK)
  84                dev_warn(&pdev->dev, "isr: Transmission underrun\n");
  85
  86        if (esr & ESAI_ESR_TLS_MASK)
  87                dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n");
  88
  89        if (esr & ESAI_ESR_TDE_MASK)
  90                dev_dbg(&pdev->dev, "isr: Transmission data exception\n");
  91
  92        if (esr & ESAI_ESR_TED_MASK)
  93                dev_dbg(&pdev->dev, "isr: Transmitting even slots\n");
  94
  95        if (esr & ESAI_ESR_TD_MASK)
  96                dev_dbg(&pdev->dev, "isr: Transmitting data\n");
  97
  98        if (esr & ESAI_ESR_RLS_MASK)
  99                dev_dbg(&pdev->dev, "isr: Just received the last slot\n");
 100
 101        if (esr & ESAI_ESR_RDE_MASK)
 102                dev_dbg(&pdev->dev, "isr: Receiving data exception\n");
 103
 104        if (esr & ESAI_ESR_RED_MASK)
 105                dev_dbg(&pdev->dev, "isr: Receiving even slots\n");
 106
 107        if (esr & ESAI_ESR_RD_MASK)
 108                dev_dbg(&pdev->dev, "isr: Receiving data\n");
 109
 110        return IRQ_HANDLED;
 111}
 112
 113/**
 114 * This function is used to calculate the divisors of psr, pm, fp and it is
 115 * supposed to be called in set_dai_sysclk() and set_bclk().
 116 *
 117 * @ratio: desired overall ratio for the paticipating dividers
 118 * @usefp: for HCK setting, there is no need to set fp divider
 119 * @fp: bypass other dividers by setting fp directly if fp != 0
 120 * @tx: current setting is for playback or capture
 121 */
 122static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
 123                                bool usefp, u32 fp)
 124{
 125        struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
 126        u32 psr, pm = 999, maxfp, prod, sub, savesub, i, j;
 127
 128        maxfp = usefp ? 16 : 1;
 129
 130        if (usefp && fp)
 131                goto out_fp;
 132
 133        if (ratio > 2 * 8 * 256 * maxfp || ratio < 2) {
 134                dev_err(dai->dev, "the ratio is out of range (2 ~ %d)\n",
 135                                2 * 8 * 256 * maxfp);
 136                return -EINVAL;
 137        } else if (ratio % 2) {
 138                dev_err(dai->dev, "the raio must be even if using upper divider\n");
 139                return -EINVAL;
 140        }
 141
 142        ratio /= 2;
 143
 144        psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
 145
 146        /* Do not loop-search if PM (1 ~ 256) alone can serve the ratio */
 147        if (ratio <= 256) {
 148                pm = ratio;
 149                fp = 1;
 150                goto out;
 151        }
 152
 153        /* Set the max fluctuation -- 0.1% of the max devisor */
 154        savesub = (psr ? 1 : 8)  * 256 * maxfp / 1000;
 155
 156        /* Find the best value for PM */
 157        for (i = 1; i <= 256; i++) {
 158                for (j = 1; j <= maxfp; j++) {
 159                        /* PSR (1 or 8) * PM (1 ~ 256) * FP (1 ~ 16) */
 160                        prod = (psr ? 1 : 8) * i * j;
 161
 162                        if (prod == ratio)
 163                                sub = 0;
 164                        else if (prod / ratio == 1)
 165                                sub = prod - ratio;
 166                        else if (ratio / prod == 1)
 167                                sub = ratio - prod;
 168                        else
 169                                continue;
 170
 171                        /* Calculate the fraction */
 172                        sub = sub * 1000 / ratio;
 173                        if (sub < savesub) {
 174                                savesub = sub;
 175                                pm = i;
 176                                fp = j;
 177                        }
 178
 179                        /* We are lucky */
 180                        if (savesub == 0)
 181                                goto out;
 182                }
 183        }
 184
 185        if (pm == 999) {
 186                dev_err(dai->dev, "failed to calculate proper divisors\n");
 187                return -EINVAL;
 188        }
 189
 190out:
 191        regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
 192                           ESAI_xCCR_xPSR_MASK | ESAI_xCCR_xPM_MASK,
 193                           psr | ESAI_xCCR_xPM(pm));
 194
 195out_fp:
 196        /* Bypass fp if not being required */
 197        if (maxfp <= 1)
 198                return 0;
 199
 200        regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
 201                           ESAI_xCCR_xFP_MASK, ESAI_xCCR_xFP(fp));
 202
 203        return 0;
 204}
 205
 206/**
 207 * This function mainly configures the clock frequency of MCLK (HCKT/HCKR)
 208 *
 209 * @Parameters:
 210 * clk_id: The clock source of HCKT/HCKR
 211 *        (Input from outside; output from inside, FSYS or EXTAL)
 212 * freq: The required clock rate of HCKT/HCKR
 213 * dir: The clock direction of HCKT/HCKR
 214 *
 215 * Note: If the direction is input, we do not care about clk_id.
 216 */
 217static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 218                                   unsigned int freq, int dir)
 219{
 220        struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
 221        struct clk *clksrc = esai_priv->extalclk;
 222        bool tx = (clk_id <= ESAI_HCKT_EXTAL || esai_priv->synchronous);
 223        bool in = dir == SND_SOC_CLOCK_IN;
 224        u32 ratio, ecr = 0;
 225        unsigned long clk_rate;
 226        int ret;
 227
 228        if (freq == 0) {
 229                dev_err(dai->dev, "%sput freq of HCK%c should not be 0Hz\n",
 230                        in ? "in" : "out", tx ? 'T' : 'R');
 231                return -EINVAL;
 232        }
 233
 234        /* Bypass divider settings if the requirement doesn't change */
 235        if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx])
 236                return 0;
 237
 238        /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */
 239        esai_priv->sck_div[tx] = true;
 240
 241        /* Set the direction of HCKT/HCKR pins */
 242        regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
 243                           ESAI_xCCR_xHCKD, in ? 0 : ESAI_xCCR_xHCKD);
 244
 245        if (in)
 246                goto out;
 247
 248        switch (clk_id) {
 249        case ESAI_HCKT_FSYS:
 250        case ESAI_HCKR_FSYS:
 251                clksrc = esai_priv->fsysclk;
 252                break;
 253        case ESAI_HCKT_EXTAL:
 254                ecr |= ESAI_ECR_ETI;
 255                break;
 256        case ESAI_HCKR_EXTAL:
 257                ecr |= esai_priv->synchronous ? ESAI_ECR_ETI : ESAI_ECR_ERI;
 258                break;
 259        default:
 260                return -EINVAL;
 261        }
 262
 263        if (IS_ERR(clksrc)) {
 264                dev_err(dai->dev, "no assigned %s clock\n",
 265                                clk_id % 2 ? "extal" : "fsys");
 266                return PTR_ERR(clksrc);
 267        }
 268        clk_rate = clk_get_rate(clksrc);
 269
 270        ratio = clk_rate / freq;
 271        if (ratio * freq > clk_rate)
 272                ret = ratio * freq - clk_rate;
 273        else if (ratio * freq < clk_rate)
 274                ret = clk_rate - ratio * freq;
 275        else
 276                ret = 0;
 277
 278        /* Block if clock source can not be divided into the required rate */
 279        if (ret != 0 && clk_rate / ret < 1000) {
 280                dev_err(dai->dev, "failed to derive required HCK%c rate\n",
 281                                tx ? 'T' : 'R');
 282                return -EINVAL;
 283        }
 284
 285        /* Only EXTAL source can be output directly without using PSR and PM */
 286        if (ratio == 1 && clksrc == esai_priv->extalclk) {
 287                /* Bypass all the dividers if not being needed */
 288                ecr |= tx ? ESAI_ECR_ETO : ESAI_ECR_ERO;
 289                goto out;
 290        } else if (ratio < 2) {
 291                /* The ratio should be no less than 2 if using other sources */
 292                dev_err(dai->dev, "failed to derive required HCK%c rate\n",
 293                                tx ? 'T' : 'R');
 294                return -EINVAL;
 295        }
 296
 297        ret = fsl_esai_divisor_cal(dai, tx, ratio, false, 0);
 298        if (ret)
 299                return ret;
 300
 301        esai_priv->sck_div[tx] = false;
 302
 303out:
 304        esai_priv->hck_dir[tx] = dir;
 305        esai_priv->hck_rate[tx] = freq;
 306
 307        regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
 308                           tx ? ESAI_ECR_ETI | ESAI_ECR_ETO :
 309                           ESAI_ECR_ERI | ESAI_ECR_ERO, ecr);
 310
 311        return 0;
 312}
 313
 314/**
 315 * This function configures the related dividers according to the bclk rate
 316 */
 317static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
 318{
 319        struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
 320        u32 hck_rate = esai_priv->hck_rate[tx];
 321        u32 sub, ratio = hck_rate / freq;
 322        int ret;
 323
 324        /* Don't apply for fully slave mode or unchanged bclk */
 325        if (esai_priv->slave_mode || esai_priv->sck_rate[tx] == freq)
 326                return 0;
 327
 328        if (ratio * freq > hck_rate)
 329                sub = ratio * freq - hck_rate;
 330        else if (ratio * freq < hck_rate)
 331                sub = hck_rate - ratio * freq;
 332        else
 333                sub = 0;
 334
 335        /* Block if clock source can not be divided into the required rate */
 336        if (sub != 0 && hck_rate / sub < 1000) {
 337                dev_err(dai->dev, "failed to derive required SCK%c rate\n",
 338                                tx ? 'T' : 'R');
 339                return -EINVAL;
 340        }
 341
 342        /* The ratio should be contented by FP alone if bypassing PM and PSR */
 343        if (!esai_priv->sck_div[tx] && (ratio > 16 || ratio == 0)) {
 344                dev_err(dai->dev, "the ratio is out of range (1 ~ 16)\n");
 345                return -EINVAL;
 346        }
 347
 348        ret = fsl_esai_divisor_cal(dai, tx, ratio, true,
 349                        esai_priv->sck_div[tx] ? 0 : ratio);
 350        if (ret)
 351                return ret;
 352
 353        /* Save current bclk rate */
 354        esai_priv->sck_rate[tx] = freq;
 355
 356        return 0;
 357}
 358
 359static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
 360                                     u32 rx_mask, int slots, int slot_width)
 361{
 362        struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
 363
 364        regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
 365                           ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
 366
 367        regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
 368                           ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
 369
 370        esai_priv->slot_width = slot_width;
 371        esai_priv->slots = slots;
 372        esai_priv->tx_mask = tx_mask;
 373        esai_priv->rx_mask = rx_mask;
 374
 375        return 0;
 376}
 377
 378static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 379{
 380        struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
 381        u32 xcr = 0, xccr = 0, mask;
 382
 383        /* DAI mode */
 384        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 385        case SND_SOC_DAIFMT_I2S:
 386                /* Data on rising edge of bclk, frame low, 1clk before data */
 387                xcr |= ESAI_xCR_xFSR;
 388                xccr |= ESAI_xCCR_xFSP | ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
 389                break;
 390        case SND_SOC_DAIFMT_LEFT_J:
 391                /* Data on rising edge of bclk, frame high */
 392                xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
 393                break;
 394        case SND_SOC_DAIFMT_RIGHT_J:
 395                /* Data on rising edge of bclk, frame high, right aligned */
 396                xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
 397                xcr  |= ESAI_xCR_xWA;
 398                break;
 399        case SND_SOC_DAIFMT_DSP_A:
 400                /* Data on rising edge of bclk, frame high, 1clk before data */
 401                xcr |= ESAI_xCR_xFSL | ESAI_xCR_xFSR;
 402                xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
 403                break;
 404        case SND_SOC_DAIFMT_DSP_B:
 405                /* Data on rising edge of bclk, frame high */
 406                xcr |= ESAI_xCR_xFSL;
 407                xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
 408                break;
 409        default:
 410                return -EINVAL;
 411        }
 412
 413        /* DAI clock inversion */
 414        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 415        case SND_SOC_DAIFMT_NB_NF:
 416                /* Nothing to do for both normal cases */
 417                break;
 418        case SND_SOC_DAIFMT_IB_NF:
 419                /* Invert bit clock */
 420                xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
 421                break;
 422        case SND_SOC_DAIFMT_NB_IF:
 423                /* Invert frame clock */
 424                xccr ^= ESAI_xCCR_xFSP;
 425                break;
 426        case SND_SOC_DAIFMT_IB_IF:
 427                /* Invert both clocks */
 428                xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP;
 429                break;
 430        default:
 431                return -EINVAL;
 432        }
 433
 434        esai_priv->slave_mode = false;
 435
 436        /* DAI clock master masks */
 437        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 438        case SND_SOC_DAIFMT_CBM_CFM:
 439                esai_priv->slave_mode = true;
 440                break;
 441        case SND_SOC_DAIFMT_CBS_CFM:
 442                xccr |= ESAI_xCCR_xCKD;
 443                break;
 444        case SND_SOC_DAIFMT_CBM_CFS:
 445                xccr |= ESAI_xCCR_xFSD;
 446                break;
 447        case SND_SOC_DAIFMT_CBS_CFS:
 448                xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
 449                break;
 450        default:
 451                return -EINVAL;
 452        }
 453
 454        mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR | ESAI_xCR_xWA;
 455        regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr);
 456        regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr);
 457
 458        mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP |
 459                ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
 460        regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr);
 461        regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr);
 462
 463        return 0;
 464}
 465
 466static int fsl_esai_startup(struct snd_pcm_substream *substream,
 467                            struct snd_soc_dai *dai)
 468{
 469        struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
 470
 471        if (!dai->active) {
 472                /* Set synchronous mode */
 473                regmap_update_bits(esai_priv->regmap, REG_ESAI_SAICR,
 474                                   ESAI_SAICR_SYNC, esai_priv->synchronous ?
 475                                   ESAI_SAICR_SYNC : 0);
 476
 477                /* Set a default slot number -- 2 */
 478                regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
 479                                   ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2));
 480                regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
 481                                   ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2));
 482        }
 483
 484        return 0;
 485
 486}
 487
 488static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
 489                              struct snd_pcm_hw_params *params,
 490                              struct snd_soc_dai *dai)
 491{
 492        struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
 493        bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 494        u32 width = params_width(params);
 495        u32 channels = params_channels(params);
 496        u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
 497        u32 slot_width = width;
 498        u32 bclk, mask, val;
 499        int ret;
 500
 501        /* Override slot_width if being specifically set */
 502        if (esai_priv->slot_width)
 503                slot_width = esai_priv->slot_width;
 504
 505        bclk = params_rate(params) * slot_width * esai_priv->slots;
 506
 507        ret = fsl_esai_set_bclk(dai, esai_priv->synchronous || tx, bclk);
 508        if (ret)
 509                return ret;
 510
 511        mask = ESAI_xCR_xSWS_MASK;
 512        val = ESAI_xCR_xSWS(slot_width, width);
 513
 514        regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), mask, val);
 515        /* Recording in synchronous mode needs to set TCR also */
 516        if (!tx && esai_priv->synchronous)
 517                regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, val);
 518
 519        /* Use Normal mode to support monaural audio */
 520        regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
 521                           ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ?
 522                           ESAI_xCR_xMOD_NETWORK : 0);
 523
 524        regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
 525                           ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR);
 526
 527        mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK |
 528              (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK);
 529        val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) |
 530             (tx ? ESAI_xFCR_TE(pins) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(pins));
 531
 532        regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val);
 533
 534        if (tx)
 535                regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
 536                                ESAI_xCR_PADC, ESAI_xCR_PADC);
 537
 538        /* Remove ESAI personal reset by configuring ESAI_PCRC and ESAI_PRRC */
 539        regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
 540                           ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO));
 541        regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
 542                           ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO));
 543        return 0;
 544}
 545
 546static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
 547                            struct snd_soc_dai *dai)
 548{
 549        struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
 550        bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 551        u8 i, channels = substream->runtime->channels;
 552        u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
 553        u32 mask;
 554
 555        switch (cmd) {
 556        case SNDRV_PCM_TRIGGER_START:
 557        case SNDRV_PCM_TRIGGER_RESUME:
 558        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 559                regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
 560                                   ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN);
 561
 562                /* Write initial words reqiured by ESAI as normal procedure */
 563                for (i = 0; tx && i < channels; i++)
 564                        regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);
 565
 566                /*
 567                 * When set the TE/RE in the end of enablement flow, there
 568                 * will be channel swap issue for multi data line case.
 569                 * In order to workaround this issue, we switch the bit
 570                 * enablement sequence to below sequence
 571                 * 1) clear the xSMB & xSMA: which is done in probe and
 572                 *                           stop state.
 573                 * 2) set TE/RE
 574                 * 3) set xSMB
 575                 * 4) set xSMA:  xSMA is the last one in this flow, which
 576                 *               will trigger esai to start.
 577                 */
 578                regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
 579                                   tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
 580                                   tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
 581                mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask;
 582
 583                regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
 584                                   ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask));
 585                regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
 586                                   ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask));
 587
 588                break;
 589        case SNDRV_PCM_TRIGGER_SUSPEND:
 590        case SNDRV_PCM_TRIGGER_STOP:
 591        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 592                regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
 593                                   tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
 594                regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
 595                                   ESAI_xSMA_xS_MASK, 0);
 596                regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
 597                                   ESAI_xSMB_xS_MASK, 0);
 598
 599                /* Disable and reset FIFO */
 600                regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
 601                                   ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR);
 602                regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
 603                                   ESAI_xFCR_xFR, 0);
 604                break;
 605        default:
 606                return -EINVAL;
 607        }
 608
 609        return 0;
 610}
 611
 612static const struct snd_soc_dai_ops fsl_esai_dai_ops = {
 613        .startup = fsl_esai_startup,
 614        .trigger = fsl_esai_trigger,
 615        .hw_params = fsl_esai_hw_params,
 616        .set_sysclk = fsl_esai_set_dai_sysclk,
 617        .set_fmt = fsl_esai_set_dai_fmt,
 618        .set_tdm_slot = fsl_esai_set_dai_tdm_slot,
 619};
 620
 621static int fsl_esai_dai_probe(struct snd_soc_dai *dai)
 622{
 623        struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
 624
 625        snd_soc_dai_init_dma_data(dai, &esai_priv->dma_params_tx,
 626                                  &esai_priv->dma_params_rx);
 627
 628        return 0;
 629}
 630
 631static struct snd_soc_dai_driver fsl_esai_dai = {
 632        .probe = fsl_esai_dai_probe,
 633        .playback = {
 634                .stream_name = "CPU-Playback",
 635                .channels_min = 1,
 636                .channels_max = 12,
 637                .rates = SNDRV_PCM_RATE_8000_192000,
 638                .formats = FSL_ESAI_FORMATS,
 639        },
 640        .capture = {
 641                .stream_name = "CPU-Capture",
 642                .channels_min = 1,
 643                .channels_max = 8,
 644                .rates = SNDRV_PCM_RATE_8000_192000,
 645                .formats = FSL_ESAI_FORMATS,
 646        },
 647        .ops = &fsl_esai_dai_ops,
 648};
 649
 650static const struct snd_soc_component_driver fsl_esai_component = {
 651        .name           = "fsl-esai",
 652};
 653
 654static const struct reg_default fsl_esai_reg_defaults[] = {
 655        {REG_ESAI_ETDR,  0x00000000},
 656        {REG_ESAI_ECR,   0x00000000},
 657        {REG_ESAI_TFCR,  0x00000000},
 658        {REG_ESAI_RFCR,  0x00000000},
 659        {REG_ESAI_TX0,   0x00000000},
 660        {REG_ESAI_TX1,   0x00000000},
 661        {REG_ESAI_TX2,   0x00000000},
 662        {REG_ESAI_TX3,   0x00000000},
 663        {REG_ESAI_TX4,   0x00000000},
 664        {REG_ESAI_TX5,   0x00000000},
 665        {REG_ESAI_TSR,   0x00000000},
 666        {REG_ESAI_SAICR, 0x00000000},
 667        {REG_ESAI_TCR,   0x00000000},
 668        {REG_ESAI_TCCR,  0x00000000},
 669        {REG_ESAI_RCR,   0x00000000},
 670        {REG_ESAI_RCCR,  0x00000000},
 671        {REG_ESAI_TSMA,  0x0000ffff},
 672        {REG_ESAI_TSMB,  0x0000ffff},
 673        {REG_ESAI_RSMA,  0x0000ffff},
 674        {REG_ESAI_RSMB,  0x0000ffff},
 675        {REG_ESAI_PRRC,  0x00000000},
 676        {REG_ESAI_PCRC,  0x00000000},
 677};
 678
 679static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
 680{
 681        switch (reg) {
 682        case REG_ESAI_ERDR:
 683        case REG_ESAI_ECR:
 684        case REG_ESAI_ESR:
 685        case REG_ESAI_TFCR:
 686        case REG_ESAI_TFSR:
 687        case REG_ESAI_RFCR:
 688        case REG_ESAI_RFSR:
 689        case REG_ESAI_RX0:
 690        case REG_ESAI_RX1:
 691        case REG_ESAI_RX2:
 692        case REG_ESAI_RX3:
 693        case REG_ESAI_SAISR:
 694        case REG_ESAI_SAICR:
 695        case REG_ESAI_TCR:
 696        case REG_ESAI_TCCR:
 697        case REG_ESAI_RCR:
 698        case REG_ESAI_RCCR:
 699        case REG_ESAI_TSMA:
 700        case REG_ESAI_TSMB:
 701        case REG_ESAI_RSMA:
 702        case REG_ESAI_RSMB:
 703        case REG_ESAI_PRRC:
 704        case REG_ESAI_PCRC:
 705                return true;
 706        default:
 707                return false;
 708        }
 709}
 710
 711static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg)
 712{
 713        switch (reg) {
 714        case REG_ESAI_ERDR:
 715        case REG_ESAI_ESR:
 716        case REG_ESAI_TFSR:
 717        case REG_ESAI_RFSR:
 718        case REG_ESAI_RX0:
 719        case REG_ESAI_RX1:
 720        case REG_ESAI_RX2:
 721        case REG_ESAI_RX3:
 722        case REG_ESAI_SAISR:
 723                return true;
 724        default:
 725                return false;
 726        }
 727}
 728
 729static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
 730{
 731        switch (reg) {
 732        case REG_ESAI_ETDR:
 733        case REG_ESAI_ECR:
 734        case REG_ESAI_TFCR:
 735        case REG_ESAI_RFCR:
 736        case REG_ESAI_TX0:
 737        case REG_ESAI_TX1:
 738        case REG_ESAI_TX2:
 739        case REG_ESAI_TX3:
 740        case REG_ESAI_TX4:
 741        case REG_ESAI_TX5:
 742        case REG_ESAI_TSR:
 743        case REG_ESAI_SAICR:
 744        case REG_ESAI_TCR:
 745        case REG_ESAI_TCCR:
 746        case REG_ESAI_RCR:
 747        case REG_ESAI_RCCR:
 748        case REG_ESAI_TSMA:
 749        case REG_ESAI_TSMB:
 750        case REG_ESAI_RSMA:
 751        case REG_ESAI_RSMB:
 752        case REG_ESAI_PRRC:
 753        case REG_ESAI_PCRC:
 754                return true;
 755        default:
 756                return false;
 757        }
 758}
 759
 760static const struct regmap_config fsl_esai_regmap_config = {
 761        .reg_bits = 32,
 762        .reg_stride = 4,
 763        .val_bits = 32,
 764
 765        .max_register = REG_ESAI_PCRC,
 766        .reg_defaults = fsl_esai_reg_defaults,
 767        .num_reg_defaults = ARRAY_SIZE(fsl_esai_reg_defaults),
 768        .readable_reg = fsl_esai_readable_reg,
 769        .volatile_reg = fsl_esai_volatile_reg,
 770        .writeable_reg = fsl_esai_writeable_reg,
 771        .cache_type = REGCACHE_FLAT,
 772};
 773
 774static int fsl_esai_probe(struct platform_device *pdev)
 775{
 776        struct device_node *np = pdev->dev.of_node;
 777        struct fsl_esai *esai_priv;
 778        struct resource *res;
 779        const __be32 *iprop;
 780        void __iomem *regs;
 781        int irq, ret;
 782
 783        esai_priv = devm_kzalloc(&pdev->dev, sizeof(*esai_priv), GFP_KERNEL);
 784        if (!esai_priv)
 785                return -ENOMEM;
 786
 787        esai_priv->pdev = pdev;
 788        snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np);
 789
 790        /* Get the addresses and IRQ */
 791        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 792        regs = devm_ioremap_resource(&pdev->dev, res);
 793        if (IS_ERR(regs))
 794                return PTR_ERR(regs);
 795
 796        esai_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
 797                        "core", regs, &fsl_esai_regmap_config);
 798        if (IS_ERR(esai_priv->regmap)) {
 799                dev_err(&pdev->dev, "failed to init regmap: %ld\n",
 800                                PTR_ERR(esai_priv->regmap));
 801                return PTR_ERR(esai_priv->regmap);
 802        }
 803
 804        esai_priv->coreclk = devm_clk_get(&pdev->dev, "core");
 805        if (IS_ERR(esai_priv->coreclk)) {
 806                dev_err(&pdev->dev, "failed to get core clock: %ld\n",
 807                                PTR_ERR(esai_priv->coreclk));
 808                return PTR_ERR(esai_priv->coreclk);
 809        }
 810
 811        esai_priv->extalclk = devm_clk_get(&pdev->dev, "extal");
 812        if (IS_ERR(esai_priv->extalclk))
 813                dev_warn(&pdev->dev, "failed to get extal clock: %ld\n",
 814                                PTR_ERR(esai_priv->extalclk));
 815
 816        esai_priv->fsysclk = devm_clk_get(&pdev->dev, "fsys");
 817        if (IS_ERR(esai_priv->fsysclk))
 818                dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
 819                                PTR_ERR(esai_priv->fsysclk));
 820
 821        esai_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
 822        if (IS_ERR(esai_priv->spbaclk))
 823                dev_warn(&pdev->dev, "failed to get spba clock: %ld\n",
 824                                PTR_ERR(esai_priv->spbaclk));
 825
 826        irq = platform_get_irq(pdev, 0);
 827        if (irq < 0) {
 828                dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
 829                return irq;
 830        }
 831
 832        ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0,
 833                               esai_priv->name, esai_priv);
 834        if (ret) {
 835                dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
 836                return ret;
 837        }
 838
 839        /* Set a default slot number */
 840        esai_priv->slots = 2;
 841
 842        /* Set a default master/slave state */
 843        esai_priv->slave_mode = true;
 844
 845        /* Determine the FIFO depth */
 846        iprop = of_get_property(np, "fsl,fifo-depth", NULL);
 847        if (iprop)
 848                esai_priv->fifo_depth = be32_to_cpup(iprop);
 849        else
 850                esai_priv->fifo_depth = 64;
 851
 852        esai_priv->dma_params_tx.maxburst = 16;
 853        esai_priv->dma_params_rx.maxburst = 16;
 854        esai_priv->dma_params_tx.addr = res->start + REG_ESAI_ETDR;
 855        esai_priv->dma_params_rx.addr = res->start + REG_ESAI_ERDR;
 856
 857        esai_priv->synchronous =
 858                of_property_read_bool(np, "fsl,esai-synchronous");
 859
 860        /* Implement full symmetry for synchronous mode */
 861        if (esai_priv->synchronous) {
 862                fsl_esai_dai.symmetric_rates = 1;
 863                fsl_esai_dai.symmetric_channels = 1;
 864                fsl_esai_dai.symmetric_samplebits = 1;
 865        }
 866
 867        dev_set_drvdata(&pdev->dev, esai_priv);
 868
 869        /* Reset ESAI unit */
 870        ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ERST);
 871        if (ret) {
 872                dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
 873                return ret;
 874        }
 875
 876        /*
 877         * We need to enable ESAI so as to access some of its registers.
 878         * Otherwise, we would fail to dump regmap from user space.
 879         */
 880        ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ESAIEN);
 881        if (ret) {
 882                dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret);
 883                return ret;
 884        }
 885
 886        esai_priv->tx_mask = 0xFFFFFFFF;
 887        esai_priv->rx_mask = 0xFFFFFFFF;
 888
 889        /* Clear the TSMA, TSMB, RSMA, RSMB */
 890        regmap_write(esai_priv->regmap, REG_ESAI_TSMA, 0);
 891        regmap_write(esai_priv->regmap, REG_ESAI_TSMB, 0);
 892        regmap_write(esai_priv->regmap, REG_ESAI_RSMA, 0);
 893        regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0);
 894
 895        ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component,
 896                                              &fsl_esai_dai, 1);
 897        if (ret) {
 898                dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
 899                return ret;
 900        }
 901
 902        pm_runtime_enable(&pdev->dev);
 903
 904        regcache_cache_only(esai_priv->regmap, true);
 905
 906        ret = imx_pcm_dma_init(pdev, IMX_ESAI_DMABUF_SIZE);
 907        if (ret)
 908                dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
 909
 910        return ret;
 911}
 912
 913static int fsl_esai_remove(struct platform_device *pdev)
 914{
 915        pm_runtime_disable(&pdev->dev);
 916
 917        return 0;
 918}
 919
 920static const struct of_device_id fsl_esai_dt_ids[] = {
 921        { .compatible = "fsl,imx35-esai", },
 922        { .compatible = "fsl,vf610-esai", },
 923        {}
 924};
 925MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
 926
 927#ifdef CONFIG_PM
 928static int fsl_esai_runtime_resume(struct device *dev)
 929{
 930        struct fsl_esai *esai = dev_get_drvdata(dev);
 931        int ret;
 932
 933        /*
 934         * Some platforms might use the same bit to gate all three or two of
 935         * clocks, so keep all clocks open/close at the same time for safety
 936         */
 937        ret = clk_prepare_enable(esai->coreclk);
 938        if (ret)
 939                return ret;
 940        if (!IS_ERR(esai->spbaclk)) {
 941                ret = clk_prepare_enable(esai->spbaclk);
 942                if (ret)
 943                        goto err_spbaclk;
 944        }
 945        if (!IS_ERR(esai->extalclk)) {
 946                ret = clk_prepare_enable(esai->extalclk);
 947                if (ret)
 948                        goto err_extalclk;
 949        }
 950        if (!IS_ERR(esai->fsysclk)) {
 951                ret = clk_prepare_enable(esai->fsysclk);
 952                if (ret)
 953                        goto err_fsysclk;
 954        }
 955
 956        regcache_cache_only(esai->regmap, false);
 957
 958        /* FIFO reset for safety */
 959        regmap_update_bits(esai->regmap, REG_ESAI_TFCR,
 960                           ESAI_xFCR_xFR, ESAI_xFCR_xFR);
 961        regmap_update_bits(esai->regmap, REG_ESAI_RFCR,
 962                           ESAI_xFCR_xFR, ESAI_xFCR_xFR);
 963
 964        ret = regcache_sync(esai->regmap);
 965        if (ret)
 966                goto err_regcache_sync;
 967
 968        /* FIFO reset done */
 969        regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
 970        regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
 971
 972        return 0;
 973
 974err_regcache_sync:
 975        if (!IS_ERR(esai->fsysclk))
 976                clk_disable_unprepare(esai->fsysclk);
 977err_fsysclk:
 978        if (!IS_ERR(esai->extalclk))
 979                clk_disable_unprepare(esai->extalclk);
 980err_extalclk:
 981        if (!IS_ERR(esai->spbaclk))
 982                clk_disable_unprepare(esai->spbaclk);
 983err_spbaclk:
 984        clk_disable_unprepare(esai->coreclk);
 985
 986        return ret;
 987}
 988
 989static int fsl_esai_runtime_suspend(struct device *dev)
 990{
 991        struct fsl_esai *esai = dev_get_drvdata(dev);
 992
 993        regcache_cache_only(esai->regmap, true);
 994        regcache_mark_dirty(esai->regmap);
 995
 996        if (!IS_ERR(esai->fsysclk))
 997                clk_disable_unprepare(esai->fsysclk);
 998        if (!IS_ERR(esai->extalclk))
 999                clk_disable_unprepare(esai->extalclk);
1000        if (!IS_ERR(esai->spbaclk))
1001                clk_disable_unprepare(esai->spbaclk);
1002        clk_disable_unprepare(esai->coreclk);
1003
1004        return 0;
1005}
1006#endif /* CONFIG_PM */
1007
1008static const struct dev_pm_ops fsl_esai_pm_ops = {
1009        SET_RUNTIME_PM_OPS(fsl_esai_runtime_suspend,
1010                           fsl_esai_runtime_resume,
1011                           NULL)
1012        SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1013                                pm_runtime_force_resume)
1014};
1015
1016static struct platform_driver fsl_esai_driver = {
1017        .probe = fsl_esai_probe,
1018        .remove = fsl_esai_remove,
1019        .driver = {
1020                .name = "fsl-esai-dai",
1021                .pm = &fsl_esai_pm_ops,
1022                .of_match_table = fsl_esai_dt_ids,
1023        },
1024};
1025
1026module_platform_driver(fsl_esai_driver);
1027
1028MODULE_AUTHOR("Freescale Semiconductor, Inc.");
1029MODULE_DESCRIPTION("Freescale ESAI CPU DAI driver");
1030MODULE_LICENSE("GPL v2");
1031MODULE_ALIAS("platform:fsl-esai-dai");
1032