Unverified Commit 4aecaa0a authored by S.j. Wang's avatar S.j. Wang Committed by Mark Brown
Browse files

ASoC: fsl_asrc: replace the process_option table with function



When we want to support more sample rate, for example 12kHz/24kHz
we need update the process_option table, if we want to support more
sample rate next time, the table need to be updated again. which
is not flexible.

We got a function fsl_asrc_sel_proc to replace the table, which can
give the pre-processing and post-processing options according to
the sample rate.

Signed-off-by: default avatarShengjiu Wang <shengjiu.wang@nxp.com>
Acked-by: default avatarNicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent c8609f38
Loading
Loading
Loading
Loading
+51 −20
Original line number Original line Diff line number Diff line
@@ -26,24 +26,6 @@
#define pair_dbg(fmt, ...) \
#define pair_dbg(fmt, ...) \
	dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
	dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)


/* Sample rates are aligned with that defined in pcm.h file */
static const u8 process_option[][12][2] = {
	/* 8kHz 11.025kHz 16kHz 22.05kHz 32kHz 44.1kHz 48kHz   64kHz   88.2kHz 96kHz   176kHz  192kHz */
	{{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},	/* 5512Hz */
	{{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},	/* 8kHz */
	{{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},	/* 11025Hz */
	{{1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},	/* 16kHz */
	{{1, 2}, {1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},	/* 22050Hz */
	{{1, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},},	/* 32kHz */
	{{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},},	/* 44.1kHz */
	{{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},},	/* 48kHz */
	{{2, 2}, {2, 2}, {2, 2}, {2, 1}, {1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},},	/* 64kHz */
	{{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},},	/* 88.2kHz */
	{{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},},	/* 96kHz */
	{{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},	/* 176kHz */
	{{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},	/* 192kHz */
};

/* Corresponding to process_option */
/* Corresponding to process_option */
static int supported_input_rate[] = {
static int supported_input_rate[] = {
	5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200,
	5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200,
@@ -79,6 +61,52 @@ static unsigned char output_clk_map_imx53[] = {


static unsigned char *clk_map[2];
static unsigned char *clk_map[2];


/**
 * Select the pre-processing and post-processing options
 * Make sure to exclude following unsupported cases before
 * calling this function:
 * 1) inrate > 8.125 * outrate
 * 2) inrate > 16.125 * outrate
 *
 * inrate: input sample rate
 * outrate: output sample rate
 * pre_proc: return value for pre-processing option
 * post_proc: return value for post-processing option
 */
static void fsl_asrc_sel_proc(int inrate, int outrate,
			     int *pre_proc, int *post_proc)
{
	bool post_proc_cond2;
	bool post_proc_cond0;

	/* select pre_proc between [0, 2] */
	if (inrate * 8 > 33 * outrate)
		*pre_proc = 2;
	else if (inrate * 8 > 15 * outrate) {
		if (inrate > 152000)
			*pre_proc = 2;
		else
			*pre_proc = 1;
	} else if (inrate < 76000)
		*pre_proc = 0;
	else if (inrate > 152000)
		*pre_proc = 2;
	else
		*pre_proc = 1;

	/* Condition for selection of post-processing */
	post_proc_cond2 = (inrate * 15 > outrate * 16 && outrate < 56000) ||
			  (inrate > 56000 && outrate < 56000);
	post_proc_cond0 = inrate * 23 < outrate * 8;

	if (post_proc_cond2)
		*post_proc = 2;
	else if (post_proc_cond0)
		*post_proc = 0;
	else
		*post_proc = 1;
}

/**
/**
 * Request ASRC pair
 * Request ASRC pair
 *
 *
@@ -239,6 +267,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
	u32 inrate, outrate, indiv, outdiv;
	u32 inrate, outrate, indiv, outdiv;
	u32 clk_index[2], div[2];
	u32 clk_index[2], div[2];
	int in, out, channels;
	int in, out, channels;
	int pre_proc, post_proc;
	struct clk *clk;
	struct clk *clk;
	bool ideal;
	bool ideal;


@@ -377,11 +406,13 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
			   ASRCTR_IDRi_MASK(index) | ASRCTR_USRi_MASK(index),
			   ASRCTR_IDRi_MASK(index) | ASRCTR_USRi_MASK(index),
			   ASRCTR_IDR(index) | ASRCTR_USR(index));
			   ASRCTR_IDR(index) | ASRCTR_USR(index));


	fsl_asrc_sel_proc(inrate, outrate, &pre_proc, &post_proc);

	/* Apply configurations for pre- and post-processing */
	/* Apply configurations for pre- and post-processing */
	regmap_update_bits(asrc_priv->regmap, REG_ASRCFG,
	regmap_update_bits(asrc_priv->regmap, REG_ASRCFG,
			   ASRCFG_PREMODi_MASK(index) |	ASRCFG_POSTMODi_MASK(index),
			   ASRCFG_PREMODi_MASK(index) |	ASRCFG_POSTMODi_MASK(index),
			   ASRCFG_PREMOD(index, process_option[in][out][0]) |
			   ASRCFG_PREMOD(index, pre_proc) |
			   ASRCFG_POSTMOD(index, process_option[in][out][1]));
			   ASRCFG_POSTMOD(index, post_proc));


	return fsl_asrc_set_ideal_ratio(pair, inrate, outrate);
	return fsl_asrc_set_ideal_ratio(pair, inrate, outrate);
}
}