Merge tag 'sound-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[linux-block.git] / sound / soc / fsl / fsl_asrc.c
CommitLineData
2ba28053
FE
1// SPDX-License-Identifier: GPL-2.0
2//
3// Freescale ASRC ALSA SoC Digital Audio Interface (DAI) driver
4//
5// Copyright (C) 2014 Freescale Semiconductor, Inc.
6//
7// Author: Nicolin Chen <nicoleotsuka@gmail.com>
3117bb31
NC
8
9#include <linux/clk.h>
10#include <linux/delay.h>
11#include <linux/dma-mapping.h>
12#include <linux/module.h>
13#include <linux/of_platform.h>
c6547c2e 14#include <linux/dma/imx-dma.h>
3117bb31
NC
15#include <linux/pm_runtime.h>
16#include <sound/dmaengine_pcm.h>
17#include <sound/pcm_params.h>
18
19#include "fsl_asrc.h"
20
21#define IDEAL_RATIO_DECIMAL_DEPTH 26
32038634 22#define DIVIDER_NUM 64
d2de3f5e 23#define INIT_RETRY_NUM 50
3117bb31
NC
24
25#define pair_err(fmt, ...) \
7470704d 26 dev_err(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
3117bb31
NC
27
28#define pair_dbg(fmt, ...) \
7470704d 29 dev_dbg(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
3117bb31 30
d2de3f5e
SW
31#define pair_warn(fmt, ...) \
32 dev_warn(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
33
3117bb31 34/* Corresponding to process_option */
d281bf5d
W
35static unsigned int supported_asrc_rate[] = {
36 5512, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
37 64000, 88200, 96000, 128000, 176400, 192000,
3117bb31
NC
38};
39
d281bf5d
W
40static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints = {
41 .count = ARRAY_SIZE(supported_asrc_rate),
42 .list = supported_asrc_rate,
3117bb31
NC
43};
44
45e039d9 45/*
3117bb31
NC
46 * The following tables map the relationship between asrc_inclk/asrc_outclk in
47 * fsl_asrc.h and the registers of ASRCSR
48 */
c05f10f2 49static unsigned char input_clk_map_imx35[ASRC_CLK_MAP_LEN] = {
3117bb31 50 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
c05f10f2
SW
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,
3117bb31
NC
53};
54
c05f10f2 55static unsigned char output_clk_map_imx35[ASRC_CLK_MAP_LEN] = {
3117bb31 56 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
c05f10f2
SW
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,
3117bb31
NC
59};
60
61/* i.MX53 uses the same map for input and output */
c05f10f2 62static unsigned char input_clk_map_imx53[ASRC_CLK_MAP_LEN] = {
3117bb31
NC
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,
c05f10f2
SW
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,
3117bb31
NC
67};
68
c05f10f2 69static unsigned char output_clk_map_imx53[ASRC_CLK_MAP_LEN] = {
3117bb31
NC
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,
c05f10f2
SW
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,
3117bb31
NC
74};
75
45e039d9 76/*
c05f10f2
SW
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
82 */
83static unsigned char clk_map_imx8qm[2][ASRC_CLK_MAP_LEN] = {
84 {
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,
88 },
89 {
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,
93 },
94};
95
96static unsigned char clk_map_imx8qxp[2][ASRC_CLK_MAP_LEN] = {
97 {
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,
101 },
102 {
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,
106 },
107};
3117bb31 108
32038634
SW
109/*
110 * According to RM, the divider range is 1 ~ 8,
111 * prescaler is power of 2 from 1 ~ 128.
112 */
113static 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 */
122};
123
124/*
125 * Check if the divider is available for internal ratio mode
126 */
127static bool fsl_asrc_divider_avail(int clk_rate, int rate, int *div)
128{
129 u32 rem, i;
130 u64 n;
131
132 if (div)
133 *div = 0;
134
135 if (clk_rate == 0 || rate == 0)
136 return false;
137
138 n = clk_rate;
139 rem = do_div(n, rate);
140
141 if (div)
142 *div = n;
143
144 if (rem != 0)
145 return false;
146
147 for (i = 0; i < DIVIDER_NUM; i++) {
148 if (n == asrc_clk_divider[i])
149 break;
150 }
151
152 if (i == DIVIDER_NUM)
153 return false;
154
155 return true;
156}
157
4aecaa0a 158/**
45e039d9
PLB
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
164 *
4aecaa0a
W
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
169 *
4aecaa0a
W
170 */
171static void fsl_asrc_sel_proc(int inrate, int outrate,
172 int *pre_proc, int *post_proc)
173{
174 bool post_proc_cond2;
175 bool post_proc_cond0;
176
177 /* select pre_proc between [0, 2] */
178 if (inrate * 8 > 33 * outrate)
179 *pre_proc = 2;
180 else if (inrate * 8 > 15 * outrate) {
181 if (inrate > 152000)
182 *pre_proc = 2;
183 else
184 *pre_proc = 1;
185 } else if (inrate < 76000)
186 *pre_proc = 0;
187 else if (inrate > 152000)
188 *pre_proc = 2;
189 else
190 *pre_proc = 1;
191
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;
196
197 if (post_proc_cond2)
198 *post_proc = 2;
199 else if (post_proc_cond0)
200 *post_proc = 0;
201 else
202 *post_proc = 1;
203}
204
3117bb31 205/**
45e039d9
PLB
206 * fsl_asrc_request_pair - Request ASRC pair
207 * @channels: number of channels
208 * @pair: pointer to pair
3117bb31
NC
209 *
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.
213 */
c16e923d 214static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
3117bb31
NC
215{
216 enum asrc_pair_index index = ASRC_INVALID_PAIR;
7470704d
SW
217 struct fsl_asrc *asrc = pair->asrc;
218 struct device *dev = &asrc->pdev->dev;
3117bb31
NC
219 unsigned long lock_flags;
220 int i, ret = 0;
221
7470704d 222 spin_lock_irqsave(&asrc->lock, lock_flags);
3117bb31
NC
223
224 for (i = ASRC_PAIR_A; i < ASRC_PAIR_MAX_NUM; i++) {
7470704d 225 if (asrc->pair[i] != NULL)
3117bb31
NC
226 continue;
227
228 index = i;
229
230 if (i != ASRC_PAIR_B)
231 break;
232 }
233
234 if (index == ASRC_INVALID_PAIR) {
235 dev_err(dev, "all pairs are busy now\n");
236 ret = -EBUSY;
7470704d 237 } else if (asrc->channel_avail < channels) {
3117bb31
NC
238 dev_err(dev, "can't afford required channels: %d\n", channels);
239 ret = -EINVAL;
240 } else {
7470704d
SW
241 asrc->channel_avail -= channels;
242 asrc->pair[index] = pair;
3117bb31
NC
243 pair->channels = channels;
244 pair->index = index;
245 }
246
7470704d 247 spin_unlock_irqrestore(&asrc->lock, lock_flags);
3117bb31
NC
248
249 return ret;
250}
251
252/**
45e039d9
PLB
253 * fsl_asrc_release_pair - Release ASRC pair
254 * @pair: pair to release
3117bb31 255 *
7470704d 256 * It clears the resource from asrc and releases the occupied channels.
3117bb31 257 */
c16e923d 258static void fsl_asrc_release_pair(struct fsl_asrc_pair *pair)
3117bb31 259{
7470704d 260 struct fsl_asrc *asrc = pair->asrc;
3117bb31
NC
261 enum asrc_pair_index index = pair->index;
262 unsigned long lock_flags;
263
264 /* Make sure the pair is disabled */
7470704d 265 regmap_update_bits(asrc->regmap, REG_ASRCTR,
3117bb31
NC
266 ASRCTR_ASRCEi_MASK(index), 0);
267
7470704d 268 spin_lock_irqsave(&asrc->lock, lock_flags);
3117bb31 269
7470704d
SW
270 asrc->channel_avail += pair->channels;
271 asrc->pair[index] = NULL;
3117bb31
NC
272 pair->error = 0;
273
7470704d 274 spin_unlock_irqrestore(&asrc->lock, lock_flags);
3117bb31
NC
275}
276
277/**
45e039d9
PLB
278 * fsl_asrc_set_watermarks- configure input and output thresholds
279 * @pair: pointer to pair
280 * @in: input threshold
281 * @out: output threshold
3117bb31
NC
282 */
283static void fsl_asrc_set_watermarks(struct fsl_asrc_pair *pair, u32 in, u32 out)
284{
7470704d 285 struct fsl_asrc *asrc = pair->asrc;
3117bb31
NC
286 enum asrc_pair_index index = pair->index;
287
7470704d 288 regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
3117bb31
NC
289 ASRMCRi_EXTTHRSHi_MASK |
290 ASRMCRi_INFIFO_THRESHOLD_MASK |
291 ASRMCRi_OUTFIFO_THRESHOLD_MASK,
292 ASRMCRi_EXTTHRSHi |
293 ASRMCRi_INFIFO_THRESHOLD(in) |
294 ASRMCRi_OUTFIFO_THRESHOLD(out));
295}
296
297/**
45e039d9
PLB
298 * fsl_asrc_cal_asrck_divisor - Calculate the total divisor between asrck clock rate and sample rate
299 * @pair: pointer to pair
300 * @div: divider
3117bb31
NC
301 *
302 * It follows the formula clk_rate = samplerate * (2 ^ prescaler) * divider
303 */
304static u32 fsl_asrc_cal_asrck_divisor(struct fsl_asrc_pair *pair, u32 div)
305{
306 u32 ps;
307
308 /* Calculate the divisors: prescaler [2^0, 2^7], divder [1, 8] */
309 for (ps = 0; div > 8; ps++)
310 div >>= 1;
311
312 return ((div - 1) << ASRCDRi_AxCPi_WIDTH) | ps;
313}
314
315/**
45e039d9
PLB
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
3117bb31
NC
320 *
321 * The ratio is a 32-bit fixed point value with 26 fractional bits.
322 */
323static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair,
324 int inrate, int outrate)
325{
7470704d 326 struct fsl_asrc *asrc = pair->asrc;
3117bb31
NC
327 enum asrc_pair_index index = pair->index;
328 unsigned long ratio;
329 int i;
330
331 if (!outrate) {
332 pair_err("output rate should not be zero\n");
333 return -EINVAL;
334 }
335
336 /* Calculate the intergal part of the ratio */
337 ratio = (inrate / outrate) << IDEAL_RATIO_DECIMAL_DEPTH;
338
339 /* ... and then the 26 depth decimal part */
340 inrate %= outrate;
341
342 for (i = 1; i <= IDEAL_RATIO_DECIMAL_DEPTH; i++) {
343 inrate <<= 1;
344
345 if (inrate < outrate)
346 continue;
347
348 ratio |= 1 << (IDEAL_RATIO_DECIMAL_DEPTH - i);
349 inrate -= outrate;
350
351 if (!inrate)
352 break;
353 }
354
7470704d
SW
355 regmap_write(asrc->regmap, REG_ASRIDRL(index), ratio);
356 regmap_write(asrc->regmap, REG_ASRIDRH(index), ratio >> 24);
3117bb31
NC
357
358 return 0;
359}
360
361/**
45e039d9
PLB
362 * fsl_asrc_config_pair - Configure the assigned ASRC pair
363 * @pair: pointer to pair
364 * @use_ideal_rate: boolean configuration
3117bb31
NC
365 *
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.
b39eb1e2
SW
369 *
370 * Note:
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.
3117bb31 376 */
b39eb1e2 377static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
3117bb31 378{
be7bd03f
SW
379 struct fsl_asrc_pair_priv *pair_priv = pair->private;
380 struct asrc_config *config = pair_priv->config;
7470704d 381 struct fsl_asrc *asrc = pair->asrc;
be7bd03f 382 struct fsl_asrc_priv *asrc_priv = asrc->private;
3117bb31 383 enum asrc_pair_index index = pair->index;
4bf62571
SW
384 enum asrc_word_width input_word_width;
385 enum asrc_word_width output_word_width;
4e13eb72 386 u32 inrate, outrate, indiv, outdiv;
32038634 387 u32 clk_index[2], div[2];
b39eb1e2 388 u64 clk_rate;
3117bb31 389 int in, out, channels;
4aecaa0a 390 int pre_proc, post_proc;
3117bb31 391 struct clk *clk;
32038634 392 bool ideal, div_avail;
3117bb31
NC
393
394 if (!config) {
395 pair_err("invalid pair config\n");
396 return -EINVAL;
397 }
398
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);
402 return -EINVAL;
403 }
404
4bf62571
SW
405 switch (snd_pcm_format_width(config->input_format)) {
406 case 8:
407 input_word_width = ASRC_WIDTH_8_BIT;
408 break;
409 case 16:
410 input_word_width = ASRC_WIDTH_16_BIT;
411 break;
412 case 24:
413 input_word_width = ASRC_WIDTH_24_BIT;
414 break;
415 default:
416 pair_err("does not support this input format, %d\n",
417 config->input_format);
418 return -EINVAL;
419 }
420
421 switch (snd_pcm_format_width(config->output_format)) {
422 case 16:
423 output_word_width = ASRC_WIDTH_16_BIT;
424 break;
425 case 24:
426 output_word_width = ASRC_WIDTH_24_BIT;
427 break;
428 default:
429 pair_err("does not support this output format, %d\n",
430 config->output_format);
3117bb31
NC
431 return -EINVAL;
432 }
433
4e13eb72
NC
434 inrate = config->input_sample_rate;
435 outrate = config->output_sample_rate;
436 ideal = config->inclk == INCLK_NONE;
437
3117bb31 438 /* Validate input and output sample rates */
d281bf5d
W
439 for (in = 0; in < ARRAY_SIZE(supported_asrc_rate); in++)
440 if (inrate == supported_asrc_rate[in])
3117bb31
NC
441 break;
442
d281bf5d 443 if (in == ARRAY_SIZE(supported_asrc_rate)) {
3117bb31
NC
444 pair_err("unsupported input sample rate: %dHz\n", inrate);
445 return -EINVAL;
446 }
447
448 for (out = 0; out < ARRAY_SIZE(supported_asrc_rate); out++)
449 if (outrate == supported_asrc_rate[out])
450 break;
451
452 if (out == ARRAY_SIZE(supported_asrc_rate)) {
453 pair_err("unsupported output sample rate: %dHz\n", outrate);
454 return -EINVAL;
455 }
456
d281bf5d 457 if ((outrate >= 5512 && outrate <= 30000) &&
b06c58c2 458 (outrate > 24 * inrate || inrate > 8 * outrate)) {
fff6e03c
ZW
459 pair_err("exceed supported ratio range [1/24, 8] for \
460 inrate/outrate: %d/%d\n", inrate, outrate);
461 return -EINVAL;
462 }
463
3117bb31 464 /* Validate input and output clock sources */
be7bd03f
SW
465 clk_index[IN] = asrc_priv->clk_map[IN][config->inclk];
466 clk_index[OUT] = asrc_priv->clk_map[OUT][config->outclk];
3117bb31
NC
467
468 /* We only have output clock for ideal ratio mode */
be7bd03f 469 clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]];
3117bb31 470
b39eb1e2 471 clk_rate = clk_get_rate(clk);
32038634 472 div_avail = fsl_asrc_divider_avail(clk_rate, inrate, &div[IN]);
b39eb1e2
SW
473
474 /*
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.
480 */
32038634 481 if (div[IN] == 0 || (!ideal && !div_avail)) {
3117bb31
NC
482 pair_err("failed to support input sample rate %dHz by asrck_%x\n",
483 inrate, clk_index[ideal ? OUT : IN]);
484 return -EINVAL;
485 }
486
b39eb1e2 487 div[IN] = min_t(u32, 1024, div[IN]);
3117bb31 488
be7bd03f 489 clk = asrc_priv->asrck_clk[clk_index[OUT]];
b39eb1e2
SW
490 clk_rate = clk_get_rate(clk);
491 if (ideal && use_ideal_rate)
32038634 492 div_avail = fsl_asrc_divider_avail(clk_rate, IDEAL_RATIO_RATE, &div[OUT]);
3117bb31 493 else
32038634 494 div_avail = fsl_asrc_divider_avail(clk_rate, outrate, &div[OUT]);
3117bb31 495
b39eb1e2 496 /* Output divider has the same limitation as the input one */
32038634 497 if (div[OUT] == 0 || (!ideal && !div_avail)) {
3117bb31
NC
498 pair_err("failed to support output sample rate %dHz by asrck_%x\n",
499 outrate, clk_index[OUT]);
500 return -EINVAL;
501 }
502
b39eb1e2
SW
503 div[OUT] = min_t(u32, 1024, div[OUT]);
504
3117bb31
NC
505 /* Set the channel number */
506 channels = config->channel_num;
507
be7bd03f 508 if (asrc_priv->soc->channel_bits < 4)
3117bb31
NC
509 channels /= 2;
510
511 /* Update channels for current pair */
7470704d 512 regmap_update_bits(asrc->regmap, REG_ASRCNCR,
be7bd03f
SW
513 ASRCNCR_ANCi_MASK(index, asrc_priv->soc->channel_bits),
514 ASRCNCR_ANCi(index, channels, asrc_priv->soc->channel_bits));
3117bb31
NC
515
516 /* Default setting: Automatic selection for processing mode */
7470704d 517 regmap_update_bits(asrc->regmap, REG_ASRCTR,
3117bb31 518 ASRCTR_ATSi_MASK(index), ASRCTR_ATS(index));
7470704d 519 regmap_update_bits(asrc->regmap, REG_ASRCTR,
3117bb31
NC
520 ASRCTR_USRi_MASK(index), 0);
521
522 /* Set the input and output clock sources */
7470704d 523 regmap_update_bits(asrc->regmap, REG_ASRCSR,
3117bb31
NC
524 ASRCSR_AICSi_MASK(index) | ASRCSR_AOCSi_MASK(index),
525 ASRCSR_AICS(index, clk_index[IN]) |
526 ASRCSR_AOCS(index, clk_index[OUT]));
527
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]);
531
532 /* Suppose indiv and outdiv includes prescaler, so add its MASK too */
7470704d 533 regmap_update_bits(asrc->regmap, REG_ASRCDR(index),
3117bb31
NC
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));
537
538 /* Implement word_width configurations */
7470704d 539 regmap_update_bits(asrc->regmap, REG_ASRMCR1(index),
3117bb31 540 ASRMCR1i_OW16_MASK | ASRMCR1i_IWD_MASK,
4bf62571
SW
541 ASRMCR1i_OW16(output_word_width) |
542 ASRMCR1i_IWD(input_word_width));
3117bb31
NC
543
544 /* Enable BUFFER STALL */
7470704d 545 regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
3117bb31
NC
546 ASRMCRi_BUFSTALLi_MASK, ASRMCRi_BUFSTALLi);
547
548 /* Set default thresholds for input and output FIFO */
549 fsl_asrc_set_watermarks(pair, ASRC_INPUTFIFO_THRESHOLD,
550 ASRC_INPUTFIFO_THRESHOLD);
551
4091fb95 552 /* Configure the following only for Ideal Ratio mode */
3117bb31
NC
553 if (!ideal)
554 return 0;
555
556 /* Clear ASTSx bit to use Ideal Ratio mode */
7470704d 557 regmap_update_bits(asrc->regmap, REG_ASRCTR,
3117bb31
NC
558 ASRCTR_ATSi_MASK(index), 0);
559
560 /* Enable Ideal Ratio mode */
7470704d 561 regmap_update_bits(asrc->regmap, REG_ASRCTR,
3117bb31
NC
562 ASRCTR_IDRi_MASK(index) | ASRCTR_USRi_MASK(index),
563 ASRCTR_IDR(index) | ASRCTR_USR(index));
564
4aecaa0a
W
565 fsl_asrc_sel_proc(inrate, outrate, &pre_proc, &post_proc);
566
3117bb31 567 /* Apply configurations for pre- and post-processing */
7470704d 568 regmap_update_bits(asrc->regmap, REG_ASRCFG,
3117bb31 569 ASRCFG_PREMODi_MASK(index) | ASRCFG_POSTMODi_MASK(index),
4aecaa0a
W
570 ASRCFG_PREMOD(index, pre_proc) |
571 ASRCFG_POSTMOD(index, post_proc));
3117bb31
NC
572
573 return fsl_asrc_set_ideal_ratio(pair, inrate, outrate);
574}
575
576/**
45e039d9
PLB
577 * fsl_asrc_start_pair - Start the assigned ASRC pair
578 * @pair: pointer to pair
3117bb31
NC
579 *
580 * It enables the assigned pair and makes it stopped at the stall level.
581 */
582static void fsl_asrc_start_pair(struct fsl_asrc_pair *pair)
583{
7470704d 584 struct fsl_asrc *asrc = pair->asrc;
3117bb31 585 enum asrc_pair_index index = pair->index;
d2de3f5e 586 int reg, retry = INIT_RETRY_NUM, i;
3117bb31
NC
587
588 /* Enable the current pair */
7470704d 589 regmap_update_bits(asrc->regmap, REG_ASRCTR,
3117bb31
NC
590 ASRCTR_ASRCEi_MASK(index), ASRCTR_ASRCE(index));
591
592 /* Wait for status of initialization */
593 do {
594 udelay(5);
7470704d 595 regmap_read(asrc->regmap, REG_ASRCFG, &reg);
3117bb31
NC
596 reg &= ASRCFG_INIRQi_MASK(index);
597 } while (!reg && --retry);
598
d2de3f5e
SW
599 /* NOTE: Doesn't treat initialization timeout as an error */
600 if (!retry)
601 pair_warn("initialization isn't finished\n");
602
3117bb31 603 /* Make the input fifo to ASRC STALL level */
7470704d 604 regmap_read(asrc->regmap, REG_ASRCNCR, &reg);
3117bb31 605 for (i = 0; i < pair->channels * 4; i++)
7470704d 606 regmap_write(asrc->regmap, REG_ASRDI(index), 0);
3117bb31
NC
607
608 /* Enable overload interrupt */
7470704d 609 regmap_write(asrc->regmap, REG_ASRIER, ASRIER_AOLIE);
3117bb31
NC
610}
611
612/**
45e039d9
PLB
613 * fsl_asrc_stop_pair - Stop the assigned ASRC pair
614 * @pair: pointer to pair
3117bb31
NC
615 */
616static void fsl_asrc_stop_pair(struct fsl_asrc_pair *pair)
617{
7470704d 618 struct fsl_asrc *asrc = pair->asrc;
3117bb31
NC
619 enum asrc_pair_index index = pair->index;
620
621 /* Stop the current pair */
7470704d 622 regmap_update_bits(asrc->regmap, REG_ASRCTR,
3117bb31
NC
623 ASRCTR_ASRCEi_MASK(index), 0);
624}
625
626/**
45e039d9
PLB
627 * fsl_asrc_get_dma_channel- Get DMA channel according to the pair and direction.
628 * @pair: pointer to pair
629 * @dir: DMA direction
3117bb31 630 */
cff1f8b4 631static struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair,
632 bool dir)
3117bb31 633{
7470704d 634 struct fsl_asrc *asrc = pair->asrc;
3117bb31
NC
635 enum asrc_pair_index index = pair->index;
636 char name[4];
637
638 sprintf(name, "%cx%c", dir == IN ? 'r' : 't', index + 'a');
639
7470704d 640 return dma_request_slave_channel(&asrc->pdev->dev, name);
3117bb31 641}
3117bb31 642
53f67a78
W
643static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream,
644 struct snd_soc_dai *dai)
645{
7470704d 646 struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
be7bd03f 647 struct fsl_asrc_priv *asrc_priv = asrc->private;
53f67a78
W
648
649 /* Odd channel number is not valid for older ASRC (channel_bits==3) */
be7bd03f 650 if (asrc_priv->soc->channel_bits == 3)
53f67a78
W
651 snd_pcm_hw_constraint_step(substream->runtime, 0,
652 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
653
d281bf5d
W
654
655 return snd_pcm_hw_constraint_list(substream->runtime, 0,
656 SNDRV_PCM_HW_PARAM_RATE, &fsl_asrc_rate_constraints);
53f67a78
W
657}
658
d0250cf4
SW
659/* Select proper clock source for internal ratio mode */
660static void fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv,
661 struct fsl_asrc_pair *pair,
662 int in_rate,
663 int out_rate)
664{
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;
b2967435 669 int i, j;
d0250cf4
SW
670
671 rate[IN] = in_rate;
672 rate[OUT] = out_rate;
673
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 */
32038634 680 if (fsl_asrc_divider_avail(clk_rate, rate[j], NULL))
d0250cf4
SW
681 break;
682 }
683
684 select_clk[j] = i;
685 }
686
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;
691 }
692
693 config->inclk = select_clk[IN];
694 config->outclk = select_clk[OUT];
695}
696
3117bb31
NC
697static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
698 struct snd_pcm_hw_params *params,
699 struct snd_soc_dai *dai)
700{
7470704d 701 struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
d0250cf4 702 struct fsl_asrc_priv *asrc_priv = asrc->private;
3117bb31
NC
703 struct snd_pcm_runtime *runtime = substream->runtime;
704 struct fsl_asrc_pair *pair = runtime->private_data;
be7bd03f 705 struct fsl_asrc_pair_priv *pair_priv = pair->private;
3117bb31
NC
706 unsigned int channels = params_channels(params);
707 unsigned int rate = params_rate(params);
708 struct asrc_config config;
4bf62571 709 int ret;
3117bb31
NC
710
711 ret = fsl_asrc_request_pair(channels, pair);
712 if (ret) {
713 dev_err(dai->dev, "fail to request asrc pair\n");
714 return ret;
715 }
716
be7bd03f 717 pair_priv->config = &config;
3117bb31 718
3117bb31
NC
719 config.pair = pair->index;
720 config.channel_num = channels;
3117bb31
NC
721
722 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
4bf62571 723 config.input_format = params_format(params);
4520af41 724 config.output_format = asrc->asrc_format;
3117bb31 725 config.input_sample_rate = rate;
7470704d 726 config.output_sample_rate = asrc->asrc_rate;
3117bb31 727 } else {
4520af41 728 config.input_format = asrc->asrc_format;
4bf62571 729 config.output_format = params_format(params);
7470704d 730 config.input_sample_rate = asrc->asrc_rate;
3117bb31
NC
731 config.output_sample_rate = rate;
732 }
733
d0250cf4
SW
734 fsl_asrc_select_clk(asrc_priv, pair,
735 config.input_sample_rate,
736 config.output_sample_rate);
737
b39eb1e2 738 ret = fsl_asrc_config_pair(pair, false);
3117bb31
NC
739 if (ret) {
740 dev_err(dai->dev, "fail to config asrc pair\n");
741 return ret;
742 }
743
744 return 0;
745}
746
747static int fsl_asrc_dai_hw_free(struct snd_pcm_substream *substream,
748 struct snd_soc_dai *dai)
749{
750 struct snd_pcm_runtime *runtime = substream->runtime;
751 struct fsl_asrc_pair *pair = runtime->private_data;
752
753 if (pair)
754 fsl_asrc_release_pair(pair);
755
756 return 0;
757}
758
759static int fsl_asrc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
760 struct snd_soc_dai *dai)
761{
762 struct snd_pcm_runtime *runtime = substream->runtime;
763 struct fsl_asrc_pair *pair = runtime->private_data;
764
765 switch (cmd) {
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);
770 break;
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);
775 break;
776 default:
777 return -EINVAL;
778 }
779
780 return 0;
781}
782
29a22ebf 783static const struct snd_soc_dai_ops fsl_asrc_dai_ops = {
53f67a78 784 .startup = fsl_asrc_dai_startup,
3117bb31
NC
785 .hw_params = fsl_asrc_dai_hw_params,
786 .hw_free = fsl_asrc_dai_hw_free,
787 .trigger = fsl_asrc_dai_trigger,
788};
789
790static int fsl_asrc_dai_probe(struct snd_soc_dai *dai)
791{
7470704d 792 struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
3117bb31 793
7470704d
SW
794 snd_soc_dai_init_dma_data(dai, &asrc->dma_params_tx,
795 &asrc->dma_params_rx);
3117bb31
NC
796
797 return 0;
798}
799
3117bb31
NC
800#define FSL_ASRC_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | \
801 SNDRV_PCM_FMTBIT_S16_LE | \
109539c9 802 SNDRV_PCM_FMTBIT_S24_3LE)
3117bb31
NC
803
804static struct snd_soc_dai_driver fsl_asrc_dai = {
805 .probe = fsl_asrc_dai_probe,
806 .playback = {
807 .stream_name = "ASRC-Playback",
808 .channels_min = 1,
809 .channels_max = 10,
d281bf5d
W
810 .rate_min = 5512,
811 .rate_max = 192000,
812 .rates = SNDRV_PCM_RATE_KNOT,
109539c9
SW
813 .formats = FSL_ASRC_FORMATS |
814 SNDRV_PCM_FMTBIT_S8,
3117bb31
NC
815 },
816 .capture = {
817 .stream_name = "ASRC-Capture",
818 .channels_min = 1,
819 .channels_max = 10,
d281bf5d
W
820 .rate_min = 5512,
821 .rate_max = 192000,
822 .rates = SNDRV_PCM_RATE_KNOT,
3117bb31
NC
823 .formats = FSL_ASRC_FORMATS,
824 },
825 .ops = &fsl_asrc_dai_ops,
826};
827
3117bb31
NC
828static bool fsl_asrc_readable_reg(struct device *dev, unsigned int reg)
829{
830 switch (reg) {
831 case REG_ASRCTR:
832 case REG_ASRIER:
833 case REG_ASRCNCR:
834 case REG_ASRCFG:
835 case REG_ASRCSR:
836 case REG_ASRCDR1:
837 case REG_ASRCDR2:
838 case REG_ASRSTR:
839 case REG_ASRPM1:
840 case REG_ASRPM2:
841 case REG_ASRPM3:
842 case REG_ASRPM4:
843 case REG_ASRPM5:
844 case REG_ASRTFR1:
845 case REG_ASRCCR:
846 case REG_ASRDOA:
847 case REG_ASRDOB:
848 case REG_ASRDOC:
849 case REG_ASRIDRHA:
850 case REG_ASRIDRLA:
851 case REG_ASRIDRHB:
852 case REG_ASRIDRLB:
853 case REG_ASRIDRHC:
854 case REG_ASRIDRLC:
855 case REG_ASR76K:
856 case REG_ASR56K:
857 case REG_ASRMCRA:
858 case REG_ASRFSTA:
859 case REG_ASRMCRB:
860 case REG_ASRFSTB:
861 case REG_ASRMCRC:
862 case REG_ASRFSTC:
863 case REG_ASRMCR1A:
864 case REG_ASRMCR1B:
865 case REG_ASRMCR1C:
866 return true;
867 default:
868 return false;
869 }
870}
871
872static bool fsl_asrc_volatile_reg(struct device *dev, unsigned int reg)
873{
874 switch (reg) {
875 case REG_ASRSTR:
876 case REG_ASRDIA:
877 case REG_ASRDIB:
878 case REG_ASRDIC:
879 case REG_ASRDOA:
880 case REG_ASRDOB:
881 case REG_ASRDOC:
882 case REG_ASRFSTA:
883 case REG_ASRFSTB:
884 case REG_ASRFSTC:
885 case REG_ASRCFG:
886 return true;
887 default:
888 return false;
889 }
890}
891
892static bool fsl_asrc_writeable_reg(struct device *dev, unsigned int reg)
893{
894 switch (reg) {
895 case REG_ASRCTR:
896 case REG_ASRIER:
897 case REG_ASRCNCR:
898 case REG_ASRCFG:
899 case REG_ASRCSR:
900 case REG_ASRCDR1:
901 case REG_ASRCDR2:
902 case REG_ASRSTR:
903 case REG_ASRPM1:
904 case REG_ASRPM2:
905 case REG_ASRPM3:
906 case REG_ASRPM4:
907 case REG_ASRPM5:
908 case REG_ASRTFR1:
909 case REG_ASRCCR:
910 case REG_ASRDIA:
911 case REG_ASRDIB:
912 case REG_ASRDIC:
913 case REG_ASRIDRHA:
914 case REG_ASRIDRLA:
915 case REG_ASRIDRHB:
916 case REG_ASRIDRLB:
917 case REG_ASRIDRHC:
918 case REG_ASRIDRLC:
919 case REG_ASR76K:
920 case REG_ASR56K:
921 case REG_ASRMCRA:
922 case REG_ASRMCRB:
923 case REG_ASRMCRC:
924 case REG_ASRMCR1A:
925 case REG_ASRMCR1B:
926 case REG_ASRMCR1C:
927 return true;
928 default:
929 return false;
930 }
931}
932
86a570c5
NC
933static 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 },
955};
956
bf16d883 957static const struct regmap_config fsl_asrc_regmap_config = {
3117bb31
NC
958 .reg_bits = 32,
959 .reg_stride = 4,
960 .val_bits = 32,
961
962 .max_register = REG_ASRMCR1C,
86a570c5
NC
963 .reg_defaults = fsl_asrc_reg,
964 .num_reg_defaults = ARRAY_SIZE(fsl_asrc_reg),
3117bb31
NC
965 .readable_reg = fsl_asrc_readable_reg,
966 .volatile_reg = fsl_asrc_volatile_reg,
967 .writeable_reg = fsl_asrc_writeable_reg,
b4138868 968 .cache_type = REGCACHE_FLAT,
3117bb31
NC
969};
970
971/**
45e039d9
PLB
972 * fsl_asrc_init - Initialize ASRC registers with a default configuration
973 * @asrc: ASRC context
3117bb31 974 */
7470704d 975static int fsl_asrc_init(struct fsl_asrc *asrc)
3117bb31 976{
f8953043
SW
977 unsigned long ipg_rate;
978
3117bb31 979 /* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
7470704d 980 regmap_write(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEN);
3117bb31
NC
981
982 /* Disable interrupt by default */
7470704d 983 regmap_write(asrc->regmap, REG_ASRIER, 0x0);
3117bb31
NC
984
985 /* Apply recommended settings for parameters from Reference Manual */
7470704d
SW
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);
3117bb31
NC
991
992 /* Base address for task queue FIFO. Set to 0x7C */
7470704d 993 regmap_update_bits(asrc->regmap, REG_ASRTFR1,
3117bb31
NC
994 ASRTFR1_TF_BASE_MASK, ASRTFR1_TF_BASE(0xfc));
995
f8953043
SW
996 /*
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
1000 */
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);
3117bb31
NC
1004}
1005
1006/**
45e039d9
PLB
1007 * fsl_asrc_isr- Interrupt handler for ASRC
1008 * @irq: irq number
1009 * @dev_id: ASRC context
3117bb31
NC
1010 */
1011static irqreturn_t fsl_asrc_isr(int irq, void *dev_id)
1012{
7470704d
SW
1013 struct fsl_asrc *asrc = (struct fsl_asrc *)dev_id;
1014 struct device *dev = &asrc->pdev->dev;
3117bb31
NC
1015 enum asrc_pair_index index;
1016 u32 status;
1017
7470704d 1018 regmap_read(asrc->regmap, REG_ASRSTR, &status);
3117bb31
NC
1019
1020 /* Clean overload error */
7470704d 1021 regmap_write(asrc->regmap, REG_ASRSTR, ASRSTR_AOLE);
3117bb31
NC
1022
1023 /*
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.
1027 */
1028 for (index = ASRC_PAIR_A; index < ASRC_PAIR_MAX_NUM; index++) {
7470704d 1029 if (!asrc->pair[index])
3117bb31
NC
1030 continue;
1031
1032 if (status & ASRSTR_ATQOL) {
7470704d 1033 asrc->pair[index]->error |= ASRC_TASK_Q_OVERLOAD;
3117bb31
NC
1034 dev_dbg(dev, "ASRC Task Queue FIFO overload\n");
1035 }
1036
1037 if (status & ASRSTR_AOOL(index)) {
7470704d 1038 asrc->pair[index]->error |= ASRC_OUTPUT_TASK_OVERLOAD;
3117bb31
NC
1039 pair_dbg("Output Task Overload\n");
1040 }
1041
1042 if (status & ASRSTR_AIOL(index)) {
7470704d 1043 asrc->pair[index]->error |= ASRC_INPUT_TASK_OVERLOAD;
3117bb31
NC
1044 pair_dbg("Input Task Overload\n");
1045 }
1046
1047 if (status & ASRSTR_AODO(index)) {
7470704d 1048 asrc->pair[index]->error |= ASRC_OUTPUT_BUFFER_OVERFLOW;
3117bb31
NC
1049 pair_dbg("Output Data Buffer has overflowed\n");
1050 }
1051
1052 if (status & ASRSTR_AIDU(index)) {
7470704d 1053 asrc->pair[index]->error |= ASRC_INPUT_BUFFER_UNDERRUN;
3117bb31
NC
1054 pair_dbg("Input Data Buffer has underflowed\n");
1055 }
1056 }
1057
1058 return IRQ_HANDLED;
1059}
1060
be7bd03f
SW
1061static int fsl_asrc_get_fifo_addr(u8 dir, enum asrc_pair_index index)
1062{
1063 return REG_ASRDx(dir, index);
1064}
1065
cab04ab5
SW
1066static int fsl_asrc_runtime_resume(struct device *dev);
1067static int fsl_asrc_runtime_suspend(struct device *dev);
1068
3117bb31
NC
1069static int fsl_asrc_probe(struct platform_device *pdev)
1070{
1071 struct device_node *np = pdev->dev.of_node;
be7bd03f 1072 struct fsl_asrc_priv *asrc_priv;
7470704d 1073 struct fsl_asrc *asrc;
3117bb31
NC
1074 struct resource *res;
1075 void __iomem *regs;
1076 int irq, ret, i;
c4993272 1077 u32 asrc_fmt = 0;
c05f10f2 1078 u32 map_idx;
3117bb31 1079 char tmp[16];
4520af41 1080 u32 width;
3117bb31 1081
7470704d
SW
1082 asrc = devm_kzalloc(&pdev->dev, sizeof(*asrc), GFP_KERNEL);
1083 if (!asrc)
3117bb31
NC
1084 return -ENOMEM;
1085
be7bd03f
SW
1086 asrc_priv = devm_kzalloc(&pdev->dev, sizeof(*asrc_priv), GFP_KERNEL);
1087 if (!asrc_priv)
1088 return -ENOMEM;
1089
7470704d 1090 asrc->pdev = pdev;
be7bd03f 1091 asrc->private = asrc_priv;
3117bb31
NC
1092
1093 /* Get the addresses and IRQ */
c66d7621 1094 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
3117bb31
NC
1095 if (IS_ERR(regs))
1096 return PTR_ERR(regs);
1097
7470704d 1098 asrc->paddr = res->start;
3117bb31 1099
cab04ab5 1100 asrc->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &fsl_asrc_regmap_config);
7470704d 1101 if (IS_ERR(asrc->regmap)) {
3117bb31 1102 dev_err(&pdev->dev, "failed to init regmap\n");
7470704d 1103 return PTR_ERR(asrc->regmap);
3117bb31
NC
1104 }
1105
1106 irq = platform_get_irq(pdev, 0);
cf9441ad 1107 if (irq < 0)
3117bb31 1108 return irq;
3117bb31
NC
1109
1110 ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0,
7470704d 1111 dev_name(&pdev->dev), asrc);
3117bb31
NC
1112 if (ret) {
1113 dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret);
1114 return ret;
1115 }
1116
7470704d
SW
1117 asrc->mem_clk = devm_clk_get(&pdev->dev, "mem");
1118 if (IS_ERR(asrc->mem_clk)) {
3117bb31 1119 dev_err(&pdev->dev, "failed to get mem clock\n");
7470704d 1120 return PTR_ERR(asrc->mem_clk);
3117bb31
NC
1121 }
1122
7470704d
SW
1123 asrc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
1124 if (IS_ERR(asrc->ipg_clk)) {
3117bb31 1125 dev_err(&pdev->dev, "failed to get ipg clock\n");
7470704d 1126 return PTR_ERR(asrc->ipg_clk);
3117bb31
NC
1127 }
1128
7470704d
SW
1129 asrc->spba_clk = devm_clk_get(&pdev->dev, "spba");
1130 if (IS_ERR(asrc->spba_clk))
13b8a97a
SW
1131 dev_warn(&pdev->dev, "failed to get spba clock\n");
1132
3117bb31
NC
1133 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
1134 sprintf(tmp, "asrck_%x", i);
be7bd03f
SW
1135 asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp);
1136 if (IS_ERR(asrc_priv->asrck_clk[i])) {
3117bb31 1137 dev_err(&pdev->dev, "failed to get %s clock\n", tmp);
be7bd03f 1138 return PTR_ERR(asrc_priv->asrck_clk[i]);
3117bb31
NC
1139 }
1140 }
1141
be7bd03f 1142 asrc_priv->soc = of_device_get_match_data(&pdev->dev);
be7bd03f
SW
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);
1149
f3d8ac8c 1150 if (of_device_is_compatible(np, "fsl,imx35-asrc")) {
be7bd03f
SW
1151 asrc_priv->clk_map[IN] = input_clk_map_imx35;
1152 asrc_priv->clk_map[OUT] = output_clk_map_imx35;
c05f10f2 1153 } else if (of_device_is_compatible(np, "fsl,imx53-asrc")) {
be7bd03f
SW
1154 asrc_priv->clk_map[IN] = input_clk_map_imx53;
1155 asrc_priv->clk_map[OUT] = output_clk_map_imx53;
c05f10f2
SW
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);
1159 if (ret) {
1160 dev_err(&pdev->dev, "failed to get clk map index\n");
1161 return ret;
1162 }
1163
1164 if (map_idx > 1) {
1165 dev_err(&pdev->dev, "unsupported clk map index\n");
1166 return -EINVAL;
1167 }
1168 if (of_device_is_compatible(np, "fsl,imx8qm-asrc")) {
be7bd03f
SW
1169 asrc_priv->clk_map[IN] = clk_map_imx8qm[map_idx];
1170 asrc_priv->clk_map[OUT] = clk_map_imx8qm[map_idx];
c05f10f2 1171 } else {
be7bd03f
SW
1172 asrc_priv->clk_map[IN] = clk_map_imx8qxp[map_idx];
1173 asrc_priv->clk_map[OUT] = clk_map_imx8qxp[map_idx];
c05f10f2 1174 }
3117bb31
NC
1175 }
1176
7470704d 1177 asrc->channel_avail = 10;
3117bb31
NC
1178
1179 ret = of_property_read_u32(np, "fsl,asrc-rate",
7470704d 1180 &asrc->asrc_rate);
3117bb31
NC
1181 if (ret) {
1182 dev_err(&pdev->dev, "failed to get output rate\n");
c0296950 1183 return ret;
3117bb31
NC
1184 }
1185
c4993272
SW
1186 ret = of_property_read_u32(np, "fsl,asrc-format", &asrc_fmt);
1187 asrc->asrc_format = (__force snd_pcm_format_t)asrc_fmt;
3117bb31 1188 if (ret) {
4520af41
SW
1189 ret = of_property_read_u32(np, "fsl,asrc-width", &width);
1190 if (ret) {
1191 dev_err(&pdev->dev, "failed to decide output format\n");
1192 return ret;
1193 }
1194
1195 switch (width) {
1196 case 16:
1197 asrc->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
1198 break;
1199 case 24:
1200 asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
1201 break;
1202 default:
1203 dev_warn(&pdev->dev,
1204 "unsupported width, use default S24_LE\n");
1205 asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
1206 break;
1207 }
3117bb31
NC
1208 }
1209
c4993272 1210 if (!(FSL_ASRC_FORMATS & pcm_format_to_bits(asrc->asrc_format))) {
4520af41
SW
1211 dev_warn(&pdev->dev, "unsupported width, use default S24_LE\n");
1212 asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
3117bb31
NC
1213 }
1214
7470704d 1215 platform_set_drvdata(pdev, asrc);
7470704d 1216 spin_lock_init(&asrc->lock);
cab04ab5
SW
1217 pm_runtime_enable(&pdev->dev);
1218 if (!pm_runtime_enabled(&pdev->dev)) {
1219 ret = fsl_asrc_runtime_resume(&pdev->dev);
1220 if (ret)
1221 goto err_pm_disable;
1222 }
1223
d0504074
MC
1224 ret = pm_runtime_resume_and_get(&pdev->dev);
1225 if (ret < 0)
cab04ab5 1226 goto err_pm_get_sync;
cab04ab5
SW
1227
1228 ret = fsl_asrc_init(asrc);
1229 if (ret) {
1230 dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
1231 goto err_pm_get_sync;
1232 }
1233
1234 ret = pm_runtime_put_sync(&pdev->dev);
6a564338 1235 if (ret < 0 && ret != -ENOSYS)
cab04ab5 1236 goto err_pm_get_sync;
3117bb31
NC
1237
1238 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component,
1239 &fsl_asrc_dai, 1);
1240 if (ret) {
1241 dev_err(&pdev->dev, "failed to register ASoC DAI\n");
cab04ab5 1242 goto err_pm_get_sync;
3117bb31
NC
1243 }
1244
3117bb31 1245 return 0;
cab04ab5
SW
1246
1247err_pm_get_sync:
1248 if (!pm_runtime_status_suspended(&pdev->dev))
1249 fsl_asrc_runtime_suspend(&pdev->dev);
1250err_pm_disable:
1251 pm_runtime_disable(&pdev->dev);
1252 return ret;
1253}
1254
7a2d15b9 1255static void fsl_asrc_remove(struct platform_device *pdev)
cab04ab5
SW
1256{
1257 pm_runtime_disable(&pdev->dev);
1258 if (!pm_runtime_status_suspended(&pdev->dev))
1259 fsl_asrc_runtime_suspend(&pdev->dev);
3117bb31
NC
1260}
1261
3117bb31
NC
1262static int fsl_asrc_runtime_resume(struct device *dev)
1263{
7470704d 1264 struct fsl_asrc *asrc = dev_get_drvdata(dev);
be7bd03f 1265 struct fsl_asrc_priv *asrc_priv = asrc->private;
d2de3f5e 1266 int reg, retry = INIT_RETRY_NUM;
b1ade0f2 1267 int i, ret;
393dc21d 1268 u32 asrctr;
3117bb31 1269
7470704d 1270 ret = clk_prepare_enable(asrc->mem_clk);
b1ade0f2
FE
1271 if (ret)
1272 return ret;
7470704d 1273 ret = clk_prepare_enable(asrc->ipg_clk);
b1ade0f2
FE
1274 if (ret)
1275 goto disable_mem_clk;
7470704d
SW
1276 if (!IS_ERR(asrc->spba_clk)) {
1277 ret = clk_prepare_enable(asrc->spba_clk);
13b8a97a
SW
1278 if (ret)
1279 goto disable_ipg_clk;
1280 }
b1ade0f2 1281 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
be7bd03f 1282 ret = clk_prepare_enable(asrc_priv->asrck_clk[i]);
b1ade0f2
FE
1283 if (ret)
1284 goto disable_asrck_clk;
1285 }
3117bb31 1286
393dc21d
SW
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);
1291
1292 /* Restore all registers */
1293 regcache_cache_only(asrc->regmap, false);
1294 regcache_mark_dirty(asrc->regmap);
1295 regcache_sync(asrc->regmap);
1296
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);
1300
1301 /* Restart enabled pairs */
1302 regmap_update_bits(asrc->regmap, REG_ASRCTR,
1303 ASRCTR_ASRCEi_ALL_MASK, asrctr);
1304
d2de3f5e
SW
1305 /* Wait for status of initialization for all enabled pairs */
1306 do {
1307 udelay(5);
1308 regmap_read(asrc->regmap, REG_ASRCFG, &reg);
1309 reg = (reg >> ASRCFG_INIRQi_SHIFT(0)) & 0x7;
1310 } while ((reg != ((asrctr >> ASRCTR_ASRCEi_SHIFT(0)) & 0x7)) && --retry);
1311
1312 /*
1313 * NOTE: Doesn't treat initialization timeout as an error
1314 * Some of the pairs may success, then still can continue.
1315 */
1316 if (!retry) {
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);
1320 }
1321 }
1322
3117bb31 1323 return 0;
b1ade0f2
FE
1324
1325disable_asrck_clk:
1326 for (i--; i >= 0; i--)
be7bd03f 1327 clk_disable_unprepare(asrc_priv->asrck_clk[i]);
7470704d
SW
1328 if (!IS_ERR(asrc->spba_clk))
1329 clk_disable_unprepare(asrc->spba_clk);
13b8a97a 1330disable_ipg_clk:
7470704d 1331 clk_disable_unprepare(asrc->ipg_clk);
b1ade0f2 1332disable_mem_clk:
7470704d 1333 clk_disable_unprepare(asrc->mem_clk);
b1ade0f2 1334 return ret;
3117bb31
NC
1335}
1336
1337static int fsl_asrc_runtime_suspend(struct device *dev)
1338{
7470704d 1339 struct fsl_asrc *asrc = dev_get_drvdata(dev);
be7bd03f 1340 struct fsl_asrc_priv *asrc_priv = asrc->private;
3117bb31
NC
1341 int i;
1342
393dc21d
SW
1343 regmap_read(asrc->regmap, REG_ASRCFG,
1344 &asrc_priv->regcache_cfg);
1345
1346 regcache_cache_only(asrc->regmap, true);
1347
3117bb31 1348 for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
be7bd03f 1349 clk_disable_unprepare(asrc_priv->asrck_clk[i]);
7470704d
SW
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);
3117bb31
NC
1354
1355 return 0;
1356}
3117bb31 1357
3117bb31
NC
1358static const struct dev_pm_ops fsl_asrc_pm = {
1359 SET_RUNTIME_PM_OPS(fsl_asrc_runtime_suspend, fsl_asrc_runtime_resume, NULL)
393dc21d
SW
1360 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1361 pm_runtime_force_resume)
3117bb31
NC
1362};
1363
c05f10f2
SW
1364static const struct fsl_asrc_soc_data fsl_asrc_imx35_data = {
1365 .use_edma = false,
1366 .channel_bits = 3,
1367};
1368
1369static const struct fsl_asrc_soc_data fsl_asrc_imx53_data = {
1370 .use_edma = false,
1371 .channel_bits = 4,
1372};
1373
1374static const struct fsl_asrc_soc_data fsl_asrc_imx8qm_data = {
1375 .use_edma = true,
1376 .channel_bits = 4,
1377};
1378
1379static const struct fsl_asrc_soc_data fsl_asrc_imx8qxp_data = {
1380 .use_edma = true,
1381 .channel_bits = 4,
1382};
1383
3117bb31 1384static const struct of_device_id fsl_asrc_ids[] = {
c05f10f2
SW
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 },
3117bb31
NC
1389 {}
1390};
1391MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
1392
1393static struct platform_driver fsl_asrc_driver = {
1394 .probe = fsl_asrc_probe,
7a2d15b9 1395 .remove_new = fsl_asrc_remove,
3117bb31
NC
1396 .driver = {
1397 .name = "fsl-asrc",
1398 .of_match_table = fsl_asrc_ids,
1399 .pm = &fsl_asrc_pm,
1400 },
1401};
1402module_platform_driver(fsl_asrc_driver);
1403
1404MODULE_DESCRIPTION("Freescale ASRC ASoC driver");
1405MODULE_AUTHOR("Nicolin Chen <nicoleotsuka@gmail.com>");
1406MODULE_ALIAS("platform:fsl-asrc");
1407MODULE_LICENSE("GPL v2");