Esempio n. 1
0
static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
				   struct rsnd_mod *mod)
{
	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
	u32 zcmcr = 0;
	u32 vrpdr = 0;
	u32 vrdbr = 0;
	int i;

	for (i = 0; i < dvc->mute.cfg.size; i++)
		zcmcr |= (!!dvc->mute.cfg.val[i]) << i;

	if (dvc->ren.val) {
		vrpdr = rsnd_dvc_get_vrpdr(dvc);
		vrdbr = rsnd_dvc_get_vrdbr(dvc);
	}

	/* Disable DVC Register access */
	rsnd_mod_write(mod, DVC_DVUER, 0);

	/* Zero Cross Mute Function */
	rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);

	/* Volume Ramp Function */
	rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
	rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
	/* add DVC_VRWTR here */

	/* Digital Volume Function Parameter */
	rsnd_dvc_volume_parameter(io, mod);

	/* Enable DVC Register access */
	rsnd_mod_write(mod, DVC_DVUER, 1);
}
Esempio n. 2
0
File: ssiu.c Progetto: 020gzh/linux
static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
			       struct rsnd_dai_stream *io,
			       struct rsnd_priv *priv)
{
	int ret;

	ret = rsnd_ssiu_init(mod, io, priv);
	if (ret < 0)
		return ret;

	if (rsnd_runtime_is_ssi_tdm(io)) {
		/*
		 * TDM Extend Mode
		 * see
		 *	rsnd_ssi_config_init()
		 */
		rsnd_mod_write(mod, SSI_MODE, 0x1);
	}

	if (rsnd_ssi_use_busif(io)) {
		rsnd_mod_write(mod, SSI_BUSIF_ADINR,
			       rsnd_get_adinr_bit(mod, io) |
			       (rsnd_io_is_play(io) ?
				rsnd_runtime_channel_after_ctu(io) :
				rsnd_runtime_channel_original(io)));
		rsnd_mod_write(mod, SSI_BUSIF_MODE,  1);
		rsnd_mod_write(mod, SSI_BUSIF_DALIGN,
			       rsnd_get_dalign(mod, io));
	}

	return 0;
}
Esempio n. 3
0
File: mix.c Progetto: 020gzh/linux
static void rsnd_mix_volume_parameter(struct rsnd_dai_stream *io,
				      struct rsnd_mod *mod)
{
	rsnd_mod_write(mod, MIX_MDBAR, 0);
	rsnd_mod_write(mod, MIX_MDBBR, 0);
	rsnd_mod_write(mod, MIX_MDBCR, 0);
	rsnd_mod_write(mod, MIX_MDBDR, 0);
}
Esempio n. 4
0
File: ssi.c Progetto: 020gzh/linux
static void rsnd_ssi_register_setup(struct rsnd_mod *mod)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);

	rsnd_mod_write(mod, SSIWSR,	ssi->wsr);
	rsnd_mod_write(mod, SSICR,	ssi->cr_own	|
					ssi->cr_clk	|
					ssi->cr_mode); /* without EN */
}
Esempio n. 5
0
File: src.c Progetto: MaxChina/linux
static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
			      struct rsnd_dai *rdai)
{
	struct rsnd_src *src = rsnd_mod_to_src(mod);

	rsnd_mod_write(mod, SSI_CTRL, 0);
	rsnd_mod_write(mod, SRC_CTRL, 0);

	rsnd_dma_stop(rsnd_mod_to_dma(&src->mod));

	return rsnd_src_stop(mod, rdai);
}
Esempio n. 6
0
File: mix.c Progetto: krzk/linux
static void rsnd_mix_volume_update(struct rsnd_dai_stream *io,
				  struct rsnd_mod *mod)
{
	/* Disable MIX dB setting */
	rsnd_mod_write(mod, MIX_MDBER, 0);

	/* common volume parameter */
	rsnd_mix_volume_parameter(io, mod);

	/* Enable MIX dB setting */
	rsnd_mod_write(mod, MIX_MDBER, 1);
}
Esempio n. 7
0
static int rsnd_src_start_gen2(struct rsnd_mod *mod,
			       struct rsnd_dai *rdai,
			       struct rsnd_dai_stream *io)
{
	struct rsnd_src *src = rsnd_mod_to_src(mod);

	rsnd_dma_start(rsnd_mod_to_dma(&src->mod));

	rsnd_mod_write(mod, SSI_CTRL, 0x1);
	rsnd_mod_write(mod, SRC_CTRL, 0x11);

