cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fsl_asrc.c (38688B)


      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/dma/imx-dma.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, j;
    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_runtime_resume(struct device *dev);
   1059static int fsl_asrc_runtime_suspend(struct device *dev);
   1060
   1061static int fsl_asrc_probe(struct platform_device *pdev)
   1062{
   1063	struct device_node *np = pdev->dev.of_node;
   1064	struct fsl_asrc_priv *asrc_priv;
   1065	struct fsl_asrc *asrc;
   1066	struct resource *res;
   1067	void __iomem *regs;
   1068	int irq, ret, i;
   1069	u32 map_idx;
   1070	char tmp[16];
   1071	u32 width;
   1072
   1073	asrc = devm_kzalloc(&pdev->dev, sizeof(*asrc), GFP_KERNEL);
   1074	if (!asrc)
   1075		return -ENOMEM;
   1076
   1077	asrc_priv = devm_kzalloc(&pdev->dev, sizeof(*asrc_priv), GFP_KERNEL);
   1078	if (!asrc_priv)
   1079		return -ENOMEM;
   1080
   1081	asrc->pdev = pdev;
   1082	asrc->private = asrc_priv;
   1083
   1084	/* Get the addresses and IRQ */
   1085	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
   1086	if (IS_ERR(regs))
   1087		return PTR_ERR(regs);
   1088
   1089	asrc->paddr = res->start;
   1090
   1091	asrc->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &fsl_asrc_regmap_config);
   1092	if (IS_ERR(asrc->regmap)) {
   1093		dev_err(&pdev->dev, "failed to init regmap\n");
   1094		return PTR_ERR(asrc->regmap);
   1095	}
   1096
   1097	irq = platform_get_irq(pdev, 0);
   1098	if (irq < 0)
   1099		return irq;
   1100
   1101	ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0,
   1102			       dev_name(&pdev->dev), asrc);
   1103	if (ret) {
   1104		dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret);
   1105		return ret;
   1106	}
   1107
   1108	asrc->mem_clk = devm_clk_get(&pdev->dev, "mem");
   1109	if (IS_ERR(asrc->mem_clk)) {
   1110		dev_err(&pdev->dev, "failed to get mem clock\n");
   1111		return PTR_ERR(asrc->mem_clk);
   1112	}
   1113
   1114	asrc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
   1115	if (IS_ERR(asrc->ipg_clk)) {
   1116		dev_err(&pdev->dev, "failed to get ipg clock\n");
   1117		return PTR_ERR(asrc->ipg_clk);
   1118	}
   1119
   1120	asrc->spba_clk = devm_clk_get(&pdev->dev, "spba");
   1121	if (IS_ERR(asrc->spba_clk))
   1122		dev_warn(&pdev->dev, "failed to get spba clock\n");
   1123
   1124	for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
   1125		sprintf(tmp, "asrck_%x", i);
   1126		asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp);
   1127		if (IS_ERR(asrc_priv->asrck_clk[i])) {
   1128			dev_err(&pdev->dev, "failed to get %s clock\n", tmp);
   1129			return PTR_ERR(asrc_priv->asrck_clk[i]);
   1130		}
   1131	}
   1132
   1133	asrc_priv->soc = of_device_get_match_data(&pdev->dev);
   1134	asrc->use_edma = asrc_priv->soc->use_edma;
   1135	asrc->get_dma_channel = fsl_asrc_get_dma_channel;
   1136	asrc->request_pair = fsl_asrc_request_pair;
   1137	asrc->release_pair = fsl_asrc_release_pair;
   1138	asrc->get_fifo_addr = fsl_asrc_get_fifo_addr;
   1139	asrc->pair_priv_size = sizeof(struct fsl_asrc_pair_priv);
   1140
   1141	if (of_device_is_compatible(np, "fsl,imx35-asrc")) {
   1142		asrc_priv->clk_map[IN] = input_clk_map_imx35;
   1143		asrc_priv->clk_map[OUT] = output_clk_map_imx35;
   1144	} else if (of_device_is_compatible(np, "fsl,imx53-asrc")) {
   1145		asrc_priv->clk_map[IN] = input_clk_map_imx53;
   1146		asrc_priv->clk_map[OUT] = output_clk_map_imx53;
   1147	} else if (of_device_is_compatible(np, "fsl,imx8qm-asrc") ||
   1148		   of_device_is_compatible(np, "fsl,imx8qxp-asrc")) {
   1149		ret = of_property_read_u32(np, "fsl,asrc-clk-map", &map_idx);
   1150		if (ret) {
   1151			dev_err(&pdev->dev, "failed to get clk map index\n");
   1152			return ret;
   1153		}
   1154
   1155		if (map_idx > 1) {
   1156			dev_err(&pdev->dev, "unsupported clk map index\n");
   1157			return -EINVAL;
   1158		}
   1159		if (of_device_is_compatible(np, "fsl,imx8qm-asrc")) {
   1160			asrc_priv->clk_map[IN] = clk_map_imx8qm[map_idx];
   1161			asrc_priv->clk_map[OUT] = clk_map_imx8qm[map_idx];
   1162		} else {
   1163			asrc_priv->clk_map[IN] = clk_map_imx8qxp[map_idx];
   1164			asrc_priv->clk_map[OUT] = clk_map_imx8qxp[map_idx];
   1165		}
   1166	}
   1167
   1168	asrc->channel_avail = 10;
   1169
   1170	ret = of_property_read_u32(np, "fsl,asrc-rate",
   1171				   &asrc->asrc_rate);
   1172	if (ret) {
   1173		dev_err(&pdev->dev, "failed to get output rate\n");
   1174		return ret;
   1175	}
   1176
   1177	ret = of_property_read_u32(np, "fsl,asrc-format", &asrc->asrc_format);
   1178	if (ret) {
   1179		ret = of_property_read_u32(np, "fsl,asrc-width", &width);
   1180		if (ret) {
   1181			dev_err(&pdev->dev, "failed to decide output format\n");
   1182			return ret;
   1183		}
   1184
   1185		switch (width) {
   1186		case 16:
   1187			asrc->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
   1188			break;
   1189		case 24:
   1190			asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
   1191			break;
   1192		default:
   1193			dev_warn(&pdev->dev,
   1194				 "unsupported width, use default S24_LE\n");
   1195			asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
   1196			break;
   1197		}
   1198	}
   1199
   1200	if (!(FSL_ASRC_FORMATS & (1ULL << asrc->asrc_format))) {
   1201		dev_warn(&pdev->dev, "unsupported width, use default S24_LE\n");
   1202		asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
   1203	}
   1204
   1205	platform_set_drvdata(pdev, asrc);
   1206	spin_lock_init(&asrc->lock);
   1207	pm_runtime_enable(&pdev->dev);
   1208	if (!pm_runtime_enabled(&pdev->dev)) {
   1209		ret = fsl_asrc_runtime_resume(&pdev->dev);
   1210		if (ret)
   1211			goto err_pm_disable;
   1212	}
   1213
   1214	ret = pm_runtime_resume_and_get(&pdev->dev);
   1215	if (ret < 0)
   1216		goto err_pm_get_sync;
   1217
   1218	ret = fsl_asrc_init(asrc);
   1219	if (ret) {
   1220		dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
   1221		goto err_pm_get_sync;
   1222	}
   1223
   1224	ret = pm_runtime_put_sync(&pdev->dev);
   1225	if (ret < 0)
   1226		goto err_pm_get_sync;
   1227
   1228	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component,
   1229					      &fsl_asrc_dai, 1);
   1230	if (ret) {
   1231		dev_err(&pdev->dev, "failed to register ASoC DAI\n");
   1232		goto err_pm_get_sync;
   1233	}
   1234
   1235	return 0;
   1236
   1237err_pm_get_sync:
   1238	if (!pm_runtime_status_suspended(&pdev->dev))
   1239		fsl_asrc_runtime_suspend(&pdev->dev);
   1240err_pm_disable:
   1241	pm_runtime_disable(&pdev->dev);
   1242	return ret;
   1243}
   1244
   1245static int fsl_asrc_remove(struct platform_device *pdev)
   1246{
   1247	pm_runtime_disable(&pdev->dev);
   1248	if (!pm_runtime_status_suspended(&pdev->dev))
   1249		fsl_asrc_runtime_suspend(&pdev->dev);
   1250
   1251	return 0;
   1252}
   1253
   1254static int fsl_asrc_runtime_resume(struct device *dev)
   1255{
   1256	struct fsl_asrc *asrc = dev_get_drvdata(dev);
   1257	struct fsl_asrc_priv *asrc_priv = asrc->private;
   1258	int i, ret;
   1259	u32 asrctr;
   1260
   1261	ret = clk_prepare_enable(asrc->mem_clk);
   1262	if (ret)
   1263		return ret;
   1264	ret = clk_prepare_enable(asrc->ipg_clk);
   1265	if (ret)
   1266		goto disable_mem_clk;
   1267	if (!IS_ERR(asrc->spba_clk)) {
   1268		ret = clk_prepare_enable(asrc->spba_clk);
   1269		if (ret)
   1270			goto disable_ipg_clk;
   1271	}
   1272	for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
   1273		ret = clk_prepare_enable(asrc_priv->asrck_clk[i]);
   1274		if (ret)
   1275			goto disable_asrck_clk;
   1276	}
   1277
   1278	/* Stop all pairs provisionally */
   1279	regmap_read(asrc->regmap, REG_ASRCTR, &asrctr);
   1280	regmap_update_bits(asrc->regmap, REG_ASRCTR,
   1281			   ASRCTR_ASRCEi_ALL_MASK, 0);
   1282
   1283	/* Restore all registers */
   1284	regcache_cache_only(asrc->regmap, false);
   1285	regcache_mark_dirty(asrc->regmap);
   1286	regcache_sync(asrc->regmap);
   1287
   1288	regmap_update_bits(asrc->regmap, REG_ASRCFG,
   1289			   ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
   1290			   ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
   1291
   1292	/* Restart enabled pairs */
   1293	regmap_update_bits(asrc->regmap, REG_ASRCTR,
   1294			   ASRCTR_ASRCEi_ALL_MASK, asrctr);
   1295
   1296	return 0;
   1297
   1298disable_asrck_clk:
   1299	for (i--; i >= 0; i--)
   1300		clk_disable_unprepare(asrc_priv->asrck_clk[i]);
   1301	if (!IS_ERR(asrc->spba_clk))
   1302		clk_disable_unprepare(asrc->spba_clk);
   1303disable_ipg_clk:
   1304	clk_disable_unprepare(asrc->ipg_clk);
   1305disable_mem_clk:
   1306	clk_disable_unprepare(asrc->mem_clk);
   1307	return ret;
   1308}
   1309
   1310static int fsl_asrc_runtime_suspend(struct device *dev)
   1311{
   1312	struct fsl_asrc *asrc = dev_get_drvdata(dev);
   1313	struct fsl_asrc_priv *asrc_priv = asrc->private;
   1314	int i;
   1315
   1316	regmap_read(asrc->regmap, REG_ASRCFG,
   1317		    &asrc_priv->regcache_cfg);
   1318
   1319	regcache_cache_only(asrc->regmap, true);
   1320
   1321	for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
   1322		clk_disable_unprepare(asrc_priv->asrck_clk[i]);
   1323	if (!IS_ERR(asrc->spba_clk))
   1324		clk_disable_unprepare(asrc->spba_clk);
   1325	clk_disable_unprepare(asrc->ipg_clk);
   1326	clk_disable_unprepare(asrc->mem_clk);
   1327
   1328	return 0;
   1329}
   1330
   1331static const struct dev_pm_ops fsl_asrc_pm = {
   1332	SET_RUNTIME_PM_OPS(fsl_asrc_runtime_suspend, fsl_asrc_runtime_resume, NULL)
   1333	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
   1334				pm_runtime_force_resume)
   1335};
   1336
   1337static const struct fsl_asrc_soc_data fsl_asrc_imx35_data = {
   1338	.use_edma = false,
   1339	.channel_bits = 3,
   1340};
   1341
   1342static const struct fsl_asrc_soc_data fsl_asrc_imx53_data = {
   1343	.use_edma = false,
   1344	.channel_bits = 4,
   1345};
   1346
   1347static const struct fsl_asrc_soc_data fsl_asrc_imx8qm_data = {
   1348	.use_edma = true,
   1349	.channel_bits = 4,
   1350};
   1351
   1352static const struct fsl_asrc_soc_data fsl_asrc_imx8qxp_data = {
   1353	.use_edma = true,
   1354	.channel_bits = 4,
   1355};
   1356
   1357static const struct of_device_id fsl_asrc_ids[] = {
   1358	{ .compatible = "fsl,imx35-asrc", .data = &fsl_asrc_imx35_data },
   1359	{ .compatible = "fsl,imx53-asrc", .data = &fsl_asrc_imx53_data },
   1360	{ .compatible = "fsl,imx8qm-asrc", .data = &fsl_asrc_imx8qm_data },
   1361	{ .compatible = "fsl,imx8qxp-asrc", .data = &fsl_asrc_imx8qxp_data },
   1362	{}
   1363};
   1364MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
   1365
   1366static struct platform_driver fsl_asrc_driver = {
   1367	.probe = fsl_asrc_probe,
   1368	.remove = fsl_asrc_remove,
   1369	.driver = {
   1370		.name = "fsl-asrc",
   1371		.of_match_table = fsl_asrc_ids,
   1372		.pm = &fsl_asrc_pm,
   1373	},
   1374};
   1375module_platform_driver(fsl_asrc_driver);
   1376
   1377MODULE_DESCRIPTION("Freescale ASRC ASoC driver");
   1378MODULE_AUTHOR("Nicolin Chen <nicoleotsuka@gmail.com>");
   1379MODULE_ALIAS("platform:fsl-asrc");
   1380MODULE_LICENSE("GPL v2");