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/dma/imx-dma.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
23 #define INIT_RETRY_NUM 50
25 #define pair_err(fmt, ...) \
26 dev_err(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
28 #define pair_dbg(fmt, ...) \
29 dev_dbg(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
31 #define pair_warn(fmt, ...) \
32 dev_warn(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
34 /* Corresponding to process_option */
35 static unsigned int supported_asrc_rate
[] = {
36 5512, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
37 64000, 88200, 96000, 128000, 176400, 192000,
40 static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints
= {
41 .count
= ARRAY_SIZE(supported_asrc_rate
),
42 .list
= supported_asrc_rate
,
46 * The following tables map the relationship between asrc_inclk/asrc_outclk in
47 * fsl_asrc.h and the registers of ASRCSR
49 static unsigned char input_clk_map_imx35
[ASRC_CLK_MAP_LEN
] = {
50 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
51 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
52 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
55 static unsigned char output_clk_map_imx35
[ASRC_CLK_MAP_LEN
] = {
56 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
57 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
58 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
61 /* i.MX53 uses the same map for input and output */
62 static unsigned char input_clk_map_imx53
[ASRC_CLK_MAP_LEN
] = {
63 /* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
64 0x0, 0x1, 0x2, 0x7, 0x4, 0x5, 0x6, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xe, 0xd,
65 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
66 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
69 static unsigned char output_clk_map_imx53
[ASRC_CLK_MAP_LEN
] = {
70 /* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
71 0x8, 0x9, 0xa, 0x7, 0xc, 0x5, 0x6, 0xb, 0x0, 0x1, 0x2, 0x3, 0x4, 0xf, 0xe, 0xd,
72 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
73 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
77 * i.MX8QM/i.MX8QXP uses the same map for input and output.
78 * clk_map_imx8qm[0] is for i.MX8QM asrc0
79 * clk_map_imx8qm[1] is for i.MX8QM asrc1
80 * clk_map_imx8qxp[0] is for i.MX8QXP asrc0
81 * clk_map_imx8qxp[1] is for i.MX8QXP asrc1
83 static unsigned char clk_map_imx8qm
[2][ASRC_CLK_MAP_LEN
] = {
85 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
86 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
87 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
90 0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
91 0x0, 0x1, 0x2, 0x3, 0xb, 0xc, 0xf, 0xf, 0xd, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
92 0x4, 0x5, 0x6, 0xf, 0x8, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
96 static unsigned char clk_map_imx8qxp
[2][ASRC_CLK_MAP_LEN
] = {
98 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
99 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xf, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xf,
100 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
103 0xf, 0xf, 0xf, 0xf, 0xf, 0x7, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x0,
104 0x0, 0x1, 0x2, 0x3, 0x7, 0x8, 0xf, 0xf, 0x9, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
105 0xf, 0xf, 0x6, 0xf, 0xf, 0xf, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
110 * According to RM, the divider range is 1 ~ 8,
111 * prescaler is power of 2 from 1 ~ 128.
113 static int asrc_clk_divider
[DIVIDER_NUM
] = {
114 1, 2, 4, 8, 16, 32, 64, 128, /* divider = 1 */
115 2, 4, 8, 16, 32, 64, 128, 256, /* divider = 2 */
116 3, 6, 12, 24, 48, 96, 192, 384, /* divider = 3 */
117 4, 8, 16, 32, 64, 128, 256, 512, /* divider = 4 */
118 5, 10, 20, 40, 80, 160, 320, 640, /* divider = 5 */
119 6, 12, 24, 48, 96, 192, 384, 768, /* divider = 6 */
120 7, 14, 28, 56, 112, 224, 448, 896, /* divider = 7 */
121 8, 16, 32, 64, 128, 256, 512, 1024, /* divider = 8 */
125 * Check if the divider is available for internal ratio mode
127 static bool fsl_asrc_divider_avail(int clk_rate
, int rate
, int *div
)
135 if (clk_rate
== 0 || rate
== 0)
139 rem
= do_div(n
, rate
);
147 for (i
= 0; i
< DIVIDER_NUM
; i
++) {
148 if (n
== asrc_clk_divider
[i
])
152 if (i
== DIVIDER_NUM
)
159 * fsl_asrc_sel_proc - Select the pre-processing and post-processing options
160 * @inrate: input sample rate
161 * @outrate: output sample rate
162 * @pre_proc: return value for pre-processing option
163 * @post_proc: return value for post-processing option
165 * Make sure to exclude following unsupported cases before
166 * calling this function:
167 * 1) inrate > 8.125 * outrate
168 * 2) inrate > 16.125 * outrate
171 static void fsl_asrc_sel_proc(int inrate
, int outrate
,
172 int *pre_proc
, int *post_proc
)
174 bool post_proc_cond2
;
175 bool post_proc_cond0
;
177 /* select pre_proc between [0, 2] */
178 if (inrate
* 8 > 33 * outrate
)
180 else if (inrate
* 8 > 15 * outrate
) {
185 } else if (inrate
< 76000)
187 else if (inrate
> 152000)
192 /* Condition for selection of post-processing */
193 post_proc_cond2
= (inrate
* 15 > outrate
* 16 && outrate
< 56000) ||
194 (inrate
> 56000 && outrate
< 56000);
195 post_proc_cond0
= inrate
* 23 < outrate
* 8;
199 else if (post_proc_cond0
)
206 * fsl_asrc_request_pair - Request ASRC pair
207 * @channels: number of channels
208 * @pair: pointer to pair
210 * It assigns pair by the order of A->C->B because allocation of pair B,
211 * within range [ANCA, ANCA+ANCB-1], depends on the channels of pair A
212 * while pair A and pair C are comparatively independent.
214 static int fsl_asrc_request_pair(int channels
, struct fsl_asrc_pair
*pair
)
216 enum asrc_pair_index index
= ASRC_INVALID_PAIR
;
217 struct fsl_asrc
*asrc
= pair
->asrc
;
218 struct device
*dev
= &asrc
->pdev
->dev
;
219 unsigned long lock_flags
;
222 spin_lock_irqsave(&asrc
->lock
, lock_flags
);
224 for (i
= ASRC_PAIR_A
; i
< ASRC_PAIR_MAX_NUM
; i
++) {
225 if (asrc
->pair
[i
] != NULL
)
230 if (i
!= ASRC_PAIR_B
)
234 if (index
== ASRC_INVALID_PAIR
) {
235 dev_err(dev
, "all pairs are busy now\n");
237 } else if (asrc
->channel_avail
< channels
) {
238 dev_err(dev
, "can't afford required channels: %d\n", channels
);
241 asrc
->channel_avail
-= channels
;
242 asrc
->pair
[index
] = pair
;
243 pair
->channels
= channels
;
247 spin_unlock_irqrestore(&asrc
->lock
, lock_flags
);
253 * fsl_asrc_release_pair - Release ASRC pair
254 * @pair: pair to release
256 * It clears the resource from asrc and releases the occupied channels.
258 static void fsl_asrc_release_pair(struct fsl_asrc_pair
*pair
)
260 struct fsl_asrc
*asrc
= pair
->asrc
;
261 enum asrc_pair_index index
= pair
->index
;
262 unsigned long lock_flags
;
264 /* Make sure the pair is disabled */
265 regmap_update_bits(asrc
->regmap
, REG_ASRCTR
,
266 ASRCTR_ASRCEi_MASK(index
), 0);
268 spin_lock_irqsave(&asrc
->lock
, lock_flags
);
270 asrc
->channel_avail
+= pair
->channels
;
271 asrc
->pair
[index
] = NULL
;
274 spin_unlock_irqrestore(&asrc
->lock
, lock_flags
);
278 * fsl_asrc_set_watermarks- configure input and output thresholds
279 * @pair: pointer to pair
280 * @in: input threshold
281 * @out: output threshold
283 static void fsl_asrc_set_watermarks(struct fsl_asrc_pair
*pair
, u32 in
, u32 out
)
285 struct fsl_asrc
*asrc
= pair
->asrc
;
286 enum asrc_pair_index index
= pair
->index
;
288 regmap_update_bits(asrc
->regmap
, REG_ASRMCR(index
),
289 ASRMCRi_EXTTHRSHi_MASK
|
290 ASRMCRi_INFIFO_THRESHOLD_MASK
|
291 ASRMCRi_OUTFIFO_THRESHOLD_MASK
,
293 ASRMCRi_INFIFO_THRESHOLD(in
) |
294 ASRMCRi_OUTFIFO_THRESHOLD(out
));
298 * fsl_asrc_cal_asrck_divisor - Calculate the total divisor between asrck clock rate and sample rate
299 * @pair: pointer to pair
302 * It follows the formula clk_rate = samplerate * (2 ^ prescaler) * divider
304 static u32
fsl_asrc_cal_asrck_divisor(struct fsl_asrc_pair
*pair
, u32 div
)
308 /* Calculate the divisors: prescaler [2^0, 2^7], divder [1, 8] */
309 for (ps
= 0; div
> 8; ps
++)
312 return ((div
- 1) << ASRCDRi_AxCPi_WIDTH
) | ps
;
316 * fsl_asrc_set_ideal_ratio - Calculate and set the ratio for Ideal Ratio mode only
317 * @pair: pointer to pair
318 * @inrate: input rate
319 * @outrate: output rate
321 * The ratio is a 32-bit fixed point value with 26 fractional bits.
323 static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair
*pair
,
324 int inrate
, int outrate
)
326 struct fsl_asrc
*asrc
= pair
->asrc
;
327 enum asrc_pair_index index
= pair
->index
;
332 pair_err("output rate should not be zero\n");
336 /* Calculate the intergal part of the ratio */
337 ratio
= (inrate
/ outrate
) << IDEAL_RATIO_DECIMAL_DEPTH
;
339 /* ... and then the 26 depth decimal part */
342 for (i
= 1; i
<= IDEAL_RATIO_DECIMAL_DEPTH
; i
++) {
345 if (inrate
< outrate
)
348 ratio
|= 1 << (IDEAL_RATIO_DECIMAL_DEPTH
- i
);
355 regmap_write(asrc
->regmap
, REG_ASRIDRL(index
), ratio
);
356 regmap_write(asrc
->regmap
, REG_ASRIDRH(index
), ratio
>> 24);
362 * fsl_asrc_config_pair - Configure the assigned ASRC pair
363 * @pair: pointer to pair
364 * @use_ideal_rate: boolean configuration
366 * It configures those ASRC registers according to a configuration instance
367 * of struct asrc_config which includes in/output sample rate, width, channel
368 * and clock settings.
371 * The ideal ratio configuration can work with a flexible clock rate setting.
372 * Using IDEAL_RATIO_RATE gives a faster converting speed but overloads ASRC.
373 * For a regular audio playback, the clock rate should not be slower than an
374 * clock rate aligning with the output sample rate; For a use case requiring
375 * faster conversion, set use_ideal_rate to have the faster speed.
377 static int fsl_asrc_config_pair(struct fsl_asrc_pair
*pair
, bool use_ideal_rate
)
379 struct fsl_asrc_pair_priv
*pair_priv
= pair
->private;
380 struct asrc_config
*config
= pair_priv
->config
;
381 struct fsl_asrc
*asrc
= pair
->asrc
;
382 struct fsl_asrc_priv
*asrc_priv
= asrc
->private;
383 enum asrc_pair_index index
= pair
->index
;
384 enum asrc_word_width input_word_width
;
385 enum asrc_word_width output_word_width
;
386 u32 inrate
, outrate
, indiv
, outdiv
;
387 u32 clk_index
[2], div
[2];
389 int in
, out
, channels
;
390 int pre_proc
, post_proc
;
392 bool ideal
, div_avail
;
395 pair_err("invalid pair config\n");
399 /* Validate channels */
400 if (config
->channel_num
< 1 || config
->channel_num
> 10) {
401 pair_err("does not support %d channels\n", config
->channel_num
);
405 switch (snd_pcm_format_width(config
->input_format
)) {
407 input_word_width
= ASRC_WIDTH_8_BIT
;
410 input_word_width
= ASRC_WIDTH_16_BIT
;
413 input_word_width
= ASRC_WIDTH_24_BIT
;
416 pair_err("does not support this input format, %d\n",
417 config
->input_format
);
421 switch (snd_pcm_format_width(config
->output_format
)) {
423 output_word_width
= ASRC_WIDTH_16_BIT
;
426 output_word_width
= ASRC_WIDTH_24_BIT
;
429 pair_err("does not support this output format, %d\n",
430 config
->output_format
);
434 inrate
= config
->input_sample_rate
;
435 outrate
= config
->output_sample_rate
;
436 ideal
= config
->inclk
== INCLK_NONE
;
438 /* Validate input and output sample rates */
439 for (in
= 0; in
< ARRAY_SIZE(supported_asrc_rate
); in
++)
440 if (inrate
== supported_asrc_rate
[in
])
443 if (in
== ARRAY_SIZE(supported_asrc_rate
)) {
444 pair_err("unsupported input sample rate: %dHz\n", inrate
);
448 for (out
= 0; out
< ARRAY_SIZE(supported_asrc_rate
); out
++)
449 if (outrate
== supported_asrc_rate
[out
])
452 if (out
== ARRAY_SIZE(supported_asrc_rate
)) {
453 pair_err("unsupported output sample rate: %dHz\n", outrate
);
457 if ((outrate
>= 5512 && outrate
<= 30000) &&
458 (outrate
> 24 * inrate
|| inrate
> 8 * outrate
)) {
459 pair_err("exceed supported ratio range [1/24, 8] for \
460 inrate/outrate: %d/%d\n", inrate
, outrate
);
464 /* Validate input and output clock sources */
465 clk_index
[IN
] = asrc_priv
->clk_map
[IN
][config
->inclk
];
466 clk_index
[OUT
] = asrc_priv
->clk_map
[OUT
][config
->outclk
];
468 /* We only have output clock for ideal ratio mode */
469 clk
= asrc_priv
->asrck_clk
[clk_index
[ideal
? OUT
: IN
]];
471 clk_rate
= clk_get_rate(clk
);
472 div_avail
= fsl_asrc_divider_avail(clk_rate
, inrate
, &div
[IN
]);
475 * The divider range is [1, 1024], defined by the hardware. For non-
476 * ideal ratio configuration, clock rate has to be strictly aligned
477 * with the sample rate. For ideal ratio configuration, clock rates
478 * only result in different converting speeds. So remainder does not
479 * matter, as long as we keep the divider within its valid range.
481 if (div
[IN
] == 0 || (!ideal
&& !div_avail
)) {
482 pair_err("failed to support input sample rate %dHz by asrck_%x\n",
483 inrate
, clk_index
[ideal
? OUT
: IN
]);
487 div
[IN
] = min_t(u32
, 1024, div
[IN
]);
489 clk
= asrc_priv
->asrck_clk
[clk_index
[OUT
]];
490 clk_rate
= clk_get_rate(clk
);
491 if (ideal
&& use_ideal_rate
)
492 div_avail
= fsl_asrc_divider_avail(clk_rate
, IDEAL_RATIO_RATE
, &div
[OUT
]);
494 div_avail
= fsl_asrc_divider_avail(clk_rate
, outrate
, &div
[OUT
]);
496 /* Output divider has the same limitation as the input one */
497 if (div
[OUT
] == 0 || (!ideal
&& !div_avail
)) {
498 pair_err("failed to support output sample rate %dHz by asrck_%x\n",
499 outrate
, clk_index
[OUT
]);
503 div
[OUT
] = min_t(u32
, 1024, div
[OUT
]);
505 /* Set the channel number */
506 channels
= config
->channel_num
;
508 if (asrc_priv
->soc
->channel_bits
< 4)
511 /* Update channels for current pair */
512 regmap_update_bits(asrc
->regmap
, REG_ASRCNCR
,
513 ASRCNCR_ANCi_MASK(index
, asrc_priv
->soc
->channel_bits
),
514 ASRCNCR_ANCi(index
, channels
, asrc_priv
->soc
->channel_bits
));
516 /* Default setting: Automatic selection for processing mode */
517 regmap_update_bits(asrc
->regmap
, REG_ASRCTR
,
518 ASRCTR_ATSi_MASK(index
), ASRCTR_ATS(index
));
519 regmap_update_bits(asrc
->regmap
, REG_ASRCTR
,
520 ASRCTR_USRi_MASK(index
), 0);
522 /* Set the input and output clock sources */
523 regmap_update_bits(asrc
->regmap
, REG_ASRCSR
,
524 ASRCSR_AICSi_MASK(index
) | ASRCSR_AOCSi_MASK(index
),
525 ASRCSR_AICS(index
, clk_index
[IN
]) |
526 ASRCSR_AOCS(index
, clk_index
[OUT
]));
528 /* Calculate the input clock divisors */
529 indiv
= fsl_asrc_cal_asrck_divisor(pair
, div
[IN
]);
530 outdiv
= fsl_asrc_cal_asrck_divisor(pair
, div
[OUT
]);
532 /* Suppose indiv and outdiv includes prescaler, so add its MASK too */
533 regmap_update_bits(asrc
->regmap
, REG_ASRCDR(index
),
534 ASRCDRi_AOCPi_MASK(index
) | ASRCDRi_AICPi_MASK(index
) |
535 ASRCDRi_AOCDi_MASK(index
) | ASRCDRi_AICDi_MASK(index
),
536 ASRCDRi_AOCP(index
, outdiv
) | ASRCDRi_AICP(index
, indiv
));
538 /* Implement word_width configurations */
539 regmap_update_bits(asrc
->regmap
, REG_ASRMCR1(index
),
540 ASRMCR1i_OW16_MASK
| ASRMCR1i_IWD_MASK
,
541 ASRMCR1i_OW16(output_word_width
) |
542 ASRMCR1i_IWD(input_word_width
));
544 /* Enable BUFFER STALL */
545 regmap_update_bits(asrc
->regmap
, REG_ASRMCR(index
),
546 ASRMCRi_BUFSTALLi_MASK
, ASRMCRi_BUFSTALLi
);
548 /* Set default thresholds for input and output FIFO */
549 fsl_asrc_set_watermarks(pair
, ASRC_INPUTFIFO_THRESHOLD
,
550 ASRC_INPUTFIFO_THRESHOLD
);
552 /* Configure the following only for Ideal Ratio mode */
556 /* Clear ASTSx bit to use Ideal Ratio mode */
557 regmap_update_bits(asrc
->regmap
, REG_ASRCTR
,
558 ASRCTR_ATSi_MASK(index
), 0);
560 /* Enable Ideal Ratio mode */
561 regmap_update_bits(asrc
->regmap
, REG_ASRCTR
,
562 ASRCTR_IDRi_MASK(index
) | ASRCTR_USRi_MASK(index
),
563 ASRCTR_IDR(index
) | ASRCTR_USR(index
));
565 fsl_asrc_sel_proc(inrate
, outrate
, &pre_proc
, &post_proc
);
567 /* Apply configurations for pre- and post-processing */
568 regmap_update_bits(asrc
->regmap
, REG_ASRCFG
,
569 ASRCFG_PREMODi_MASK(index
) | ASRCFG_POSTMODi_MASK(index
),
570 ASRCFG_PREMOD(index
, pre_proc
) |
571 ASRCFG_POSTMOD(index
, post_proc
));
573 return fsl_asrc_set_ideal_ratio(pair
, inrate
, outrate
);
577 * fsl_asrc_start_pair - Start the assigned ASRC pair
578 * @pair: pointer to pair
580 * It enables the assigned pair and makes it stopped at the stall level.
582 static void fsl_asrc_start_pair(struct fsl_asrc_pair
*pair
)
584 struct fsl_asrc
*asrc
= pair
->asrc
;
585 enum asrc_pair_index index
= pair
->index
;
586 int reg
, retry
= INIT_RETRY_NUM
, i
;
588 /* Enable the current pair */
589 regmap_update_bits(asrc
->regmap
, REG_ASRCTR
,
590 ASRCTR_ASRCEi_MASK(index
), ASRCTR_ASRCE(index
));
592 /* Wait for status of initialization */
595 regmap_read(asrc
->regmap
, REG_ASRCFG
, ®
);
596 reg
&= ASRCFG_INIRQi_MASK(index
);
597 } while (!reg
&& --retry
);
599 /* NOTE: Doesn't treat initialization timeout as an error */
601 pair_warn("initialization isn't finished\n");
603 /* Make the input fifo to ASRC STALL level */
604 regmap_read(asrc
->regmap
, REG_ASRCNCR
, ®
);
605 for (i
= 0; i
< pair
->channels
* 4; i
++)
606 regmap_write(asrc
->regmap
, REG_ASRDI(index
), 0);
608 /* Enable overload interrupt */
609 regmap_write(asrc
->regmap
, REG_ASRIER
, ASRIER_AOLIE
);
613 * fsl_asrc_stop_pair - Stop the assigned ASRC pair
614 * @pair: pointer to pair
616 static void fsl_asrc_stop_pair(struct fsl_asrc_pair
*pair
)
618 struct fsl_asrc
*asrc
= pair
->asrc
;
619 enum asrc_pair_index index
= pair
->index
;
621 /* Stop the current pair */
622 regmap_update_bits(asrc
->regmap
, REG_ASRCTR
,
623 ASRCTR_ASRCEi_MASK(index
), 0);
627 * fsl_asrc_get_dma_channel- Get DMA channel according to the pair and direction.
628 * @pair: pointer to pair
629 * @dir: DMA direction
631 static struct dma_chan
*fsl_asrc_get_dma_channel(struct fsl_asrc_pair
*pair
,
634 struct fsl_asrc
*asrc
= pair
->asrc
;
635 enum asrc_pair_index index
= pair
->index
;
638 sprintf(name
, "%cx%c", dir
== IN
? 'r' : 't', index
+ 'a');
640 return dma_request_slave_channel(&asrc
->pdev
->dev
, name
);
643 static int fsl_asrc_dai_startup(struct snd_pcm_substream
*substream
,
644 struct snd_soc_dai
*dai
)
646 struct fsl_asrc
*asrc
= snd_soc_dai_get_drvdata(dai
);
647 struct fsl_asrc_priv
*asrc_priv
= asrc
->private;
649 /* Odd channel number is not valid for older ASRC (channel_bits==3) */
650 if (asrc_priv
->soc
->channel_bits
== 3)
651 snd_pcm_hw_constraint_step(substream
->runtime
, 0,
652 SNDRV_PCM_HW_PARAM_CHANNELS
, 2);
655 return snd_pcm_hw_constraint_list(substream
->runtime
, 0,
656 SNDRV_PCM_HW_PARAM_RATE
, &fsl_asrc_rate_constraints
);
659 /* Select proper clock source for internal ratio mode */
660 static void fsl_asrc_select_clk(struct fsl_asrc_priv
*asrc_priv
,
661 struct fsl_asrc_pair
*pair
,
665 struct fsl_asrc_pair_priv
*pair_priv
= pair
->private;
666 struct asrc_config
*config
= pair_priv
->config
;
667 int rate
[2], select_clk
[2]; /* Array size 2 means IN and OUT */
668 int clk_rate
, clk_index
;
672 rate
[OUT
] = out_rate
;
674 /* Select proper clock source for internal ratio mode */
675 for (j
= 0; j
< 2; j
++) {
676 for (i
= 0; i
< ASRC_CLK_MAP_LEN
; i
++) {
677 clk_index
= asrc_priv
->clk_map
[j
][i
];
678 clk_rate
= clk_get_rate(asrc_priv
->asrck_clk
[clk_index
]);
679 /* Only match a perfect clock source with no remainder */
680 if (fsl_asrc_divider_avail(clk_rate
, rate
[j
], NULL
))
687 /* Switch to ideal ratio mode if there is no proper clock source */
688 if (select_clk
[IN
] == ASRC_CLK_MAP_LEN
|| select_clk
[OUT
] == ASRC_CLK_MAP_LEN
) {
689 select_clk
[IN
] = INCLK_NONE
;
690 select_clk
[OUT
] = OUTCLK_ASRCK1_CLK
;
693 config
->inclk
= select_clk
[IN
];
694 config
->outclk
= select_clk
[OUT
];
697 static int fsl_asrc_dai_hw_params(struct snd_pcm_substream
*substream
,
698 struct snd_pcm_hw_params
*params
,
699 struct snd_soc_dai
*dai
)
701 struct fsl_asrc
*asrc
= snd_soc_dai_get_drvdata(dai
);
702 struct fsl_asrc_priv
*asrc_priv
= asrc
->private;
703 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
704 struct fsl_asrc_pair
*pair
= runtime
->private_data
;
705 struct fsl_asrc_pair_priv
*pair_priv
= pair
->private;
706 unsigned int channels
= params_channels(params
);
707 unsigned int rate
= params_rate(params
);
708 struct asrc_config config
;
711 ret
= fsl_asrc_request_pair(channels
, pair
);
713 dev_err(dai
->dev
, "fail to request asrc pair\n");
717 pair_priv
->config
= &config
;
719 config
.pair
= pair
->index
;
720 config
.channel_num
= channels
;
722 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
723 config
.input_format
= params_format(params
);
724 config
.output_format
= asrc
->asrc_format
;
725 config
.input_sample_rate
= rate
;
726 config
.output_sample_rate
= asrc
->asrc_rate
;
728 config
.input_format
= asrc
->asrc_format
;
729 config
.output_format
= params_format(params
);
730 config
.input_sample_rate
= asrc
->asrc_rate
;
731 config
.output_sample_rate
= rate
;
734 fsl_asrc_select_clk(asrc_priv
, pair
,
735 config
.input_sample_rate
,
736 config
.output_sample_rate
);
738 ret
= fsl_asrc_config_pair(pair
, false);
740 dev_err(dai
->dev
, "fail to config asrc pair\n");
747 static int fsl_asrc_dai_hw_free(struct snd_pcm_substream
*substream
,
748 struct snd_soc_dai
*dai
)
750 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
751 struct fsl_asrc_pair
*pair
= runtime
->private_data
;
754 fsl_asrc_release_pair(pair
);
759 static int fsl_asrc_dai_trigger(struct snd_pcm_substream
*substream
, int cmd
,
760 struct snd_soc_dai
*dai
)
762 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
763 struct fsl_asrc_pair
*pair
= runtime
->private_data
;
766 case SNDRV_PCM_TRIGGER_START
:
767 case SNDRV_PCM_TRIGGER_RESUME
:
768 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
769 fsl_asrc_start_pair(pair
);
771 case SNDRV_PCM_TRIGGER_STOP
:
772 case SNDRV_PCM_TRIGGER_SUSPEND
:
773 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
774 fsl_asrc_stop_pair(pair
);
783 static int fsl_asrc_dai_probe(struct snd_soc_dai
*dai
)
785 struct fsl_asrc
*asrc
= snd_soc_dai_get_drvdata(dai
);
787 snd_soc_dai_init_dma_data(dai
, &asrc
->dma_params_tx
,
788 &asrc
->dma_params_rx
);
793 static const struct snd_soc_dai_ops fsl_asrc_dai_ops
= {
794 .probe
= fsl_asrc_dai_probe
,
795 .startup
= fsl_asrc_dai_startup
,
796 .hw_params
= fsl_asrc_dai_hw_params
,
797 .hw_free
= fsl_asrc_dai_hw_free
,
798 .trigger
= fsl_asrc_dai_trigger
,
801 #define FSL_ASRC_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | \
802 SNDRV_PCM_FMTBIT_S16_LE | \
803 SNDRV_PCM_FMTBIT_S24_3LE)
805 static struct snd_soc_dai_driver fsl_asrc_dai
= {
807 .stream_name
= "ASRC-Playback",
812 .rates
= SNDRV_PCM_RATE_KNOT
,
813 .formats
= FSL_ASRC_FORMATS
|
817 .stream_name
= "ASRC-Capture",
822 .rates
= SNDRV_PCM_RATE_KNOT
,
823 .formats
= FSL_ASRC_FORMATS
,
825 .ops
= &fsl_asrc_dai_ops
,
828 static bool fsl_asrc_readable_reg(struct device
*dev
, unsigned int reg
)
872 static bool fsl_asrc_volatile_reg(struct device
*dev
, unsigned int reg
)
892 static bool fsl_asrc_writeable_reg(struct device
*dev
, unsigned int reg
)
933 static struct reg_default fsl_asrc_reg
[] = {
934 { REG_ASRCTR
, 0x0000 }, { REG_ASRIER
, 0x0000 },
935 { REG_ASRCNCR
, 0x0000 }, { REG_ASRCFG
, 0x0000 },
936 { REG_ASRCSR
, 0x0000 }, { REG_ASRCDR1
, 0x0000 },
937 { REG_ASRCDR2
, 0x0000 }, { REG_ASRSTR
, 0x0000 },
938 { REG_ASRRA
, 0x0000 }, { REG_ASRRB
, 0x0000 },
939 { REG_ASRRC
, 0x0000 }, { REG_ASRPM1
, 0x0000 },
940 { REG_ASRPM2
, 0x0000 }, { REG_ASRPM3
, 0x0000 },
941 { REG_ASRPM4
, 0x0000 }, { REG_ASRPM5
, 0x0000 },
942 { REG_ASRTFR1
, 0x0000 }, { REG_ASRCCR
, 0x0000 },
943 { REG_ASRDIA
, 0x0000 }, { REG_ASRDOA
, 0x0000 },
944 { REG_ASRDIB
, 0x0000 }, { REG_ASRDOB
, 0x0000 },
945 { REG_ASRDIC
, 0x0000 }, { REG_ASRDOC
, 0x0000 },
946 { REG_ASRIDRHA
, 0x0000 }, { REG_ASRIDRLA
, 0x0000 },
947 { REG_ASRIDRHB
, 0x0000 }, { REG_ASRIDRLB
, 0x0000 },
948 { REG_ASRIDRHC
, 0x0000 }, { REG_ASRIDRLC
, 0x0000 },
949 { REG_ASR76K
, 0x0A47 }, { REG_ASR56K
, 0x0DF3 },
950 { REG_ASRMCRA
, 0x0000 }, { REG_ASRFSTA
, 0x0000 },
951 { REG_ASRMCRB
, 0x0000 }, { REG_ASRFSTB
, 0x0000 },
952 { REG_ASRMCRC
, 0x0000 }, { REG_ASRFSTC
, 0x0000 },
953 { REG_ASRMCR1A
, 0x0000 }, { REG_ASRMCR1B
, 0x0000 },
954 { REG_ASRMCR1C
, 0x0000 },
957 static const struct regmap_config fsl_asrc_regmap_config
= {
962 .max_register
= REG_ASRMCR1C
,
963 .reg_defaults
= fsl_asrc_reg
,
964 .num_reg_defaults
= ARRAY_SIZE(fsl_asrc_reg
),
965 .readable_reg
= fsl_asrc_readable_reg
,
966 .volatile_reg
= fsl_asrc_volatile_reg
,
967 .writeable_reg
= fsl_asrc_writeable_reg
,
968 .cache_type
= REGCACHE_FLAT
,
972 * fsl_asrc_init - Initialize ASRC registers with a default configuration
973 * @asrc: ASRC context
975 static int fsl_asrc_init(struct fsl_asrc
*asrc
)
977 unsigned long ipg_rate
;
979 /* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
980 regmap_write(asrc
->regmap
, REG_ASRCTR
, ASRCTR_ASRCEN
);
982 /* Disable interrupt by default */
983 regmap_write(asrc
->regmap
, REG_ASRIER
, 0x0);
985 /* Apply recommended settings for parameters from Reference Manual */
986 regmap_write(asrc
->regmap
, REG_ASRPM1
, 0x7fffff);
987 regmap_write(asrc
->regmap
, REG_ASRPM2
, 0x255555);
988 regmap_write(asrc
->regmap
, REG_ASRPM3
, 0xff7280);
989 regmap_write(asrc
->regmap
, REG_ASRPM4
, 0xff7280);
990 regmap_write(asrc
->regmap
, REG_ASRPM5
, 0xff7280);
992 /* Base address for task queue FIFO. Set to 0x7C */
993 regmap_update_bits(asrc
->regmap
, REG_ASRTFR1
,
994 ASRTFR1_TF_BASE_MASK
, ASRTFR1_TF_BASE(0xfc));
997 * Set the period of the 76KHz and 56KHz sampling clocks based on
998 * the ASRC processing clock.
999 * On iMX6, ipg_clk = 133MHz, REG_ASR76K = 0x06D6, REG_ASR56K = 0x0947
1001 ipg_rate
= clk_get_rate(asrc
->ipg_clk
);
1002 regmap_write(asrc
->regmap
, REG_ASR76K
, ipg_rate
/ 76000);
1003 return regmap_write(asrc
->regmap
, REG_ASR56K
, ipg_rate
/ 56000);
1007 * fsl_asrc_isr- Interrupt handler for ASRC
1009 * @dev_id: ASRC context
1011 static irqreturn_t
fsl_asrc_isr(int irq
, void *dev_id
)
1013 struct fsl_asrc
*asrc
= (struct fsl_asrc
*)dev_id
;
1014 struct device
*dev
= &asrc
->pdev
->dev
;
1015 enum asrc_pair_index index
;
1018 regmap_read(asrc
->regmap
, REG_ASRSTR
, &status
);
1020 /* Clean overload error */
1021 regmap_write(asrc
->regmap
, REG_ASRSTR
, ASRSTR_AOLE
);
1024 * We here use dev_dbg() for all exceptions because ASRC itself does
1025 * not care if FIFO overflowed or underrun while a warning in the
1026 * interrupt would result a ridged conversion.
1028 for (index
= ASRC_PAIR_A
; index
< ASRC_PAIR_MAX_NUM
; index
++) {
1029 if (!asrc
->pair
[index
])
1032 if (status
& ASRSTR_ATQOL
) {
1033 asrc
->pair
[index
]->error
|= ASRC_TASK_Q_OVERLOAD
;
1034 dev_dbg(dev
, "ASRC Task Queue FIFO overload\n");
1037 if (status
& ASRSTR_AOOL(index
)) {
1038 asrc
->pair
[index
]->error
|= ASRC_OUTPUT_TASK_OVERLOAD
;
1039 pair_dbg("Output Task Overload\n");
1042 if (status
& ASRSTR_AIOL(index
)) {
1043 asrc
->pair
[index
]->error
|= ASRC_INPUT_TASK_OVERLOAD
;
1044 pair_dbg("Input Task Overload\n");
1047 if (status
& ASRSTR_AODO(index
)) {
1048 asrc
->pair
[index
]->error
|= ASRC_OUTPUT_BUFFER_OVERFLOW
;
1049 pair_dbg("Output Data Buffer has overflowed\n");
1052 if (status
& ASRSTR_AIDU(index
)) {
1053 asrc
->pair
[index
]->error
|= ASRC_INPUT_BUFFER_UNDERRUN
;
1054 pair_dbg("Input Data Buffer has underflowed\n");
1061 static int fsl_asrc_get_fifo_addr(u8 dir
, enum asrc_pair_index index
)
1063 return REG_ASRDx(dir
, index
);
1066 static int fsl_asrc_runtime_resume(struct device
*dev
);
1067 static int fsl_asrc_runtime_suspend(struct device
*dev
);
1069 static int fsl_asrc_probe(struct platform_device
*pdev
)
1071 struct device_node
*np
= pdev
->dev
.of_node
;
1072 struct fsl_asrc_priv
*asrc_priv
;
1073 struct fsl_asrc
*asrc
;
1074 struct resource
*res
;
1082 asrc
= devm_kzalloc(&pdev
->dev
, sizeof(*asrc
), GFP_KERNEL
);
1086 asrc_priv
= devm_kzalloc(&pdev
->dev
, sizeof(*asrc_priv
), GFP_KERNEL
);
1091 asrc
->private = asrc_priv
;
1093 /* Get the addresses and IRQ */
1094 regs
= devm_platform_get_and_ioremap_resource(pdev
, 0, &res
);
1096 return PTR_ERR(regs
);
1098 asrc
->paddr
= res
->start
;
1100 asrc
->regmap
= devm_regmap_init_mmio(&pdev
->dev
, regs
, &fsl_asrc_regmap_config
);
1101 if (IS_ERR(asrc
->regmap
)) {
1102 dev_err(&pdev
->dev
, "failed to init regmap\n");
1103 return PTR_ERR(asrc
->regmap
);
1106 irq
= platform_get_irq(pdev
, 0);
1110 ret
= devm_request_irq(&pdev
->dev
, irq
, fsl_asrc_isr
, 0,
1111 dev_name(&pdev
->dev
), asrc
);
1113 dev_err(&pdev
->dev
, "failed to claim irq %u: %d\n", irq
, ret
);
1117 asrc
->mem_clk
= devm_clk_get(&pdev
->dev
, "mem");
1118 if (IS_ERR(asrc
->mem_clk
)) {
1119 dev_err(&pdev
->dev
, "failed to get mem clock\n");
1120 return PTR_ERR(asrc
->mem_clk
);
1123 asrc
->ipg_clk
= devm_clk_get(&pdev
->dev
, "ipg");
1124 if (IS_ERR(asrc
->ipg_clk
)) {
1125 dev_err(&pdev
->dev
, "failed to get ipg clock\n");
1126 return PTR_ERR(asrc
->ipg_clk
);
1129 asrc
->spba_clk
= devm_clk_get(&pdev
->dev
, "spba");
1130 if (IS_ERR(asrc
->spba_clk
))
1131 dev_warn(&pdev
->dev
, "failed to get spba clock\n");
1133 for (i
= 0; i
< ASRC_CLK_MAX_NUM
; i
++) {
1134 sprintf(tmp
, "asrck_%x", i
);
1135 asrc_priv
->asrck_clk
[i
] = devm_clk_get(&pdev
->dev
, tmp
);
1136 if (IS_ERR(asrc_priv
->asrck_clk
[i
])) {
1137 dev_err(&pdev
->dev
, "failed to get %s clock\n", tmp
);
1138 return PTR_ERR(asrc_priv
->asrck_clk
[i
]);
1142 asrc_priv
->soc
= of_device_get_match_data(&pdev
->dev
);
1143 asrc
->use_edma
= asrc_priv
->soc
->use_edma
;
1144 asrc
->get_dma_channel
= fsl_asrc_get_dma_channel
;
1145 asrc
->request_pair
= fsl_asrc_request_pair
;
1146 asrc
->release_pair
= fsl_asrc_release_pair
;
1147 asrc
->get_fifo_addr
= fsl_asrc_get_fifo_addr
;
1148 asrc
->pair_priv_size
= sizeof(struct fsl_asrc_pair_priv
);
1150 if (of_device_is_compatible(np
, "fsl,imx35-asrc")) {
1151 asrc_priv
->clk_map
[IN
] = input_clk_map_imx35
;
1152 asrc_priv
->clk_map
[OUT
] = output_clk_map_imx35
;
1153 } else if (of_device_is_compatible(np
, "fsl,imx53-asrc")) {
1154 asrc_priv
->clk_map
[IN
] = input_clk_map_imx53
;
1155 asrc_priv
->clk_map
[OUT
] = output_clk_map_imx53
;
1156 } else if (of_device_is_compatible(np
, "fsl,imx8qm-asrc") ||
1157 of_device_is_compatible(np
, "fsl,imx8qxp-asrc")) {
1158 ret
= of_property_read_u32(np
, "fsl,asrc-clk-map", &map_idx
);
1160 dev_err(&pdev
->dev
, "failed to get clk map index\n");
1165 dev_err(&pdev
->dev
, "unsupported clk map index\n");
1168 if (of_device_is_compatible(np
, "fsl,imx8qm-asrc")) {
1169 asrc_priv
->clk_map
[IN
] = clk_map_imx8qm
[map_idx
];
1170 asrc_priv
->clk_map
[OUT
] = clk_map_imx8qm
[map_idx
];
1172 asrc_priv
->clk_map
[IN
] = clk_map_imx8qxp
[map_idx
];
1173 asrc_priv
->clk_map
[OUT
] = clk_map_imx8qxp
[map_idx
];
1177 asrc
->channel_avail
= 10;
1179 ret
= of_property_read_u32(np
, "fsl,asrc-rate",
1182 dev_err(&pdev
->dev
, "failed to get output rate\n");
1186 ret
= of_property_read_u32(np
, "fsl,asrc-format", &asrc_fmt
);
1187 asrc
->asrc_format
= (__force snd_pcm_format_t
)asrc_fmt
;
1189 ret
= of_property_read_u32(np
, "fsl,asrc-width", &width
);
1191 dev_err(&pdev
->dev
, "failed to decide output format\n");
1197 asrc
->asrc_format
= SNDRV_PCM_FORMAT_S16_LE
;
1200 asrc
->asrc_format
= SNDRV_PCM_FORMAT_S24_LE
;
1203 dev_warn(&pdev
->dev
,
1204 "unsupported width, use default S24_LE\n");
1205 asrc
->asrc_format
= SNDRV_PCM_FORMAT_S24_LE
;
1210 if (!(FSL_ASRC_FORMATS
& pcm_format_to_bits(asrc
->asrc_format
))) {
1211 dev_warn(&pdev
->dev
, "unsupported width, use default S24_LE\n");
1212 asrc
->asrc_format
= SNDRV_PCM_FORMAT_S24_LE
;
1215 platform_set_drvdata(pdev
, asrc
);
1216 spin_lock_init(&asrc
->lock
);
1217 pm_runtime_enable(&pdev
->dev
);
1218 if (!pm_runtime_enabled(&pdev
->dev
)) {
1219 ret
= fsl_asrc_runtime_resume(&pdev
->dev
);
1221 goto err_pm_disable
;
1224 ret
= pm_runtime_resume_and_get(&pdev
->dev
);
1226 goto err_pm_get_sync
;
1228 ret
= fsl_asrc_init(asrc
);
1230 dev_err(&pdev
->dev
, "failed to init asrc %d\n", ret
);
1231 goto err_pm_get_sync
;
1234 ret
= pm_runtime_put_sync(&pdev
->dev
);
1235 if (ret
< 0 && ret
!= -ENOSYS
)
1236 goto err_pm_get_sync
;
1238 ret
= devm_snd_soc_register_component(&pdev
->dev
, &fsl_asrc_component
,
1241 dev_err(&pdev
->dev
, "failed to register ASoC DAI\n");
1242 goto err_pm_get_sync
;
1248 if (!pm_runtime_status_suspended(&pdev
->dev
))
1249 fsl_asrc_runtime_suspend(&pdev
->dev
);
1251 pm_runtime_disable(&pdev
->dev
);
1255 static void fsl_asrc_remove(struct platform_device
*pdev
)
1257 pm_runtime_disable(&pdev
->dev
);
1258 if (!pm_runtime_status_suspended(&pdev
->dev
))
1259 fsl_asrc_runtime_suspend(&pdev
->dev
);
1262 static int fsl_asrc_runtime_resume(struct device
*dev
)
1264 struct fsl_asrc
*asrc
= dev_get_drvdata(dev
);
1265 struct fsl_asrc_priv
*asrc_priv
= asrc
->private;
1266 int reg
, retry
= INIT_RETRY_NUM
;
1270 ret
= clk_prepare_enable(asrc
->mem_clk
);
1273 ret
= clk_prepare_enable(asrc
->ipg_clk
);
1275 goto disable_mem_clk
;
1276 if (!IS_ERR(asrc
->spba_clk
)) {
1277 ret
= clk_prepare_enable(asrc
->spba_clk
);
1279 goto disable_ipg_clk
;
1281 for (i
= 0; i
< ASRC_CLK_MAX_NUM
; i
++) {
1282 ret
= clk_prepare_enable(asrc_priv
->asrck_clk
[i
]);
1284 goto disable_asrck_clk
;
1287 /* Stop all pairs provisionally */
1288 regmap_read(asrc
->regmap
, REG_ASRCTR
, &asrctr
);
1289 regmap_update_bits(asrc
->regmap
, REG_ASRCTR
,
1290 ASRCTR_ASRCEi_ALL_MASK
, 0);
1292 /* Restore all registers */
1293 regcache_cache_only(asrc
->regmap
, false);
1294 regcache_mark_dirty(asrc
->regmap
);
1295 regcache_sync(asrc
->regmap
);
1297 regmap_update_bits(asrc
->regmap
, REG_ASRCFG
,
1298 ASRCFG_NDPRi_ALL_MASK
| ASRCFG_POSTMODi_ALL_MASK
|
1299 ASRCFG_PREMODi_ALL_MASK
, asrc_priv
->regcache_cfg
);
1301 /* Restart enabled pairs */
1302 regmap_update_bits(asrc
->regmap
, REG_ASRCTR
,
1303 ASRCTR_ASRCEi_ALL_MASK
, asrctr
);
1305 /* Wait for status of initialization for all enabled pairs */
1308 regmap_read(asrc
->regmap
, REG_ASRCFG
, ®
);
1309 reg
= (reg
>> ASRCFG_INIRQi_SHIFT(0)) & 0x7;
1310 } while ((reg
!= ((asrctr
>> ASRCTR_ASRCEi_SHIFT(0)) & 0x7)) && --retry
);
1313 * NOTE: Doesn't treat initialization timeout as an error
1314 * Some of the pairs may success, then still can continue.
1317 for (i
= ASRC_PAIR_A
; i
< ASRC_PAIR_MAX_NUM
; i
++) {
1318 if ((asrctr
& ASRCTR_ASRCEi_MASK(i
)) && !(reg
& (1 << i
)))
1319 dev_warn(dev
, "Pair %c initialization isn't finished\n", 'A' + i
);
1326 for (i
--; i
>= 0; i
--)
1327 clk_disable_unprepare(asrc_priv
->asrck_clk
[i
]);
1328 if (!IS_ERR(asrc
->spba_clk
))
1329 clk_disable_unprepare(asrc
->spba_clk
);
1331 clk_disable_unprepare(asrc
->ipg_clk
);
1333 clk_disable_unprepare(asrc
->mem_clk
);
1337 static int fsl_asrc_runtime_suspend(struct device
*dev
)
1339 struct fsl_asrc
*asrc
= dev_get_drvdata(dev
);
1340 struct fsl_asrc_priv
*asrc_priv
= asrc
->private;
1343 regmap_read(asrc
->regmap
, REG_ASRCFG
,
1344 &asrc_priv
->regcache_cfg
);
1346 regcache_cache_only(asrc
->regmap
, true);
1348 for (i
= 0; i
< ASRC_CLK_MAX_NUM
; i
++)
1349 clk_disable_unprepare(asrc_priv
->asrck_clk
[i
]);
1350 if (!IS_ERR(asrc
->spba_clk
))
1351 clk_disable_unprepare(asrc
->spba_clk
);
1352 clk_disable_unprepare(asrc
->ipg_clk
);
1353 clk_disable_unprepare(asrc
->mem_clk
);
1358 static const struct dev_pm_ops fsl_asrc_pm
= {
1359 SET_RUNTIME_PM_OPS(fsl_asrc_runtime_suspend
, fsl_asrc_runtime_resume
, NULL
)
1360 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
1361 pm_runtime_force_resume
)
1364 static const struct fsl_asrc_soc_data fsl_asrc_imx35_data
= {
1369 static const struct fsl_asrc_soc_data fsl_asrc_imx53_data
= {
1374 static const struct fsl_asrc_soc_data fsl_asrc_imx8qm_data
= {
1379 static const struct fsl_asrc_soc_data fsl_asrc_imx8qxp_data
= {
1384 static const struct of_device_id fsl_asrc_ids
[] = {
1385 { .compatible
= "fsl,imx35-asrc", .data
= &fsl_asrc_imx35_data
},
1386 { .compatible
= "fsl,imx53-asrc", .data
= &fsl_asrc_imx53_data
},
1387 { .compatible
= "fsl,imx8qm-asrc", .data
= &fsl_asrc_imx8qm_data
},
1388 { .compatible
= "fsl,imx8qxp-asrc", .data
= &fsl_asrc_imx8qxp_data
},
1391 MODULE_DEVICE_TABLE(of
, fsl_asrc_ids
);
1393 static struct platform_driver fsl_asrc_driver
= {
1394 .probe
= fsl_asrc_probe
,
1395 .remove
= fsl_asrc_remove
,
1398 .of_match_table
= fsl_asrc_ids
,
1402 module_platform_driver(fsl_asrc_driver
);
1404 MODULE_DESCRIPTION("Freescale ASRC ASoC driver");
1405 MODULE_AUTHOR("Nicolin Chen <nicoleotsuka@gmail.com>");
1406 MODULE_ALIAS("platform:fsl-asrc");
1407 MODULE_LICENSE("GPL v2");