Beispiel #1
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;
}
Beispiel #2
0
static int rsnd_ssi_dma_complete(struct rsnd_dma *dma)
{
	struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma);
	struct rsnd_dai_stream *io = ssi->io;
	u32 status = rsnd_mod_read(&ssi->mod, SSISR);

	rsnd_ssi_record_error(ssi, status);

	rsnd_dai_pointer_update(ssi->io, io->byte_per_period);

	return 0;
}
Beispiel #3
0
static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
{
	struct rsnd_ssi *ssi = data;
	struct rsnd_mod *mod = &ssi->mod;
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
	int is_dma = rsnd_ssi_is_dma_mode(mod);
	u32 status = rsnd_mod_read(mod, SSISR);

	if (!io)
		return IRQ_NONE;

	/* PIO only */
	if (!is_dma && (status & DIRQ)) {
		struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
		u32 *buf = (u32 *)(runtime->dma_area +
				   rsnd_dai_pointer_offset(io, 0));

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

		rsnd_dai_pointer_update(io, sizeof(*buf));
	}

	/* PIO / DMA */
	if (status & (UIRQ | OIRQ)) {
		struct device *dev = rsnd_priv_to_dev(priv);

		/*
		 * restart SSI
		 */
		dev_dbg(dev, "%s[%d] restart\n",
			rsnd_mod_name(mod), rsnd_mod_id(mod));

		rsnd_ssi_stop(mod, priv);
		if (ssi->err < 1024)
			rsnd_ssi_start(mod, priv);
		else
			dev_warn(dev, "no more SSI restart\n");
	}

	rsnd_ssi_record_error(ssi, status);

	return IRQ_HANDLED;
}
Beispiel #4
0
static int rsnd_ssi_stop(struct rsnd_mod *mod,
			 struct rsnd_priv *priv)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);

	rsnd_src_ssi_irq_disable(mod);

	rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR));

	rsnd_ssi_hw_stop(ssi);

	rsnd_src_ssiu_stop(mod);

	return 0;
}
Beispiel #5
0
static int rsnd_ssi_dma_stop(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);

	ssi->cr_etc = 0;

	rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR));

	rsnd_ssi_hw_stop(ssi, rdai);

	rsnd_dma_stop(dma);

	return 0;
}