Esempio n. 1
0
static int spi_st_transfer_one(struct spi_master *master,
			       struct spi_device *spi, struct spi_transfer *t)
{
	struct spi_st *spi_st = spi_master_get_devdata(master);
	uint32_t ctl = 0;

	/* Setup transfer */
	spi_st->tx_ptr = t->tx_buf;
	spi_st->rx_ptr = t->rx_buf;

	if (spi->bits_per_word > 8) {
		/*
		 * Anything greater than 8 bits-per-word requires 2
		 * bytes-per-word in the RX/TX buffers
		 */
		spi_st->bytes_per_word = 2;
		spi_st->words_remaining = t->len / 2;

	} else if (spi->bits_per_word == 8 && !(t->len & 0x1)) {
		/*
		 * If transfer is even-length, and 8 bits-per-word, then
		 * implement as half-length 16 bits-per-word transfer
		 */
		spi_st->bytes_per_word = 2;
		spi_st->words_remaining = t->len / 2;

		/* Set SSC_CTL to 16 bits-per-word */
		ctl = readl_relaxed(spi_st->base + SSC_CTL);
		writel_relaxed((ctl | 0xf), spi_st->base + SSC_CTL);

		readl_relaxed(spi_st->base + SSC_RBUF);

	} else {
		spi_st->bytes_per_word = 1;
		spi_st->words_remaining = t->len;
	}

	reinit_completion(&spi_st->done);

	/* Start transfer by writing to the TX FIFO */
	ssc_write_tx_fifo(spi_st);
	writel_relaxed(SSC_IEN_TEEN, spi_st->base + SSC_IEN);

	/* Wait for transfer to complete */
	wait_for_completion(&spi_st->done);

	/* Restore SSC_CTL if necessary */
	if (ctl)
		writel_relaxed(ctl, spi_st->base + SSC_CTL);

	spi_finalize_current_transfer(spi->master);

	return t->len;
}
Esempio n. 2
0
static int spi_stm_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
{
	struct spi_stm *spi_stm;
	uint32_t ctl = 0;

	spi_stm = spi_master_get_devdata(spi->master);

	/* Setup transfer */
	spi_stm->tx_ptr = t->tx_buf;
	spi_stm->rx_ptr = t->rx_buf;

	if (spi_stm->bits_per_word > 8) {
		/* Anything greater than 8 bits-per-word requires 2
		 * bytes-per-word in the RX/TX buffers */
		spi_stm->bytes_per_word = 2;
		spi_stm->words_remaining = t->len/2;
	} else if (spi_stm->bits_per_word == 8 &&
		   ((t->len & 0x1) == 0)) {
		/* If transfer is even-length, and 8 bits-per-word, then
		 * implement as half-length 16 bits-per-word transfer */
		spi_stm->bytes_per_word = 2;
		spi_stm->words_remaining = t->len/2;

		/* Set SSC_CTL to 16 bits-per-word */
		ctl = ssc_load32(spi_stm, SSC_CTL);
		ssc_store32(spi_stm, SSC_CTL, (ctl | 0xf));

		ssc_load32(spi_stm, SSC_RBUF);

	} else {
		spi_stm->bytes_per_word = 1;
		spi_stm->words_remaining = t->len;
	}

	INIT_COMPLETION(spi_stm->done);

	/* Start transfer by writing to the TX FIFO */
	ssc_write_tx_fifo(spi_stm);
	ssc_store32(spi_stm, SSC_IEN, SSC_IEN_TEEN);

	/* Wait for transfer to complete */
	wait_for_completion(&spi_stm->done);

	/* Restore SSC_CTL if necessary */
	if (ctl)
		ssc_store32(spi_stm, SSC_CTL, ctl);

	return t->len;

}
Esempio n. 3
0
/* Interrupt fired when TX shift register becomes empty */
static irqreturn_t spi_stm_irq(int irq, void *dev_id)
{
	struct spi_stm *spi_stm = (struct spi_stm *)dev_id;

	/* Read RX FIFO */
	ssc_read_rx_fifo(spi_stm);

	/* Fill TX FIFO */
	if (spi_stm->words_remaining) {
		ssc_write_tx_fifo(spi_stm);
	} else {
		/* TX/RX complete */
		ssc_store32(spi_stm, SSC_IEN, 0x0);
		complete(&spi_stm->done);
	}

	return IRQ_HANDLED;
}
Esempio n. 4
0
/* Interrupt fired when TX shift register becomes empty */
static irqreturn_t spi_st_irq(int irq, void *dev_id)
{
	struct spi_st *spi_st = (struct spi_st *)dev_id;

	/* Read RX FIFO */
	ssc_read_rx_fifo(spi_st);

	/* Fill TX FIFO */
	if (spi_st->words_remaining) {
		ssc_write_tx_fifo(spi_st);
	} else {
		/* TX/RX complete */
		writel_relaxed(0x0, spi_st->base + SSC_IEN);
		/*
		 * read SSC_IEN to ensure that this bit is set
		 * before re-enabling interrupt
		 */
		readl(spi_st->base + SSC_IEN);
		complete(&spi_st->done);
	}

	return IRQ_HANDLED;
}