Esempio n. 1
0
File: src.c Progetto: Abioy/kasan
static int rsnd_src_set_convert_rate(struct rsnd_mod *mod)
{
	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	struct rsnd_src *src = rsnd_mod_to_src(mod);
	u32 convert_rate = rsnd_src_convert_rate(src);
	u32 fsrate = 0;

	if (convert_rate)
		fsrate = 0x0400000 / convert_rate * runtime->rate;

	/* set/clear soft reset */
	rsnd_mod_write(mod, SRC_SWRSR, 0);
	rsnd_mod_write(mod, SRC_SWRSR, 1);

	/* Set channel number and output bit length */
	rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod));

	/* Enable the initial value of IFS */
	if (fsrate) {
		rsnd_mod_write(mod, SRC_IFSCR, 1);

		/* Set initial value of IFS */
		rsnd_mod_write(mod, SRC_IFSVR, fsrate);
	}

	/* use DMA transfer */
	rsnd_mod_write(mod, SRC_BUSIF_MODE, 1);

	return 0;
}
Esempio n. 2
0
/*
 *		Gen2 functions
 */
static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
					  struct rsnd_dai *rdai)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	struct rsnd_src *src = rsnd_mod_to_src(mod);
	uint ratio;
	int ret;

	/* 6 - 1/6 are very enough ratio for SRC_BSDSR */
	if (!rsnd_src_convert_rate(src))
		ratio = 0;
	else if (rsnd_src_convert_rate(src) > runtime->rate)
		ratio = 100 * rsnd_src_convert_rate(src) / runtime->rate;
	else
		ratio = 100 * runtime->rate / rsnd_src_convert_rate(src);

	if (ratio > 600) {
		dev_err(dev, "FSO/FSI ratio error\n");
		return -EINVAL;
	}

	ret = rsnd_src_set_convert_rate(mod, rdai);
	if (ret < 0)
		return ret;

	rsnd_mod_write(mod, SRC_SRCCR, 0x00011110);

	switch (rsnd_mod_id(mod)) {
	case 5:
	case 6:
	case 7:
	case 8:
		rsnd_mod_write(mod, SRC_BSDSR, 0x02400000);
		break;
	default:
		rsnd_mod_write(mod, SRC_BSDSR, 0x01800000);
		break;
	}

	rsnd_mod_write(mod, SRC_BSISR, 0x00100060);

	return 0;
}
Esempio n. 3
0
static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod,
					    struct rsnd_dai *rdai,
					    struct rsnd_dai_stream *io)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	struct rsnd_src *src = rsnd_mod_to_src(mod);
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	u32 convert_rate = rsnd_src_convert_rate(src);
	u32 mask;
	u32 val;
	int shift;
	int id = rsnd_mod_id(mod);
	int ret;

	/*
	 * SRC_TIMING_SELECT
	 */
	shift	= (id % 4) * 8;
	mask	= 0x1F << shift;

	/*
	 * ADG is used as source clock if SRC was used,
	 * then, SSI WS is used as destination clock.
	 * SSI WS is used as source clock if SRC is not used
	 * (when playback, source/destination become reverse when capture)
	 */
	ret = 0;
	if (convert_rate) {
		/* use ADG */
		val = 0;
		ret = rsnd_adg_set_convert_clk_gen1(priv, mod,
						    runtime->rate,
						    convert_rate);
	} else if (8 == id) {
		/* use SSI WS, but SRU8 is special */
		val = id << shift;
	} else {
		/* use SSI WS */
		val = (id + 1) << shift;
	}

	if (ret < 0)
		return ret;

	switch (id / 4) {
	case 0:
		rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val);
		break;
	case 1:
		rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val);
		break;
	case 2:
		rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val);
		break;
	}

	return 0;
}
Esempio n. 4
0
File: src.c Progetto: MaxChina/linux
static int rsnd_src_stop(struct rsnd_mod *mod,
			 struct rsnd_dai *rdai)
{
	struct rsnd_src *src = rsnd_mod_to_src(mod);

