1 // SPDX-License-Identifier: GPL-2.0
3 // Freescale ASRC ALSA SoC Digital Audio Interface (DAI) driver
5 // Copyright (C) 2014 Freescale Semiconductor, Inc.
7 // Author: Nicolin Chen <nicoleotsuka@gmail.com>
10 #include <linux/delay.h>
11 #include <linux/dma-mapping.h>
12 #include <linux/module.h>
13 #include <linux/of_platform.h>
14 #include <linux/platform_data/dma-imx.h>
15 #include <linux/pm_runtime.h>
16 #include <sound/dmaengine_pcm.h>
17 #include <sound/pcm_params.h>
21 #define IDEAL_RATIO_DECIMAL_DEPTH 26
22 #define DIVIDER_NUM 64
24 #define pair_err(fmt, ...) \
25 dev_err(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
27 #define pair_dbg(fmt, ...) \
28 dev_dbg(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
30 /* Corresponding to process_option */
31 static unsigned int supported_asrc_rate[] = {
32 5512, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
33 64000, 88200, 96000, 128000, 176400, 192000,
36 static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints = {
37 .count = ARRAY_SIZE(supported_asrc_rate),
38 .list = supported_asrc_rate,
42 * The following tables map the relationship between asrc_inclk/asrc_outclk in
43 * fsl_asrc.h and the registers of ASRCSR
45 static unsigned char input_clk_map_imx35[ASRC_CLK_MAP_LEN] = {
46 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
47 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
48 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
51 static unsigned char output_clk_map_imx35[ASRC_CLK_MAP_LEN] = {
52 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
53 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
54 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
57 /* i.MX53 uses the same map for input and output */
58 static unsigned char input_clk_map_imx53[ASRC_CLK_MAP_LEN] = {
59 /* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
60 0x0, 0x1, 0x2, 0x7, 0x4, 0x5, 0x6, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xe, 0xd,
61 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
62 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
65 static unsigned char output_clk_map_imx53[ASRC_CLK_MAP_LEN] = {
66 /* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
67 0x8, 0x9, 0xa, 0x7, 0xc, 0x5, 0x6, 0xb, 0x0, 0x1, 0x2, 0x3, 0x4, 0xf, 0xe, 0xd,
68 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
69 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
73 * i.MX8QM/i.MX8QXP uses the same map for input and output.
74 * clk_map_imx8qm[0] is for i.MX8QM asrc0
75 * clk_map_imx8qm[1] is for i.MX8QM asrc1
76 * clk_map_imx8qxp[0] is for i.MX8QXP asrc0
77 * clk_map_imx8qxp[1] is for i.MX8QXP asrc1
79 static unsigned char clk_map_imx8qm[2][ASRC_CLK_MAP_LEN] = {
81 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
82 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
83 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
86 0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
87 0x0, 0x1, 0x2, 0x3, 0xb, 0xc, 0xf, 0xf, 0xd, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
88 0x4, 0x5, 0x6, 0xf, 0x8, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
92 static unsigned char clk_map_imx8qxp[2][ASRC_CLK_MAP_LEN] = {
94 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
95 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xf, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xf,
96 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
99 0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
100 0x0, 0x1, 0x2, 0x3, 0x7, 0x8, 0xf, 0xf, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
101 0xf, 0xf, 0x6, 0xf, 0xf, 0xf, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
106 * According to RM, the divider range is 1 ~ 8,
107 * prescaler is power of 2 from 1 ~ 128.
109 static int asrc_clk_divider[DIVIDER_NUM] = {
110 1, 2, 4, 8, 16, 32, 64, 128, /* divider = 1 */
111 2, 4, 8, 16, 32, 64, 128, 256, /* divider = 2 */
112 3, 6, 12, 24, 48, 96, 192, 384, /* divider = 3 */
113 4, 8, 16, 32, 64, 128, 256, 512, /* divider = 4 */
114 5, 10, 20, 40, 80, 160, 320, 640, /* divider = 5 */
115 6, 12, 24, 48, 96, 192, 384, 768, /* divider = 6 */
116 7, 14, 28, 56, 112, 224, 448, 896, /* divider = 7 */
117 8, 16, 32, 64, 128, 256, 512, 1024, /* divider = 8 */
121 * Check if the divider is available for internal ratio mode
123 static bool fsl_asrc_divider_avail(int clk_rate, int rate, int *div)
131 if (clk_rate == 0 || rate == 0)
135 rem = do_div(n, rate);
143 for (i = 0; i < DIVIDER_NUM; i++) {
144 if (n == asrc_clk_divider[i])
148 if (i == DIVIDER_NUM)
155 * fsl_asrc_sel_proc - Select the pre-processing and post-processing options
156 * @inrate: input sample rate
157 * @outrate: output sample rate
158 * @pre_proc: return value for pre-processing option
159 * @post_proc: return value for post-processing option
161 * Make sure to exclude following unsupported cases before
162 * calling this function:
163 * 1) inrate > 8.125 * outrate
164 * 2) inrate > 16.125 * outrate
167 static void fsl_asrc_sel_proc(int inrate, int outrate,
168 int *pre_proc, int *post_proc)
170 bool post_proc_cond2;
171 bool post_proc_cond0;
173 /* select pre_proc between [0, 2] */
174 if (inrate * 8 > 33 * outrate)
176 else if (inrate * 8 > 15 * outrate) {
181 } else if (inrate < 76000)
183 else if (inrate > 152000)
188 /* Condition for selection of post-processing */
189 post_proc_cond2 = (inrate * 15 > outrate * 16 && outrate < 56000) ||
190 (inrate > 56000 && outrate < 56000);
191 post_proc_cond0 = inrate * 23 < outrate * 8;
195 else if (post_proc_cond0)
202 * fsl_asrc_request_pair - Request ASRC pair
203 * @channels: number of channels
204 * @pair: pointer to pair
206 * It assigns pair by the order of A->C->B because allocation of pair B,
207 * within range [ANCA, ANCA+ANCB-1], depends on the channels of pair A
208 * while pair A and pair C are comparatively independent.
210 static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
212 enum asrc_pair_index index = ASRC_INVALID_PAIR;
213 struct fsl_asrc *asrc = pair->asrc;
214 struct device *dev = &asrc->pdev->dev;
215 unsigned long lock_flags;
218 spin_lock_irqsave(&asrc->lock, lock_flags);
220 for (i = ASRC_PAIR_A; i < ASRC_PAIR_MAX_NUM; i++) {
221 if (asrc->pair[i] != NULL)
226 if (i != ASRC_PAIR_B)
230 if (index == ASRC_INVALID_PAIR) {
231 dev_err(dev, "all pairs are busy now\n");
233 } else if (asrc->channel_avail < channels) {
234 dev_err(dev, "can't afford required channels: %d\n", channels);
237 asrc->channel_avail -= channels;
238 asrc->pair[index] = pair;
239 pair->channels = channels;
243 spin_unlock_irqrestore(&asrc->lock, lock_flags);
249 * fsl_asrc_release_pair - Release ASRC pair
250 * @pair: pair to release
252 * It clears the resource from asrc and releases the occupied channels.
254 static void fsl_asrc_release_pair(struct fsl_asrc_pair *pair)
256 struct fsl_asrc *asrc = pair->asrc;
257 enum asrc_pair_index index = pair->index;
258 unsigned long lock_flags;
260 /* Make sure the pair is disabled */
261 regmap_update_bits(asrc->regmap, REG_ASRCTR,
262 ASRCTR_ASRCEi_MASK(index), 0);
264 spin_lock_irqsave(&asrc->lock, lock_flags);
266 asrc->channel_avail += pair->channels;
267 asrc->pair[index] = NULL;
270 spin_unlock_irqrestore(&asrc->lock, lock_flags);
274 * fsl_asrc_set_watermarks- configure input and output thresholds
275 * @pair: pointer to pair
276 * @in: input threshold
277 * @out: output threshold
279 static void fsl_asrc_set_watermarks(struct fsl_asrc_pair *pair, u32 in, u32 out)
281 struct fsl_asrc *asrc = pair->asrc;
282 enum asrc_pair_index index = pair->index;
284 regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
285 ASRMCRi_EXTTHRSHi_MASK |
286 ASRMCRi_INFIFO_THRESHOLD_MASK |
287 ASRMCRi_OUTFIFO_THRESHOLD_MASK,
289 ASRMCRi_INFIFO_THRESHOLD(in) |
290 ASRMCRi_OUTFIFO_THRESHOLD(out));
294 * fsl_asrc_cal_asrck_divisor - Calculate the total divisor between asrck clock rate and sample rate
295 * @pair: pointer to pair
298 * It follows the formula clk_rate = samplerate * (2 ^ prescaler) * divider
300 static u32 fsl_asrc_cal_asrck_divisor(struct fsl_asrc_pair *pair, u32 div)
304 /* Calculate the divisors: prescaler [2^0, 2^7], divder [1, 8] */
305 for (ps = 0; div > 8; ps++)
308 return ((div - 1) << ASRCDRi_AxCPi_WIDTH) | ps;
312 * fsl_asrc_set_ideal_ratio - Calculate and set the ratio for Ideal Ratio mode only
313 * @pair: pointer to pair
314 * @inrate: input rate
315 * @outrate: output rate
317 * The ratio is a 32-bit fixed point value with 26 fractional bits.
319 static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair,
320 int inrate, int outrate)
322 struct fsl_asrc *asrc = pair->asrc;
323 enum asrc_pair_index index = pair->index;
328 pair_err("output rate should not be zero\n");
332 /* Calculate the intergal part of the ratio */
333 ratio = (inrate / outrate) << IDEAL_RATIO_DECIMAL_DEPTH;
335 /* ... and then the 26 depth decimal part */
338 for (i = 1; i <= IDEAL_RATIO_DECIMAL_DEPTH; i++) {
341 if (inrate < outrate)
344 ratio |= 1 << (IDEAL_RATIO_DECIMAL_DEPTH - i);
351 regmap_write(asrc->regmap, REG_ASRIDRL(index), ratio);
352 regmap_write(asrc->regmap, REG_ASRIDRH(index), ratio >> 24);
358 * fsl_asrc_config_pair - Configure the assigned ASRC pair
359 * @pair: pointer to pair
360 * @use_ideal_rate: boolean configuration
362 * It configures those ASRC registers according to a configuration instance
363 * of struct asrc_config which includes in/output sample rate, width, channel
364 * and clock settings.
367 * The ideal ratio configuration can work with a flexible clock rate setting.
368 * Using IDEAL_RATIO_RATE gives a faster converting speed but overloads ASRC.
369 * For a regular audio playback, the clock rate should not be slower than an
370 * clock rate aligning with the output sample rate; For a use case requiring
371 * faster conversion, set use_ideal_rate to have the faster speed.
373 static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
375 struct fsl_asrc_pair_priv *pair_priv = pair->private;
376 struct asrc_config *config = pair_priv->config;
377 struct fsl_asrc *asrc = pair->asrc;
378 struct fsl_asrc_priv *asrc_priv = asrc->private;
379 enum asrc_pair_index index = pair->index;
380 enum asrc_word_width input_word_width;
381 enum asrc_word_width output_word_width;
382 u32 inrate, outrate, indiv, outdiv;
383 u32 clk_index[2], div[2];
385 int in, out, channels;
386 int pre_proc, post_proc;
388 bool ideal, div_avail;
391 pair_err("invalid pair config\n");
395 /* Validate channels */
396 if (config->channel_num < 1 || config->channel_num > 10) {
397 pair_err("does not support %d channels\n", config->channel_num);
401 switch (snd_pcm_format_width(config->input_format)) {
403 input_word_width = ASRC_WIDTH_8_BIT;
406 input_word_width = ASRC_WIDTH_16_BIT;
409 input_word_width = ASRC_WIDTH_24_BIT;
412 pair_err("does not support this input format, %d\n",
413 config->input_format);
417 switch (snd_pcm_format_width(config->output_format)) {
419 output_word_width = ASRC_WIDTH_16_BIT;
422 output_word_width = ASRC_WIDTH_24_BIT;
425 pair_err("does not support this output format, %d\n",
426 config->output_format);
430 inrate = config->input_sample_rate;
431 outrate = config->output_sample_rate;
432 ideal = config->inclk == INCLK_NONE;
434 /* Validate input and output sample rates */
435 for (in = 0; in < ARRAY_SIZE(supported_asrc_rate); in++)
436 if (inrate == supported_asrc_rate[in])
439 if (in == ARRAY_SIZE(supported_asrc_rate)) {
440 pair_err("unsupported input sample rate: %dHz\n", inrate);
444 for (out = 0; out < ARRAY_SIZE(supported_asrc_rate); out++)
445 if (outrate == supported_asrc_rate[out])
448 if (out == ARRAY_SIZE(supported_asrc_rate)) {
449 pair_err("unsupported output sample rate: %dHz\n", outrate);
453 if ((outrate >= 5512 && outrate <= 30000) &&
454 (outrate > 24 * inrate || inrate > 8 * outrate)) {
455 pair_err("exceed supported ratio range [1/24, 8] for \
456 inrate/outrate: %d/%d\n", inrate, outrate);
460 /* Validate input and output clock sources */
461 clk_index[IN] = asrc_priv->clk_map[IN][config->inclk];
462 clk_index[OUT] = asrc_priv->clk_map[OUT][config->outclk];
464 /* We only have output clock for ideal ratio mode */
465 clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]];
467 clk_rate = clk_get_rate(clk);
468 div_avail = fsl_asrc_divider_avail(clk_rate, inrate, &div[IN]);
471 * The divider range is [1, 1024], defined by the hardware. For non-
472 * ideal ratio configuration, clock rate has to be strictly aligned
473 * with the sample rate. For ideal ratio configuration, clock rates
474 * only result in different converting speeds. So remainder does not
475 * matter, as long as we keep the divider within its valid range.
477 if (div[IN] == 0 || (!ideal && !div_avail)) {
478 pair_err("failed to support input sample rate %dHz by asrck_%x\n",
479 inrate, clk_index[ideal ? OUT : IN]);
483 div[IN] = min_t(u32, 1024, div[IN]);
485 clk = asrc_priv->asrck_clk[clk_index[OUT]];
486 clk_rate = clk_get_rate(clk);
487 if (ideal && use_ideal_rate)
488 div_avail = fsl_asrc_divider_avail(clk_rate, IDEAL_RATIO_RATE, &div[OUT]);
490 div_avail = fsl_asrc_divider_avail(clk_rate, outrate, &div[OUT]);
492 /* Output divider has the same limitation as the input one */
493 if (div[OUT] == 0 || (!ideal && !div_avail)) {
494 pair_err("failed to support output sample rate %dHz by asrck_%x\n",
495 outrate, clk_index[OUT]);
499 div[OUT] = min_t(u32, 1024, div[OUT]);
501 /* Set the channel number */
502 channels = config->channel_num;
504 if (asrc_priv->soc->channel_bits < 4)
507 /* Update channels for current pair */
508 regmap_update_bits(asrc->regmap, REG_ASRCNCR,
509 ASRCNCR_ANCi_MASK(index, asrc_priv->soc->channel_bits),
510 ASRCNCR_ANCi(index, channels, asrc_priv->soc->channel_bits));
512 /* Default setting: Automatic selection for processing mode */
513 regmap_update_bits(asrc->regmap, REG_ASRCTR,
514 ASRCTR_ATSi_MASK(index), ASRCTR_ATS(index));
515 regmap_update_bits(asrc->regmap, REG_ASRCTR,
516 ASRCTR_USRi_MASK(index), 0);
518 /* Set the input and output clock sources */
519 regmap_update_bits(asrc->regmap, REG_ASRCSR,
520 ASRCSR_AICSi_MASK(index) | ASRCSR_AOCSi_MASK(index),
521 ASRCSR_AICS(index, clk_index[IN]) |
522 ASRCSR_AOCS(index, clk_index[OUT]));
524 /* Calculate the input clock divisors */
525 indiv = fsl_asrc_cal_asrck_divisor(pair, div[IN]);
526 outdiv = fsl_asrc_cal_asrck_divisor(pair, div[OUT]);
528 /* Suppose indiv and outdiv includes prescaler, so add its MASK too */
529 regmap_update_bits(asrc->regmap, REG_ASRCDR(index),
530 ASRCDRi_AOCPi_MASK(index) | ASRCDRi_AICPi_MASK(index) |
531 ASRCDRi_AOCDi_MASK(index) | ASRCDRi_AICDi_MASK(index),
532 ASRCDRi_AOCP(index, outdiv) | ASRCDRi_AICP(index, indiv));
534 /* Implement word_width configurations */
535 regmap_update_bits(asrc->regmap, REG_ASRMCR1(index),
536 ASRMCR1i_OW16_MASK | ASRMCR1i_IWD_MASK,
537 ASRMCR1i_OW16(output_word_width) |
538 ASRMCR1i_IWD(input_word_width));
540 /* Enable BUFFER STALL */
541 regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
542 ASRMCRi_BUFSTALLi_MASK, ASRMCRi_BUFSTALLi);
544 /* Set default thresholds for input and output FIFO */
545 fsl_asrc_set_watermarks(pair, ASRC_INPUTFIFO_THRESHOLD,
546 ASRC_INPUTFIFO_THRESHOLD);
548 /* Configure the following only for Ideal Ratio mode */
552 /* Clear ASTSx bit to use Ideal Ratio mode */
553 regmap_update_bits(asrc->regmap, REG_ASRCTR,
554 ASRCTR_ATSi_MASK(index), 0);
556 /* Enable Ideal Ratio mode */
557 regmap_update_bits(asrc->regmap, REG_ASRCTR,
558 ASRCTR_IDRi_MASK(index) | ASRCTR_USRi_MASK(index),
559 ASRCTR_IDR(index) | ASRCTR_USR(index));
561 fsl_asrc_sel_proc(inrate, outrate, &pre_proc, &post_proc);
563 /* Apply configurations for pre- and post-processing */
564 regmap_update_bits(asrc->regmap, REG_ASRCFG,
565 ASRCFG_PREMODi_MASK(index) | ASRCFG_POSTMODi_MASK(index),
566 ASRCFG_PREMOD(index, pre_proc) |
567 ASRCFG_POSTMOD(index, post_proc));
569 return fsl_asrc_set_ideal_ratio(pair, inrate, outrate);
573 * fsl_asrc_start_pair - Start the assigned ASRC pair
574 * @pair: pointer to pair
576 * It enables the assigned pair and makes it stopped at the stall level.
578 static void fsl_asrc_start_pair(struct fsl_asrc_pair *pair)
580 struct fsl_asrc *asrc = pair->asrc;
581 enum asrc_pair_index index = pair->index;
582 int reg, retry = 10, i;
584 /* Enable the current pair */
585 regmap_update_bits(asrc->regmap, REG_ASRCTR,
586 ASRCTR_ASRCEi_MASK(index), ASRCTR_ASRCE(index));
588 /* Wait for status of initialization */
591 regmap_read(asrc->regmap, REG_ASRCFG, ®);
592 reg &= ASRCFG_INIRQi_MASK(index);
593 } while (!reg && --retry);
595 /* Make the input fifo to ASRC STALL level */
596 regmap_read(asrc->regmap, REG_ASRCNCR, ®);
597 for (i = 0; i < pair->channels * 4; i++)
598 regmap_write(asrc->regmap, REG_ASRDI(index), 0);
600 /* Enable overload interrupt */
601 regmap_write(asrc->regmap, REG_ASRIER, ASRIER_AOLIE);
605 * fsl_asrc_stop_pair - Stop the assigned ASRC pair
606 * @pair: pointer to pair
608 static void fsl_asrc_stop_pair(struct fsl_asrc_pair *pair)
610 struct fsl_asrc *asrc = pair->asrc;
611 enum asrc_pair_index index = pair->index;
613 /* Stop the current pair */
614 regmap_update_bits(asrc->regmap, REG_ASRCTR,
615 ASRCTR_ASRCEi_MASK(index), 0);
619 * fsl_asrc_get_dma_channel- Get DMA channel according to the pair and direction.
620 * @pair: pointer to pair
621 * @dir: DMA direction
623 static struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair,
626 struct fsl_asrc *asrc = pair->asrc;
627 enum asrc_pair_index index = pair->index;
630 sprintf(name, "%cx%c", dir == IN ? 'r' : 't', index + 'a');
632 return dma_request_slave_channel(&asrc->pdev->dev, name);
635 static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream,
636 struct snd_soc_dai *dai)
638 struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
639 struct fsl_asrc_priv *asrc_priv = asrc->private;
641 /* Odd channel number is not valid for older ASRC (channel_bits==3) */
642 if (asrc_priv->soc->channel_bits == 3)
643 snd_pcm_hw_constraint_step(substream->runtime, 0,
644 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
647 return snd_pcm_hw_constraint_list(substream->runtime, 0,
648 SNDRV_PCM_HW_PARAM_RATE, &fsl_asrc_rate_constraints);
651 /* Select proper clock source for internal ratio mode */
652 static void fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv,
653 struct fsl_asrc_pair *pair,
657 struct fsl_asrc_pair_priv *pair_priv = pair->private;
658 struct asrc_config *config = pair_priv->config;
659 int rate[2], select_clk[2]; /* Array size 2 means IN and OUT */
660 int clk_rate, clk_index;
664 rate[OUT] = out_rate;
666 /* Select proper clock source for internal ratio mode */
667 for (j = 0; j < 2; j++) {
668 for (i = 0; i < ASRC_CLK_MAP_LEN; i++) {
669 clk_index = asrc_priv->clk_map[j][i];
670 clk_rate = clk_get_rate(asrc_priv->asrck_clk[clk_index]);
671 /* Only match a perfect clock source with no remainder */
672 if (fsl_asrc_divider_avail(clk_rate, rate[j], NULL))
679 /* Switch to ideal ratio mode if there is no proper clock source */
680 if (select_clk[IN] == ASRC_CLK_MAP_LEN || select_clk[OUT] == ASRC_CLK_MAP_LEN) {
681 select_clk[IN] = INCLK_NONE;
682 select_clk[OUT] = OUTCLK_ASRCK1_CLK;
685 config->inclk = select_clk[IN];
686 config->outclk = select_clk[OUT];
689 static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
690 struct snd_pcm_hw_params *params,
691 struct snd_soc_dai *dai)
693 struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
694 struct fsl_asrc_priv *asrc_priv = asrc->private;
695 struct snd_pcm_runtime *runtime = substream->runtime;
696 struct fsl_asrc_pair *pair = runtime->private_data;
697 struct fsl_asrc_pair_priv *pair_priv = pair->private;
698 unsigned int channels = params_channels(params);
699 unsigned int rate = params_rate(params);
700 struct asrc_config config;
703 ret = fsl_asrc_request_pair(channels, pair);
705 dev_err(dai->dev, "fail to request asrc pair\n");
709 pair_priv->config = &config;
711 config.pair = pair->index;
712 config.channel_num = channels;
714 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
715 config.input_format = params_format(params);
716 config.output_format = asrc->asrc_format;
717 config.input_sample_rate = rate;
718 config.output_sample_rate = asrc->asrc_rate;
720 config.input_format = asrc->asrc_format;
721 config.output_format = params_format(params);
722 config.input_sample_rate = asrc->asrc_rate;
723 config.output_sample_rate = rate;
726 fsl_asrc_select_clk(asrc_priv, pair,
727 config.input_sample_rate,
728 config.output_sample_rate);
730 ret = fsl_asrc_config_pair(pair, false);
732 dev_err(dai->dev, "fail to config asrc pair\n");
739 static int fsl_asrc_dai_hw_free(struct snd_pcm_substream *substream,
740 struct snd_soc_dai *dai)
742 struct snd_pcm_runtime *runtime = substream->runtime;
743 struct fsl_asrc_pair *pair = runtime->private_data;
746 fsl_asrc_release_pair(pair);
751 static int fsl_asrc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
752 struct snd_soc_dai *dai)
754 struct snd_pcm_runtime *runtime = substream->runtime;
755 struct fsl_asrc_pair *pair = runtime->private_data;
758 case SNDRV_PCM_TRIGGER_START:
759 case SNDRV_PCM_TRIGGER_RESUME:
760 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
761 fsl_asrc_start_pair(pair);
763 case SNDRV_PCM_TRIGGER_STOP:
764 case SNDRV_PCM_TRIGGER_SUSPEND:
765 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
766 fsl_asrc_stop_pair(pair);
775 static const struct snd_soc_dai_ops fsl_asrc_dai_ops = {
776 .startup = fsl_asrc_dai_startup,
777 .hw_params = fsl_asrc_dai_hw_params,
778 .hw_free = fsl_asrc_dai_hw_free,
779 .trigger = fsl_asrc_dai_trigger,
782 static int fsl_asrc_dai_probe(struct snd_soc_dai *dai)
784 struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
786 snd_soc_dai_init_dma_data(dai, &asrc->dma_params_tx,
787 &asrc->dma_params_rx);
792 #define FSL_ASRC_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | \
793 SNDRV_PCM_FMTBIT_S16_LE | \
794 SNDRV_PCM_FMTBIT_S24_3LE)
796 static struct snd_soc_dai_driver fsl_asrc_dai = {
797 .probe = fsl_asrc_dai_probe,
799 .stream_name = "ASRC-Playback",
804 .rates = SNDRV_PCM_RATE_KNOT,
805 .formats = FSL_ASRC_FORMATS |
809 .stream_name = "ASRC-Capture",
814 .rates = SNDRV_PCM_RATE_KNOT,
815 .formats = FSL_ASRC_FORMATS,
817 .ops = &fsl_asrc_dai_ops,
820 static bool fsl_asrc_readable_reg(struct device *dev, unsigned int reg)
864 static bool fsl_asrc_volatile_reg(struct device *dev, unsigned int reg)
884 static bool fsl_asrc_writeable_reg(struct device *dev, unsigned int reg)
925 static struct reg_default fsl_asrc_reg[] = {
926 { REG_ASRCTR, 0x0000 }, { REG_ASRIER, 0x0000 },
927 { REG_ASRCNCR, 0x0000 }, { REG_ASRCFG, 0x0000 },
928 { REG_ASRCSR, 0x0000 }, { REG_ASRCDR1, 0x0000 },
929 { REG_ASRCDR2, 0x0000 }, { REG_ASRSTR, 0x0000 },
930 { REG_ASRRA, 0x0000 }, { REG_ASRRB, 0x0000 },
931 { REG_ASRRC, 0x0000 }, { REG_ASRPM1, 0x0000 },
932 { REG_ASRPM2, 0x0000 }, { REG_ASRPM3, 0x0000 },
933 { REG_ASRPM4, 0x0000 }, { REG_ASRPM5, 0x0000 },
934 { REG_ASRTFR1, 0x0000 }, { REG_ASRCCR, 0x0000 },
935 { REG_ASRDIA, 0x0000 }, { REG_ASRDOA, 0x0000 },
936 { REG_ASRDIB, 0x0000 }, { REG_ASRDOB, 0x0000 },
937 { REG_ASRDIC, 0x0000 }, { REG_ASRDOC, 0x0000 },
938 { REG_ASRIDRHA, 0x0000 }, { REG_ASRIDRLA, 0x0000 },
939 { REG_ASRIDRHB, 0x0000 }, { REG_ASRIDRLB, 0x0000 },
940 { REG_ASRIDRHC, 0x0000 }, { REG_ASRIDRLC, 0x0000 },
941 { REG_ASR76K, 0x0A47 }, { REG_ASR56K, 0x0DF3 },
942 { REG_ASRMCRA, 0x0000 }, { REG_ASRFSTA, 0x0000 },
943 { REG_ASRMCRB, 0x0000 }, { REG_ASRFSTB, 0x0000 },
944 { REG_ASRMCRC, 0x0000 }, { REG_ASRFSTC, 0x0000 },
945 { REG_ASRMCR1A, 0x0000 }, { REG_ASRMCR1B, 0x0000 },
946 { REG_ASRMCR1C, 0x0000 },
949 static const struct regmap_config fsl_asrc_regmap_config = {
954 .max_register = REG_ASRMCR1C,
955 .reg_defaults = fsl_asrc_reg,
956 .num_reg_defaults = ARRAY_SIZE(fsl_asrc_reg),
957 .readable_reg = fsl_asrc_readable_reg,
958 .volatile_reg = fsl_asrc_volatile_reg,
959 .writeable_reg = fsl_asrc_writeable_reg,
960 .cache_type = REGCACHE_FLAT,
964 * fsl_asrc_init - Initialize ASRC registers with a default configuration
965 * @asrc: ASRC context
967 static int fsl_asrc_init(struct fsl_asrc *asrc)
969 unsigned long ipg_rate;
971 /* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
972 regmap_write(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEN);
974 /* Disable interrupt by default */
975 regmap_write(asrc->regmap, REG_ASRIER, 0x0);
977 /* Apply recommended settings for parameters from Reference Manual */
978 regmap_write(asrc->regmap, REG_ASRPM1, 0x7fffff);
979 regmap_write(asrc->regmap, REG_ASRPM2, 0x255555);
980 regmap_write(asrc->regmap, REG_ASRPM3, 0xff7280);
981 regmap_write(asrc->regmap, REG_ASRPM4, 0xff7280);
982 regmap_write(asrc->regmap, REG_ASRPM5, 0xff7280);
984 /* Base address for task queue FIFO. Set to 0x7C */
985 regmap_update_bits(asrc->regmap, REG_ASRTFR1,
986 ASRTFR1_TF_BASE_MASK, ASRTFR1_TF_BASE(0xfc));
989 * Set the period of the 76KHz and 56KHz sampling clocks based on
990 * the ASRC processing clock.
991 * On iMX6, ipg_clk = 133MHz, REG_ASR76K = 0x06D6, REG_ASR56K = 0x0947
993 ipg_rate = clk_get_rate(asrc->ipg_clk);
994 regmap_write(asrc->regmap, REG_ASR76K, ipg_rate / 76000);
995 return regmap_write(asrc->regmap, REG_ASR56K, ipg_rate / 56000);
999 * fsl_asrc_isr- Interrupt handler for ASRC
1001 * @dev_id: ASRC context
1003 static irqreturn_t fsl_asrc_isr(int irq, void *dev_id)
1005 struct fsl_asrc *asrc = (struct fsl_asrc *)dev_id;
1006 struct device *dev = &asrc->pdev->dev;
1007 enum asrc_pair_index index;
1010 regmap_read(asrc->regmap, REG_ASRSTR, &status);
1012 /* Clean overload error */
1013 regmap_write(asrc->regmap, REG_ASRSTR, ASRSTR_AOLE);
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.
1020 for (index = ASRC_PAIR_A; index < ASRC_PAIR_MAX_NUM; index++) {
1021 if (!asrc->pair[index])
1024 if (status & ASRSTR_ATQOL) {
1025 asrc->pair[index]->error |= ASRC_TASK_Q_OVERLOAD;
1026 dev_dbg(dev, "ASRC Task Queue FIFO overload\n");
1029 if (status & ASRSTR_AOOL(index)) {
1030 asrc->pair[index]->error |= ASRC_OUTPUT_TASK_OVERLOAD;
1031 pair_dbg("Output Task Overload\n");
1034 if (status & ASRSTR_AIOL(index)) {
1035 asrc->pair[index]->error |= ASRC_INPUT_TASK_OVERLOAD;
1036 pair_dbg("Input Task Overload\n");
1039 if (status & ASRSTR_AODO(index)) {
1040 asrc->pair[index]->error |= ASRC_OUTPUT_BUFFER_OVERFLOW;
1041 pair_dbg("Output Data Buffer has overflowed\n");
1044 if (status & ASRSTR_AIDU(index)) {
1045 asrc->pair[index]->error |= ASRC_INPUT_BUFFER_UNDERRUN;
1046 pair_dbg("Input Data Buffer has underflowed\n");
1053 static int fsl_asrc_get_fifo_addr(u8 dir, enum asrc_pair_index index)
1055 return REG_ASRDx(dir, index);
1058 static int fsl_asrc_runtime_resume(struct device *dev);
1059 static int fsl_asrc_runtime_suspend(struct device *dev);
1061 static int fsl_asrc_probe(struct platform_device *pdev)
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;
1073 asrc = devm_kzalloc(&pdev->dev, sizeof(*asrc), GFP_KERNEL);
1077 asrc_priv = devm_kzalloc(&pdev->dev, sizeof(*asrc_priv), GFP_KERNEL);
1082 asrc->private = asrc_priv;
1084 /* Get the addresses and IRQ */
1085 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
1087 return PTR_ERR(regs);
1089 asrc->paddr = res->start;
1091 asrc->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &fsl_asrc_regmap_config);
1092 if (IS_ERR(asrc->regmap)) {
1093 dev_err(&pdev->dev, "failed to init regmap\n");
1094 return PTR_ERR(asrc->regmap);
1097 irq = platform_get_irq(pdev, 0);
1101 ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0,
1102 dev_name(&pdev->dev), asrc);
1104 dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret);
1108 asrc->mem_clk = devm_clk_get(&pdev->dev, "mem");
1109 if (IS_ERR(asrc->mem_clk)) {
1110 dev_err(&pdev->dev, "failed to get mem clock\n");
1111 return PTR_ERR(asrc->mem_clk);
1114 asrc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
1115 if (IS_ERR(asrc->ipg_clk)) {
1116 dev_err(&pdev->dev, "failed to get ipg clock\n");
1117 return PTR_ERR(asrc->ipg_clk);
1120 asrc->spba_clk = devm_clk_get(&pdev->dev, "spba");
1121 if (IS_ERR(asrc->spba_clk))
1122 dev_warn(&pdev->dev, "failed to get spba clock\n");
1124 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
1125 sprintf(tmp, "asrck_%x", i);
1126 asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp);
1127 if (IS_ERR(asrc_priv->asrck_clk[i])) {
1128 dev_err(&pdev->dev, "failed to get %s clock\n", tmp);
1129 return PTR_ERR(asrc_priv->asrck_clk[i]);
1133 asrc_priv->soc = of_device_get_match_data(&pdev->dev);
1134 asrc->use_edma = asrc_priv->soc->use_edma;
1135 asrc->get_dma_channel = fsl_asrc_get_dma_channel;
1136 asrc->request_pair = fsl_asrc_request_pair;
1137 asrc->release_pair = fsl_asrc_release_pair;
1138 asrc->get_fifo_addr = fsl_asrc_get_fifo_addr;
1139 asrc->pair_priv_size = sizeof(struct fsl_asrc_pair_priv);
1141 if (of_device_is_compatible(np, "fsl,imx35-asrc")) {
1142 asrc_priv->clk_map[IN] = input_clk_map_imx35;
1143 asrc_priv->clk_map[OUT] = output_clk_map_imx35;
1144 } else if (of_device_is_compatible(np, "fsl,imx53-asrc")) {
1145 asrc_priv->clk_map[IN] = input_clk_map_imx53;
1146 asrc_priv->clk_map[OUT] = output_clk_map_imx53;
1147 } else if (of_device_is_compatible(np, "fsl,imx8qm-asrc") ||
1148 of_device_is_compatible(np, "fsl,imx8qxp-asrc")) {
1149 ret = of_property_read_u32(np, "fsl,asrc-clk-map", &map_idx);
1151 dev_err(&pdev->dev, "failed to get clk map index\n");
1156 dev_err(&pdev->dev, "unsupported clk map index\n");
1159 if (of_device_is_compatible(np, "fsl,imx8qm-asrc")) {
1160 asrc_priv->clk_map[IN] = clk_map_imx8qm[map_idx];
1161 asrc_priv->clk_map[OUT] = clk_map_imx8qm[map_idx];
1163 asrc_priv->clk_map[IN] = clk_map_imx8qxp[map_idx];
1164 asrc_priv->clk_map[OUT] = clk_map_imx8qxp[map_idx];
1168 asrc->channel_avail = 10;
1170 ret = of_property_read_u32(np, "fsl,asrc-rate",
1173 dev_err(&pdev->dev, "failed to get output rate\n");
1177 ret = of_property_read_u32(np, "fsl,asrc-format", &asrc->asrc_format);
1179 ret = of_property_read_u32(np, "fsl,asrc-width", &width);
1181 dev_err(&pdev->dev, "failed to decide output format\n");
1187 asrc->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
1190 asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
1193 dev_warn(&pdev->dev,
1194 "unsupported width, use default S24_LE\n");
1195 asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
1200 if (!(FSL_ASRC_FORMATS & (1ULL << asrc->asrc_format))) {
1201 dev_warn(&pdev->dev, "unsupported width, use default S24_LE\n");
1202 asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
1205 platform_set_drvdata(pdev, asrc);
1206 spin_lock_init(&asrc->lock);
1207 pm_runtime_enable(&pdev->dev);
1208 if (!pm_runtime_enabled(&pdev->dev)) {
1209 ret = fsl_asrc_runtime_resume(&pdev->dev);
1211 goto err_pm_disable;
1214 ret = pm_runtime_get_sync(&pdev->dev);
1216 pm_runtime_put_noidle(&pdev->dev);
1217 goto err_pm_get_sync;
1220 ret = fsl_asrc_init(asrc);
1222 dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
1223 goto err_pm_get_sync;
1226 ret = pm_runtime_put_sync(&pdev->dev);
1228 goto err_pm_get_sync;
1230 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component,
1233 dev_err(&pdev->dev, "failed to register ASoC DAI\n");
1234 goto err_pm_get_sync;
1240 if (!pm_runtime_status_suspended(&pdev->dev))
1241 fsl_asrc_runtime_suspend(&pdev->dev);
1243 pm_runtime_disable(&pdev->dev);
1247 static int fsl_asrc_remove(struct platform_device *pdev)
1249 pm_runtime_disable(&pdev->dev);
1250 if (!pm_runtime_status_suspended(&pdev->dev))
1251 fsl_asrc_runtime_suspend(&pdev->dev);
1256 static int fsl_asrc_runtime_resume(struct device *dev)
1258 struct fsl_asrc *asrc = dev_get_drvdata(dev);
1259 struct fsl_asrc_priv *asrc_priv = asrc->private;
1263 ret = clk_prepare_enable(asrc->mem_clk);
1266 ret = clk_prepare_enable(asrc->ipg_clk);
1268 goto disable_mem_clk;
1269 if (!IS_ERR(asrc->spba_clk)) {
1270 ret = clk_prepare_enable(asrc->spba_clk);
1272 goto disable_ipg_clk;
1274 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
1275 ret = clk_prepare_enable(asrc_priv->asrck_clk[i]);
1277 goto disable_asrck_clk;
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);
1285 /* Restore all registers */
1286 regcache_cache_only(asrc->regmap, false);
1287 regcache_mark_dirty(asrc->regmap);
1288 regcache_sync(asrc->regmap);
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);
1294 /* Restart enabled pairs */
1295 regmap_update_bits(asrc->regmap, REG_ASRCTR,
1296 ASRCTR_ASRCEi_ALL_MASK, asrctr);
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);
1306 clk_disable_unprepare(asrc->ipg_clk);
1308 clk_disable_unprepare(asrc->mem_clk);
1312 static int fsl_asrc_runtime_suspend(struct device *dev)
1314 struct fsl_asrc *asrc = dev_get_drvdata(dev);
1315 struct fsl_asrc_priv *asrc_priv = asrc->private;
1318 regmap_read(asrc->regmap, REG_ASRCFG,
1319 &asrc_priv->regcache_cfg);
1321 regcache_cache_only(asrc->regmap, true);
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);
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)
1339 static const struct fsl_asrc_soc_data fsl_asrc_imx35_data = {
1344 static const struct fsl_asrc_soc_data fsl_asrc_imx53_data = {
1349 static const struct fsl_asrc_soc_data fsl_asrc_imx8qm_data = {
1354 static const struct fsl_asrc_soc_data fsl_asrc_imx8qxp_data = {
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 },
1366 MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
1368 static struct platform_driver fsl_asrc_driver = {
1369 .probe = fsl_asrc_probe,
1370 .remove = fsl_asrc_remove,
1373 .of_match_table = fsl_asrc_ids,
1377 module_platform_driver(fsl_asrc_driver);
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");