Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Freescale ESAI ALSA SoC Digital Audio Interface (DAI) driver
0004 //
0005 // Copyright (C) 2014 Freescale Semiconductor, Inc.
0006 
0007 #include <linux/clk.h>
0008 #include <linux/dmaengine.h>
0009 #include <linux/module.h>
0010 #include <linux/of_irq.h>
0011 #include <linux/of_platform.h>
0012 #include <linux/pm_runtime.h>
0013 #include <sound/dmaengine_pcm.h>
0014 #include <sound/pcm_params.h>
0015 
0016 #include "fsl_esai.h"
0017 #include "imx-pcm.h"
0018 
0019 #define FSL_ESAI_FORMATS    (SNDRV_PCM_FMTBIT_S8 | \
0020                 SNDRV_PCM_FMTBIT_S16_LE | \
0021                 SNDRV_PCM_FMTBIT_S20_3LE | \
0022                 SNDRV_PCM_FMTBIT_S24_LE)
0023 
0024 /**
0025  * struct fsl_esai_soc_data - soc specific data
0026  * @reset_at_xrun: flags for enable reset operaton
0027  */
0028 struct fsl_esai_soc_data {
0029     bool reset_at_xrun;
0030 };
0031 
0032 /**
0033  * struct fsl_esai - ESAI private data
0034  * @dma_params_rx: DMA parameters for receive channel
0035  * @dma_params_tx: DMA parameters for transmit channel
0036  * @pdev: platform device pointer
0037  * @regmap: regmap handler
0038  * @coreclk: clock source to access register
0039  * @extalclk: esai clock source to derive HCK, SCK and FS
0040  * @fsysclk: system clock source to derive HCK, SCK and FS
0041  * @spbaclk: SPBA clock (optional, depending on SoC design)
0042  * @work: work to handle the reset operation
0043  * @soc: soc specific data
0044  * @lock: spin lock between hw_reset() and trigger()
0045  * @fifo_depth: depth of tx/rx FIFO
0046  * @slot_width: width of each DAI slot
0047  * @slots: number of slots
0048  * @tx_mask: slot mask for TX
0049  * @rx_mask: slot mask for RX
0050  * @channels: channel num for tx or rx
0051  * @hck_rate: clock rate of desired HCKx clock
0052  * @sck_rate: clock rate of desired SCKx clock
0053  * @hck_dir: the direction of HCKx pads
0054  * @sck_div: if using PSR/PM dividers for SCKx clock
0055  * @consumer_mode: if fully using DAI clock consumer mode
0056  * @synchronous: if using tx/rx synchronous mode
0057  * @name: driver name
0058  */
0059 struct fsl_esai {
0060     struct snd_dmaengine_dai_dma_data dma_params_rx;
0061     struct snd_dmaengine_dai_dma_data dma_params_tx;
0062     struct platform_device *pdev;
0063     struct regmap *regmap;
0064     struct clk *coreclk;
0065     struct clk *extalclk;
0066     struct clk *fsysclk;
0067     struct clk *spbaclk;
0068     struct work_struct work;
0069     const struct fsl_esai_soc_data *soc;
0070     spinlock_t lock; /* Protect hw_reset and trigger */
0071     u32 fifo_depth;
0072     u32 slot_width;
0073     u32 slots;
0074     u32 tx_mask;
0075     u32 rx_mask;
0076     u32 channels[2];
0077     u32 hck_rate[2];
0078     u32 sck_rate[2];
0079     bool hck_dir[2];
0080     bool sck_div[2];
0081     bool consumer_mode;
0082     bool synchronous;
0083     char name[32];
0084 };
0085 
0086 static struct fsl_esai_soc_data fsl_esai_vf610 = {
0087     .reset_at_xrun = true,
0088 };
0089 
0090 static struct fsl_esai_soc_data fsl_esai_imx35 = {
0091     .reset_at_xrun = true,
0092 };
0093 
0094 static struct fsl_esai_soc_data fsl_esai_imx6ull = {
0095     .reset_at_xrun = false,
0096 };
0097 
0098 static irqreturn_t esai_isr(int irq, void *devid)
0099 {
0100     struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
0101     struct platform_device *pdev = esai_priv->pdev;
0102     u32 esr;
0103     u32 saisr;
0104 
0105     regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr);
0106     regmap_read(esai_priv->regmap, REG_ESAI_SAISR, &saisr);
0107 
0108     if ((saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE)) &&
0109         esai_priv->soc->reset_at_xrun) {
0110         dev_dbg(&pdev->dev, "reset module for xrun\n");
0111         regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
0112                    ESAI_xCR_xEIE_MASK, 0);
0113         regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
0114                    ESAI_xCR_xEIE_MASK, 0);
0115         schedule_work(&esai_priv->work);
0116     }
0117 
0118     if (esr & ESAI_ESR_TINIT_MASK)
0119         dev_dbg(&pdev->dev, "isr: Transmission Initialized\n");
0120 
0121     if (esr & ESAI_ESR_RFF_MASK)
0122         dev_warn(&pdev->dev, "isr: Receiving overrun\n");
0123 
0124     if (esr & ESAI_ESR_TFE_MASK)
0125         dev_warn(&pdev->dev, "isr: Transmission underrun\n");
0126 
0127     if (esr & ESAI_ESR_TLS_MASK)
0128         dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n");
0129 
0130     if (esr & ESAI_ESR_TDE_MASK)
0131         dev_dbg(&pdev->dev, "isr: Transmission data exception\n");
0132 
0133     if (esr & ESAI_ESR_TED_MASK)
0134         dev_dbg(&pdev->dev, "isr: Transmitting even slots\n");
0135 
0136     if (esr & ESAI_ESR_TD_MASK)
0137         dev_dbg(&pdev->dev, "isr: Transmitting data\n");
0138 
0139     if (esr & ESAI_ESR_RLS_MASK)
0140         dev_dbg(&pdev->dev, "isr: Just received the last slot\n");
0141 
0142     if (esr & ESAI_ESR_RDE_MASK)
0143         dev_dbg(&pdev->dev, "isr: Receiving data exception\n");
0144 
0145     if (esr & ESAI_ESR_RED_MASK)
0146         dev_dbg(&pdev->dev, "isr: Receiving even slots\n");
0147 
0148     if (esr & ESAI_ESR_RD_MASK)
0149         dev_dbg(&pdev->dev, "isr: Receiving data\n");
0150 
0151     return IRQ_HANDLED;
0152 }
0153 
0154 /**
0155  * fsl_esai_divisor_cal - This function is used to calculate the
0156  * divisors of psr, pm, fp and it is supposed to be called in
0157  * set_dai_sysclk() and set_bclk().
0158  *
0159  * @dai: pointer to DAI
0160  * @tx: current setting is for playback or capture
0161  * @ratio: desired overall ratio for the paticipating dividers
0162  * @usefp: for HCK setting, there is no need to set fp divider
0163  * @fp: bypass other dividers by setting fp directly if fp != 0
0164  */
0165 static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
0166                 bool usefp, u32 fp)
0167 {
0168     struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0169     u32 psr, pm = 999, maxfp, prod, sub, savesub, i, j;
0170 
0171     maxfp = usefp ? 16 : 1;
0172 
0173     if (usefp && fp)
0174         goto out_fp;
0175 
0176     if (ratio > 2 * 8 * 256 * maxfp || ratio < 2) {
0177         dev_err(dai->dev, "the ratio is out of range (2 ~ %d)\n",
0178                 2 * 8 * 256 * maxfp);
0179         return -EINVAL;
0180     } else if (ratio % 2) {
0181         dev_err(dai->dev, "the raio must be even if using upper divider\n");
0182         return -EINVAL;
0183     }
0184 
0185     ratio /= 2;
0186 
0187     psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
0188 
0189     /* Do not loop-search if PM (1 ~ 256) alone can serve the ratio */
0190     if (ratio <= 256) {
0191         pm = ratio;
0192         fp = 1;
0193         goto out;
0194     }
0195 
0196     /* Set the max fluctuation -- 0.1% of the max devisor */
0197     savesub = (psr ? 1 : 8)  * 256 * maxfp / 1000;
0198 
0199     /* Find the best value for PM */
0200     for (i = 1; i <= 256; i++) {
0201         for (j = 1; j <= maxfp; j++) {
0202             /* PSR (1 or 8) * PM (1 ~ 256) * FP (1 ~ 16) */
0203             prod = (psr ? 1 : 8) * i * j;
0204 
0205             if (prod == ratio)
0206                 sub = 0;
0207             else if (prod / ratio == 1)
0208                 sub = prod - ratio;
0209             else if (ratio / prod == 1)
0210                 sub = ratio - prod;
0211             else
0212                 continue;
0213 
0214             /* Calculate the fraction */
0215             sub = sub * 1000 / ratio;
0216             if (sub < savesub) {
0217                 savesub = sub;
0218                 pm = i;
0219                 fp = j;
0220             }
0221 
0222             /* We are lucky */
0223             if (savesub == 0)
0224                 goto out;
0225         }
0226     }
0227 
0228     if (pm == 999) {
0229         dev_err(dai->dev, "failed to calculate proper divisors\n");
0230         return -EINVAL;
0231     }
0232 
0233 out:
0234     regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
0235                ESAI_xCCR_xPSR_MASK | ESAI_xCCR_xPM_MASK,
0236                psr | ESAI_xCCR_xPM(pm));
0237 
0238 out_fp:
0239     /* Bypass fp if not being required */
0240     if (maxfp <= 1)
0241         return 0;
0242 
0243     regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
0244                ESAI_xCCR_xFP_MASK, ESAI_xCCR_xFP(fp));
0245 
0246     return 0;
0247 }
0248 
0249 /**
0250  * fsl_esai_set_dai_sysclk - configure the clock frequency of MCLK (HCKT/HCKR)
0251  * @dai: pointer to DAI
0252  * @clk_id: The clock source of HCKT/HCKR
0253  *    (Input from outside; output from inside, FSYS or EXTAL)
0254  * @freq: The required clock rate of HCKT/HCKR
0255  * @dir: The clock direction of HCKT/HCKR
0256  *
0257  * Note: If the direction is input, we do not care about clk_id.
0258  */
0259 static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
0260                    unsigned int freq, int dir)
0261 {
0262     struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0263     struct clk *clksrc = esai_priv->extalclk;
0264     bool tx = (clk_id <= ESAI_HCKT_EXTAL || esai_priv->synchronous);
0265     bool in = dir == SND_SOC_CLOCK_IN;
0266     u32 ratio, ecr = 0;
0267     unsigned long clk_rate;
0268     int ret;
0269 
0270     if (freq == 0) {
0271         dev_err(dai->dev, "%sput freq of HCK%c should not be 0Hz\n",
0272             in ? "in" : "out", tx ? 'T' : 'R');
0273         return -EINVAL;
0274     }
0275 
0276     /* Bypass divider settings if the requirement doesn't change */
0277     if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx])
0278         return 0;
0279 
0280     /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */
0281     esai_priv->sck_div[tx] = true;
0282 
0283     /* Set the direction of HCKT/HCKR pins */
0284     regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
0285                ESAI_xCCR_xHCKD, in ? 0 : ESAI_xCCR_xHCKD);
0286 
0287     if (in)
0288         goto out;
0289 
0290     switch (clk_id) {
0291     case ESAI_HCKT_FSYS:
0292     case ESAI_HCKR_FSYS:
0293         clksrc = esai_priv->fsysclk;
0294         break;
0295     case ESAI_HCKT_EXTAL:
0296         ecr |= ESAI_ECR_ETI;
0297         break;
0298     case ESAI_HCKR_EXTAL:
0299         ecr |= esai_priv->synchronous ? ESAI_ECR_ETI : ESAI_ECR_ERI;
0300         break;
0301     default:
0302         return -EINVAL;
0303     }
0304 
0305     if (IS_ERR(clksrc)) {
0306         dev_err(dai->dev, "no assigned %s clock\n",
0307             (clk_id % 2) ? "extal" : "fsys");
0308         return PTR_ERR(clksrc);
0309     }
0310     clk_rate = clk_get_rate(clksrc);
0311 
0312     ratio = clk_rate / freq;
0313     if (ratio * freq > clk_rate)
0314         ret = ratio * freq - clk_rate;
0315     else if (ratio * freq < clk_rate)
0316         ret = clk_rate - ratio * freq;
0317     else
0318         ret = 0;
0319 
0320     /* Block if clock source can not be divided into the required rate */
0321     if (ret != 0 && clk_rate / ret < 1000) {
0322         dev_err(dai->dev, "failed to derive required HCK%c rate\n",
0323                 tx ? 'T' : 'R');
0324         return -EINVAL;
0325     }
0326 
0327     /* Only EXTAL source can be output directly without using PSR and PM */
0328     if (ratio == 1 && clksrc == esai_priv->extalclk) {
0329         /* Bypass all the dividers if not being needed */
0330         ecr |= tx ? ESAI_ECR_ETO : ESAI_ECR_ERO;
0331         goto out;
0332     } else if (ratio < 2) {
0333         /* The ratio should be no less than 2 if using other sources */
0334         dev_err(dai->dev, "failed to derive required HCK%c rate\n",
0335                 tx ? 'T' : 'R');
0336         return -EINVAL;
0337     }
0338 
0339     ret = fsl_esai_divisor_cal(dai, tx, ratio, false, 0);
0340     if (ret)
0341         return ret;
0342 
0343     esai_priv->sck_div[tx] = false;
0344 
0345 out:
0346     esai_priv->hck_dir[tx] = dir;
0347     esai_priv->hck_rate[tx] = freq;
0348 
0349     regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
0350                tx ? ESAI_ECR_ETI | ESAI_ECR_ETO :
0351                ESAI_ECR_ERI | ESAI_ECR_ERO, ecr);
0352 
0353     return 0;
0354 }
0355 
0356 /**
0357  * fsl_esai_set_bclk - configure the related dividers according to the bclk rate
0358  * @dai: pointer to DAI
0359  * @tx: direction boolean
0360  * @freq: bclk freq
0361  */
0362 static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
0363 {
0364     struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0365     u32 hck_rate = esai_priv->hck_rate[tx];
0366     u32 sub, ratio = hck_rate / freq;
0367     int ret;
0368 
0369     /* Don't apply for fully consumer mode or unchanged bclk */
0370     if (esai_priv->consumer_mode || esai_priv->sck_rate[tx] == freq)
0371         return 0;
0372 
0373     if (ratio * freq > hck_rate)
0374         sub = ratio * freq - hck_rate;
0375     else if (ratio * freq < hck_rate)
0376         sub = hck_rate - ratio * freq;
0377     else
0378         sub = 0;
0379 
0380     /* Block if clock source can not be divided into the required rate */
0381     if (sub != 0 && hck_rate / sub < 1000) {
0382         dev_err(dai->dev, "failed to derive required SCK%c rate\n",
0383                 tx ? 'T' : 'R');
0384         return -EINVAL;
0385     }
0386 
0387     /* The ratio should be contented by FP alone if bypassing PM and PSR */
0388     if (!esai_priv->sck_div[tx] && (ratio > 16 || ratio == 0)) {
0389         dev_err(dai->dev, "the ratio is out of range (1 ~ 16)\n");
0390         return -EINVAL;
0391     }
0392 
0393     ret = fsl_esai_divisor_cal(dai, tx, ratio, true,
0394             esai_priv->sck_div[tx] ? 0 : ratio);
0395     if (ret)
0396         return ret;
0397 
0398     /* Save current bclk rate */
0399     esai_priv->sck_rate[tx] = freq;
0400 
0401     return 0;
0402 }
0403 
0404 static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
0405                      u32 rx_mask, int slots, int slot_width)
0406 {
0407     struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0408 
0409     regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
0410                ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
0411 
0412     regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
0413                ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
0414 
0415     esai_priv->slot_width = slot_width;
0416     esai_priv->slots = slots;
0417     esai_priv->tx_mask = tx_mask;
0418     esai_priv->rx_mask = rx_mask;
0419 
0420     return 0;
0421 }
0422 
0423 static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0424 {
0425     struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0426     u32 xcr = 0, xccr = 0, mask;
0427 
0428     /* DAI mode */
0429     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0430     case SND_SOC_DAIFMT_I2S:
0431         /* Data on rising edge of bclk, frame low, 1clk before data */
0432         xcr |= ESAI_xCR_xFSR;
0433         xccr |= ESAI_xCCR_xFSP | ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
0434         break;
0435     case SND_SOC_DAIFMT_LEFT_J:
0436         /* Data on rising edge of bclk, frame high */
0437         xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
0438         break;
0439     case SND_SOC_DAIFMT_RIGHT_J:
0440         /* Data on rising edge of bclk, frame high, right aligned */
0441         xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
0442         xcr  |= ESAI_xCR_xWA;
0443         break;
0444     case SND_SOC_DAIFMT_DSP_A:
0445         /* Data on rising edge of bclk, frame high, 1clk before data */
0446         xcr |= ESAI_xCR_xFSL | ESAI_xCR_xFSR;
0447         xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
0448         break;
0449     case SND_SOC_DAIFMT_DSP_B:
0450         /* Data on rising edge of bclk, frame high */
0451         xcr |= ESAI_xCR_xFSL;
0452         xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
0453         break;
0454     default:
0455         return -EINVAL;
0456     }
0457 
0458     /* DAI clock inversion */
0459     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0460     case SND_SOC_DAIFMT_NB_NF:
0461         /* Nothing to do for both normal cases */
0462         break;
0463     case SND_SOC_DAIFMT_IB_NF:
0464         /* Invert bit clock */
0465         xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
0466         break;
0467     case SND_SOC_DAIFMT_NB_IF:
0468         /* Invert frame clock */
0469         xccr ^= ESAI_xCCR_xFSP;
0470         break;
0471     case SND_SOC_DAIFMT_IB_IF:
0472         /* Invert both clocks */
0473         xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP;
0474         break;
0475     default:
0476         return -EINVAL;
0477     }
0478 
0479     esai_priv->consumer_mode = false;
0480 
0481     /* DAI clock provider masks */
0482     switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0483     case SND_SOC_DAIFMT_BC_FC:
0484         esai_priv->consumer_mode = true;
0485         break;
0486     case SND_SOC_DAIFMT_BP_FC:
0487         xccr |= ESAI_xCCR_xCKD;
0488         break;
0489     case SND_SOC_DAIFMT_BC_FP:
0490         xccr |= ESAI_xCCR_xFSD;
0491         break;
0492     case SND_SOC_DAIFMT_BP_FP:
0493         xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
0494         break;
0495     default:
0496         return -EINVAL;
0497     }
0498 
0499     mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR | ESAI_xCR_xWA;
0500     regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr);
0501     regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr);
0502 
0503     mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP |
0504         ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
0505     regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr);
0506     regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr);
0507 
0508     return 0;
0509 }
0510 
0511 static int fsl_esai_startup(struct snd_pcm_substream *substream,
0512                 struct snd_soc_dai *dai)
0513 {
0514     struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0515 
0516     if (!snd_soc_dai_active(dai)) {
0517         /* Set synchronous mode */
0518         regmap_update_bits(esai_priv->regmap, REG_ESAI_SAICR,
0519                    ESAI_SAICR_SYNC, esai_priv->synchronous ?
0520                    ESAI_SAICR_SYNC : 0);
0521 
0522         /* Set slots count */
0523         regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
0524                    ESAI_xCCR_xDC_MASK,
0525                    ESAI_xCCR_xDC(esai_priv->slots));
0526         regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
0527                    ESAI_xCCR_xDC_MASK,
0528                    ESAI_xCCR_xDC(esai_priv->slots));
0529     }
0530 
0531     return 0;
0532 
0533 }
0534 
0535 static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
0536                   struct snd_pcm_hw_params *params,
0537                   struct snd_soc_dai *dai)
0538 {
0539     struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0540     bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
0541     u32 width = params_width(params);
0542     u32 channels = params_channels(params);
0543     u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
0544     u32 slot_width = width;
0545     u32 bclk, mask, val;
0546     int ret;
0547 
0548     /* Override slot_width if being specifically set */
0549     if (esai_priv->slot_width)
0550         slot_width = esai_priv->slot_width;
0551 
0552     bclk = params_rate(params) * slot_width * esai_priv->slots;
0553 
0554     ret = fsl_esai_set_bclk(dai, esai_priv->synchronous || tx, bclk);
0555     if (ret)
0556         return ret;
0557 
0558     mask = ESAI_xCR_xSWS_MASK;
0559     val = ESAI_xCR_xSWS(slot_width, width);
0560 
0561     regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), mask, val);
0562     /* Recording in synchronous mode needs to set TCR also */
0563     if (!tx && esai_priv->synchronous)
0564         regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, val);
0565 
0566     /* Use Normal mode to support monaural audio */
0567     regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
0568                ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ?
0569                ESAI_xCR_xMOD_NETWORK : 0);
0570 
0571     regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
0572                ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR);
0573 
0574     mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK |
0575           (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK);
0576     val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) |
0577          (tx ? ESAI_xFCR_TE(pins) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(pins));
0578 
0579     regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val);
0580 
0581     if (tx)
0582         regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
0583                 ESAI_xCR_PADC, ESAI_xCR_PADC);
0584 
0585     /* Remove ESAI personal reset by configuring ESAI_PCRC and ESAI_PRRC */
0586     regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
0587                ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO));
0588     regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
0589                ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO));
0590     return 0;
0591 }
0592 
0593 static int fsl_esai_hw_init(struct fsl_esai *esai_priv)
0594 {
0595     struct platform_device *pdev = esai_priv->pdev;
0596     int ret;
0597 
0598     /* Reset ESAI unit */
0599     ret = regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
0600                  ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
0601                  ESAI_ECR_ESAIEN | ESAI_ECR_ERST);
0602     if (ret) {
0603         dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
0604         return ret;
0605     }
0606 
0607     /*
0608      * We need to enable ESAI so as to access some of its registers.
0609      * Otherwise, we would fail to dump regmap from user space.
0610      */
0611     ret = regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
0612                  ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
0613                  ESAI_ECR_ESAIEN);
0614     if (ret) {
0615         dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret);
0616         return ret;
0617     }
0618 
0619     regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
0620                ESAI_PRRC_PDC_MASK, 0);
0621     regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
0622                ESAI_PCRC_PC_MASK, 0);
0623 
0624     return 0;
0625 }
0626 
0627 static int fsl_esai_register_restore(struct fsl_esai *esai_priv)
0628 {
0629     int ret;
0630 
0631     /* FIFO reset for safety */
0632     regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR,
0633                ESAI_xFCR_xFR, ESAI_xFCR_xFR);
0634     regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR,
0635                ESAI_xFCR_xFR, ESAI_xFCR_xFR);
0636 
0637     regcache_mark_dirty(esai_priv->regmap);
0638     ret = regcache_sync(esai_priv->regmap);
0639     if (ret)
0640         return ret;
0641 
0642     /* FIFO reset done */
0643     regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
0644     regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
0645 
0646     return 0;
0647 }
0648 
0649 static void fsl_esai_trigger_start(struct fsl_esai *esai_priv, bool tx)
0650 {
0651     u8 i, channels = esai_priv->channels[tx];
0652     u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
0653     u32 mask;
0654 
0655     regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
0656                ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN);
0657 
0658     /* Write initial words reqiured by ESAI as normal procedure */
0659     for (i = 0; tx && i < channels; i++)
0660         regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);
0661 
0662     /*
0663      * When set the TE/RE in the end of enablement flow, there
0664      * will be channel swap issue for multi data line case.
0665      * In order to workaround this issue, we switch the bit
0666      * enablement sequence to below sequence
0667      * 1) clear the xSMB & xSMA: which is done in probe and
0668      *                           stop state.
0669      * 2) set TE/RE
0670      * 3) set xSMB
0671      * 4) set xSMA:  xSMA is the last one in this flow, which
0672      *               will trigger esai to start.
0673      */
0674     regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
0675                tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
0676                tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
0677     mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask;
0678 
0679     regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
0680                ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask));
0681     regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
0682                ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask));
0683 
0684     /* Enable Exception interrupt */
0685     regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
0686                ESAI_xCR_xEIE_MASK, ESAI_xCR_xEIE);
0687 }
0688 
0689 static void fsl_esai_trigger_stop(struct fsl_esai *esai_priv, bool tx)
0690 {
0691     regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
0692                ESAI_xCR_xEIE_MASK, 0);
0693 
0694     regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
0695                tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
0696     regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
0697                ESAI_xSMA_xS_MASK, 0);
0698     regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
0699                ESAI_xSMB_xS_MASK, 0);
0700 
0701     /* Disable and reset FIFO */
0702     regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
0703                ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR);
0704     regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
0705                ESAI_xFCR_xFR, 0);
0706 }
0707 
0708 static void fsl_esai_hw_reset(struct work_struct *work)
0709 {
0710     struct fsl_esai *esai_priv = container_of(work, struct fsl_esai, work);
0711     bool tx = true, rx = false, enabled[2];
0712     unsigned long lock_flags;
0713     u32 tfcr, rfcr;
0714 
0715     spin_lock_irqsave(&esai_priv->lock, lock_flags);
0716     /* Save the registers */
0717     regmap_read(esai_priv->regmap, REG_ESAI_TFCR, &tfcr);
0718     regmap_read(esai_priv->regmap, REG_ESAI_RFCR, &rfcr);
0719     enabled[tx] = tfcr & ESAI_xFCR_xFEN;
0720     enabled[rx] = rfcr & ESAI_xFCR_xFEN;
0721 
0722     /* Stop the tx & rx */
0723     fsl_esai_trigger_stop(esai_priv, tx);
0724     fsl_esai_trigger_stop(esai_priv, rx);
0725 
0726     /* Reset the esai, and ignore return value */
0727     fsl_esai_hw_init(esai_priv);
0728 
0729     /* Enforce ESAI personal resets for both TX and RX */
0730     regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
0731                ESAI_xCR_xPR_MASK, ESAI_xCR_xPR);
0732     regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
0733                ESAI_xCR_xPR_MASK, ESAI_xCR_xPR);
0734 
0735     /* Restore registers by regcache_sync, and ignore return value */
0736     fsl_esai_register_restore(esai_priv);
0737 
0738     /* Remove ESAI personal resets by configuring PCRC and PRRC also */
0739     regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
0740                ESAI_xCR_xPR_MASK, 0);
0741     regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
0742                ESAI_xCR_xPR_MASK, 0);
0743     regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
0744                ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO));
0745     regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
0746                ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO));
0747 
0748     /* Restart tx / rx, if they already enabled */
0749     if (enabled[tx])
0750         fsl_esai_trigger_start(esai_priv, tx);
0751     if (enabled[rx])
0752         fsl_esai_trigger_start(esai_priv, rx);
0753 
0754     spin_unlock_irqrestore(&esai_priv->lock, lock_flags);
0755 }
0756 
0757 static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
0758                 struct snd_soc_dai *dai)
0759 {
0760     struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0761     bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
0762     unsigned long lock_flags;
0763 
0764     esai_priv->channels[tx] = substream->runtime->channels;
0765 
0766     switch (cmd) {
0767     case SNDRV_PCM_TRIGGER_START:
0768     case SNDRV_PCM_TRIGGER_RESUME:
0769     case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0770         spin_lock_irqsave(&esai_priv->lock, lock_flags);
0771         fsl_esai_trigger_start(esai_priv, tx);
0772         spin_unlock_irqrestore(&esai_priv->lock, lock_flags);
0773         break;
0774     case SNDRV_PCM_TRIGGER_SUSPEND:
0775     case SNDRV_PCM_TRIGGER_STOP:
0776     case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0777         spin_lock_irqsave(&esai_priv->lock, lock_flags);
0778         fsl_esai_trigger_stop(esai_priv, tx);
0779         spin_unlock_irqrestore(&esai_priv->lock, lock_flags);
0780         break;
0781     default:
0782         return -EINVAL;
0783     }
0784 
0785     return 0;
0786 }
0787 
0788 static const struct snd_soc_dai_ops fsl_esai_dai_ops = {
0789     .startup = fsl_esai_startup,
0790     .trigger = fsl_esai_trigger,
0791     .hw_params = fsl_esai_hw_params,
0792     .set_sysclk = fsl_esai_set_dai_sysclk,
0793     .set_fmt = fsl_esai_set_dai_fmt,
0794     .set_tdm_slot = fsl_esai_set_dai_tdm_slot,
0795 };
0796 
0797 static int fsl_esai_dai_probe(struct snd_soc_dai *dai)
0798 {
0799     struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
0800 
0801     snd_soc_dai_init_dma_data(dai, &esai_priv->dma_params_tx,
0802                   &esai_priv->dma_params_rx);
0803 
0804     return 0;
0805 }
0806 
0807 static struct snd_soc_dai_driver fsl_esai_dai = {
0808     .probe = fsl_esai_dai_probe,
0809     .playback = {
0810         .stream_name = "CPU-Playback",
0811         .channels_min = 1,
0812         .channels_max = 12,
0813         .rates = SNDRV_PCM_RATE_8000_192000,
0814         .formats = FSL_ESAI_FORMATS,
0815     },
0816     .capture = {
0817         .stream_name = "CPU-Capture",
0818         .channels_min = 1,
0819         .channels_max = 8,
0820         .rates = SNDRV_PCM_RATE_8000_192000,
0821         .formats = FSL_ESAI_FORMATS,
0822     },
0823     .ops = &fsl_esai_dai_ops,
0824 };
0825 
0826 static const struct snd_soc_component_driver fsl_esai_component = {
0827     .name           = "fsl-esai",
0828     .legacy_dai_naming  = 1,
0829 };
0830 
0831 static const struct reg_default fsl_esai_reg_defaults[] = {
0832     {REG_ESAI_ETDR,  0x00000000},
0833     {REG_ESAI_ECR,   0x00000000},
0834     {REG_ESAI_TFCR,  0x00000000},
0835     {REG_ESAI_RFCR,  0x00000000},
0836     {REG_ESAI_TX0,   0x00000000},
0837     {REG_ESAI_TX1,   0x00000000},
0838     {REG_ESAI_TX2,   0x00000000},
0839     {REG_ESAI_TX3,   0x00000000},
0840     {REG_ESAI_TX4,   0x00000000},
0841     {REG_ESAI_TX5,   0x00000000},
0842     {REG_ESAI_TSR,   0x00000000},
0843     {REG_ESAI_SAICR, 0x00000000},
0844     {REG_ESAI_TCR,   0x00000000},
0845     {REG_ESAI_TCCR,  0x00000000},
0846     {REG_ESAI_RCR,   0x00000000},
0847     {REG_ESAI_RCCR,  0x00000000},
0848     {REG_ESAI_TSMA,  0x0000ffff},
0849     {REG_ESAI_TSMB,  0x0000ffff},
0850     {REG_ESAI_RSMA,  0x0000ffff},
0851     {REG_ESAI_RSMB,  0x0000ffff},
0852     {REG_ESAI_PRRC,  0x00000000},
0853     {REG_ESAI_PCRC,  0x00000000},
0854 };
0855 
0856 static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
0857 {
0858     switch (reg) {
0859     case REG_ESAI_ERDR:
0860     case REG_ESAI_ECR:
0861     case REG_ESAI_ESR:
0862     case REG_ESAI_TFCR:
0863     case REG_ESAI_TFSR:
0864     case REG_ESAI_RFCR:
0865     case REG_ESAI_RFSR:
0866     case REG_ESAI_RX0:
0867     case REG_ESAI_RX1:
0868     case REG_ESAI_RX2:
0869     case REG_ESAI_RX3:
0870     case REG_ESAI_SAISR:
0871     case REG_ESAI_SAICR:
0872     case REG_ESAI_TCR:
0873     case REG_ESAI_TCCR:
0874     case REG_ESAI_RCR:
0875     case REG_ESAI_RCCR:
0876     case REG_ESAI_TSMA:
0877     case REG_ESAI_TSMB:
0878     case REG_ESAI_RSMA:
0879     case REG_ESAI_RSMB:
0880     case REG_ESAI_PRRC:
0881     case REG_ESAI_PCRC:
0882         return true;
0883     default:
0884         return false;
0885     }
0886 }
0887 
0888 static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg)
0889 {
0890     switch (reg) {
0891     case REG_ESAI_ERDR:
0892     case REG_ESAI_ESR:
0893     case REG_ESAI_TFSR:
0894     case REG_ESAI_RFSR:
0895     case REG_ESAI_RX0:
0896     case REG_ESAI_RX1:
0897     case REG_ESAI_RX2:
0898     case REG_ESAI_RX3:
0899     case REG_ESAI_SAISR:
0900         return true;
0901     default:
0902         return false;
0903     }
0904 }
0905 
0906 static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
0907 {
0908     switch (reg) {
0909     case REG_ESAI_ETDR:
0910     case REG_ESAI_ECR:
0911     case REG_ESAI_TFCR:
0912     case REG_ESAI_RFCR:
0913     case REG_ESAI_TX0:
0914     case REG_ESAI_TX1:
0915     case REG_ESAI_TX2:
0916     case REG_ESAI_TX3:
0917     case REG_ESAI_TX4:
0918     case REG_ESAI_TX5:
0919     case REG_ESAI_TSR:
0920     case REG_ESAI_SAICR:
0921     case REG_ESAI_TCR:
0922     case REG_ESAI_TCCR:
0923     case REG_ESAI_RCR:
0924     case REG_ESAI_RCCR:
0925     case REG_ESAI_TSMA:
0926     case REG_ESAI_TSMB:
0927     case REG_ESAI_RSMA:
0928     case REG_ESAI_RSMB:
0929     case REG_ESAI_PRRC:
0930     case REG_ESAI_PCRC:
0931         return true;
0932     default:
0933         return false;
0934     }
0935 }
0936 
0937 static const struct regmap_config fsl_esai_regmap_config = {
0938     .reg_bits = 32,
0939     .reg_stride = 4,
0940     .val_bits = 32,
0941 
0942     .max_register = REG_ESAI_PCRC,
0943     .reg_defaults = fsl_esai_reg_defaults,
0944     .num_reg_defaults = ARRAY_SIZE(fsl_esai_reg_defaults),
0945     .readable_reg = fsl_esai_readable_reg,
0946     .volatile_reg = fsl_esai_volatile_reg,
0947     .writeable_reg = fsl_esai_writeable_reg,
0948     .cache_type = REGCACHE_FLAT,
0949 };
0950 
0951 static int fsl_esai_runtime_resume(struct device *dev);
0952 static int fsl_esai_runtime_suspend(struct device *dev);
0953 
0954 static int fsl_esai_probe(struct platform_device *pdev)
0955 {
0956     struct device_node *np = pdev->dev.of_node;
0957     struct fsl_esai *esai_priv;
0958     struct resource *res;
0959     const __be32 *iprop;
0960     void __iomem *regs;
0961     int irq, ret;
0962 
0963     esai_priv = devm_kzalloc(&pdev->dev, sizeof(*esai_priv), GFP_KERNEL);
0964     if (!esai_priv)
0965         return -ENOMEM;
0966 
0967     esai_priv->pdev = pdev;
0968     snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np);
0969 
0970     esai_priv->soc = of_device_get_match_data(&pdev->dev);
0971 
0972     /* Get the addresses and IRQ */
0973     regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
0974     if (IS_ERR(regs))
0975         return PTR_ERR(regs);
0976 
0977     esai_priv->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &fsl_esai_regmap_config);
0978     if (IS_ERR(esai_priv->regmap)) {
0979         dev_err(&pdev->dev, "failed to init regmap: %ld\n",
0980                 PTR_ERR(esai_priv->regmap));
0981         return PTR_ERR(esai_priv->regmap);
0982     }
0983 
0984     esai_priv->coreclk = devm_clk_get(&pdev->dev, "core");
0985     if (IS_ERR(esai_priv->coreclk)) {
0986         dev_err(&pdev->dev, "failed to get core clock: %ld\n",
0987                 PTR_ERR(esai_priv->coreclk));
0988         return PTR_ERR(esai_priv->coreclk);
0989     }
0990 
0991     esai_priv->extalclk = devm_clk_get(&pdev->dev, "extal");
0992     if (IS_ERR(esai_priv->extalclk))
0993         dev_warn(&pdev->dev, "failed to get extal clock: %ld\n",
0994                 PTR_ERR(esai_priv->extalclk));
0995 
0996     esai_priv->fsysclk = devm_clk_get(&pdev->dev, "fsys");
0997     if (IS_ERR(esai_priv->fsysclk))
0998         dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
0999                 PTR_ERR(esai_priv->fsysclk));
1000 
1001     esai_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
1002     if (IS_ERR(esai_priv->spbaclk))
1003         dev_warn(&pdev->dev, "failed to get spba clock: %ld\n",
1004                 PTR_ERR(esai_priv->spbaclk));
1005 
1006     irq = platform_get_irq(pdev, 0);
1007     if (irq < 0)
1008         return irq;
1009 
1010     ret = devm_request_irq(&pdev->dev, irq, esai_isr, IRQF_SHARED,
1011                    esai_priv->name, esai_priv);
1012     if (ret) {
1013         dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
1014         return ret;
1015     }
1016 
1017     /* Set a default slot number */
1018     esai_priv->slots = 2;
1019 
1020     /* Set a default clock provider state */
1021     esai_priv->consumer_mode = true;
1022 
1023     /* Determine the FIFO depth */
1024     iprop = of_get_property(np, "fsl,fifo-depth", NULL);
1025     if (iprop)
1026         esai_priv->fifo_depth = be32_to_cpup(iprop);
1027     else
1028         esai_priv->fifo_depth = 64;
1029 
1030     esai_priv->dma_params_tx.maxburst = 16;
1031     esai_priv->dma_params_rx.maxburst = 16;
1032     esai_priv->dma_params_tx.addr = res->start + REG_ESAI_ETDR;
1033     esai_priv->dma_params_rx.addr = res->start + REG_ESAI_ERDR;
1034 
1035     esai_priv->synchronous =
1036         of_property_read_bool(np, "fsl,esai-synchronous");
1037 
1038     /* Implement full symmetry for synchronous mode */
1039     if (esai_priv->synchronous) {
1040         fsl_esai_dai.symmetric_rate = 1;
1041         fsl_esai_dai.symmetric_channels = 1;
1042         fsl_esai_dai.symmetric_sample_bits = 1;
1043     }
1044 
1045     dev_set_drvdata(&pdev->dev, esai_priv);
1046     spin_lock_init(&esai_priv->lock);
1047     pm_runtime_enable(&pdev->dev);
1048     if (!pm_runtime_enabled(&pdev->dev)) {
1049         ret = fsl_esai_runtime_resume(&pdev->dev);
1050         if (ret)
1051             goto err_pm_disable;
1052     }
1053 
1054     ret = pm_runtime_resume_and_get(&pdev->dev);
1055     if (ret < 0)
1056         goto err_pm_get_sync;
1057 
1058     ret = fsl_esai_hw_init(esai_priv);
1059     if (ret)
1060         goto err_pm_get_sync;
1061 
1062     esai_priv->tx_mask = 0xFFFFFFFF;
1063     esai_priv->rx_mask = 0xFFFFFFFF;
1064 
1065     /* Clear the TSMA, TSMB, RSMA, RSMB */
1066     regmap_write(esai_priv->regmap, REG_ESAI_TSMA, 0);
1067     regmap_write(esai_priv->regmap, REG_ESAI_TSMB, 0);
1068     regmap_write(esai_priv->regmap, REG_ESAI_RSMA, 0);
1069     regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0);
1070 
1071     ret = pm_runtime_put_sync(&pdev->dev);
1072     if (ret < 0)
1073         goto err_pm_get_sync;
1074 
1075     /*
1076      * Register platform component before registering cpu dai for there
1077      * is not defer probe for platform component in snd_soc_add_pcm_runtime().
1078      */
1079     ret = imx_pcm_dma_init(pdev);
1080     if (ret) {
1081         dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
1082         goto err_pm_get_sync;
1083     }
1084 
1085     ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component,
1086                           &fsl_esai_dai, 1);
1087     if (ret) {
1088         dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
1089         goto err_pm_get_sync;
1090     }
1091 
1092     INIT_WORK(&esai_priv->work, fsl_esai_hw_reset);
1093 
1094     return ret;
1095 
1096 err_pm_get_sync:
1097     if (!pm_runtime_status_suspended(&pdev->dev))
1098         fsl_esai_runtime_suspend(&pdev->dev);
1099 err_pm_disable:
1100     pm_runtime_disable(&pdev->dev);
1101     return ret;
1102 }
1103 
1104 static int fsl_esai_remove(struct platform_device *pdev)
1105 {
1106     struct fsl_esai *esai_priv = platform_get_drvdata(pdev);
1107 
1108     pm_runtime_disable(&pdev->dev);
1109     if (!pm_runtime_status_suspended(&pdev->dev))
1110         fsl_esai_runtime_suspend(&pdev->dev);
1111 
1112     cancel_work_sync(&esai_priv->work);
1113 
1114     return 0;
1115 }
1116 
1117 static const struct of_device_id fsl_esai_dt_ids[] = {
1118     { .compatible = "fsl,imx35-esai", .data = &fsl_esai_imx35 },
1119     { .compatible = "fsl,vf610-esai", .data = &fsl_esai_vf610 },
1120     { .compatible = "fsl,imx6ull-esai", .data = &fsl_esai_imx6ull },
1121     {}
1122 };
1123 MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
1124 
1125 static int fsl_esai_runtime_resume(struct device *dev)
1126 {
1127     struct fsl_esai *esai = dev_get_drvdata(dev);
1128     int ret;
1129 
1130     /*
1131      * Some platforms might use the same bit to gate all three or two of
1132      * clocks, so keep all clocks open/close at the same time for safety
1133      */
1134     ret = clk_prepare_enable(esai->coreclk);
1135     if (ret)
1136         return ret;
1137     if (!IS_ERR(esai->spbaclk)) {
1138         ret = clk_prepare_enable(esai->spbaclk);
1139         if (ret)
1140             goto err_spbaclk;
1141     }
1142     if (!IS_ERR(esai->extalclk)) {
1143         ret = clk_prepare_enable(esai->extalclk);
1144         if (ret)
1145             goto err_extalclk;
1146     }
1147     if (!IS_ERR(esai->fsysclk)) {
1148         ret = clk_prepare_enable(esai->fsysclk);
1149         if (ret)
1150             goto err_fsysclk;
1151     }
1152 
1153     regcache_cache_only(esai->regmap, false);
1154 
1155     ret = fsl_esai_register_restore(esai);
1156     if (ret)
1157         goto err_regcache_sync;
1158 
1159     return 0;
1160 
1161 err_regcache_sync:
1162     if (!IS_ERR(esai->fsysclk))
1163         clk_disable_unprepare(esai->fsysclk);
1164 err_fsysclk:
1165     if (!IS_ERR(esai->extalclk))
1166         clk_disable_unprepare(esai->extalclk);
1167 err_extalclk:
1168     if (!IS_ERR(esai->spbaclk))
1169         clk_disable_unprepare(esai->spbaclk);
1170 err_spbaclk:
1171     clk_disable_unprepare(esai->coreclk);
1172 
1173     return ret;
1174 }
1175 
1176 static int fsl_esai_runtime_suspend(struct device *dev)
1177 {
1178     struct fsl_esai *esai = dev_get_drvdata(dev);
1179 
1180     regcache_cache_only(esai->regmap, true);
1181 
1182     if (!IS_ERR(esai->fsysclk))
1183         clk_disable_unprepare(esai->fsysclk);
1184     if (!IS_ERR(esai->extalclk))
1185         clk_disable_unprepare(esai->extalclk);
1186     if (!IS_ERR(esai->spbaclk))
1187         clk_disable_unprepare(esai->spbaclk);
1188     clk_disable_unprepare(esai->coreclk);
1189 
1190     return 0;
1191 }
1192 
1193 static const struct dev_pm_ops fsl_esai_pm_ops = {
1194     SET_RUNTIME_PM_OPS(fsl_esai_runtime_suspend,
1195                fsl_esai_runtime_resume,
1196                NULL)
1197     SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1198                 pm_runtime_force_resume)
1199 };
1200 
1201 static struct platform_driver fsl_esai_driver = {
1202     .probe = fsl_esai_probe,
1203     .remove = fsl_esai_remove,
1204     .driver = {
1205         .name = "fsl-esai-dai",
1206         .pm = &fsl_esai_pm_ops,
1207         .of_match_table = fsl_esai_dt_ids,
1208     },
1209 };
1210 
1211 module_platform_driver(fsl_esai_driver);
1212 
1213 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
1214 MODULE_DESCRIPTION("Freescale ESAI CPU DAI driver");
1215 MODULE_LICENSE("GPL v2");
1216 MODULE_ALIAS("platform:fsl-esai-dai");