Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Freescale ASRC ALSA SoC Digital Audio Interface (DAI) driver
0004 //
0005 // Copyright (C) 2014 Freescale Semiconductor, Inc.
0006 //
0007 // Author: Nicolin Chen <nicoleotsuka@gmail.com>
0008 
0009 #include <linux/clk.h>
0010 #include <linux/delay.h>
0011 #include <linux/dma-mapping.h>
0012 #include <linux/module.h>
0013 #include <linux/of_platform.h>
0014 #include <linux/dma/imx-dma.h>
0015 #include <linux/pm_runtime.h>
0016 #include <sound/dmaengine_pcm.h>
0017 #include <sound/pcm_params.h>
0018 
0019 #include "fsl_asrc.h"
0020 
0021 #define IDEAL_RATIO_DECIMAL_DEPTH 26
0022 #define DIVIDER_NUM  64
0023 
0024 #define pair_err(fmt, ...) \
0025     dev_err(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
0026 
0027 #define pair_dbg(fmt, ...) \
0028     dev_dbg(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
0029 
0030 /* Corresponding to process_option */
0031 static unsigned int supported_asrc_rate[] = {
0032     5512, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
0033     64000, 88200, 96000, 128000, 176400, 192000,
0034 };
0035 
0036 static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints = {
0037     .count = ARRAY_SIZE(supported_asrc_rate),
0038     .list = supported_asrc_rate,
0039 };
0040 
0041 /*
0042  * The following tables map the relationship between asrc_inclk/asrc_outclk in
0043  * fsl_asrc.h and the registers of ASRCSR
0044  */
0045 static unsigned char input_clk_map_imx35[ASRC_CLK_MAP_LEN] = {
0046     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
0047     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
0048     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
0049 };
0050 
0051 static unsigned char output_clk_map_imx35[ASRC_CLK_MAP_LEN] = {
0052     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
0053     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
0054     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
0055 };
0056 
0057 /* i.MX53 uses the same map for input and output */
0058 static unsigned char input_clk_map_imx53[ASRC_CLK_MAP_LEN] = {
0059 /*  0x0  0x1  0x2  0x3  0x4  0x5  0x6  0x7  0x8  0x9  0xa  0xb  0xc  0xd  0xe  0xf */
0060     0x0, 0x1, 0x2, 0x7, 0x4, 0x5, 0x6, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xe, 0xd,
0061     0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
0062     0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
0063 };
0064 
0065 static unsigned char output_clk_map_imx53[ASRC_CLK_MAP_LEN] = {
0066 /*  0x0  0x1  0x2  0x3  0x4  0x5  0x6  0x7  0x8  0x9  0xa  0xb  0xc  0xd  0xe  0xf */
0067     0x8, 0x9, 0xa, 0x7, 0xc, 0x5, 0x6, 0xb, 0x0, 0x1, 0x2, 0x3, 0x4, 0xf, 0xe, 0xd,
0068     0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
0069     0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
0070 };
0071 
0072 /*
0073  * i.MX8QM/i.MX8QXP uses the same map for input and output.
0074  * clk_map_imx8qm[0] is for i.MX8QM asrc0
0075  * clk_map_imx8qm[1] is for i.MX8QM asrc1
0076  * clk_map_imx8qxp[0] is for i.MX8QXP asrc0
0077  * clk_map_imx8qxp[1] is for i.MX8QXP asrc1
0078  */
0079 static unsigned char clk_map_imx8qm[2][ASRC_CLK_MAP_LEN] = {
0080     {
0081     0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
0082     0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
0083     0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
0084     },
0085     {
0086     0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
0087     0x0, 0x1, 0x2, 0x3, 0xb, 0xc, 0xf, 0xf, 0xd, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
0088     0x4, 0x5, 0x6, 0xf, 0x8, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
0089     },
0090 };
0091 
0092 static unsigned char clk_map_imx8qxp[2][ASRC_CLK_MAP_LEN] = {
0093     {
0094     0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
0095     0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xf, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xf,
0096     0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
0097     },
0098     {
0099     0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
0100     0x0, 0x1, 0x2, 0x3, 0x7, 0x8, 0xf, 0xf, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
0101     0xf, 0xf, 0x6, 0xf, 0xf, 0xf, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
0102     },
0103 };
0104 
0105 /*
0106  * According to RM, the divider range is 1 ~ 8,
0107  * prescaler is power of 2 from 1 ~ 128.
0108  */
0109 static int asrc_clk_divider[DIVIDER_NUM] = {
0110     1,  2,  4,  8,  16,  32,  64,  128,  /* divider = 1 */
0111     2,  4,  8, 16,  32,  64, 128,  256,  /* divider = 2 */
0112     3,  6, 12, 24,  48,  96, 192,  384,  /* divider = 3 */
0113     4,  8, 16, 32,  64, 128, 256,  512,  /* divider = 4 */
0114     5, 10, 20, 40,  80, 160, 320,  640,  /* divider = 5 */
0115     6, 12, 24, 48,  96, 192, 384,  768,  /* divider = 6 */
0116     7, 14, 28, 56, 112, 224, 448,  896,  /* divider = 7 */
0117     8, 16, 32, 64, 128, 256, 512, 1024,  /* divider = 8 */
0118 };
0119 
0120 /*
0121  * Check if the divider is available for internal ratio mode
0122  */
0123 static bool fsl_asrc_divider_avail(int clk_rate, int rate, int *div)
0124 {
0125     u32 rem, i;
0126     u64 n;
0127 
0128     if (div)
0129         *div = 0;
0130 
0131     if (clk_rate == 0 || rate == 0)
0132         return false;
0133 
0134     n = clk_rate;
0135     rem = do_div(n, rate);
0136 
0137     if (div)
0138         *div = n;
0139 
0140     if (rem != 0)
0141         return false;
0142 
0143     for (i = 0; i < DIVIDER_NUM; i++) {
0144         if (n == asrc_clk_divider[i])
0145             break;
0146     }
0147 
0148     if (i == DIVIDER_NUM)
0149         return false;
0150 
0151     return true;
0152 }
0153 
0154 /**
0155  * fsl_asrc_sel_proc - Select the pre-processing and post-processing options
0156  * @inrate: input sample rate
0157  * @outrate: output sample rate
0158  * @pre_proc: return value for pre-processing option
0159  * @post_proc: return value for post-processing option
0160  *
0161  * Make sure to exclude following unsupported cases before
0162  * calling this function:
0163  * 1) inrate > 8.125 * outrate
0164  * 2) inrate > 16.125 * outrate
0165  *
0166  */
0167 static void fsl_asrc_sel_proc(int inrate, int outrate,
0168                  int *pre_proc, int *post_proc)
0169 {
0170     bool post_proc_cond2;
0171     bool post_proc_cond0;
0172 
0173     /* select pre_proc between [0, 2] */
0174     if (inrate * 8 > 33 * outrate)
0175         *pre_proc = 2;
0176     else if (inrate * 8 > 15 * outrate) {
0177         if (inrate > 152000)
0178             *pre_proc = 2;
0179         else
0180             *pre_proc = 1;
0181     } else if (inrate < 76000)
0182         *pre_proc = 0;
0183     else if (inrate > 152000)
0184         *pre_proc = 2;
0185     else
0186         *pre_proc = 1;
0187 
0188     /* Condition for selection of post-processing */
0189     post_proc_cond2 = (inrate * 15 > outrate * 16 && outrate < 56000) ||
0190               (inrate > 56000 && outrate < 56000);
0191     post_proc_cond0 = inrate * 23 < outrate * 8;
0192 
0193     if (post_proc_cond2)
0194         *post_proc = 2;
0195     else if (post_proc_cond0)
0196         *post_proc = 0;
0197     else
0198         *post_proc = 1;
0199 }
0200 
0201 /**
0202  * fsl_asrc_request_pair - Request ASRC pair
0203  * @channels: number of channels
0204  * @pair: pointer to pair
0205  *
0206  * It assigns pair by the order of A->C->B because allocation of pair B,
0207  * within range [ANCA, ANCA+ANCB-1], depends on the channels of pair A
0208  * while pair A and pair C are comparatively independent.
0209  */
0210 static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
0211 {
0212     enum asrc_pair_index index = ASRC_INVALID_PAIR;
0213     struct fsl_asrc *asrc = pair->asrc;
0214     struct device *dev = &asrc->pdev->dev;
0215     unsigned long lock_flags;
0216     int i, ret = 0;
0217 
0218     spin_lock_irqsave(&asrc->lock, lock_flags);
0219 
0220     for (i = ASRC_PAIR_A; i < ASRC_PAIR_MAX_NUM; i++) {
0221         if (asrc->pair[i] != NULL)
0222             continue;
0223 
0224         index = i;
0225 
0226         if (i != ASRC_PAIR_B)
0227             break;
0228     }
0229 
0230     if (index == ASRC_INVALID_PAIR) {
0231         dev_err(dev, "all pairs are busy now\n");
0232         ret = -EBUSY;
0233     } else if (asrc->channel_avail < channels) {
0234         dev_err(dev, "can't afford required channels: %d\n", channels);
0235         ret = -EINVAL;
0236     } else {
0237         asrc->channel_avail -= channels;
0238         asrc->pair[index] = pair;
0239         pair->channels = channels;
0240         pair->index = index;
0241     }
0242 
0243     spin_unlock_irqrestore(&asrc->lock, lock_flags);
0244 
0245     return ret;
0246 }
0247 
0248 /**
0249  * fsl_asrc_release_pair - Release ASRC pair
0250  * @pair: pair to release
0251  *
0252  * It clears the resource from asrc and releases the occupied channels.
0253  */
0254 static void fsl_asrc_release_pair(struct fsl_asrc_pair *pair)
0255 {
0256     struct fsl_asrc *asrc = pair->asrc;
0257     enum asrc_pair_index index = pair->index;
0258     unsigned long lock_flags;
0259 
0260     /* Make sure the pair is disabled */
0261     regmap_update_bits(asrc->regmap, REG_ASRCTR,
0262                ASRCTR_ASRCEi_MASK(index), 0);
0263 
0264     spin_lock_irqsave(&asrc->lock, lock_flags);
0265 
0266     asrc->channel_avail += pair->channels;
0267     asrc->pair[index] = NULL;
0268     pair->error = 0;
0269 
0270     spin_unlock_irqrestore(&asrc->lock, lock_flags);
0271 }
0272 
0273 /**
0274  * fsl_asrc_set_watermarks- configure input and output thresholds
0275  * @pair: pointer to pair
0276  * @in: input threshold
0277  * @out: output threshold
0278  */
0279 static void fsl_asrc_set_watermarks(struct fsl_asrc_pair *pair, u32 in, u32 out)
0280 {
0281     struct fsl_asrc *asrc = pair->asrc;
0282     enum asrc_pair_index index = pair->index;
0283 
0284     regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
0285                ASRMCRi_EXTTHRSHi_MASK |
0286                ASRMCRi_INFIFO_THRESHOLD_MASK |
0287                ASRMCRi_OUTFIFO_THRESHOLD_MASK,
0288                ASRMCRi_EXTTHRSHi |
0289                ASRMCRi_INFIFO_THRESHOLD(in) |
0290                ASRMCRi_OUTFIFO_THRESHOLD(out));
0291 }
0292 
0293 /**
0294  * fsl_asrc_cal_asrck_divisor - Calculate the total divisor between asrck clock rate and sample rate
0295  * @pair: pointer to pair
0296  * @div: divider
0297  *
0298  * It follows the formula clk_rate = samplerate * (2 ^ prescaler) * divider
0299  */
0300 static u32 fsl_asrc_cal_asrck_divisor(struct fsl_asrc_pair *pair, u32 div)
0301 {
0302     u32 ps;
0303 
0304     /* Calculate the divisors: prescaler [2^0, 2^7], divder [1, 8] */
0305     for (ps = 0; div > 8; ps++)
0306         div >>= 1;
0307 
0308     return ((div - 1) << ASRCDRi_AxCPi_WIDTH) | ps;
0309 }
0310 
0311 /**
0312  * fsl_asrc_set_ideal_ratio - Calculate and set the ratio for Ideal Ratio mode only
0313  * @pair: pointer to pair
0314  * @inrate: input rate
0315  * @outrate: output rate
0316  *
0317  * The ratio is a 32-bit fixed point value with 26 fractional bits.
0318  */
0319 static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair,
0320                     int inrate, int outrate)
0321 {
0322     struct fsl_asrc *asrc = pair->asrc;
0323     enum asrc_pair_index index = pair->index;
0324     unsigned long ratio;
0325     int i;
0326 
0327     if (!outrate) {
0328         pair_err("output rate should not be zero\n");
0329         return -EINVAL;
0330     }
0331 
0332     /* Calculate the intergal part of the ratio */
0333     ratio = (inrate / outrate) << IDEAL_RATIO_DECIMAL_DEPTH;
0334 
0335     /* ... and then the 26 depth decimal part */
0336     inrate %= outrate;
0337 
0338     for (i = 1; i <= IDEAL_RATIO_DECIMAL_DEPTH; i++) {
0339         inrate <<= 1;
0340 
0341         if (inrate < outrate)
0342             continue;
0343 
0344         ratio |= 1 << (IDEAL_RATIO_DECIMAL_DEPTH - i);
0345         inrate -= outrate;
0346 
0347         if (!inrate)
0348             break;
0349     }
0350 
0351     regmap_write(asrc->regmap, REG_ASRIDRL(index), ratio);
0352     regmap_write(asrc->regmap, REG_ASRIDRH(index), ratio >> 24);
0353 
0354     return 0;
0355 }
0356 
0357 /**
0358  * fsl_asrc_config_pair - Configure the assigned ASRC pair
0359  * @pair: pointer to pair
0360  * @use_ideal_rate: boolean configuration
0361  *
0362  * It configures those ASRC registers according to a configuration instance
0363  * of struct asrc_config which includes in/output sample rate, width, channel
0364  * and clock settings.
0365  *
0366  * Note:
0367  * The ideal ratio configuration can work with a flexible clock rate setting.
0368  * Using IDEAL_RATIO_RATE gives a faster converting speed but overloads ASRC.
0369  * For a regular audio playback, the clock rate should not be slower than an
0370  * clock rate aligning with the output sample rate; For a use case requiring
0371  * faster conversion, set use_ideal_rate to have the faster speed.
0372  */
0373 static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
0374 {
0375     struct fsl_asrc_pair_priv *pair_priv = pair->private;
0376     struct asrc_config *config = pair_priv->config;
0377     struct fsl_asrc *asrc = pair->asrc;
0378     struct fsl_asrc_priv *asrc_priv = asrc->private;
0379     enum asrc_pair_index index = pair->index;
0380     enum asrc_word_width input_word_width;
0381     enum asrc_word_width output_word_width;
0382     u32 inrate, outrate, indiv, outdiv;
0383     u32 clk_index[2], div[2];
0384     u64 clk_rate;
0385     int in, out, channels;
0386     int pre_proc, post_proc;
0387     struct clk *clk;
0388     bool ideal, div_avail;
0389 
0390     if (!config) {
0391         pair_err("invalid pair config\n");
0392         return -EINVAL;
0393     }
0394 
0395     /* Validate channels */
0396     if (config->channel_num < 1 || config->channel_num > 10) {
0397         pair_err("does not support %d channels\n", config->channel_num);
0398         return -EINVAL;
0399     }
0400 
0401     switch (snd_pcm_format_width(config->input_format)) {
0402     case 8:
0403         input_word_width = ASRC_WIDTH_8_BIT;
0404         break;
0405     case 16:
0406         input_word_width = ASRC_WIDTH_16_BIT;
0407         break;
0408     case 24:
0409         input_word_width = ASRC_WIDTH_24_BIT;
0410         break;
0411     default:
0412         pair_err("does not support this input format, %d\n",
0413              config->input_format);
0414         return -EINVAL;
0415     }
0416 
0417     switch (snd_pcm_format_width(config->output_format)) {
0418     case 16:
0419         output_word_width = ASRC_WIDTH_16_BIT;
0420         break;
0421     case 24:
0422         output_word_width = ASRC_WIDTH_24_BIT;
0423         break;
0424     default:
0425         pair_err("does not support this output format, %d\n",
0426              config->output_format);
0427         return -EINVAL;
0428     }
0429 
0430     inrate = config->input_sample_rate;
0431     outrate = config->output_sample_rate;
0432     ideal = config->inclk == INCLK_NONE;
0433 
0434     /* Validate input and output sample rates */
0435     for (in = 0; in < ARRAY_SIZE(supported_asrc_rate); in++)
0436         if (inrate == supported_asrc_rate[in])
0437             break;
0438 
0439     if (in == ARRAY_SIZE(supported_asrc_rate)) {
0440         pair_err("unsupported input sample rate: %dHz\n", inrate);
0441         return -EINVAL;
0442     }
0443 
0444     for (out = 0; out < ARRAY_SIZE(supported_asrc_rate); out++)
0445         if (outrate == supported_asrc_rate[out])
0446             break;
0447 
0448     if (out == ARRAY_SIZE(supported_asrc_rate)) {
0449         pair_err("unsupported output sample rate: %dHz\n", outrate);
0450         return -EINVAL;
0451     }
0452 
0453     if ((outrate >= 5512 && outrate <= 30000) &&
0454         (outrate > 24 * inrate || inrate > 8 * outrate)) {
0455         pair_err("exceed supported ratio range [1/24, 8] for \
0456                 inrate/outrate: %d/%d\n", inrate, outrate);
0457         return -EINVAL;
0458     }
0459 
0460     /* Validate input and output clock sources */
0461     clk_index[IN] = asrc_priv->clk_map[IN][config->inclk];
0462     clk_index[OUT] = asrc_priv->clk_map[OUT][config->outclk];
0463 
0464     /* We only have output clock for ideal ratio mode */
0465     clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]];
0466 
0467     clk_rate = clk_get_rate(clk);
0468     div_avail = fsl_asrc_divider_avail(clk_rate, inrate, &div[IN]);
0469 
0470     /*
0471      * The divider range is [1, 1024], defined by the hardware. For non-
0472      * ideal ratio configuration, clock rate has to be strictly aligned
0473      * with the sample rate. For ideal ratio configuration, clock rates
0474      * only result in different converting speeds. So remainder does not
0475      * matter, as long as we keep the divider within its valid range.
0476      */
0477     if (div[IN] == 0 || (!ideal && !div_avail)) {
0478         pair_err("failed to support input sample rate %dHz by asrck_%x\n",
0479                 inrate, clk_index[ideal ? OUT : IN]);
0480         return -EINVAL;
0481     }
0482 
0483     div[IN] = min_t(u32, 1024, div[IN]);
0484 
0485     clk = asrc_priv->asrck_clk[clk_index[OUT]];
0486     clk_rate = clk_get_rate(clk);
0487     if (ideal && use_ideal_rate)
0488         div_avail = fsl_asrc_divider_avail(clk_rate, IDEAL_RATIO_RATE, &div[OUT]);
0489     else
0490         div_avail = fsl_asrc_divider_avail(clk_rate, outrate, &div[OUT]);
0491 
0492     /* Output divider has the same limitation as the input one */
0493     if (div[OUT] == 0 || (!ideal && !div_avail)) {
0494         pair_err("failed to support output sample rate %dHz by asrck_%x\n",
0495                 outrate, clk_index[OUT]);
0496         return -EINVAL;
0497     }
0498 
0499     div[OUT] = min_t(u32, 1024, div[OUT]);
0500 
0501     /* Set the channel number */
0502     channels = config->channel_num;
0503 
0504     if (asrc_priv->soc->channel_bits < 4)
0505         channels /= 2;
0506 
0507     /* Update channels for current pair */
0508     regmap_update_bits(asrc->regmap, REG_ASRCNCR,
0509                ASRCNCR_ANCi_MASK(index, asrc_priv->soc->channel_bits),
0510                ASRCNCR_ANCi(index, channels, asrc_priv->soc->channel_bits));
0511 
0512     /* Default setting: Automatic selection for processing mode */
0513     regmap_update_bits(asrc->regmap, REG_ASRCTR,
0514                ASRCTR_ATSi_MASK(index), ASRCTR_ATS(index));
0515     regmap_update_bits(asrc->regmap, REG_ASRCTR,
0516                ASRCTR_USRi_MASK(index), 0);
0517 
0518     /* Set the input and output clock sources */
0519     regmap_update_bits(asrc->regmap, REG_ASRCSR,
0520                ASRCSR_AICSi_MASK(index) | ASRCSR_AOCSi_MASK(index),
0521                ASRCSR_AICS(index, clk_index[IN]) |
0522                ASRCSR_AOCS(index, clk_index[OUT]));
0523 
0524     /* Calculate the input clock divisors */
0525     indiv = fsl_asrc_cal_asrck_divisor(pair, div[IN]);
0526     outdiv = fsl_asrc_cal_asrck_divisor(pair, div[OUT]);
0527 
0528     /* Suppose indiv and outdiv includes prescaler, so add its MASK too */
0529     regmap_update_bits(asrc->regmap, REG_ASRCDR(index),
0530                ASRCDRi_AOCPi_MASK(index) | ASRCDRi_AICPi_MASK(index) |
0531                ASRCDRi_AOCDi_MASK(index) | ASRCDRi_AICDi_MASK(index),
0532                ASRCDRi_AOCP(index, outdiv) | ASRCDRi_AICP(index, indiv));
0533 
0534     /* Implement word_width configurations */
0535     regmap_update_bits(asrc->regmap, REG_ASRMCR1(index),
0536                ASRMCR1i_OW16_MASK | ASRMCR1i_IWD_MASK,
0537                ASRMCR1i_OW16(output_word_width) |
0538                ASRMCR1i_IWD(input_word_width));
0539 
0540     /* Enable BUFFER STALL */
0541     regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
0542                ASRMCRi_BUFSTALLi_MASK, ASRMCRi_BUFSTALLi);
0543 
0544     /* Set default thresholds for input and output FIFO */
0545     fsl_asrc_set_watermarks(pair, ASRC_INPUTFIFO_THRESHOLD,
0546                 ASRC_INPUTFIFO_THRESHOLD);
0547 
0548     /* Configure the following only for Ideal Ratio mode */
0549     if (!ideal)
0550         return 0;
0551 
0552     /* Clear ASTSx bit to use Ideal Ratio mode */
0553     regmap_update_bits(asrc->regmap, REG_ASRCTR,
0554                ASRCTR_ATSi_MASK(index), 0);
0555 
0556     /* Enable Ideal Ratio mode */
0557     regmap_update_bits(asrc->regmap, REG_ASRCTR,
0558                ASRCTR_IDRi_MASK(index) | ASRCTR_USRi_MASK(index),
0559                ASRCTR_IDR(index) | ASRCTR_USR(index));
0560 
0561     fsl_asrc_sel_proc(inrate, outrate, &pre_proc, &post_proc);
0562 
0563     /* Apply configurations for pre- and post-processing */
0564     regmap_update_bits(asrc->regmap, REG_ASRCFG,
0565                ASRCFG_PREMODi_MASK(index) | ASRCFG_POSTMODi_MASK(index),
0566                ASRCFG_PREMOD(index, pre_proc) |
0567                ASRCFG_POSTMOD(index, post_proc));
0568 
0569     return fsl_asrc_set_ideal_ratio(pair, inrate, outrate);
0570 }
0571 
0572 /**
0573  * fsl_asrc_start_pair - Start the assigned ASRC pair
0574  * @pair: pointer to pair
0575  *
0576  * It enables the assigned pair and makes it stopped at the stall level.
0577  */
0578 static void fsl_asrc_start_pair(struct fsl_asrc_pair *pair)
0579 {
0580     struct fsl_asrc *asrc = pair->asrc;
0581     enum asrc_pair_index index = pair->index;
0582     int reg, retry = 10, i;
0583 
0584     /* Enable the current pair */
0585     regmap_update_bits(asrc->regmap, REG_ASRCTR,
0586                ASRCTR_ASRCEi_MASK(index), ASRCTR_ASRCE(index));
0587 
0588     /* Wait for status of initialization */
0589     do {
0590         udelay(5);
0591         regmap_read(asrc->regmap, REG_ASRCFG, &reg);
0592         reg &= ASRCFG_INIRQi_MASK(index);
0593     } while (!reg && --retry);
0594 
0595     /* Make the input fifo to ASRC STALL level */
0596     regmap_read(asrc->regmap, REG_ASRCNCR, &reg);
0597     for (i = 0; i < pair->channels * 4; i++)
0598         regmap_write(asrc->regmap, REG_ASRDI(index), 0);
0599 
0600     /* Enable overload interrupt */
0601     regmap_write(asrc->regmap, REG_ASRIER, ASRIER_AOLIE);
0602 }
0603 
0604 /**
0605  * fsl_asrc_stop_pair - Stop the assigned ASRC pair
0606  * @pair: pointer to pair
0607  */
0608 static void fsl_asrc_stop_pair(struct fsl_asrc_pair *pair)
0609 {
0610     struct fsl_asrc *asrc = pair->asrc;
0611     enum asrc_pair_index index = pair->index;
0612 
0613     /* Stop the current pair */
0614     regmap_update_bits(asrc->regmap, REG_ASRCTR,
0615                ASRCTR_ASRCEi_MASK(index), 0);
0616 }
0617 
0618 /**
0619  * fsl_asrc_get_dma_channel- Get DMA channel according to the pair and direction.
0620  * @pair: pointer to pair
0621  * @dir: DMA direction
0622  */
0623 static struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair,
0624                          bool dir)
0625 {
0626     struct fsl_asrc *asrc = pair->asrc;
0627     enum asrc_pair_index index = pair->index;
0628     char name[4];
0629 
0630     sprintf(name, "%cx%c", dir == IN ? 'r' : 't', index + 'a');
0631 
0632     return dma_request_slave_channel(&asrc->pdev->dev, name);
0633 }
0634 
0635 static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream,
0636                 struct snd_soc_dai *dai)
0637 {
0638     struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
0639     struct fsl_asrc_priv *asrc_priv = asrc->private;
0640 
0641     /* Odd channel number is not valid for older ASRC (channel_bits==3) */
0642     if (asrc_priv->soc->channel_bits == 3)
0643         snd_pcm_hw_constraint_step(substream->runtime, 0,
0644                        SNDRV_PCM_HW_PARAM_CHANNELS, 2);
0645 
0646 
0647     return snd_pcm_hw_constraint_list(substream->runtime, 0,
0648             SNDRV_PCM_HW_PARAM_RATE, &fsl_asrc_rate_constraints);
0649 }
0650 
0651 /* Select proper clock source for internal ratio mode */
0652 static void fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv,
0653                 struct fsl_asrc_pair *pair,
0654                 int in_rate,
0655                 int out_rate)
0656 {
0657     struct fsl_asrc_pair_priv *pair_priv = pair->private;
0658     struct asrc_config *config = pair_priv->config;
0659     int rate[2], select_clk[2]; /* Array size 2 means IN and OUT */
0660     int clk_rate, clk_index;
0661     int i, j;
0662 
0663     rate[IN] = in_rate;
0664     rate[OUT] = out_rate;
0665 
0666     /* Select proper clock source for internal ratio mode */
0667     for (j = 0; j < 2; j++) {
0668         for (i = 0; i < ASRC_CLK_MAP_LEN; i++) {
0669             clk_index = asrc_priv->clk_map[j][i];
0670             clk_rate = clk_get_rate(asrc_priv->asrck_clk[clk_index]);
0671             /* Only match a perfect clock source with no remainder */
0672             if (fsl_asrc_divider_avail(clk_rate, rate[j], NULL))
0673                 break;
0674         }
0675 
0676         select_clk[j] = i;
0677     }
0678 
0679     /* Switch to ideal ratio mode if there is no proper clock source */
0680     if (select_clk[IN] == ASRC_CLK_MAP_LEN || select_clk[OUT] == ASRC_CLK_MAP_LEN) {
0681         select_clk[IN] = INCLK_NONE;
0682         select_clk[OUT] = OUTCLK_ASRCK1_CLK;
0683     }
0684 
0685     config->inclk = select_clk[IN];
0686     config->outclk = select_clk[OUT];
0687 }
0688 
0689 static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
0690                   struct snd_pcm_hw_params *params,
0691                   struct snd_soc_dai *dai)
0692 {
0693     struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
0694     struct fsl_asrc_priv *asrc_priv = asrc->private;
0695     struct snd_pcm_runtime *runtime = substream->runtime;
0696     struct fsl_asrc_pair *pair = runtime->private_data;
0697     struct fsl_asrc_pair_priv *pair_priv = pair->private;
0698     unsigned int channels = params_channels(params);
0699     unsigned int rate = params_rate(params);
0700     struct asrc_config config;
0701     int ret;
0702 
0703     ret = fsl_asrc_request_pair(channels, pair);
0704     if (ret) {
0705         dev_err(dai->dev, "fail to request asrc pair\n");
0706         return ret;
0707     }
0708 
0709     pair_priv->config = &config;
0710 
0711     config.pair = pair->index;
0712     config.channel_num = channels;
0713 
0714     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0715         config.input_format   = params_format(params);
0716         config.output_format  = asrc->asrc_format;
0717         config.input_sample_rate  = rate;
0718         config.output_sample_rate = asrc->asrc_rate;
0719     } else {
0720         config.input_format   = asrc->asrc_format;
0721         config.output_format  = params_format(params);
0722         config.input_sample_rate  = asrc->asrc_rate;
0723         config.output_sample_rate = rate;
0724     }
0725 
0726     fsl_asrc_select_clk(asrc_priv, pair,
0727                 config.input_sample_rate,
0728                 config.output_sample_rate);
0729 
0730     ret = fsl_asrc_config_pair(pair, false);
0731     if (ret) {
0732         dev_err(dai->dev, "fail to config asrc pair\n");
0733         return ret;
0734     }
0735 
0736     return 0;
0737 }
0738 
0739 static int fsl_asrc_dai_hw_free(struct snd_pcm_substream *substream,
0740                 struct snd_soc_dai *dai)
0741 {
0742     struct snd_pcm_runtime *runtime = substream->runtime;
0743     struct fsl_asrc_pair *pair = runtime->private_data;
0744 
0745     if (pair)
0746         fsl_asrc_release_pair(pair);
0747 
0748     return 0;
0749 }
0750 
0751 static int fsl_asrc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
0752                 struct snd_soc_dai *dai)
0753 {
0754     struct snd_pcm_runtime *runtime = substream->runtime;
0755     struct fsl_asrc_pair *pair = runtime->private_data;
0756 
0757     switch (cmd) {
0758     case SNDRV_PCM_TRIGGER_START:
0759     case SNDRV_PCM_TRIGGER_RESUME:
0760     case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0761         fsl_asrc_start_pair(pair);
0762         break;
0763     case SNDRV_PCM_TRIGGER_STOP:
0764     case SNDRV_PCM_TRIGGER_SUSPEND:
0765     case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0766         fsl_asrc_stop_pair(pair);
0767         break;
0768     default:
0769         return -EINVAL;
0770     }
0771 
0772     return 0;
0773 }
0774 
0775 static const struct snd_soc_dai_ops fsl_asrc_dai_ops = {
0776     .startup      = fsl_asrc_dai_startup,
0777     .hw_params    = fsl_asrc_dai_hw_params,
0778     .hw_free      = fsl_asrc_dai_hw_free,
0779     .trigger      = fsl_asrc_dai_trigger,
0780 };
0781 
0782 static int fsl_asrc_dai_probe(struct snd_soc_dai *dai)
0783 {
0784     struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
0785 
0786     snd_soc_dai_init_dma_data(dai, &asrc->dma_params_tx,
0787                   &asrc->dma_params_rx);
0788 
0789     return 0;
0790 }
0791 
0792 #define FSL_ASRC_FORMATS    (SNDRV_PCM_FMTBIT_S24_LE | \
0793                  SNDRV_PCM_FMTBIT_S16_LE | \
0794                  SNDRV_PCM_FMTBIT_S24_3LE)
0795 
0796 static struct snd_soc_dai_driver fsl_asrc_dai = {
0797     .probe = fsl_asrc_dai_probe,
0798     .playback = {
0799         .stream_name = "ASRC-Playback",
0800         .channels_min = 1,
0801         .channels_max = 10,
0802         .rate_min = 5512,
0803         .rate_max = 192000,
0804         .rates = SNDRV_PCM_RATE_KNOT,
0805         .formats = FSL_ASRC_FORMATS |
0806                SNDRV_PCM_FMTBIT_S8,
0807     },
0808     .capture = {
0809         .stream_name = "ASRC-Capture",
0810         .channels_min = 1,
0811         .channels_max = 10,
0812         .rate_min = 5512,
0813         .rate_max = 192000,
0814         .rates = SNDRV_PCM_RATE_KNOT,
0815         .formats = FSL_ASRC_FORMATS,
0816     },
0817     .ops = &fsl_asrc_dai_ops,
0818 };
0819 
0820 static bool fsl_asrc_readable_reg(struct device *dev, unsigned int reg)
0821 {
0822     switch (reg) {
0823     case REG_ASRCTR:
0824     case REG_ASRIER:
0825     case REG_ASRCNCR:
0826     case REG_ASRCFG:
0827     case REG_ASRCSR:
0828     case REG_ASRCDR1:
0829     case REG_ASRCDR2:
0830     case REG_ASRSTR:
0831     case REG_ASRPM1:
0832     case REG_ASRPM2:
0833     case REG_ASRPM3:
0834     case REG_ASRPM4:
0835     case REG_ASRPM5:
0836     case REG_ASRTFR1:
0837     case REG_ASRCCR:
0838     case REG_ASRDOA:
0839     case REG_ASRDOB:
0840     case REG_ASRDOC:
0841     case REG_ASRIDRHA:
0842     case REG_ASRIDRLA:
0843     case REG_ASRIDRHB:
0844     case REG_ASRIDRLB:
0845     case REG_ASRIDRHC:
0846     case REG_ASRIDRLC:
0847     case REG_ASR76K:
0848     case REG_ASR56K:
0849     case REG_ASRMCRA:
0850     case REG_ASRFSTA:
0851     case REG_ASRMCRB:
0852     case REG_ASRFSTB:
0853     case REG_ASRMCRC:
0854     case REG_ASRFSTC:
0855     case REG_ASRMCR1A:
0856     case REG_ASRMCR1B:
0857     case REG_ASRMCR1C:
0858         return true;
0859     default:
0860         return false;
0861     }
0862 }
0863 
0864 static bool fsl_asrc_volatile_reg(struct device *dev, unsigned int reg)
0865 {
0866     switch (reg) {
0867     case REG_ASRSTR:
0868     case REG_ASRDIA:
0869     case REG_ASRDIB:
0870     case REG_ASRDIC:
0871     case REG_ASRDOA:
0872     case REG_ASRDOB:
0873     case REG_ASRDOC:
0874     case REG_ASRFSTA:
0875     case REG_ASRFSTB:
0876     case REG_ASRFSTC:
0877     case REG_ASRCFG:
0878         return true;
0879     default:
0880         return false;
0881     }
0882 }
0883 
0884 static bool fsl_asrc_writeable_reg(struct device *dev, unsigned int reg)
0885 {
0886     switch (reg) {
0887     case REG_ASRCTR:
0888     case REG_ASRIER:
0889     case REG_ASRCNCR:
0890     case REG_ASRCFG:
0891     case REG_ASRCSR:
0892     case REG_ASRCDR1:
0893     case REG_ASRCDR2:
0894     case REG_ASRSTR:
0895     case REG_ASRPM1:
0896     case REG_ASRPM2:
0897     case REG_ASRPM3:
0898     case REG_ASRPM4:
0899     case REG_ASRPM5:
0900     case REG_ASRTFR1:
0901     case REG_ASRCCR:
0902     case REG_ASRDIA:
0903     case REG_ASRDIB:
0904     case REG_ASRDIC:
0905     case REG_ASRIDRHA:
0906     case REG_ASRIDRLA:
0907     case REG_ASRIDRHB:
0908     case REG_ASRIDRLB:
0909     case REG_ASRIDRHC:
0910     case REG_ASRIDRLC:
0911     case REG_ASR76K:
0912     case REG_ASR56K:
0913     case REG_ASRMCRA:
0914     case REG_ASRMCRB:
0915     case REG_ASRMCRC:
0916     case REG_ASRMCR1A:
0917     case REG_ASRMCR1B:
0918     case REG_ASRMCR1C:
0919         return true;
0920     default:
0921         return false;
0922     }
0923 }
0924 
0925 static struct reg_default fsl_asrc_reg[] = {
0926     { REG_ASRCTR, 0x0000 }, { REG_ASRIER, 0x0000 },
0927     { REG_ASRCNCR, 0x0000 }, { REG_ASRCFG, 0x0000 },
0928     { REG_ASRCSR, 0x0000 }, { REG_ASRCDR1, 0x0000 },
0929     { REG_ASRCDR2, 0x0000 }, { REG_ASRSTR, 0x0000 },
0930     { REG_ASRRA, 0x0000 }, { REG_ASRRB, 0x0000 },
0931     { REG_ASRRC, 0x0000 }, { REG_ASRPM1, 0x0000 },
0932     { REG_ASRPM2, 0x0000 }, { REG_ASRPM3, 0x0000 },
0933     { REG_ASRPM4, 0x0000 }, { REG_ASRPM5, 0x0000 },
0934     { REG_ASRTFR1, 0x0000 }, { REG_ASRCCR, 0x0000 },
0935     { REG_ASRDIA, 0x0000 }, { REG_ASRDOA, 0x0000 },
0936     { REG_ASRDIB, 0x0000 }, { REG_ASRDOB, 0x0000 },
0937     { REG_ASRDIC, 0x0000 }, { REG_ASRDOC, 0x0000 },
0938     { REG_ASRIDRHA, 0x0000 }, { REG_ASRIDRLA, 0x0000 },
0939     { REG_ASRIDRHB, 0x0000 }, { REG_ASRIDRLB, 0x0000 },
0940     { REG_ASRIDRHC, 0x0000 }, { REG_ASRIDRLC, 0x0000 },
0941     { REG_ASR76K, 0x0A47 }, { REG_ASR56K, 0x0DF3 },
0942     { REG_ASRMCRA, 0x0000 }, { REG_ASRFSTA, 0x0000 },
0943     { REG_ASRMCRB, 0x0000 }, { REG_ASRFSTB, 0x0000 },
0944     { REG_ASRMCRC, 0x0000 }, { REG_ASRFSTC, 0x0000 },
0945     { REG_ASRMCR1A, 0x0000 }, { REG_ASRMCR1B, 0x0000 },
0946     { REG_ASRMCR1C, 0x0000 },
0947 };
0948 
0949 static const struct regmap_config fsl_asrc_regmap_config = {
0950     .reg_bits = 32,
0951     .reg_stride = 4,
0952     .val_bits = 32,
0953 
0954     .max_register = REG_ASRMCR1C,
0955     .reg_defaults = fsl_asrc_reg,
0956     .num_reg_defaults = ARRAY_SIZE(fsl_asrc_reg),
0957     .readable_reg = fsl_asrc_readable_reg,
0958     .volatile_reg = fsl_asrc_volatile_reg,
0959     .writeable_reg = fsl_asrc_writeable_reg,
0960     .cache_type = REGCACHE_FLAT,
0961 };
0962 
0963 /**
0964  * fsl_asrc_init - Initialize ASRC registers with a default configuration
0965  * @asrc: ASRC context
0966  */
0967 static int fsl_asrc_init(struct fsl_asrc *asrc)
0968 {
0969     unsigned long ipg_rate;
0970 
0971     /* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
0972     regmap_write(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEN);
0973 
0974     /* Disable interrupt by default */
0975     regmap_write(asrc->regmap, REG_ASRIER, 0x0);
0976 
0977     /* Apply recommended settings for parameters from Reference Manual */
0978     regmap_write(asrc->regmap, REG_ASRPM1, 0x7fffff);
0979     regmap_write(asrc->regmap, REG_ASRPM2, 0x255555);
0980     regmap_write(asrc->regmap, REG_ASRPM3, 0xff7280);
0981     regmap_write(asrc->regmap, REG_ASRPM4, 0xff7280);
0982     regmap_write(asrc->regmap, REG_ASRPM5, 0xff7280);
0983 
0984     /* Base address for task queue FIFO. Set to 0x7C */
0985     regmap_update_bits(asrc->regmap, REG_ASRTFR1,
0986                ASRTFR1_TF_BASE_MASK, ASRTFR1_TF_BASE(0xfc));
0987 
0988     /*
0989      * Set the period of the 76KHz and 56KHz sampling clocks based on
0990      * the ASRC processing clock.
0991      * On iMX6, ipg_clk = 133MHz, REG_ASR76K = 0x06D6, REG_ASR56K = 0x0947
0992      */
0993     ipg_rate = clk_get_rate(asrc->ipg_clk);
0994     regmap_write(asrc->regmap, REG_ASR76K, ipg_rate / 76000);
0995     return regmap_write(asrc->regmap, REG_ASR56K, ipg_rate / 56000);
0996 }
0997 
0998 /**
0999  * fsl_asrc_isr- Interrupt handler for ASRC
1000  * @irq: irq number
1001  * @dev_id: ASRC context
1002  */
1003 static irqreturn_t fsl_asrc_isr(int irq, void *dev_id)
1004 {
1005     struct fsl_asrc *asrc = (struct fsl_asrc *)dev_id;
1006     struct device *dev = &asrc->pdev->dev;
1007     enum asrc_pair_index index;
1008     u32 status;
1009 
1010     regmap_read(asrc->regmap, REG_ASRSTR, &status);
1011 
1012     /* Clean overload error */
1013     regmap_write(asrc->regmap, REG_ASRSTR, ASRSTR_AOLE);
1014 
1015     /*
1016      * We here use dev_dbg() for all exceptions because ASRC itself does
1017      * not care if FIFO overflowed or underrun while a warning in the
1018      * interrupt would result a ridged conversion.
1019      */
1020     for (index = ASRC_PAIR_A; index < ASRC_PAIR_MAX_NUM; index++) {
1021         if (!asrc->pair[index])
1022             continue;
1023 
1024         if (status & ASRSTR_ATQOL) {
1025             asrc->pair[index]->error |= ASRC_TASK_Q_OVERLOAD;
1026             dev_dbg(dev, "ASRC Task Queue FIFO overload\n");
1027         }
1028 
1029         if (status & ASRSTR_AOOL(index)) {
1030             asrc->pair[index]->error |= ASRC_OUTPUT_TASK_OVERLOAD;
1031             pair_dbg("Output Task Overload\n");
1032         }
1033 
1034         if (status & ASRSTR_AIOL(index)) {
1035             asrc->pair[index]->error |= ASRC_INPUT_TASK_OVERLOAD;
1036             pair_dbg("Input Task Overload\n");
1037         }
1038 
1039         if (status & ASRSTR_AODO(index)) {
1040             asrc->pair[index]->error |= ASRC_OUTPUT_BUFFER_OVERFLOW;
1041             pair_dbg("Output Data Buffer has overflowed\n");
1042         }
1043 
1044         if (status & ASRSTR_AIDU(index)) {
1045             asrc->pair[index]->error |= ASRC_INPUT_BUFFER_UNDERRUN;
1046             pair_dbg("Input Data Buffer has underflowed\n");
1047         }
1048     }
1049 
1050     return IRQ_HANDLED;
1051 }
1052 
1053 static int fsl_asrc_get_fifo_addr(u8 dir, enum asrc_pair_index index)
1054 {
1055     return REG_ASRDx(dir, index);
1056 }
1057 
1058 static int fsl_asrc_runtime_resume(struct device *dev);
1059 static int fsl_asrc_runtime_suspend(struct device *dev);
1060 
1061 static int fsl_asrc_probe(struct platform_device *pdev)
1062 {
1063     struct device_node *np = pdev->dev.of_node;
1064     struct fsl_asrc_priv *asrc_priv;
1065     struct fsl_asrc *asrc;
1066     struct resource *res;
1067     void __iomem *regs;
1068     int irq, ret, i;
1069     u32 asrc_fmt = 0;
1070     u32 map_idx;
1071     char tmp[16];
1072     u32 width;
1073 
1074     asrc = devm_kzalloc(&pdev->dev, sizeof(*asrc), GFP_KERNEL);
1075     if (!asrc)
1076         return -ENOMEM;
1077 
1078     asrc_priv = devm_kzalloc(&pdev->dev, sizeof(*asrc_priv), GFP_KERNEL);
1079     if (!asrc_priv)
1080         return -ENOMEM;
1081 
1082     asrc->pdev = pdev;
1083     asrc->private = asrc_priv;
1084 
1085     /* Get the addresses and IRQ */
1086     regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
1087     if (IS_ERR(regs))
1088         return PTR_ERR(regs);
1089 
1090     asrc->paddr = res->start;
1091 
1092     asrc->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &fsl_asrc_regmap_config);
1093     if (IS_ERR(asrc->regmap)) {
1094         dev_err(&pdev->dev, "failed to init regmap\n");
1095         return PTR_ERR(asrc->regmap);
1096     }
1097 
1098     irq = platform_get_irq(pdev, 0);
1099     if (irq < 0)
1100         return irq;
1101 
1102     ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0,
1103                    dev_name(&pdev->dev), asrc);
1104     if (ret) {
1105         dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret);
1106         return ret;
1107     }
1108 
1109     asrc->mem_clk = devm_clk_get(&pdev->dev, "mem");
1110     if (IS_ERR(asrc->mem_clk)) {
1111         dev_err(&pdev->dev, "failed to get mem clock\n");
1112         return PTR_ERR(asrc->mem_clk);
1113     }
1114 
1115     asrc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
1116     if (IS_ERR(asrc->ipg_clk)) {
1117         dev_err(&pdev->dev, "failed to get ipg clock\n");
1118         return PTR_ERR(asrc->ipg_clk);
1119     }
1120 
1121     asrc->spba_clk = devm_clk_get(&pdev->dev, "spba");
1122     if (IS_ERR(asrc->spba_clk))
1123         dev_warn(&pdev->dev, "failed to get spba clock\n");
1124 
1125     for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
1126         sprintf(tmp, "asrck_%x", i);
1127         asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp);
1128         if (IS_ERR(asrc_priv->asrck_clk[i])) {
1129             dev_err(&pdev->dev, "failed to get %s clock\n", tmp);
1130             return PTR_ERR(asrc_priv->asrck_clk[i]);
1131         }
1132     }
1133 
1134     asrc_priv->soc = of_device_get_match_data(&pdev->dev);
1135     asrc->use_edma = asrc_priv->soc->use_edma;
1136     asrc->get_dma_channel = fsl_asrc_get_dma_channel;
1137     asrc->request_pair = fsl_asrc_request_pair;
1138     asrc->release_pair = fsl_asrc_release_pair;
1139     asrc->get_fifo_addr = fsl_asrc_get_fifo_addr;
1140     asrc->pair_priv_size = sizeof(struct fsl_asrc_pair_priv);
1141 
1142     if (of_device_is_compatible(np, "fsl,imx35-asrc")) {
1143         asrc_priv->clk_map[IN] = input_clk_map_imx35;
1144         asrc_priv->clk_map[OUT] = output_clk_map_imx35;
1145     } else if (of_device_is_compatible(np, "fsl,imx53-asrc")) {
1146         asrc_priv->clk_map[IN] = input_clk_map_imx53;
1147         asrc_priv->clk_map[OUT] = output_clk_map_imx53;
1148     } else if (of_device_is_compatible(np, "fsl,imx8qm-asrc") ||
1149            of_device_is_compatible(np, "fsl,imx8qxp-asrc")) {
1150         ret = of_property_read_u32(np, "fsl,asrc-clk-map", &map_idx);
1151         if (ret) {
1152             dev_err(&pdev->dev, "failed to get clk map index\n");
1153             return ret;
1154         }
1155 
1156         if (map_idx > 1) {
1157             dev_err(&pdev->dev, "unsupported clk map index\n");
1158             return -EINVAL;
1159         }
1160         if (of_device_is_compatible(np, "fsl,imx8qm-asrc")) {
1161             asrc_priv->clk_map[IN] = clk_map_imx8qm[map_idx];
1162             asrc_priv->clk_map[OUT] = clk_map_imx8qm[map_idx];
1163         } else {
1164             asrc_priv->clk_map[IN] = clk_map_imx8qxp[map_idx];
1165             asrc_priv->clk_map[OUT] = clk_map_imx8qxp[map_idx];
1166         }
1167     }
1168 
1169     asrc->channel_avail = 10;
1170 
1171     ret = of_property_read_u32(np, "fsl,asrc-rate",
1172                    &asrc->asrc_rate);
1173     if (ret) {
1174         dev_err(&pdev->dev, "failed to get output rate\n");
1175         return ret;
1176     }
1177 
1178     ret = of_property_read_u32(np, "fsl,asrc-format", &asrc_fmt);
1179     asrc->asrc_format = (__force snd_pcm_format_t)asrc_fmt;
1180     if (ret) {
1181         ret = of_property_read_u32(np, "fsl,asrc-width", &width);
1182         if (ret) {
1183             dev_err(&pdev->dev, "failed to decide output format\n");
1184             return ret;
1185         }
1186 
1187         switch (width) {
1188         case 16:
1189             asrc->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
1190             break;
1191         case 24:
1192             asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
1193             break;
1194         default:
1195             dev_warn(&pdev->dev,
1196                  "unsupported width, use default S24_LE\n");
1197             asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
1198             break;
1199         }
1200     }
1201 
1202     if (!(FSL_ASRC_FORMATS & pcm_format_to_bits(asrc->asrc_format))) {
1203         dev_warn(&pdev->dev, "unsupported width, use default S24_LE\n");
1204         asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
1205     }
1206 
1207     platform_set_drvdata(pdev, asrc);
1208     spin_lock_init(&asrc->lock);
1209     pm_runtime_enable(&pdev->dev);
1210     if (!pm_runtime_enabled(&pdev->dev)) {
1211         ret = fsl_asrc_runtime_resume(&pdev->dev);
1212         if (ret)
1213             goto err_pm_disable;
1214     }
1215 
1216     ret = pm_runtime_resume_and_get(&pdev->dev);
1217     if (ret < 0)
1218         goto err_pm_get_sync;
1219 
1220     ret = fsl_asrc_init(asrc);
1221     if (ret) {
1222         dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
1223         goto err_pm_get_sync;
1224     }
1225 
1226     ret = pm_runtime_put_sync(&pdev->dev);
1227     if (ret < 0)
1228         goto err_pm_get_sync;
1229 
1230     ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component,
1231                           &fsl_asrc_dai, 1);
1232     if (ret) {
1233         dev_err(&pdev->dev, "failed to register ASoC DAI\n");
1234         goto err_pm_get_sync;
1235     }
1236 
1237     return 0;
1238 
1239 err_pm_get_sync:
1240     if (!pm_runtime_status_suspended(&pdev->dev))
1241         fsl_asrc_runtime_suspend(&pdev->dev);
1242 err_pm_disable:
1243     pm_runtime_disable(&pdev->dev);
1244     return ret;
1245 }
1246 
1247 static int fsl_asrc_remove(struct platform_device *pdev)
1248 {
1249     pm_runtime_disable(&pdev->dev);
1250     if (!pm_runtime_status_suspended(&pdev->dev))
1251         fsl_asrc_runtime_suspend(&pdev->dev);
1252 
1253     return 0;
1254 }
1255 
1256 static int fsl_asrc_runtime_resume(struct device *dev)
1257 {
1258     struct fsl_asrc *asrc = dev_get_drvdata(dev);
1259     struct fsl_asrc_priv *asrc_priv = asrc->private;
1260     int i, ret;
1261     u32 asrctr;
1262 
1263     ret = clk_prepare_enable(asrc->mem_clk);
1264     if (ret)
1265         return ret;
1266     ret = clk_prepare_enable(asrc->ipg_clk);
1267     if (ret)
1268         goto disable_mem_clk;
1269     if (!IS_ERR(asrc->spba_clk)) {
1270         ret = clk_prepare_enable(asrc->spba_clk);
1271         if (ret)
1272             goto disable_ipg_clk;
1273     }
1274     for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
1275         ret = clk_prepare_enable(asrc_priv->asrck_clk[i]);
1276         if (ret)
1277             goto disable_asrck_clk;
1278     }
1279 
1280     /* Stop all pairs provisionally */
1281     regmap_read(asrc->regmap, REG_ASRCTR, &asrctr);
1282     regmap_update_bits(asrc->regmap, REG_ASRCTR,
1283                ASRCTR_ASRCEi_ALL_MASK, 0);
1284 
1285     /* Restore all registers */
1286     regcache_cache_only(asrc->regmap, false);
1287     regcache_mark_dirty(asrc->regmap);
1288     regcache_sync(asrc->regmap);
1289 
1290     regmap_update_bits(asrc->regmap, REG_ASRCFG,
1291                ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
1292                ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
1293 
1294     /* Restart enabled pairs */
1295     regmap_update_bits(asrc->regmap, REG_ASRCTR,
1296                ASRCTR_ASRCEi_ALL_MASK, asrctr);
1297 
1298     return 0;
1299 
1300 disable_asrck_clk:
1301     for (i--; i >= 0; i--)
1302         clk_disable_unprepare(asrc_priv->asrck_clk[i]);
1303     if (!IS_ERR(asrc->spba_clk))
1304         clk_disable_unprepare(asrc->spba_clk);
1305 disable_ipg_clk:
1306     clk_disable_unprepare(asrc->ipg_clk);
1307 disable_mem_clk:
1308     clk_disable_unprepare(asrc->mem_clk);
1309     return ret;
1310 }
1311 
1312 static int fsl_asrc_runtime_suspend(struct device *dev)
1313 {
1314     struct fsl_asrc *asrc = dev_get_drvdata(dev);
1315     struct fsl_asrc_priv *asrc_priv = asrc->private;
1316     int i;
1317 
1318     regmap_read(asrc->regmap, REG_ASRCFG,
1319             &asrc_priv->regcache_cfg);
1320 
1321     regcache_cache_only(asrc->regmap, true);
1322 
1323     for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
1324         clk_disable_unprepare(asrc_priv->asrck_clk[i]);
1325     if (!IS_ERR(asrc->spba_clk))
1326         clk_disable_unprepare(asrc->spba_clk);
1327     clk_disable_unprepare(asrc->ipg_clk);
1328     clk_disable_unprepare(asrc->mem_clk);
1329 
1330     return 0;
1331 }
1332 
1333 static const struct dev_pm_ops fsl_asrc_pm = {
1334     SET_RUNTIME_PM_OPS(fsl_asrc_runtime_suspend, fsl_asrc_runtime_resume, NULL)
1335     SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1336                 pm_runtime_force_resume)
1337 };
1338 
1339 static const struct fsl_asrc_soc_data fsl_asrc_imx35_data = {
1340     .use_edma = false,
1341     .channel_bits = 3,
1342 };
1343 
1344 static const struct fsl_asrc_soc_data fsl_asrc_imx53_data = {
1345     .use_edma = false,
1346     .channel_bits = 4,
1347 };
1348 
1349 static const struct fsl_asrc_soc_data fsl_asrc_imx8qm_data = {
1350     .use_edma = true,
1351     .channel_bits = 4,
1352 };
1353 
1354 static const struct fsl_asrc_soc_data fsl_asrc_imx8qxp_data = {
1355     .use_edma = true,
1356     .channel_bits = 4,
1357 };
1358 
1359 static const struct of_device_id fsl_asrc_ids[] = {
1360     { .compatible = "fsl,imx35-asrc", .data = &fsl_asrc_imx35_data },
1361     { .compatible = "fsl,imx53-asrc", .data = &fsl_asrc_imx53_data },
1362     { .compatible = "fsl,imx8qm-asrc", .data = &fsl_asrc_imx8qm_data },
1363     { .compatible = "fsl,imx8qxp-asrc", .data = &fsl_asrc_imx8qxp_data },
1364     {}
1365 };
1366 MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
1367 
1368 static struct platform_driver fsl_asrc_driver = {
1369     .probe = fsl_asrc_probe,
1370     .remove = fsl_asrc_remove,
1371     .driver = {
1372         .name = "fsl-asrc",
1373         .of_match_table = fsl_asrc_ids,
1374         .pm = &fsl_asrc_pm,
1375     },
1376 };
1377 module_platform_driver(fsl_asrc_driver);
1378 
1379 MODULE_DESCRIPTION("Freescale ASRC ASoC driver");
1380 MODULE_AUTHOR("Nicolin Chen <nicoleotsuka@gmail.com>");
1381 MODULE_ALIAS("platform:fsl-asrc");
1382 MODULE_LICENSE("GPL v2");