	if (rsnd_src_convert_rate(src))
		rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0);

	return 0;
}
Esempio n. 5
0
static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
				     struct rsnd_dai *rdai,
				     struct rsnd_dai_stream *io)
{
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	struct rsnd_src *src = rsnd_mod_to_src(mod);
	u32 convert_rate = rsnd_src_convert_rate(src);
	u32 adinr = runtime->channels;
	u32 fsrate = 0;

	if (convert_rate)
		fsrate = 0x0400000 / convert_rate * runtime->rate;

	/* set/clear soft reset */
	rsnd_mod_write(mod, SRC_SWRSR, 0);
	rsnd_mod_write(mod, SRC_SWRSR, 1);

	/*
	 * Initialize the operation of the SRC internal circuits
	 * see rsnd_src_start()
	 */
	rsnd_mod_write(mod, SRC_SRCIR, 1);

	/* Set channel number and output bit length */
	switch (runtime->sample_bits) {
	case 16:
		adinr |= OTBL_16;
		break;
	case 32:
		adinr |= OTBL_24;
		break;
	default:
		return -EIO;
	}
	rsnd_mod_write(mod, SRC_ADINR, adinr);

	/* Enable the initial value of IFS */
	if (fsrate) {
		rsnd_mod_write(mod, SRC_IFSCR, 1);

		/* Set initial value of IFS */
		rsnd_mod_write(mod, SRC_IFSVR, fsrate);
	}

	/* use DMA transfer */
	rsnd_mod_write(mod, SRC_BUSIF_MODE, 1);

	return 0;
}
Esempio n. 6
0
File: src.c Progetto: MaxChina/linux
static int rsnd_src_start(struct rsnd_mod *mod,
			  struct rsnd_dai *rdai)
{
	struct rsnd_src *src = rsnd_mod_to_src(mod);

	/*
	 * Cancel the initialization and operate the SRC function
	 * see rsnd_src_set_convert_rate()
	 */
	rsnd_mod_write(mod, SRC_SRCIR, 0);

	if (rsnd_src_convert_rate(src))
		rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);

	return 0;
}
Esempio n. 7
0
File: src.c Progetto: Abioy/kasan
static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod)
{
	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	struct rsnd_src *src = rsnd_mod_to_src(mod);
	u32 convert_rate = rsnd_src_convert_rate(src);
	int ret;

	if (convert_rate)
		ret = rsnd_adg_set_convert_clk_gen2(mod, io,
						    runtime->rate,
						    convert_rate);
	else
		ret = rsnd_adg_set_convert_timing_gen2(mod, io);

	return ret;
}
Esempio n. 8
0
unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
				   struct rsnd_dai_stream *io,
				   struct snd_pcm_runtime *runtime)
{
	struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
	struct rsnd_src *src;
	unsigned int rate = 0;

	if (src_mod) {
		src = rsnd_mod_to_src(src_mod);

		/*
		 * return convert rate if SRC is used,
		 * otherwise, return runtime->rate as usual
		 */
		rate = rsnd_src_convert_rate(src);
	}

	if (!rate)
		rate = runtime->rate;

	return rate;
}
Esempio n. 9
0
File: src.c Progetto: Abioy/kasan
static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod)
{
	struct rsnd_src *src = rsnd_mod_to_src(mod);
	int ret;

	ret = rsnd_src_set_convert_rate(mod);
	if (ret < 0)
		return ret;

	/* Select SRC mode (fixed value) */
	rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);

	/* Set the restriction value of the FS ratio (98%) */
	rsnd_mod_write(mod, SRC_MNFSR,
		       rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98);

	/* Gen1/Gen2 are not compatible */
	if (rsnd_src_convert_rate(src))
		rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);

	/* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */

	return 0;
}