	return rsnd_src_start(mod, rdai, io);
}
Esempio n. 8
0
File: src.c Progetto: Abioy/kasan
static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
{
	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);
	u32 convert_rate = rsnd_src_convert_rate(src);
	uint ratio;
	int ret;

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

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

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

	rsnd_mod_write(mod, SRC_SRCCR, 0x00011110);

	if (convert_rate) {
		/* Gen1/Gen2 are not compatible */
		rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
	}

	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. 9
0
static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
					      struct rsnd_mod *mod)
{
	struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
	u32 val[RSND_MAX_CHANNELS];
	int i;

	/* Enable Ramp */
	if (dvc->ren.val)
		for (i = 0; i < RSND_MAX_CHANNELS; i++)
			val[i] = dvc->volume.cfg.max;
	else
		for (i = 0; i < RSND_MAX_CHANNELS; i++)
			val[i] = dvc->volume.val[i];

	/* Enable Digital Volume */
	rsnd_mod_write(mod, DVC_VOL0R, val[0]);
	rsnd_mod_write(mod, DVC_VOL1R, val[1]);
	rsnd_mod_write(mod, DVC_VOL2R, val[2]);
	rsnd_mod_write(mod, DVC_VOL3R, val[3]);
	rsnd_mod_write(mod, DVC_VOL4R, val[4]);
	rsnd_mod_write(mod, DVC_VOL5R, val[5]);
	rsnd_mod_write(mod, DVC_VOL6R, val[6]);
	rsnd_mod_write(mod, DVC_VOL7R, val[7]);
}
Esempio n. 10
0
File: ssiu.c Progetto: 020gzh/linux
static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
			       struct rsnd_dai_stream *io,
			       struct rsnd_priv *priv)
{
	if (!rsnd_ssi_use_busif(io))
		return 0;

	rsnd_mod_write(mod, SSI_CTRL, 0);

	if (rsnd_ssi_multi_slaves_runtime(io))
		rsnd_mod_write(mod, SSI_CONTROL, 0);

	return 0;
}
Esempio n. 11
0
File: src.c Progetto: MaxChina/linux
static int rsnd_src_start_gen2(struct rsnd_mod *mod,
			       struct rsnd_dai *rdai)
{
	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
	struct rsnd_src *src = rsnd_mod_to_src(mod);
	u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11;

	rsnd_dma_start(rsnd_mod_to_dma(&src->mod));

	rsnd_mod_write(mod, SSI_CTRL, 0x1);
	rsnd_mod_write(mod, SRC_CTRL, val);

	return rsnd_src_start(mod, rdai);
}
Esempio n. 12
0
File: src.c Progetto: Abioy/kasan
int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);

	if (rsnd_is_gen1(priv))
		return 0;

	/* enable SSI interrupt if Gen2 */
	if (rsnd_ssi_is_dma_mode(ssi_mod))
		rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0e000000);
	else
		rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0f000000);

	return 0;
}
Esempio n. 13
0
File: src.c Progetto: Abioy/kasan
static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
{
	struct rsnd_src *src = rsnd_mod_to_src(mod);
	u32 sys_int_val, int_val, sys_int_mask;
	int irq = src->info->irq;
	int id = rsnd_mod_id(mod);

	sys_int_val =
	sys_int_mask = OUF_SRC(id);
	int_val = 0x3300;

	/*
	 * IRQ is not supported on non-DT
	 * see
	 *	rsnd_src_probe_gen2()
	 */
	if ((irq <= 0) || !enable) {
		sys_int_val = 0;
		int_val = 0;
	}

	rsnd_mod_write(mod, SRC_INT_ENABLE0, int_val);
	rsnd_mod_bset(mod, SCU_SYS_INT_EN0, sys_int_mask, sys_int_val);
	rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val);
}
Esempio n. 14
0
/*
 *		SSI PIO
 */
