Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c2818cd authored by Cory Maccarrone's avatar Cory Maccarrone Committed by Grant Likely
Browse files

SPI100k: Fix 8-bit and RX-only transfers



This change fixes 8-bit transfers and RX-only transfers.  The
SPI100k framework requires minimum 16-bit words to be written, so 8-bit
transfers must be shited by 8 bits and sent out as a 16-bit word.

Additionally, receive-only transfers were failing due to the
perceived need to fill the TX buffer with something.  This is in
fact not needed.

Signed-off-by: default avatarCory Maccarrone <darkstar6262@gmail.com>
Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
parent 4751c1c7
Loading
Loading
Loading
Loading
+12 −11
Original line number Original line Diff line number Diff line
@@ -141,7 +141,12 @@ static void spi100k_write_data(struct spi_master *master, int len, int data)
{
{
	struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
	struct omap1_spi100k *spi100k = spi_master_get_devdata(master);


	/* write 16-bit word */
	/* write 16-bit word, shifting 8-bit data if necessary */
	if (len <= 8) {
		data <<= 8;
		len = 16;
	}

	spi100k_enable_clock(master);
	spi100k_enable_clock(master);
	writew( data , spi100k->base + SPI_TX_MSB);
	writew( data , spi100k->base + SPI_TX_MSB);


@@ -162,6 +167,10 @@ static int spi100k_read_data(struct spi_master *master, int len)
	int dataH,dataL;
	int dataH,dataL;
	struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
	struct omap1_spi100k *spi100k = spi_master_get_devdata(master);


	/* Always do at least 16 bits */
	if (len <= 8)
		len = 16;

	spi100k_enable_clock(master);
	spi100k_enable_clock(master);
	writew(SPI_CTRL_SEN(0) |
	writew(SPI_CTRL_SEN(0) |
	       SPI_CTRL_WORD_SIZE(len) |
	       SPI_CTRL_WORD_SIZE(len) |
@@ -214,10 +223,6 @@ omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
	c = count;
	c = count;
	word_len = cs->word_len;
	word_len = cs->word_len;


	/* RX_ONLY mode needs dummy data in TX reg */
	if (xfer->tx_buf == NULL)
		spi100k_write_data(spi->master,word_len, 0);

	if (word_len <= 8) {
	if (word_len <= 8) {
		u8              *rx;
		u8              *rx;
		const u8        *tx;
		const u8        *tx;
@@ -227,9 +232,9 @@ omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
		do {
		do {
			c-=1;
			c-=1;
			if (xfer->tx_buf != NULL)
			if (xfer->tx_buf != NULL)
				spi100k_write_data(spi->master,word_len, *tx);
				spi100k_write_data(spi->master, word_len, *tx++);
			if (xfer->rx_buf != NULL)
			if (xfer->rx_buf != NULL)
				*rx = spi100k_read_data(spi->master,word_len);
				*rx++ = spi100k_read_data(spi->master, word_len);
		} while(c);
		} while(c);
	} else if (word_len <= 16) {
	} else if (word_len <= 16) {
		u16             *rx;
		u16             *rx;
@@ -380,10 +385,6 @@ static void omap1_spi100k_work(struct work_struct *work)
			if (t->len) {
			if (t->len) {
				unsigned count;
				unsigned count;


				/* RX_ONLY mode needs dummy data in TX reg */
				if (t->tx_buf == NULL)
					spi100k_write_data(spi->master, 8, 0);

				count = omap1_spi100k_txrx_pio(spi, t);
				count = omap1_spi100k_txrx_pio(spi, t);
				m->actual_length += count;
				m->actual_length += count;