From 75c9b03f90ca974cb072d96f423884b773ca5425 Mon Sep 17 00:00:00 2001 From: notro Date: Sat, 26 Jan 2013 20:38:03 +0100 Subject: [PATCH 056/174] spi-bcm2708: add 9-bit support using LoSSI mode --- drivers/spi/spi-bcm2708.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) --- a/drivers/spi/spi-bcm2708.c +++ b/drivers/spi/spi-bcm2708.c @@ -146,10 +146,31 @@ static inline void bcm2708_rd_fifo(struc static inline void bcm2708_wr_fifo(struct bcm2708_spi *bs, int len) { u8 byte; + u16 val; if (len > bs->len) len = bs->len; + if (unlikely(bcm2708_rd(bs, SPI_CS) & SPI_CS_LEN)) { + /* LoSSI mode */ + if (unlikely(len % 2)) { + printk(KERN_ERR"bcm2708_wr_fifo: length must be even, skipping.\n"); + bs->len = 0; + return; + } + while (len) { + if (bs->tx_buf) { + val = *(const u16 *)bs->tx_buf; + bs->tx_buf += 2; + } else + val = 0; + bcm2708_wr(bs, SPI_FIFO, val); + bs->len -= 2; + len -= 2; + } + return; + } + while (len--) { byte = bs->tx_buf ? *bs->tx_buf++ : 0; bcm2708_wr(bs, SPI_FIFO, byte); @@ -234,8 +255,12 @@ static int bcm2708_setup_state(struct sp switch (bpw) { case 8: break; + case 9: + /* Reading in LoSSI mode is a special case. See 'BCM2835 ARM Peripherals' datasheet */ + cs |= SPI_CS_LEN; + break; default: - dev_dbg(dev, "setup: invalid bits_per_word %u (must be 8)\n", + dev_dbg(dev, "setup: invalid bits_per_word %u (must be 8 or 9)\n", bpw); return -EINVAL; } @@ -283,7 +308,8 @@ static int bcm2708_process_transfer(stru ret = bcm2708_setup_state(spi->master, &spi->dev, &state, xfer->speed_hz ? xfer->speed_hz : spi->max_speed_hz, spi->chip_select, spi->mode, - spi->bits_per_word); + xfer->bits_per_word ? xfer->bits_per_word : + spi->bits_per_word); if (ret) return ret;