Ejemplo n.º 1
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_dai_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));
}
Ejemplo n.º 2
0
/*
 *		Gen1/Gen2 common functions
 */
int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod,
			   struct rsnd_dai *rdai,
			   struct rsnd_dai_stream *io)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
	struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
	struct rcar_snd_info *info = rsnd_priv_to_info(priv);
	int ssi_id = rsnd_mod_id(ssi_mod);
	int has_src = 0;

	/*
	 * SSI_MODE0
	 */
	if (info->dai_info) {
		has_src = !!src_mod;
	} else {
		struct rsnd_src *src = rsnd_mod_to_src(src_mod);
		has_src = rsnd_src_hpbif_is_enable(src);
	}

	rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
		      has_src ? 0 : (1 << ssi_id));

	/*
	 * SSI_MODE1
	 */
	if (rsnd_ssi_is_pin_sharing(ssi_mod)) {
		int shift = -1;
		switch (ssi_id) {
		case 1:
			shift = 0;
			break;
		case 2:
			shift = 2;
			break;
		case 4:
			shift = 16;
			break;
		}

		if (shift >= 0)
			rsnd_mod_bset(ssi_mod, SSI_MODE1,
				      0x3 << shift,
				      rsnd_dai_is_clk_master(rdai) ?
				      0x2 << shift : 0x1 << shift);
	}

	return 0;
}
Ejemplo n.º 3
0
static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi,
			     struct rsnd_dai *rdai)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod);
	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_dai_is_clk_master(rdai)) {
			if (rsnd_ssi_clk_from_parent(ssi))
				rsnd_ssi_hw_stop(ssi->parent, rdai);
			else
				rsnd_ssi_master_clk_stop(ssi);
		}

		clk_disable(ssi->clk);
	}

	dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod));
}
Ejemplo n.º 4
0
static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
			      struct rsnd_dai *rdai,
			      struct rsnd_dai_stream *io)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
	struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod);

	/* enable DMA transfer */
	ssi->cr_etc = DMEN;

	rsnd_dma_start(dma);

	rsnd_ssi_hw_start(ssi, ssi->rdai, io);

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

	return 0;
}
Ejemplo n.º 5
0
Archivo: src.c Proyecto: MaxChina/linux
/*
 *		Gen1/Gen2 common functions
 */
int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod,
			   struct rsnd_dai *rdai)
{
	struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod);
	struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
	int ssi_id = rsnd_mod_id(ssi_mod);

	/*
	 * SSI_MODE0
	 */
	rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
		      src_mod ? 0 : (1 << ssi_id));

	/*
	 * SSI_MODE1
	 */
	if (rsnd_ssi_is_pin_sharing(ssi_mod)) {
		int shift = -1;
		switch (ssi_id) {
		case 1:
			shift = 0;
			break;
		case 2:
			shift = 2;
			break;
		case 4:
			shift = 16;
			break;
		}

		if (shift >= 0)
			rsnd_mod_bset(ssi_mod, SSI_MODE1,
				      0x3 << shift,
				      rsnd_dai_is_clk_master(rdai) ?
				      0x2 << shift : 0x1 << shift);
	}

	return 0;
}
Ejemplo n.º 6
0
/*
 *		Gen1/Gen2 common functions
 */
int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
			struct rsnd_dai *rdai,
			int use_busif)
{
	struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod);
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	int ssi_id = rsnd_mod_id(ssi_mod);

	/*
	 * SSI_MODE0
	 */
	rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
		      !use_busif << ssi_id);

	/*
	 * SSI_MODE1
	 */
	if (rsnd_ssi_is_pin_sharing(ssi_mod)) {
		int shift = -1;
		switch (ssi_id) {
		case 1:
			shift = 0;
			break;
		case 2:
			shift = 2;
			break;
		case 4:
			shift = 16;
			break;
		}

		if (shift >= 0)
			rsnd_mod_bset(ssi_mod, SSI_MODE1,
				      0x3 << shift,
				      rsnd_dai_is_clk_master(rdai) ?
				      0x2 << shift : 0x1 << shift);
	}

	/*
	 * DMA settings for SSIU
	 */
	if (use_busif) {
		u32 val = 0x76543210;
		u32 mask = ~0;

		rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR,
			       rsnd_get_adinr(ssi_mod));
		rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE,  1);
		rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1);

		mask <<= runtime->channels * 4;
		val = val & mask;

		switch (runtime->sample_bits) {
		case 16:
			val |= 0x67452301 & ~mask;
			break;
		case 32:
			val |= 0x76543210 & ~mask;
			break;
		}
		rsnd_mod_write(ssi_mod, BUSIF_DALIGN, val);

	}

	return 0;
}