0001
0002
0003
0004
0005
0006
0007
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
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
0043
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
0058 static unsigned char input_clk_map_imx53[ASRC_CLK_MAP_LEN] = {
0059
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
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
0074
0075
0076
0077
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
0107
0108
0109 static int asrc_clk_divider[DIVIDER_NUM] = {
0110 1, 2, 4, 8, 16, 32, 64, 128,
0111 2, 4, 8, 16, 32, 64, 128, 256,
0112 3, 6, 12, 24, 48, 96, 192, 384,
0113 4, 8, 16, 32, 64, 128, 256, 512,
0114 5, 10, 20, 40, 80, 160, 320, 640,
0115 6, 12, 24, 48, 96, 192, 384, 768,
0116 7, 14, 28, 56, 112, 224, 448, 896,
0117 8, 16, 32, 64, 128, 256, 512, 1024,
0118 };
0119
0120
0121
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
0156
0157
0158
0159
0160
0161
0162
0163
0164
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
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
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
0203
0204
0205
0206
0207
0208
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
0250
0251
0252
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
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
0275
0276
0277
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
0295
0296
0297
0298
0299
0300 static u32 fsl_asrc_cal_asrck_divisor(struct fsl_asrc_pair *pair, u32 div)
0301 {
0302 u32 ps;
0303
0304
0305 for (ps = 0; div > 8; ps++)
0306 div >>= 1;
0307
0308 return ((div - 1) << ASRCDRi_AxCPi_WIDTH) | ps;
0309 }
0310
0311
0312
0313
0314
0315
0316
0317
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
0333 ratio = (inrate / outrate) << IDEAL_RATIO_DECIMAL_DEPTH;
0334
0335
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
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
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
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
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
0461 clk_index[IN] = asrc_priv->clk_map[IN][config->inclk];
0462 clk_index[OUT] = asrc_priv->clk_map[OUT][config->outclk];
0463
0464
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
0472
0473
0474
0475
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
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
0502 channels = config->channel_num;
0503
0504 if (asrc_priv->soc->channel_bits < 4)
0505 channels /= 2;
0506
0507
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
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
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
0525 indiv = fsl_asrc_cal_asrck_divisor(pair, div[IN]);
0526 outdiv = fsl_asrc_cal_asrck_divisor(pair, div[OUT]);
0527
0528
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
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
0541 regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
0542 ASRMCRi_BUFSTALLi_MASK, ASRMCRi_BUFSTALLi);
0543
0544
0545 fsl_asrc_set_watermarks(pair, ASRC_INPUTFIFO_THRESHOLD,
0546 ASRC_INPUTFIFO_THRESHOLD);
0547
0548
0549 if (!ideal)
0550 return 0;
0551
0552
0553 regmap_update_bits(asrc->regmap, REG_ASRCTR,
0554 ASRCTR_ATSi_MASK(index), 0);
0555
0556
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
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
0574
0575
0576
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
0585 regmap_update_bits(asrc->regmap, REG_ASRCTR,
0586 ASRCTR_ASRCEi_MASK(index), ASRCTR_ASRCE(index));
0587
0588
0589 do {
0590 udelay(5);
0591 regmap_read(asrc->regmap, REG_ASRCFG, ®);
0592 reg &= ASRCFG_INIRQi_MASK(index);
0593 } while (!reg && --retry);
0594
0595
0596 regmap_read(asrc->regmap, REG_ASRCNCR, ®);
0597 for (i = 0; i < pair->channels * 4; i++)
0598 regmap_write(asrc->regmap, REG_ASRDI(index), 0);
0599
0600
0601 regmap_write(asrc->regmap, REG_ASRIER, ASRIER_AOLIE);
0602 }
0603
0604
0605
0606
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
0614 regmap_update_bits(asrc->regmap, REG_ASRCTR,
0615 ASRCTR_ASRCEi_MASK(index), 0);
0616 }
0617
0618
0619
0620
0621
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
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
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];
0660 int clk_rate, clk_index;
0661 int i, j;
0662
0663 rate[IN] = in_rate;
0664 rate[OUT] = out_rate;
0665
0666
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
0672 if (fsl_asrc_divider_avail(clk_rate, rate[j], NULL))
0673 break;
0674 }
0675
0676 select_clk[j] = i;
0677 }
0678
0679
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
0965
0966
0967 static int fsl_asrc_init(struct fsl_asrc *asrc)
0968 {
0969 unsigned long ipg_rate;
0970
0971
0972 regmap_write(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEN);
0973
0974
0975 regmap_write(asrc->regmap, REG_ASRIER, 0x0);
0976
0977
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
0985 regmap_update_bits(asrc->regmap, REG_ASRTFR1,
0986 ASRTFR1_TF_BASE_MASK, ASRTFR1_TF_BASE(0xfc));
0987
0988
0989
0990
0991
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
1000
1001
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
1013 regmap_write(asrc->regmap, REG_ASRSTR, ASRSTR_AOLE);
1014
1015
1016
1017
1018
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
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
1281 regmap_read(asrc->regmap, REG_ASRCTR, &asrctr);
1282 regmap_update_bits(asrc->regmap, REG_ASRCTR,
1283 ASRCTR_ASRCEi_ALL_MASK, 0);
1284
1285
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
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");