xref: /kernel/linux/linux-5.10/sound/soc/fsl/fsl_asrc.c (revision 8c2ecf20)
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>
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>
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>
18
19#include "fsl_asrc.h"
20
21#define IDEAL_RATIO_DECIMAL_DEPTH 26
22#define DIVIDER_NUM  64
23
24#define pair_err(fmt, ...) \
25	dev_err(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
26
27#define pair_dbg(fmt, ...) \
28	dev_dbg(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
29
30/* Corresponding to process_option */
31static unsigned int supported_asrc_rate[] = {
32	5512, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
33	64000, 88200, 96000, 128000, 176400, 192000,
34};
35
36static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints = {
37	.count = ARRAY_SIZE(supported_asrc_rate),
38	.list = supported_asrc_rate,
39};
40
41/*
42 * The following tables map the relationship between asrc_inclk/asrc_outclk in
43 * fsl_asrc.h and the registers of ASRCSR
44 */
45static 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,
49};
50
51static 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,
55};
56
57/* i.MX53 uses the same map for input and output */
58static 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,
63};
64
65static 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,
70};
71
72/*
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
78 */
79static unsigned char clk_map_imx8qm[2][ASRC_CLK_MAP_LEN] = {
80	{
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,
84	},
85	{
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,
89	},
90};
91
92static unsigned char clk_map_imx8qxp[2][ASRC_CLK_MAP_LEN] = {
93	{
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,
97	},
98	{
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,
102	},
103};
104
105/*
106 * According to RM, the divider range is 1 ~ 8,
107 * prescaler is power of 2 from 1 ~ 128.
108 */
109static 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 */
118};
119
120/*
121 * Check if the divider is available for internal ratio mode
122 */
123static bool fsl_asrc_divider_avail(int clk_rate, int rate, int *div)
124{
125	u32 rem, i;
126	u64 n;
127
128	if (div)
129		*div = 0;
130
131	if (clk_rate == 0 || rate == 0)
132		return false;
133
134	n = clk_rate;
135	rem = do_div(n, rate);
136
137	if (div)
138		*div = n;
139
140	if (rem != 0)
141		return false;
142
143	for (i = 0; i < DIVIDER_NUM; i++) {
144		if (n == asrc_clk_divider[i])
145			break;
146	}
147
148	if (i == DIVIDER_NUM)
149		return false;
150
151	return true;
152}
153
154/**
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
160 *
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
165 *
166 */
167static void fsl_asrc_sel_proc(int inrate, int outrate,
168			     int *pre_proc, int *post_proc)
169{
170	bool post_proc_cond2;
171	bool post_proc_cond0;
172
173	/* select pre_proc between [0, 2] */
174	if (inrate * 8 > 33 * outrate)
175		*pre_proc = 2;
176	else if (inrate * 8 > 15 * outrate) {
177		if (inrate > 152000)
178			*pre_proc = 2;
179		else
180			*pre_proc = 1;
181	} else if (inrate < 76000)
182		*pre_proc = 0;
183	else if (inrate > 152000)
184		*pre_proc = 2;
185	else
186		*pre_proc = 1;
187
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;
192
193	if (post_proc_cond2)
194		*post_proc = 2;
195	else if (post_proc_cond0)
196		*post_proc = 0;
197	else
198		*post_proc = 1;
199}
200
201/**
202 * fsl_asrc_request_pair - Request ASRC pair
203 * @channels: number of channels
204 * @pair: pointer to pair
205 *
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.
209 */
210static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
211{
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;
216	int i, ret = 0;
217
218	spin_lock_irqsave(&asrc->lock, lock_flags);
219
220	for (i = ASRC_PAIR_A; i < ASRC_PAIR_MAX_NUM; i++) {
221		if (asrc->pair[i] != NULL)
222			continue;
223
224		index = i;
225
226		if (i != ASRC_PAIR_B)
227			break;
228	}
229
230	if (index == ASRC_INVALID_PAIR) {
231		dev_err(dev, "all pairs are busy now\n");
232		ret = -EBUSY;
233	} else if (asrc->channel_avail < channels) {
234		dev_err(dev, "can't afford required channels: %d\n", channels);
235		ret = -EINVAL;
236	} else {
237		asrc->channel_avail -= channels;
238		asrc->pair[index] = pair;
239		pair->channels = channels;
240		pair->index = index;
241	}
242
243	spin_unlock_irqrestore(&asrc->lock, lock_flags);
244
245	return ret;
246}
247
248/**
249 * fsl_asrc_release_pair - Release ASRC pair
250 * @pair: pair to release
251 *
252 * It clears the resource from asrc and releases the occupied channels.
253 */
254static void fsl_asrc_release_pair(struct fsl_asrc_pair *pair)
255{
256	struct fsl_asrc *asrc = pair->asrc;
257	enum asrc_pair_index index = pair->index;
258	unsigned long lock_flags;
259
260	/* Make sure the pair is disabled */
261	regmap_update_bits(asrc->regmap, REG_ASRCTR,
262			   ASRCTR_ASRCEi_MASK(index), 0);
263
264	spin_lock_irqsave(&asrc->lock, lock_flags);
265
266	asrc->channel_avail += pair->channels;
267	asrc->pair[index] = NULL;
268	pair->error = 0;
269
270	spin_unlock_irqrestore(&asrc->lock, lock_flags);
271}
272
273/**
274 * fsl_asrc_set_watermarks- configure input and output thresholds
275 * @pair: pointer to pair
276 * @in: input threshold
277 * @out: output threshold
278 */
279static void fsl_asrc_set_watermarks(struct fsl_asrc_pair *pair, u32 in, u32 out)
280{
281	struct fsl_asrc *asrc = pair->asrc;
282	enum asrc_pair_index index = pair->index;
283
284	regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
285			   ASRMCRi_EXTTHRSHi_MASK |
286			   ASRMCRi_INFIFO_THRESHOLD_MASK |
287			   ASRMCRi_OUTFIFO_THRESHOLD_MASK,
288			   ASRMCRi_EXTTHRSHi |
289			   ASRMCRi_INFIFO_THRESHOLD(in) |
290			   ASRMCRi_OUTFIFO_THRESHOLD(out));
291}
292
293/**
294 * fsl_asrc_cal_asrck_divisor - Calculate the total divisor between asrck clock rate and sample rate
295 * @pair: pointer to pair
296 * @div: divider
297 *
298 * It follows the formula clk_rate = samplerate * (2 ^ prescaler) * divider
299 */
300static u32 fsl_asrc_cal_asrck_divisor(struct fsl_asrc_pair *pair, u32 div)
301{
302	u32 ps;
303
304	/* Calculate the divisors: prescaler [2^0, 2^7], divder [1, 8] */
305	for (ps = 0; div > 8; ps++)
306		div >>= 1;
307
308	return ((div - 1) << ASRCDRi_AxCPi_WIDTH) | ps;
309}
310
311/**
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
316 *
317 * The ratio is a 32-bit fixed point value with 26 fractional bits.
318 */
319static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair,
320				    int inrate, int outrate)
321{
322	struct fsl_asrc *asrc = pair->asrc;
323	enum asrc_pair_index index = pair->index;
324	unsigned long ratio;
325	int i;
326
327	if (!outrate) {
328		pair_err("output rate should not be zero\n");
329		return -EINVAL;
330	}
331
332	/* Calculate the intergal part of the ratio */
333	ratio = (inrate / outrate) << IDEAL_RATIO_DECIMAL_DEPTH;
334
335	/* ... and then the 26 depth decimal part */
336	inrate %= outrate;
337
338	for (i = 1; i <= IDEAL_RATIO_DECIMAL_DEPTH; i++) {
339		inrate <<= 1;
340
341		if (inrate < outrate)
342			continue;
343
344		ratio |= 1 << (IDEAL_RATIO_DECIMAL_DEPTH - i);
345		inrate -= outrate;
346
347		if (!inrate)
348			break;
349	}
350
351	regmap_write(asrc->regmap, REG_ASRIDRL(index), ratio);
352	regmap_write(asrc->regmap, REG_ASRIDRH(index), ratio >> 24);
353
354	return 0;
355}
356
357/**
358 * fsl_asrc_config_pair - Configure the assigned ASRC pair
359 * @pair: pointer to pair
360 * @use_ideal_rate: boolean configuration
361 *
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.
365 *
366 * Note:
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.
372 */
373static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
374{
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];
384	u64 clk_rate;
385	int in, out, channels;
386	int pre_proc, post_proc;
387	struct clk *clk;
388	bool ideal, div_avail;
389
390	if (!config) {
391		pair_err("invalid pair config\n");
392		return -EINVAL;
393	}
394
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);
398		return -EINVAL;
399	}
400
401	switch (snd_pcm_format_width(config->input_format)) {
402	case 8:
403		input_word_width = ASRC_WIDTH_8_BIT;
404		break;
405	case 16:
406		input_word_width = ASRC_WIDTH_16_BIT;
407		break;
408	case 24:
409		input_word_width = ASRC_WIDTH_24_BIT;
410		break;
411	default:
412		pair_err("does not support this input format, %d\n",
413			 config->input_format);
414		return -EINVAL;
415	}
416
417	switch (snd_pcm_format_width(config->output_format)) {
418	case 16:
419		output_word_width = ASRC_WIDTH_16_BIT;
420		break;
421	case 24:
422		output_word_width = ASRC_WIDTH_24_BIT;
423		break;
424	default:
425		pair_err("does not support this output format, %d\n",
426			 config->output_format);
427		return -EINVAL;
428	}
429
430	inrate = config->input_sample_rate;
431	outrate = config->output_sample_rate;
432	ideal = config->inclk == INCLK_NONE;
433
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])
437			break;
438
439	if (in == ARRAY_SIZE(supported_asrc_rate)) {
440		pair_err("unsupported input sample rate: %dHz\n", inrate);
441		return -EINVAL;
442	}
443
444	for (out = 0; out < ARRAY_SIZE(supported_asrc_rate); out++)
445		if (outrate == supported_asrc_rate[out])
446			break;
447
448	if (out == ARRAY_SIZE(supported_asrc_rate)) {
449		pair_err("unsupported output sample rate: %dHz\n", outrate);
450		return -EINVAL;
451	}
452
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);
457		return -EINVAL;
458	}
459
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];
463
464	/* We only have output clock for ideal ratio mode */
465	clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]];
466
467	clk_rate = clk_get_rate(clk);
468	div_avail = fsl_asrc_divider_avail(clk_rate, inrate, &div[IN]);
469
470	/*
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.
476	 */
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]);
480		return -EINVAL;
481	}
482
483	div[IN] = min_t(u32, 1024, div[IN]);
484
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]);
489	else
490		div_avail = fsl_asrc_divider_avail(clk_rate, outrate, &div[OUT]);
491
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]);
496		return -EINVAL;
497	}
498
499	div[OUT] = min_t(u32, 1024, div[OUT]);
500
501	/* Set the channel number */
502	channels = config->channel_num;
503
504	if (asrc_priv->soc->channel_bits < 4)
505		channels /= 2;
506
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));
511
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);
517
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]));
523
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]);
527
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));
533
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));
539
540	/* Enable BUFFER STALL */
541	regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
542			   ASRMCRi_BUFSTALLi_MASK, ASRMCRi_BUFSTALLi);
543
544	/* Set default thresholds for input and output FIFO */
545	fsl_asrc_set_watermarks(pair, ASRC_INPUTFIFO_THRESHOLD,
546				ASRC_INPUTFIFO_THRESHOLD);
547
548	/* Configure the following only for Ideal Ratio mode */
549	if (!ideal)
550		return 0;
551
552	/* Clear ASTSx bit to use Ideal Ratio mode */
553	regmap_update_bits(asrc->regmap, REG_ASRCTR,
554			   ASRCTR_ATSi_MASK(index), 0);
555
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));
560
561	fsl_asrc_sel_proc(inrate, outrate, &pre_proc, &post_proc);
562
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));
568
569	return fsl_asrc_set_ideal_ratio(pair, inrate, outrate);
570}
571
572/**
573 * fsl_asrc_start_pair - Start the assigned ASRC pair
574 * @pair: pointer to pair
575 *
576 * It enables the assigned pair and makes it stopped at the stall level.
577 */
578static void fsl_asrc_start_pair(struct fsl_asrc_pair *pair)
579{
580	struct fsl_asrc *asrc = pair->asrc;
581	enum asrc_pair_index index = pair->index;
582	int reg, retry = 10, i;
583
584	/* Enable the current pair */
585	regmap_update_bits(asrc->regmap, REG_ASRCTR,
586			   ASRCTR_ASRCEi_MASK(index), ASRCTR_ASRCE(index));
587
588	/* Wait for status of initialization */
589	do {
590		udelay(5);
591		regmap_read(asrc->regmap, REG_ASRCFG, &reg);
592		reg &= ASRCFG_INIRQi_MASK(index);
593	} while (!reg && --retry);
594
595	/* Make the input fifo to ASRC STALL level */
596	regmap_read(asrc->regmap, REG_ASRCNCR, &reg);
597	for (i = 0; i < pair->channels * 4; i++)
598		regmap_write(asrc->regmap, REG_ASRDI(index), 0);
599
600	/* Enable overload interrupt */
601	regmap_write(asrc->regmap, REG_ASRIER, ASRIER_AOLIE);
602}
603
604/**
605 * fsl_asrc_stop_pair - Stop the assigned ASRC pair
606 * @pair: pointer to pair
607 */
608static void fsl_asrc_stop_pair(struct fsl_asrc_pair *pair)
609{
610	struct fsl_asrc *asrc = pair->asrc;
611	enum asrc_pair_index index = pair->index;
612
613	/* Stop the current pair */
614	regmap_update_bits(asrc->regmap, REG_ASRCTR,
615			   ASRCTR_ASRCEi_MASK(index), 0);
616}
617
618/**
619 * fsl_asrc_get_dma_channel- Get DMA channel according to the pair and direction.
620 * @pair: pointer to pair
621 * @dir: DMA direction
622 */
623static struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair,
624						 bool dir)
625{
626	struct fsl_asrc *asrc = pair->asrc;
627	enum asrc_pair_index index = pair->index;
628	char name[4];
629
630	sprintf(name, "%cx%c", dir == IN ? 'r' : 't', index + 'a');
631
632	return dma_request_slave_channel(&asrc->pdev->dev, name);
633}
634
635static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream,
636				struct snd_soc_dai *dai)
637{
638	struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
639	struct fsl_asrc_priv *asrc_priv = asrc->private;
640
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);
645
646
647	return snd_pcm_hw_constraint_list(substream->runtime, 0,
648			SNDRV_PCM_HW_PARAM_RATE, &fsl_asrc_rate_constraints);
649}
650
651/* Select proper clock source for internal ratio mode */
652static void fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv,
653				struct fsl_asrc_pair *pair,
654				int in_rate,
655				int out_rate)
656{
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;
661	int i = 0, j = 0;
662
663	rate[IN] = in_rate;
664	rate[OUT] = out_rate;
665
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))
673				break;
674		}
675
676		select_clk[j] = i;
677	}
678
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;
683	}
684
685	config->inclk = select_clk[IN];
686	config->outclk = select_clk[OUT];
687}
688
689static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
690				  struct snd_pcm_hw_params *params,
691				  struct snd_soc_dai *dai)
692{
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;
701	int ret;
702
703	ret = fsl_asrc_request_pair(channels, pair);
704	if (ret) {
705		dev_err(dai->dev, "fail to request asrc pair\n");
706		return ret;
707	}
708
709	pair_priv->config = &config;
710
711	config.pair = pair->index;
712	config.channel_num = channels;
713
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;
719	} else {
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;
724	}
725
726	fsl_asrc_select_clk(asrc_priv, pair,
727			    config.input_sample_rate,
728			    config.output_sample_rate);
729
730	ret = fsl_asrc_config_pair(pair, false);
731	if (ret) {
732		dev_err(dai->dev, "fail to config asrc pair\n");
733		return ret;
734	}
735
736	return 0;
737}
738
739static int fsl_asrc_dai_hw_free(struct snd_pcm_substream *substream,
740				struct snd_soc_dai *dai)
741{
742	struct snd_pcm_runtime *runtime = substream->runtime;
743	struct fsl_asrc_pair *pair = runtime->private_data;
744
745	if (pair)
746		fsl_asrc_release_pair(pair);
747
748	return 0;
749}
750
751static int fsl_asrc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
752				struct snd_soc_dai *dai)
753{
754	struct snd_pcm_runtime *runtime = substream->runtime;
755	struct fsl_asrc_pair *pair = runtime->private_data;
756
757	switch (cmd) {
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);
762		break;
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);
767		break;
768	default:
769		return -EINVAL;
770	}
771
772	return 0;
773}
774
775static 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,
780};
781
782static int fsl_asrc_dai_probe(struct snd_soc_dai *dai)
783{
784	struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
785
786	snd_soc_dai_init_dma_data(dai, &asrc->dma_params_tx,
787				  &asrc->dma_params_rx);
788
789	return 0;
790}
791
792#define FSL_ASRC_FORMATS	(SNDRV_PCM_FMTBIT_S24_LE | \
793				 SNDRV_PCM_FMTBIT_S16_LE | \
794				 SNDRV_PCM_FMTBIT_S24_3LE)
795
796static struct snd_soc_dai_driver fsl_asrc_dai = {
797	.probe = fsl_asrc_dai_probe,
798	.playback = {
799		.stream_name = "ASRC-Playback",
800		.channels_min = 1,
801		.channels_max = 10,
802		.rate_min = 5512,
803		.rate_max = 192000,
804		.rates = SNDRV_PCM_RATE_KNOT,
805		.formats = FSL_ASRC_FORMATS |
806			   SNDRV_PCM_FMTBIT_S8,
807	},
808	.capture = {
809		.stream_name = "ASRC-Capture",
810		.channels_min = 1,
811		.channels_max = 10,
812		.rate_min = 5512,
813		.rate_max = 192000,
814		.rates = SNDRV_PCM_RATE_KNOT,
815		.formats = FSL_ASRC_FORMATS,
816	},
817	.ops = &fsl_asrc_dai_ops,
818};
819
820static bool fsl_asrc_readable_reg(struct device *dev, unsigned int reg)
821{
822	switch (reg) {
823	case REG_ASRCTR:
824	case REG_ASRIER:
825	case REG_ASRCNCR:
826	case REG_ASRCFG:
827	case REG_ASRCSR:
828	case REG_ASRCDR1:
829	case REG_ASRCDR2:
830	case REG_ASRSTR:
831	case REG_ASRPM1:
832	case REG_ASRPM2:
833	case REG_ASRPM3:
834	case REG_ASRPM4:
835	case REG_ASRPM5:
836	case REG_ASRTFR1:
837	case REG_ASRCCR:
838	case REG_ASRDOA:
839	case REG_ASRDOB:
840	case REG_ASRDOC:
841	case REG_ASRIDRHA:
842	case REG_ASRIDRLA:
843	case REG_ASRIDRHB:
844	case REG_ASRIDRLB:
845	case REG_ASRIDRHC:
846	case REG_ASRIDRLC:
847	case REG_ASR76K:
848	case REG_ASR56K:
849	case REG_ASRMCRA:
850	case REG_ASRFSTA:
851	case REG_ASRMCRB:
852	case REG_ASRFSTB:
853	case REG_ASRMCRC:
854	case REG_ASRFSTC:
855	case REG_ASRMCR1A:
856	case REG_ASRMCR1B:
857	case REG_ASRMCR1C:
858		return true;
859	default:
860		return false;
861	}
862}
863
864static bool fsl_asrc_volatile_reg(struct device *dev, unsigned int reg)
865{
866	switch (reg) {
867	case REG_ASRSTR:
868	case REG_ASRDIA:
869	case REG_ASRDIB:
870	case REG_ASRDIC:
871	case REG_ASRDOA:
872	case REG_ASRDOB:
873	case REG_ASRDOC:
874	case REG_ASRFSTA:
875	case REG_ASRFSTB:
876	case REG_ASRFSTC:
877	case REG_ASRCFG:
878		return true;
879	default:
880		return false;
881	}
882}
883
884static bool fsl_asrc_writeable_reg(struct device *dev, unsigned int reg)
885{
886	switch (reg) {
887	case REG_ASRCTR:
888	case REG_ASRIER:
889	case REG_ASRCNCR:
890	case REG_ASRCFG:
891	case REG_ASRCSR:
892	case REG_ASRCDR1:
893	case REG_ASRCDR2:
894	case REG_ASRSTR:
895	case REG_ASRPM1:
896	case REG_ASRPM2:
897	case REG_ASRPM3:
898	case REG_ASRPM4:
899	case REG_ASRPM5:
900	case REG_ASRTFR1:
901	case REG_ASRCCR:
902	case REG_ASRDIA:
903	case REG_ASRDIB:
904	case REG_ASRDIC:
905	case REG_ASRIDRHA:
906	case REG_ASRIDRLA:
907	case REG_ASRIDRHB:
908	case REG_ASRIDRLB:
909	case REG_ASRIDRHC:
910	case REG_ASRIDRLC:
911	case REG_ASR76K:
912	case REG_ASR56K:
913	case REG_ASRMCRA:
914	case REG_ASRMCRB:
915	case REG_ASRMCRC:
916	case REG_ASRMCR1A:
917	case REG_ASRMCR1B:
918	case REG_ASRMCR1C:
919		return true;
920	default:
921		return false;
922	}
923}
924
925static 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 },
947};
948
949static const struct regmap_config fsl_asrc_regmap_config = {
950	.reg_bits = 32,
951	.reg_stride = 4,
952	.val_bits = 32,
953
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,
961};
962
963/**
964 * fsl_asrc_init - Initialize ASRC registers with a default configuration
965 * @asrc: ASRC context
966 */
967static int fsl_asrc_init(struct fsl_asrc *asrc)
968{
969	unsigned long ipg_rate;
970
971	/* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
972	regmap_write(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEN);
973
974	/* Disable interrupt by default */
975	regmap_write(asrc->regmap, REG_ASRIER, 0x0);
976
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);
983
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));
987
988	/*
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
992	 */
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);
996}
997
998/**
999 * fsl_asrc_isr- Interrupt handler for ASRC
1000 * @irq: irq number
1001 * @dev_id: ASRC context
1002 */
1003static irqreturn_t fsl_asrc_isr(int irq, void *dev_id)
1004{
1005	struct fsl_asrc *asrc = (struct fsl_asrc *)dev_id;
1006	struct device *dev = &asrc->pdev->dev;
1007	enum asrc_pair_index index;
1008	u32 status;
1009
1010	regmap_read(asrc->regmap, REG_ASRSTR, &status);
1011
1012	/* Clean overload error */
1013	regmap_write(asrc->regmap, REG_ASRSTR, ASRSTR_AOLE);
1014
1015	/*
1016	 * We here use dev_dbg() for all exceptions because ASRC itself does
1017	 * not care if FIFO overflowed or underrun while a warning in the
1018	 * interrupt would result a ridged conversion.
1019	 */
1020	for (index = ASRC_PAIR_A; index < ASRC_PAIR_MAX_NUM; index++) {
1021		if (!asrc->pair[index])
1022			continue;
1023
1024		if (status & ASRSTR_ATQOL) {
1025			asrc->pair[index]->error |= ASRC_TASK_Q_OVERLOAD;
1026			dev_dbg(dev, "ASRC Task Queue FIFO overload\n");
1027		}
1028
1029		if (status & ASRSTR_AOOL(index)) {
1030			asrc->pair[index]->error |= ASRC_OUTPUT_TASK_OVERLOAD;
1031			pair_dbg("Output Task Overload\n");
1032		}
1033
1034		if (status & ASRSTR_AIOL(index)) {
1035			asrc->pair[index]->error |= ASRC_INPUT_TASK_OVERLOAD;
1036			pair_dbg("Input Task Overload\n");
1037		}
1038
1039		if (status & ASRSTR_AODO(index)) {
1040			asrc->pair[index]->error |= ASRC_OUTPUT_BUFFER_OVERFLOW;
1041			pair_dbg("Output Data Buffer has overflowed\n");
1042		}
1043
1044		if (status & ASRSTR_AIDU(index)) {
1045			asrc->pair[index]->error |= ASRC_INPUT_BUFFER_UNDERRUN;
1046			pair_dbg("Input Data Buffer has underflowed\n");
1047		}
1048	}
1049
1050	return IRQ_HANDLED;
1051}
1052
1053static int fsl_asrc_get_fifo_addr(u8 dir, enum asrc_pair_index index)
1054{
1055	return REG_ASRDx(dir, index);
1056}
1057
1058static int fsl_asrc_probe(struct platform_device *pdev)
1059{
1060	struct device_node *np = pdev->dev.of_node;
1061	struct fsl_asrc_priv *asrc_priv;
1062	struct fsl_asrc *asrc;
1063	struct resource *res;
1064	void __iomem *regs;
1065	int irq, ret, i;
1066	u32 map_idx;
1067	char tmp[16];
1068	u32 width;
1069
1070	asrc = devm_kzalloc(&pdev->dev, sizeof(*asrc), GFP_KERNEL);
1071	if (!asrc)
1072		return -ENOMEM;
1073
1074	asrc_priv = devm_kzalloc(&pdev->dev, sizeof(*asrc_priv), GFP_KERNEL);
1075	if (!asrc_priv)
1076		return -ENOMEM;
1077
1078	asrc->pdev = pdev;
1079	asrc->private = asrc_priv;
1080
1081	/* Get the addresses and IRQ */
1082	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1083	regs = devm_ioremap_resource(&pdev->dev, res);
1084	if (IS_ERR(regs))
1085		return PTR_ERR(regs);
1086
1087	asrc->paddr = res->start;
1088
1089	asrc->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "mem", regs,
1090						 &fsl_asrc_regmap_config);
1091	if (IS_ERR(asrc->regmap)) {
1092		dev_err(&pdev->dev, "failed to init regmap\n");
1093		return PTR_ERR(asrc->regmap);
1094	}
1095
1096	irq = platform_get_irq(pdev, 0);
1097	if (irq < 0)
1098		return irq;
1099
1100	ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0,
1101			       dev_name(&pdev->dev), asrc);
1102	if (ret) {
1103		dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret);
1104		return ret;
1105	}
1106
1107	asrc->mem_clk = devm_clk_get(&pdev->dev, "mem");
1108	if (IS_ERR(asrc->mem_clk)) {
1109		dev_err(&pdev->dev, "failed to get mem clock\n");
1110		return PTR_ERR(asrc->mem_clk);
1111	}
1112
1113	asrc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
1114	if (IS_ERR(asrc->ipg_clk)) {
1115		dev_err(&pdev->dev, "failed to get ipg clock\n");
1116		return PTR_ERR(asrc->ipg_clk);
1117	}
1118
1119	asrc->spba_clk = devm_clk_get(&pdev->dev, "spba");
1120	if (IS_ERR(asrc->spba_clk))
1121		dev_warn(&pdev->dev, "failed to get spba clock\n");
1122
1123	for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
1124		sprintf(tmp, "asrck_%x", i);
1125		asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp);
1126		if (IS_ERR(asrc_priv->asrck_clk[i])) {
1127			dev_err(&pdev->dev, "failed to get %s clock\n", tmp);
1128			return PTR_ERR(asrc_priv->asrck_clk[i]);
1129		}
1130	}
1131
1132	asrc_priv->soc = of_device_get_match_data(&pdev->dev);
1133	if (!asrc_priv->soc) {
1134		dev_err(&pdev->dev, "failed to get soc data\n");
1135		return -ENODEV;
1136	}
1137
1138	asrc->use_edma = asrc_priv->soc->use_edma;
1139	asrc->get_dma_channel = fsl_asrc_get_dma_channel;
1140	asrc->request_pair = fsl_asrc_request_pair;
1141	asrc->release_pair = fsl_asrc_release_pair;
1142	asrc->get_fifo_addr = fsl_asrc_get_fifo_addr;
1143	asrc->pair_priv_size = sizeof(struct fsl_asrc_pair_priv);
1144
1145	if (of_device_is_compatible(np, "fsl,imx35-asrc")) {
1146		asrc_priv->clk_map[IN] = input_clk_map_imx35;
1147		asrc_priv->clk_map[OUT] = output_clk_map_imx35;
1148	} else if (of_device_is_compatible(np, "fsl,imx53-asrc")) {
1149		asrc_priv->clk_map[IN] = input_clk_map_imx53;
1150		asrc_priv->clk_map[OUT] = output_clk_map_imx53;
1151	} else if (of_device_is_compatible(np, "fsl,imx8qm-asrc") ||
1152		   of_device_is_compatible(np, "fsl,imx8qxp-asrc")) {
1153		ret = of_property_read_u32(np, "fsl,asrc-clk-map", &map_idx);
1154		if (ret) {
1155			dev_err(&pdev->dev, "failed to get clk map index\n");
1156			return ret;
1157		}
1158
1159		if (map_idx > 1) {
1160			dev_err(&pdev->dev, "unsupported clk map index\n");
1161			return -EINVAL;
1162		}
1163		if (of_device_is_compatible(np, "fsl,imx8qm-asrc")) {
1164			asrc_priv->clk_map[IN] = clk_map_imx8qm[map_idx];
1165			asrc_priv->clk_map[OUT] = clk_map_imx8qm[map_idx];
1166		} else {
1167			asrc_priv->clk_map[IN] = clk_map_imx8qxp[map_idx];
1168			asrc_priv->clk_map[OUT] = clk_map_imx8qxp[map_idx];
1169		}
1170	}
1171
1172	ret = fsl_asrc_init(asrc);
1173	if (ret) {
1174		dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
1175		return ret;
1176	}
1177
1178	asrc->channel_avail = 10;
1179
1180	ret = of_property_read_u32(np, "fsl,asrc-rate",
1181				   &asrc->asrc_rate);
1182	if (ret) {
1183		dev_err(&pdev->dev, "failed to get output rate\n");
1184		return ret;
1185	}
1186
1187	ret = of_property_read_u32(np, "fsl,asrc-format", &asrc->asrc_format);
1188	if (ret) {
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		}
1208	}
1209
1210	if (!(FSL_ASRC_FORMATS & (1ULL << asrc->asrc_format))) {
1211		dev_warn(&pdev->dev, "unsupported width, use default S24_LE\n");
1212		asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
1213	}
1214
1215	platform_set_drvdata(pdev, asrc);
1216	pm_runtime_enable(&pdev->dev);
1217	spin_lock_init(&asrc->lock);
1218	regcache_cache_only(asrc->regmap, true);
1219
1220	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component,
1221					      &fsl_asrc_dai, 1);
1222	if (ret) {
1223		dev_err(&pdev->dev, "failed to register ASoC DAI\n");
1224		return ret;
1225	}
1226
1227	return 0;
1228}
1229
1230#ifdef CONFIG_PM
1231static int fsl_asrc_runtime_resume(struct device *dev)
1232{
1233	struct fsl_asrc *asrc = dev_get_drvdata(dev);
1234	struct fsl_asrc_priv *asrc_priv = asrc->private;
1235	int i, ret;
1236	u32 asrctr;
1237
1238	ret = clk_prepare_enable(asrc->mem_clk);
1239	if (ret)
1240		return ret;
1241	ret = clk_prepare_enable(asrc->ipg_clk);
1242	if (ret)
1243		goto disable_mem_clk;
1244	if (!IS_ERR(asrc->spba_clk)) {
1245		ret = clk_prepare_enable(asrc->spba_clk);
1246		if (ret)
1247			goto disable_ipg_clk;
1248	}
1249	for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
1250		ret = clk_prepare_enable(asrc_priv->asrck_clk[i]);
1251		if (ret)
1252			goto disable_asrck_clk;
1253	}
1254
1255	/* Stop all pairs provisionally */
1256	regmap_read(asrc->regmap, REG_ASRCTR, &asrctr);
1257	regmap_update_bits(asrc->regmap, REG_ASRCTR,
1258			   ASRCTR_ASRCEi_ALL_MASK, 0);
1259
1260	/* Restore all registers */
1261	regcache_cache_only(asrc->regmap, false);
1262	regcache_mark_dirty(asrc->regmap);
1263	regcache_sync(asrc->regmap);
1264
1265	regmap_update_bits(asrc->regmap, REG_ASRCFG,
1266			   ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
1267			   ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
1268
1269	/* Restart enabled pairs */
1270	regmap_update_bits(asrc->regmap, REG_ASRCTR,
1271			   ASRCTR_ASRCEi_ALL_MASK, asrctr);
1272
1273	return 0;
1274
1275disable_asrck_clk:
1276	for (i--; i >= 0; i--)
1277		clk_disable_unprepare(asrc_priv->asrck_clk[i]);
1278	if (!IS_ERR(asrc->spba_clk))
1279		clk_disable_unprepare(asrc->spba_clk);
1280disable_ipg_clk:
1281	clk_disable_unprepare(asrc->ipg_clk);
1282disable_mem_clk:
1283	clk_disable_unprepare(asrc->mem_clk);
1284	return ret;
1285}
1286
1287static int fsl_asrc_runtime_suspend(struct device *dev)
1288{
1289	struct fsl_asrc *asrc = dev_get_drvdata(dev);
1290	struct fsl_asrc_priv *asrc_priv = asrc->private;
1291	int i;
1292
1293	regmap_read(asrc->regmap, REG_ASRCFG,
1294		    &asrc_priv->regcache_cfg);
1295
1296	regcache_cache_only(asrc->regmap, true);
1297
1298	for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
1299		clk_disable_unprepare(asrc_priv->asrck_clk[i]);
1300	if (!IS_ERR(asrc->spba_clk))
1301		clk_disable_unprepare(asrc->spba_clk);
1302	clk_disable_unprepare(asrc->ipg_clk);
1303	clk_disable_unprepare(asrc->mem_clk);
1304
1305	return 0;
1306}
1307#endif /* CONFIG_PM */
1308
1309static const struct dev_pm_ops fsl_asrc_pm = {
1310	SET_RUNTIME_PM_OPS(fsl_asrc_runtime_suspend, fsl_asrc_runtime_resume, NULL)
1311	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1312				pm_runtime_force_resume)
1313};
1314
1315static const struct fsl_asrc_soc_data fsl_asrc_imx35_data = {
1316	.use_edma = false,
1317	.channel_bits = 3,
1318};
1319
1320static const struct fsl_asrc_soc_data fsl_asrc_imx53_data = {
1321	.use_edma = false,
1322	.channel_bits = 4,
1323};
1324
1325static const struct fsl_asrc_soc_data fsl_asrc_imx8qm_data = {
1326	.use_edma = true,
1327	.channel_bits = 4,
1328};
1329
1330static const struct fsl_asrc_soc_data fsl_asrc_imx8qxp_data = {
1331	.use_edma = true,
1332	.channel_bits = 4,
1333};
1334
1335static const struct of_device_id fsl_asrc_ids[] = {
1336	{ .compatible = "fsl,imx35-asrc", .data = &fsl_asrc_imx35_data },
1337	{ .compatible = "fsl,imx53-asrc", .data = &fsl_asrc_imx53_data },
1338	{ .compatible = "fsl,imx8qm-asrc", .data = &fsl_asrc_imx8qm_data },
1339	{ .compatible = "fsl,imx8qxp-asrc", .data = &fsl_asrc_imx8qxp_data },
1340	{}
1341};
1342MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
1343
1344static struct platform_driver fsl_asrc_driver = {
1345	.probe = fsl_asrc_probe,
1346	.driver = {
1347		.name = "fsl-asrc",
1348		.of_match_table = fsl_asrc_ids,
1349		.pm = &fsl_asrc_pm,
1350	},
1351};
1352module_platform_driver(fsl_asrc_driver);
1353
1354MODULE_DESCRIPTION("Freescale ASRC ASoC driver");
1355MODULE_AUTHOR("Nicolin Chen <nicoleotsuka@gmail.com>");
1356MODULE_ALIAS("platform:fsl-asrc");
1357MODULE_LICENSE("GPL v2");
1358