brcm2708: update against latest rpi-3.10.y branch
[15.05/openwrt.git] / target / linux / brcm2708 / patches-3.10 / 0056-spi-bcm2708-add-9-bit-support-using-LoSSI-mode.patch
1 From 75c9b03f90ca974cb072d96f423884b773ca5425 Mon Sep 17 00:00:00 2001
2 From: notro <notro@tronnes.org>
3 Date: Sat, 26 Jan 2013 20:38:03 +0100
4 Subject: [PATCH 056/174] spi-bcm2708: add 9-bit support using LoSSI mode
5
6 ---
7  drivers/spi/spi-bcm2708.c | 30 ++++++++++++++++++++++++++++--
8  1 file changed, 28 insertions(+), 2 deletions(-)
9
10 --- a/drivers/spi/spi-bcm2708.c
11 +++ b/drivers/spi/spi-bcm2708.c
12 @@ -146,10 +146,31 @@ static inline void bcm2708_rd_fifo(struc
13  static inline void bcm2708_wr_fifo(struct bcm2708_spi *bs, int len)
14  {
15         u8 byte;
16 +       u16 val;
17  
18         if (len > bs->len)
19                 len = bs->len;
20  
21 +       if (unlikely(bcm2708_rd(bs, SPI_CS) & SPI_CS_LEN)) {
22 +               /* LoSSI mode */
23 +               if (unlikely(len % 2)) {
24 +                       printk(KERN_ERR"bcm2708_wr_fifo: length must be even, skipping.\n");
25 +                       bs->len = 0;
26 +                       return;
27 +               }
28 +               while (len) {
29 +                       if (bs->tx_buf) {
30 +                               val = *(const u16 *)bs->tx_buf;
31 +                               bs->tx_buf += 2;
32 +                       } else
33 +                               val = 0;
34 +                       bcm2708_wr(bs, SPI_FIFO, val);
35 +                       bs->len -= 2;
36 +                       len -= 2;
37 +               }
38 +               return;
39 +       }
40 +
41         while (len--) {
42                 byte = bs->tx_buf ? *bs->tx_buf++ : 0;
43                 bcm2708_wr(bs, SPI_FIFO, byte);
44 @@ -234,8 +255,12 @@ static int bcm2708_setup_state(struct sp
45         switch (bpw) {
46         case 8:
47                 break;
48 +       case 9:
49 +               /* Reading in LoSSI mode is a special case. See 'BCM2835 ARM Peripherals' datasheet */
50 +               cs |= SPI_CS_LEN;
51 +               break;
52         default:
53 -               dev_dbg(dev, "setup: invalid bits_per_word %u (must be 8)\n",
54 +               dev_dbg(dev, "setup: invalid bits_per_word %u (must be 8 or 9)\n",
55                         bpw);
56                 return -EINVAL;
57         }
58 @@ -283,7 +308,8 @@ static int bcm2708_process_transfer(stru
59                 ret = bcm2708_setup_state(spi->master, &spi->dev, &state,
60                         xfer->speed_hz ? xfer->speed_hz : spi->max_speed_hz,
61                         spi->chip_select, spi->mode,
62 -                       spi->bits_per_word);
63 +                       xfer->bits_per_word ? xfer->bits_per_word :
64 +                               spi->bits_per_word);
65                 if (ret)
66                         return ret;
67