static void set_bit_mode(struct fsl_dspi *dspi, unsigned char bits)
{
	u32 temp;

	temp = readl(dspi->base + SPI_CTAR(dspi->cs));
	temp &= ~SPI_FRAME_BITS_MASK;
	temp |= SPI_FRAME_BITS(bits);
	writel(temp, dspi->base + SPI_CTAR(dspi->cs));
}
Example #2
0
static inline int is_double_byte_mode(struct fsl_dspi *dspi)
{
	unsigned int val;

	regmap_read(dspi->regmap, SPI_CTAR(dspi->cs), &val);

	return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1;
}
static int dspi_txrx_transfer(struct spi_device *spi, struct spi_transfer *t)
{
	struct fsl_dspi *dspi = spi_master_get_devdata(spi->master);
	dspi->cur_transfer = t;
	dspi->cur_chip = spi_get_ctldata(spi);
	dspi->cs = spi->chip_select;
	dspi->void_write_data = dspi->cur_chip->void_write_data;

	dspi->dataflags = 0;
	dspi->tx = (void *)t->tx_buf;
	dspi->tx_end = dspi->tx + t->len;
	dspi->rx = t->rx_buf;
	dspi->rx_end = dspi->rx + t->len;
	dspi->len = t->len;

	if (!dspi->rx)
		dspi->dataflags |= TRAN_STATE_RX_VOID;

	if (!dspi->tx)
		dspi->dataflags |= TRAN_STATE_TX_VOID;

	writel(dspi->cur_chip->mcr_val, dspi->base + SPI_MCR);
	writel(dspi->cur_chip->ctar_val, dspi->base + SPI_CTAR(dspi->cs));
	writel(SPI_RSER_EOQFE, dspi->base + SPI_RSER);

	if (t->speed_hz)
		writel(dspi->cur_chip->ctar_val,
				dspi->base + SPI_CTAR(dspi->cs));

	dspi_transfer_write(dspi);

	if (wait_event_interruptible(dspi->waitq, dspi->waitflags))
		dev_err(&dspi->pdev->dev, "wait transfer complete fail!\n");
	dspi->waitflags = 0;

	return t->len - dspi->len;
}
Example #4
0
static irqreturn_t dspi_interrupt(int irq, void *dev_id)
{
	struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id;

	regmap_write(dspi->regmap, SPI_SR, SPI_SR_EOQF);

	dspi_transfer_read(dspi);

	if (!dspi->len) {
		if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM)
			regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs),
				SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(16));

		dspi->waitflags = 1;
		wake_up_interruptible(&dspi->waitq);
	} else {
		dspi_transfer_write(dspi);

		return IRQ_HANDLED;
	}

	return IRQ_HANDLED;
}
static inline int is_double_byte_mode(struct fsl_dspi *dspi)
{
	return ((readl(dspi->base + SPI_CTAR(dspi->cs)) & SPI_FRAME_BITS_MASK)
			== SPI_FRAME_BITS(8)) ? 0 : 1;
}
Example #6
0
static int dspi_transfer_write(struct fsl_dspi *dspi)
{
	int tx_count = 0;
	int tx_word;
	u16 d16;
	u8  d8;
	u32 dspi_pushr = 0;
	int first = 1;

	tx_word = is_double_byte_mode(dspi);

	/* If we are in word mode, but only have a single byte to transfer
	 * then switch to byte mode temporarily.  Will switch back at the
	 * end of the transfer.
	 */
	if (tx_word && (dspi->len == 1)) {
		dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM;
		regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs),
				SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));
		tx_word = 0;
	}

	while (dspi->len && (tx_count < DSPI_FIFO_SIZE)) {
		if (tx_word) {
			if (dspi->len == 1)
				break;

			if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) {
				d16 = *(u16 *)dspi->tx;
				dspi->tx += 2;
			} else {
				d16 = dspi->void_write_data;
			}

			dspi_pushr = SPI_PUSHR_TXDATA(d16) |
				SPI_PUSHR_PCS(dspi->cs) |
				SPI_PUSHR_CTAS(dspi->cs) |
				SPI_PUSHR_CONT;

			dspi->len -= 2;
		} else {
			if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) {

				d8 = *(u8 *)dspi->tx;
				dspi->tx++;
			} else {
				d8 = (u8)dspi->void_write_data;
			}

			dspi_pushr = SPI_PUSHR_TXDATA(d8) |
				SPI_PUSHR_PCS(dspi->cs) |
				SPI_PUSHR_CTAS(dspi->cs) |
				SPI_PUSHR_CONT;

			dspi->len--;
		}

		if (dspi->len == 0 || tx_count == DSPI_FIFO_SIZE - 1) {
			/* last transfer in the transfer */
			dspi_pushr |= SPI_PUSHR_EOQ;
		} else if (tx_word && (dspi->len == 1))
			dspi_pushr |= SPI_PUSHR_EOQ;

		if (first) {
			first = 0;
			dspi_pushr |= SPI_PUSHR_CTCNT; /* clear counter */
		}

		regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr);

		tx_count++;
	}

	return tx_count * (tx_word + 1);
}