static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
{
	struct rsnd_ssi *ssi = data;
	struct rsnd_dai_stream *io = ssi->io;
	u32 status = rsnd_mod_read(&ssi->mod, SSISR);
	irqreturn_t ret = IRQ_NONE;

	if (io && (status & DIRQ)) {
		struct rsnd_dai *rdai = ssi->rdai;
		struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
		u32 *buf = (u32 *)(runtime->dma_area +
				   rsnd_dai_pointer_offset(io, 0));

		rsnd_ssi_record_error(ssi, status);

		/*
		 * 8/16/32 data can be assesse to TDR/RDR register
		 * directly as 32bit data
		 * see rsnd_ssi_init()
		 */
		if (rsnd_dai_is_play(rdai, io))
			rsnd_mod_write(&ssi->mod, SSITDR, *buf);
		else
			*buf = rsnd_mod_read(&ssi->mod, SSIRDR);

		rsnd_dai_pointer_update(io, sizeof(*buf));

		ret = IRQ_HANDLED;
	}

	return ret;
}
Esempio n. 15
0
static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
			      struct rsnd_dai *rdai,
			      struct rsnd_dai_stream *io)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod);
	struct device *dev = rsnd_priv_to_dev(priv);
	u32 cr;

	if (0 == ssi->usrcnt) {
		clk_enable(ssi->clk);

		if (rsnd_rdai_is_clk_master(rdai)) {
			if (rsnd_ssi_clk_from_parent(ssi))
				rsnd_ssi_hw_start(ssi->parent, rdai, io);
			else
				rsnd_ssi_master_clk_start(ssi, io);
		}
	}

	cr  =	ssi->cr_own	|
		ssi->cr_clk	|
		ssi->cr_etc	|
		EN;

	rsnd_mod_write(&ssi->mod, SSICR, cr);

	ssi->usrcnt++;

	dev_dbg(dev, "ssi%d hw started\n", rsnd_mod_id(&ssi->mod));
}
Esempio n. 16
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. 17
0
File: mix.c Progetto: 020gzh/linux
static void rsnd_mix_volume_init(struct rsnd_dai_stream *io,
				 struct rsnd_mod *mod)
{
	rsnd_mod_write(mod, MIX_MIXIR, 1);

	/* General Information */
	rsnd_mod_write(mod, MIX_ADINR, rsnd_runtime_channel_after_ctu(io));

	/* volume step */
	rsnd_mod_write(mod, MIX_MIXMR, 0);
	rsnd_mod_write(mod, MIX_MVPDR, 0);

	/* common volume parameter */
	rsnd_mix_volume_parameter(io, mod);

	rsnd_mod_write(mod, MIX_MIXIR, 0);
}
Esempio n. 18
0
File: src.c Progetto: Abioy/kasan
int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod)
{
	/*
	 * DMA settings for SSIU
	 */
	rsnd_mod_write(ssi_mod, SSI_CTRL, 0);

	return 0;
}
Esempio n. 19
0
File: ssi.c Progetto: 19Dan01/linux
static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod);
	struct rsnd_dai_stream *io = rsnd_mod_to_io(&ssi->mod);
	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
	struct device *dev = rsnd_priv_to_dev(priv);
	u32 cr;

	if (0 == ssi->usrcnt) /* stop might be called without start */
		return;

	ssi->usrcnt--;

	if (0 == ssi->usrcnt) {
		/*
		 * disable all IRQ,
		 * and, wait all data was sent
		 */
		cr  =	ssi->cr_own	|
			ssi->cr_clk;

		rsnd_mod_write(&ssi->mod, SSICR, cr | EN);
		rsnd_ssi_status_check(&ssi->mod, DIRQ);

		/*
		 * disable SSI,
		 * and, wait idle state
		 */
		rsnd_mod_write(&ssi->mod, SSICR, cr);	/* disabled all */
		rsnd_ssi_status_check(&ssi->mod, IIRQ);

		if (rsnd_rdai_is_clk_master(rdai)) {
			if (rsnd_ssi_clk_from_parent(ssi))
				rsnd_ssi_hw_stop(ssi->parent);
			else
				rsnd_ssi_master_clk_stop(ssi);
		}

		rsnd_mod_hw_stop(&ssi->mod);
	}

	dev_dbg(dev, "%s[%d] hw stopped\n",
		rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod));
}
Esempio n. 20
0
File: ssi.c Progetto: 19Dan01/linux
static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
			      struct rsnd_dai_stream *io)
{
	struct rsnd_priv *priv = rsnd_io_to_priv(io);
	struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
	struct device *dev = rsnd_priv_to_dev(priv);
	u32 cr_mode;
	u32 cr;

	if (0 == ssi->usrcnt) {
		rsnd_mod_hw_start(&ssi->mod);

		if (rsnd_rdai_is_clk_master(rdai)) {
			if (rsnd_ssi_clk_from_parent(ssi))
				rsnd_ssi_hw_start(ssi->parent, io);
			else
				rsnd_ssi_master_clk_start(ssi, io);
		}
	}

	cr_mode = rsnd_ssi_is_dma_mode(&ssi->mod) ?
		DMEN :	/* DMA : enable DMA */
		DIEN;	/* PIO : enable Data interrupt */


	cr  =	ssi->cr_own	|
		ssi->cr_clk	|
		cr_mode		|
		UIEN | OIEN | EN;

	rsnd_mod_write(&ssi->mod, SSICR, cr);

	/* enable WS continue */
	if (rsnd_rdai_is_clk_master(rdai))
		rsnd_mod_write(&ssi->mod, SSIWSR, CONT);

	/* clear error status */
	rsnd_mod_write(&ssi->mod, SSISR, 0);

	ssi->usrcnt++;

	dev_dbg(dev, "%s[%d] hw started\n",
		rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod));
}
Esempio n. 21
0
File: src.c Progetto: Abioy/kasan
static int _rsnd_src_stop_gen2(struct rsnd_mod *mod)
{
	rsnd_src_irq_disable_gen2(mod);

	rsnd_mod_write(mod, SRC_CTRL, 0);

	rsnd_src_error_record_gen2(mod);

	return rsnd_src_stop(mod);
}
Esempio n. 22
0
File: mix.c Progetto: krzk/linux
static void rsnd_mix_volume_parameter(struct rsnd_dai_stream *io,
				      struct rsnd_mod *mod)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_mix *mix = rsnd_mod_to_mix(mod);
	u32 volA = rsnd_mix_get_vol(mix, A);
	u32 volB = rsnd_mix_get_vol(mix, B);
	u32 volC = rsnd_mix_get_vol(mix, C);
	u32 volD = rsnd_mix_get_vol(mix, D);

	dev_dbg(dev, "MIX A/B/C/D = %02x/%02x/%02x/%02x\n",
		volA, volB, volC, volD);

	rsnd_mod_write(mod, MIX_MDBAR, volA);
	rsnd_mod_write(mod, MIX_MDBBR, volB);
	rsnd_mod_write(mod, MIX_MDBCR, volC);
	rsnd_mod_write(mod, MIX_MDBDR, volD);
}
Esempio n. 23
0
File: src.c Progetto: MaxChina/linux
/*
 *		Gen2 functions
 */
static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
					  struct rsnd_dai *rdai)
{
	int ret;

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

	rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_get_adinr(mod));
	rsnd_mod_write(mod, SSI_BUSIF_MODE,  1);

	rsnd_mod_write(mod, SRC_SRCCR, 0x00011110);

	rsnd_mod_write(mod, SRC_BSDSR, 0x01800000);
	rsnd_mod_write(mod, SRC_BSISR, 0x00100060);

	return 0;
}
Esempio n. 24
0
File: src.c Progetto: Abioy/kasan
static int rsnd_src_start(struct rsnd_mod *mod)
{
	/*
	 * Cancel the initialization and operate the SRC function
	 * see rsnd_src_init()
	 */
	rsnd_mod_write(mod, SRC_SRCIR, 0);

	return 0;
}
Esempio n. 25
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. 26
0
File: ssi.c Progetto: 19Dan01/linux
static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
{
	/* under/over flow error */
	if (status & (UIRQ | OIRQ)) {
		ssi->err++;

		/* clear error status */
		rsnd_mod_write(&ssi->mod, SSISR, 0);
	}
}
Esempio n. 27
0
File: mix.c Progetto: krzk/linux
static void rsnd_mix_volume_init(struct rsnd_dai_stream *io,
				 struct rsnd_mod *mod)
{
	struct rsnd_mix *mix = rsnd_mod_to_mix(mod);

	rsnd_mod_write(mod, MIX_MIXIR, 1);

	/* General Information */
	rsnd_mod_write(mod, MIX_ADINR, rsnd_runtime_channel_after_ctu(io));

	/* volume step */
	rsnd_mod_write(mod, MIX_MIXMR, rsnd_kctrl_vals(mix->ren));
	rsnd_mod_write(mod, MIX_MVPDR, rsnd_kctrl_vals(mix->rup) << 8 |
				       rsnd_kctrl_vals(mix->rdw));

	/* common volume parameter */
	rsnd_mix_volume_parameter(io, mod);

	rsnd_mod_write(mod, MIX_MIXIR, 0);
}
Esempio n. 28
0
File: src.c Progetto: MaxChina/linux
static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod,
					  struct rsnd_dai *rdai)
{
	int ret;

	ret = rsnd_src_set_convert_rate(mod, rdai);
	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);

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

	return 0;
}
Esempio n. 29
0
/*
 *		Gen2 functions
 */
static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
					  struct rsnd_dai *rdai,
					  struct rsnd_dai_stream *io)
{
	int ret;

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

	rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_mod_read(mod, SRC_ADINR));
	rsnd_mod_write(mod, SSI_BUSIF_MODE,  rsnd_mod_read(mod, SRC_BUSIF_MODE));

	rsnd_mod_write(mod, SRC_SRCCR, 0x00011110);

	rsnd_mod_write(mod, SRC_BSDSR, 0x01800000);
	rsnd_mod_write(mod, SRC_BSISR, 0x00100060);

	return 0;
}
Esempio n. 30
0
File: src.c Progetto: MaxChina/linux
int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod,
			    struct rsnd_dai *rdai)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);

	/* enable PIO interrupt if Gen2 */
	if (rsnd_is_gen2(priv))
		rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0f000000);

	return 0;
}