Commit 81235b4ea3aa2e942ac37979433f41b748f12da1
Exists in
master
and in
13 other branches
Merge remote-tracking branches 'spi/topic/s3c64xx', 'spi/topic/sc18is602', 'spi/…
…topic/sh-hspi', 'spi/topic/sh-msiof', 'spi/topic/sh-sci', 'spi/topic/sirf' and 'spi/topic/spidev' into spi-next
Showing 15 changed files Side-by-side Diff
- Documentation/devicetree/bindings/spi/sh-hspi.txt
- Documentation/devicetree/bindings/spi/sh-msiof.txt
- Documentation/spi/spidev
- Documentation/spi/spidev_fdx.c
- Documentation/spi/spidev_test.c
- drivers/spi/Kconfig
- drivers/spi/spi-s3c64xx.c
- drivers/spi/spi-sc18is602.c
- drivers/spi/spi-sh-hspi.c
- drivers/spi/spi-sh-msiof.c
- drivers/spi/spi-sh-sci.c
- drivers/spi/spi-sirf.c
- drivers/spi/spidev.c
- include/linux/platform_data/spi-s3c64xx.h
- include/uapi/linux/spi/spidev.h
Documentation/devicetree/bindings/spi/sh-hspi.txt
1 | 1 | Renesas HSPI. |
2 | 2 | |
3 | 3 | Required properties: |
4 | -- compatible : "renesas,hspi" | |
5 | -- reg : Offset and length of the register set for the device | |
6 | -- interrupts : interrupt line used by HSPI | |
4 | +- compatible : "renesas,hspi-<soctype>", "renesas,hspi" as fallback. | |
5 | + Examples with soctypes are: | |
6 | + - "renesas,hspi-r8a7778" (R-Car M1) | |
7 | + - "renesas,hspi-r8a7779" (R-Car H1) | |
8 | +- reg : Offset and length of the register set for the device | |
9 | +- interrupt-parent : The phandle for the interrupt controller that | |
10 | + services interrupts for this device | |
11 | +- interrupts : Interrupt specifier | |
12 | +- #address-cells : Must be <1> | |
13 | +- #size-cells : Must be <0> | |
14 | + | |
15 | +Pinctrl properties might be needed, too. See | |
16 | +Documentation/devicetree/bindings/pinctrl/renesas,*. | |
17 | + | |
18 | +Example: | |
19 | + | |
20 | + hspi0: spi@fffc7000 { | |
21 | + compatible = "renesas,hspi-r8a7778", "renesas,hspi"; | |
22 | + reg = <0xfffc7000 0x18>; | |
23 | + interrupt-parent = <&gic>; | |
24 | + interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>; | |
25 | + #address-cells = <1>; | |
26 | + #size-cells = <0>; | |
27 | + status = "disabled"; | |
28 | + }; |
Documentation/devicetree/bindings/spi/sh-msiof.txt
1 | 1 | Renesas MSIOF spi controller |
2 | 2 | |
3 | 3 | Required properties: |
4 | -- compatible : "renesas,sh-msiof" for SuperH or | |
5 | - "renesas,sh-mobile-msiof" for SH Mobile series | |
6 | -- reg : Offset and length of the register set for the device | |
7 | -- interrupts : interrupt line used by MSIOF | |
4 | +- compatible : "renesas,msiof-<soctype>" for SoCs, | |
5 | + "renesas,sh-msiof" for SuperH, or | |
6 | + "renesas,sh-mobile-msiof" for SH Mobile series. | |
7 | + Examples with soctypes are: | |
8 | + "renesas,msiof-r8a7790" (R-Car H2) | |
9 | + "renesas,msiof-r8a7791" (R-Car M2) | |
10 | +- reg : Offset and length of the register set for the device | |
11 | +- interrupt-parent : The phandle for the interrupt controller that | |
12 | + services interrupts for this device | |
13 | +- interrupts : Interrupt specifier | |
14 | +- #address-cells : Must be <1> | |
15 | +- #size-cells : Must be <0> | |
8 | 16 | |
9 | 17 | Optional properties: |
10 | -- num-cs : total number of chip-selects | |
11 | -- renesas,tx-fifo-size : Overrides the default tx fifo size given in words | |
12 | -- renesas,rx-fifo-size : Overrides the default rx fifo size given in words | |
18 | +- clocks : Must contain a reference to the functional clock. | |
19 | +- num-cs : Total number of chip-selects (default is 1) | |
20 | + | |
21 | +Optional properties, deprecated for soctype-specific bindings: | |
22 | +- renesas,tx-fifo-size : Overrides the default tx fifo size given in words | |
23 | + (default is 64) | |
24 | +- renesas,rx-fifo-size : Overrides the default rx fifo size given in words | |
25 | + (default is 64, or 256 on R-Car H2 and M2) | |
26 | + | |
27 | +Pinctrl properties might be needed, too. See | |
28 | +Documentation/devicetree/bindings/pinctrl/renesas,*. | |
29 | + | |
30 | +Example: | |
31 | + | |
32 | + msiof0: spi@e6e20000 { | |
33 | + compatible = "renesas,msiof-r8a7791"; | |
34 | + reg = <0 0xe6e20000 0 0x0064>; | |
35 | + interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; | |
36 | + clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>; | |
37 | + #address-cells = <1>; | |
38 | + #size-cells = <0>; | |
39 | + status = "disabled"; | |
40 | + }; |
Documentation/spi/spidev
... | ... | @@ -85,6 +85,12 @@ |
85 | 85 | SPI_MODE_0..SPI_MODE_3; or if you prefer you can combine SPI_CPOL |
86 | 86 | (clock polarity, idle high iff this is set) or SPI_CPHA (clock phase, |
87 | 87 | sample on trailing edge iff this is set) flags. |
88 | + Note that this request is limited to SPI mode flags that fit in a | |
89 | + single byte. | |
90 | + | |
91 | + SPI_IOC_RD_MODE32, SPI_IOC_WR_MODE32 ... pass a pointer to a uin32_t | |
92 | + which will return (RD) or assign (WR) the full SPI transfer mode, | |
93 | + not limited to the bits that fit in one byte. | |
88 | 94 | |
89 | 95 | SPI_IOC_RD_LSB_FIRST, SPI_IOC_WR_LSB_FIRST ... pass a pointer to a byte |
90 | 96 | which will return (RD) or assign (WR) the bit justification used to |
Documentation/spi/spidev_fdx.c
... | ... | @@ -78,10 +78,10 @@ |
78 | 78 | |
79 | 79 | static void dumpstat(const char *name, int fd) |
80 | 80 | { |
81 | - __u8 mode, lsb, bits; | |
82 | - __u32 speed; | |
81 | + __u8 lsb, bits; | |
82 | + __u32 mode, speed; | |
83 | 83 | |
84 | - if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) { | |
84 | + if (ioctl(fd, SPI_IOC_RD_MODE32, &mode) < 0) { | |
85 | 85 | perror("SPI rd_mode"); |
86 | 86 | return; |
87 | 87 | } |
... | ... | @@ -98,7 +98,7 @@ |
98 | 98 | return; |
99 | 99 | } |
100 | 100 | |
101 | - printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n", | |
101 | + printf("%s: spi mode 0x%x, %d bits %sper word, %d Hz max\n", | |
102 | 102 | name, mode, bits, lsb ? "(lsb first) " : "", speed); |
103 | 103 | } |
104 | 104 |
Documentation/spi/spidev_test.c
... | ... | @@ -30,7 +30,7 @@ |
30 | 30 | } |
31 | 31 | |
32 | 32 | static const char *device = "/dev/spidev1.1"; |
33 | -static uint8_t mode; | |
33 | +static uint32_t mode; | |
34 | 34 | static uint8_t bits = 8; |
35 | 35 | static uint32_t speed = 500000; |
36 | 36 | static uint16_t delay; |
... | ... | @@ -57,6 +57,21 @@ |
57 | 57 | .bits_per_word = bits, |
58 | 58 | }; |
59 | 59 | |
60 | + if (mode & SPI_TX_QUAD) | |
61 | + tr.tx_nbits = 4; | |
62 | + else if (mode & SPI_TX_DUAL) | |
63 | + tr.tx_nbits = 2; | |
64 | + if (mode & SPI_RX_QUAD) | |
65 | + tr.rx_nbits = 4; | |
66 | + else if (mode & SPI_RX_DUAL) | |
67 | + tr.rx_nbits = 2; | |
68 | + if (!(mode & SPI_LOOP)) { | |
69 | + if (mode & (SPI_TX_QUAD | SPI_TX_DUAL)) | |
70 | + tr.rx_buf = 0; | |
71 | + else if (mode & (SPI_RX_QUAD | SPI_RX_DUAL)) | |
72 | + tr.tx_buf = 0; | |
73 | + } | |
74 | + | |
60 | 75 | ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); |
61 | 76 | if (ret < 1) |
62 | 77 | pabort("can't send spi message"); |
... | ... | @@ -81,7 +96,11 @@ |
81 | 96 | " -O --cpol clock polarity\n" |
82 | 97 | " -L --lsb least significant bit first\n" |
83 | 98 | " -C --cs-high chip select active high\n" |
84 | - " -3 --3wire SI/SO signals shared\n"); | |
99 | + " -3 --3wire SI/SO signals shared\n" | |
100 | + " -N --no-cs no chip select\n" | |
101 | + " -R --ready slave pulls low to pause\n" | |
102 | + " -2 --dual dual transfer\n" | |
103 | + " -4 --quad quad transfer\n"); | |
85 | 104 | exit(1); |
86 | 105 | } |
87 | 106 | |
88 | 107 | |
... | ... | @@ -101,11 +120,13 @@ |
101 | 120 | { "3wire", 0, 0, '3' }, |
102 | 121 | { "no-cs", 0, 0, 'N' }, |
103 | 122 | { "ready", 0, 0, 'R' }, |
123 | + { "dual", 0, 0, '2' }, | |
124 | + { "quad", 0, 0, '4' }, | |
104 | 125 | { NULL, 0, 0, 0 }, |
105 | 126 | }; |
106 | 127 | int c; |
107 | 128 | |
108 | - c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL); | |
129 | + c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24", lopts, NULL); | |
109 | 130 | |
110 | 131 | if (c == -1) |
111 | 132 | break; |
112 | 133 | |
... | ... | @@ -147,11 +168,23 @@ |
147 | 168 | case 'R': |
148 | 169 | mode |= SPI_READY; |
149 | 170 | break; |
171 | + case '2': | |
172 | + mode |= SPI_TX_DUAL; | |
173 | + break; | |
174 | + case '4': | |
175 | + mode |= SPI_TX_QUAD; | |
176 | + break; | |
150 | 177 | default: |
151 | 178 | print_usage(argv[0]); |
152 | 179 | break; |
153 | 180 | } |
154 | 181 | } |
182 | + if (mode & SPI_LOOP) { | |
183 | + if (mode & SPI_TX_DUAL) | |
184 | + mode |= SPI_RX_DUAL; | |
185 | + if (mode & SPI_TX_QUAD) | |
186 | + mode |= SPI_RX_QUAD; | |
187 | + } | |
155 | 188 | } |
156 | 189 | |
157 | 190 | int main(int argc, char *argv[]) |
158 | 191 | |
... | ... | @@ -168,11 +201,11 @@ |
168 | 201 | /* |
169 | 202 | * spi mode |
170 | 203 | */ |
171 | - ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); | |
204 | + ret = ioctl(fd, SPI_IOC_WR_MODE32, &mode); | |
172 | 205 | if (ret == -1) |
173 | 206 | pabort("can't set spi mode"); |
174 | 207 | |
175 | - ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); | |
208 | + ret = ioctl(fd, SPI_IOC_RD_MODE32, &mode); | |
176 | 209 | if (ret == -1) |
177 | 210 | pabort("can't get spi mode"); |
178 | 211 | |
... | ... | @@ -198,7 +231,7 @@ |
198 | 231 | if (ret == -1) |
199 | 232 | pabort("can't get max speed hz"); |
200 | 233 | |
201 | - printf("spi mode: %d\n", mode); | |
234 | + printf("spi mode: 0x%x\n", mode); | |
202 | 235 | printf("bits per word: %d\n", bits); |
203 | 236 | printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); |
204 | 237 |
drivers/spi/Kconfig
drivers/spi/spi-s3c64xx.c
... | ... | @@ -34,10 +34,6 @@ |
34 | 34 | |
35 | 35 | #include <linux/platform_data/spi-s3c64xx.h> |
36 | 36 | |
37 | -#ifdef CONFIG_S3C_DMA | |
38 | -#include <mach/dma.h> | |
39 | -#endif | |
40 | - | |
41 | 37 | #define MAX_SPI_PORTS 3 |
42 | 38 | #define S3C64XX_SPI_QUIRK_POLL (1 << 0) |
43 | 39 | |
... | ... | @@ -200,9 +196,6 @@ |
200 | 196 | unsigned cur_speed; |
201 | 197 | struct s3c64xx_spi_dma_data rx_dma; |
202 | 198 | struct s3c64xx_spi_dma_data tx_dma; |
203 | -#ifdef CONFIG_S3C_DMA | |
204 | - struct samsung_dma_ops *ops; | |
205 | -#endif | |
206 | 199 | struct s3c64xx_spi_port_config *port_conf; |
207 | 200 | unsigned int port_id; |
208 | 201 | bool cs_gpio; |
209 | 202 | |
... | ... | @@ -284,103 +277,7 @@ |
284 | 277 | spin_unlock_irqrestore(&sdd->lock, flags); |
285 | 278 | } |
286 | 279 | |
287 | -#ifdef CONFIG_S3C_DMA | |
288 | -/* FIXME: remove this section once arch/arm/mach-s3c64xx uses dmaengine */ | |
289 | - | |
290 | -static struct s3c2410_dma_client s3c64xx_spi_dma_client = { | |
291 | - .name = "samsung-spi-dma", | |
292 | -}; | |
293 | - | |
294 | 280 | static void prepare_dma(struct s3c64xx_spi_dma_data *dma, |
295 | - unsigned len, dma_addr_t buf) | |
296 | -{ | |
297 | - struct s3c64xx_spi_driver_data *sdd; | |
298 | - struct samsung_dma_prep info; | |
299 | - struct samsung_dma_config config; | |
300 | - | |
301 | - if (dma->direction == DMA_DEV_TO_MEM) { | |
302 | - sdd = container_of((void *)dma, | |
303 | - struct s3c64xx_spi_driver_data, rx_dma); | |
304 | - config.direction = sdd->rx_dma.direction; | |
305 | - config.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; | |
306 | - config.width = sdd->cur_bpw / 8; | |
307 | - sdd->ops->config((enum dma_ch)sdd->rx_dma.ch, &config); | |
308 | - } else { | |
309 | - sdd = container_of((void *)dma, | |
310 | - struct s3c64xx_spi_driver_data, tx_dma); | |
311 | - config.direction = sdd->tx_dma.direction; | |
312 | - config.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; | |
313 | - config.width = sdd->cur_bpw / 8; | |
314 | - sdd->ops->config((enum dma_ch)sdd->tx_dma.ch, &config); | |
315 | - } | |
316 | - | |
317 | - info.cap = DMA_SLAVE; | |
318 | - info.len = len; | |
319 | - info.fp = s3c64xx_spi_dmacb; | |
320 | - info.fp_param = dma; | |
321 | - info.direction = dma->direction; | |
322 | - info.buf = buf; | |
323 | - | |
324 | - sdd->ops->prepare((enum dma_ch)dma->ch, &info); | |
325 | - sdd->ops->trigger((enum dma_ch)dma->ch); | |
326 | -} | |
327 | - | |
328 | -static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) | |
329 | -{ | |
330 | - struct samsung_dma_req req; | |
331 | - struct device *dev = &sdd->pdev->dev; | |
332 | - | |
333 | - sdd->ops = samsung_dma_get_ops(); | |
334 | - | |
335 | - req.cap = DMA_SLAVE; | |
336 | - req.client = &s3c64xx_spi_dma_client; | |
337 | - | |
338 | - sdd->rx_dma.ch = (struct dma_chan *)(unsigned long)sdd->ops->request( | |
339 | - sdd->rx_dma.dmach, &req, dev, "rx"); | |
340 | - sdd->tx_dma.ch = (struct dma_chan *)(unsigned long)sdd->ops->request( | |
341 | - sdd->tx_dma.dmach, &req, dev, "tx"); | |
342 | - | |
343 | - return 1; | |
344 | -} | |
345 | - | |
346 | -static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) | |
347 | -{ | |
348 | - struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); | |
349 | - | |
350 | - /* | |
351 | - * If DMA resource was not available during | |
352 | - * probe, no need to continue with dma requests | |
353 | - * else Acquire DMA channels | |
354 | - */ | |
355 | - while (!is_polling(sdd) && !acquire_dma(sdd)) | |
356 | - usleep_range(10000, 11000); | |
357 | - | |
358 | - return 0; | |
359 | -} | |
360 | - | |
361 | -static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi) | |
362 | -{ | |
363 | - struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi); | |
364 | - | |
365 | - /* Free DMA channels */ | |
366 | - if (!is_polling(sdd)) { | |
367 | - sdd->ops->release((enum dma_ch)sdd->rx_dma.ch, | |
368 | - &s3c64xx_spi_dma_client); | |
369 | - sdd->ops->release((enum dma_ch)sdd->tx_dma.ch, | |
370 | - &s3c64xx_spi_dma_client); | |
371 | - } | |
372 | - | |
373 | - return 0; | |
374 | -} | |
375 | - | |
376 | -static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd, | |
377 | - struct s3c64xx_spi_dma_data *dma) | |
378 | -{ | |
379 | - sdd->ops->stop((enum dma_ch)dma->ch); | |
380 | -} | |
381 | -#else | |
382 | - | |
383 | -static void prepare_dma(struct s3c64xx_spi_dma_data *dma, | |
384 | 281 | struct sg_table *sgt) |
385 | 282 | { |
386 | 283 | struct s3c64xx_spi_driver_data *sdd; |
... | ... | @@ -437,6 +334,7 @@ |
437 | 334 | ret = -EBUSY; |
438 | 335 | goto out; |
439 | 336 | } |
337 | + spi->dma_rx = sdd->rx_dma.ch; | |
440 | 338 | |
441 | 339 | sdd->tx_dma.ch = dma_request_slave_channel_compat(mask, filter, |
442 | 340 | (void *)sdd->tx_dma.dmach, dev, "tx"); |
... | ... | @@ -445,6 +343,7 @@ |
445 | 343 | ret = -EBUSY; |
446 | 344 | goto out_rx; |
447 | 345 | } |
346 | + spi->dma_tx = sdd->tx_dma.ch; | |
448 | 347 | } |
449 | 348 | |
450 | 349 | ret = pm_runtime_get_sync(&sdd->pdev->dev); |
451 | 350 | |
452 | 351 | |
... | ... | @@ -477,12 +376,14 @@ |
477 | 376 | return 0; |
478 | 377 | } |
479 | 378 | |
480 | -static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd, | |
481 | - struct s3c64xx_spi_dma_data *dma) | |
379 | +static bool s3c64xx_spi_can_dma(struct spi_master *master, | |
380 | + struct spi_device *spi, | |
381 | + struct spi_transfer *xfer) | |
482 | 382 | { |
483 | - dmaengine_terminate_all(dma->ch); | |
383 | + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); | |
384 | + | |
385 | + return xfer->len > (FIFO_LVL_MASK(sdd) >> 1) + 1; | |
484 | 386 | } |
485 | -#endif | |
486 | 387 | |
487 | 388 | static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, |
488 | 389 | struct spi_device *spi, |
489 | 390 | |
... | ... | @@ -515,11 +416,7 @@ |
515 | 416 | chcfg |= S3C64XX_SPI_CH_TXCH_ON; |
516 | 417 | if (dma_mode) { |
517 | 418 | modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; |
518 | -#ifndef CONFIG_S3C_DMA | |
519 | 419 | prepare_dma(&sdd->tx_dma, &xfer->tx_sg); |
520 | -#else | |
521 | - prepare_dma(&sdd->tx_dma, xfer->len, xfer->tx_dma); | |
522 | -#endif | |
523 | 420 | } else { |
524 | 421 | switch (sdd->cur_bpw) { |
525 | 422 | case 32: |
526 | 423 | |
... | ... | @@ -551,11 +448,7 @@ |
551 | 448 | writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) |
552 | 449 | | S3C64XX_SPI_PACKET_CNT_EN, |
553 | 450 | regs + S3C64XX_SPI_PACKET_CNT); |
554 | -#ifndef CONFIG_S3C_DMA | |
555 | 451 | prepare_dma(&sdd->rx_dma, &xfer->rx_sg); |
556 | -#else | |
557 | - prepare_dma(&sdd->rx_dma, xfer->len, xfer->rx_dma); | |
558 | -#endif | |
559 | 452 | } |
560 | 453 | } |
561 | 454 | |
... | ... | @@ -764,81 +657,6 @@ |
764 | 657 | |
765 | 658 | #define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) |
766 | 659 | |
767 | -static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd, | |
768 | - struct spi_message *msg) | |
769 | -{ | |
770 | - struct device *dev = &sdd->pdev->dev; | |
771 | - struct spi_transfer *xfer; | |
772 | - | |
773 | - if (is_polling(sdd) || msg->is_dma_mapped) | |
774 | - return 0; | |
775 | - | |
776 | - /* First mark all xfer unmapped */ | |
777 | - list_for_each_entry(xfer, &msg->transfers, transfer_list) { | |
778 | - xfer->rx_dma = XFER_DMAADDR_INVALID; | |
779 | - xfer->tx_dma = XFER_DMAADDR_INVALID; | |
780 | - } | |
781 | - | |
782 | - /* Map until end or first fail */ | |
783 | - list_for_each_entry(xfer, &msg->transfers, transfer_list) { | |
784 | - | |
785 | - if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1)) | |
786 | - continue; | |
787 | - | |
788 | - if (xfer->tx_buf != NULL) { | |
789 | - xfer->tx_dma = dma_map_single(dev, | |
790 | - (void *)xfer->tx_buf, xfer->len, | |
791 | - DMA_TO_DEVICE); | |
792 | - if (dma_mapping_error(dev, xfer->tx_dma)) { | |
793 | - dev_err(dev, "dma_map_single Tx failed\n"); | |
794 | - xfer->tx_dma = XFER_DMAADDR_INVALID; | |
795 | - return -ENOMEM; | |
796 | - } | |
797 | - } | |
798 | - | |
799 | - if (xfer->rx_buf != NULL) { | |
800 | - xfer->rx_dma = dma_map_single(dev, xfer->rx_buf, | |
801 | - xfer->len, DMA_FROM_DEVICE); | |
802 | - if (dma_mapping_error(dev, xfer->rx_dma)) { | |
803 | - dev_err(dev, "dma_map_single Rx failed\n"); | |
804 | - dma_unmap_single(dev, xfer->tx_dma, | |
805 | - xfer->len, DMA_TO_DEVICE); | |
806 | - xfer->tx_dma = XFER_DMAADDR_INVALID; | |
807 | - xfer->rx_dma = XFER_DMAADDR_INVALID; | |
808 | - return -ENOMEM; | |
809 | - } | |
810 | - } | |
811 | - } | |
812 | - | |
813 | - return 0; | |
814 | -} | |
815 | - | |
816 | -static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd, | |
817 | - struct spi_message *msg) | |
818 | -{ | |
819 | - struct device *dev = &sdd->pdev->dev; | |
820 | - struct spi_transfer *xfer; | |
821 | - | |
822 | - if (is_polling(sdd) || msg->is_dma_mapped) | |
823 | - return; | |
824 | - | |
825 | - list_for_each_entry(xfer, &msg->transfers, transfer_list) { | |
826 | - | |
827 | - if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1)) | |
828 | - continue; | |
829 | - | |
830 | - if (xfer->rx_buf != NULL | |
831 | - && xfer->rx_dma != XFER_DMAADDR_INVALID) | |
832 | - dma_unmap_single(dev, xfer->rx_dma, | |
833 | - xfer->len, DMA_FROM_DEVICE); | |
834 | - | |
835 | - if (xfer->tx_buf != NULL | |
836 | - && xfer->tx_dma != XFER_DMAADDR_INVALID) | |
837 | - dma_unmap_single(dev, xfer->tx_dma, | |
838 | - xfer->len, DMA_TO_DEVICE); | |
839 | - } | |
840 | -} | |
841 | - | |
842 | 660 | static int s3c64xx_spi_prepare_message(struct spi_master *master, |
843 | 661 | struct spi_message *msg) |
844 | 662 | { |
... | ... | @@ -856,13 +674,6 @@ |
856 | 674 | s3c64xx_spi_config(sdd); |
857 | 675 | } |
858 | 676 | |
859 | - /* Map all the transfers if needed */ | |
860 | - if (s3c64xx_spi_map_mssg(sdd, msg)) { | |
861 | - dev_err(&spi->dev, | |
862 | - "Xfer: Unable to map message buffers!\n"); | |
863 | - return -ENOMEM; | |
864 | - } | |
865 | - | |
866 | 677 | /* Configure feedback delay */ |
867 | 678 | writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK); |
868 | 679 | |
... | ... | @@ -886,13 +697,6 @@ |
886 | 697 | bpw = xfer->bits_per_word; |
887 | 698 | speed = xfer->speed_hz ? : spi->max_speed_hz; |
888 | 699 | |
889 | - if (xfer->len % (bpw / 8)) { | |
890 | - dev_err(&spi->dev, | |
891 | - "Xfer length(%u) not a multiple of word size(%u)\n", | |
892 | - xfer->len, bpw / 8); | |
893 | - return -EIO; | |
894 | - } | |
895 | - | |
896 | 700 | if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) { |
897 | 701 | sdd->cur_bpw = bpw; |
898 | 702 | sdd->cur_speed = speed; |
899 | 703 | |
... | ... | @@ -934,10 +738,10 @@ |
934 | 738 | if (use_dma) { |
935 | 739 | if (xfer->tx_buf != NULL |
936 | 740 | && (sdd->state & TXBUSY)) |
937 | - s3c64xx_spi_dma_stop(sdd, &sdd->tx_dma); | |
741 | + dmaengine_terminate_all(sdd->tx_dma.ch); | |
938 | 742 | if (xfer->rx_buf != NULL |
939 | 743 | && (sdd->state & RXBUSY)) |
940 | - s3c64xx_spi_dma_stop(sdd, &sdd->rx_dma); | |
744 | + dmaengine_terminate_all(sdd->rx_dma.ch); | |
941 | 745 | } |
942 | 746 | } else { |
943 | 747 | flush_fifo(sdd); |
... | ... | @@ -946,16 +750,6 @@ |
946 | 750 | return status; |
947 | 751 | } |
948 | 752 | |
949 | -static int s3c64xx_spi_unprepare_message(struct spi_master *master, | |
950 | - struct spi_message *msg) | |
951 | -{ | |
952 | - struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); | |
953 | - | |
954 | - s3c64xx_spi_unmap_mssg(sdd, msg); | |
955 | - | |
956 | - return 0; | |
957 | -} | |
958 | - | |
959 | 753 | static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata( |
960 | 754 | struct spi_device *spi) |
961 | 755 | { |
... | ... | @@ -1329,7 +1123,6 @@ |
1329 | 1123 | master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; |
1330 | 1124 | master->prepare_message = s3c64xx_spi_prepare_message; |
1331 | 1125 | master->transfer_one = s3c64xx_spi_transfer_one; |
1332 | - master->unprepare_message = s3c64xx_spi_unprepare_message; | |
1333 | 1126 | master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer; |
1334 | 1127 | master->num_chipselect = sci->num_cs; |
1335 | 1128 | master->dma_alignment = 8; |
... | ... | @@ -1338,6 +1131,8 @@ |
1338 | 1131 | /* the spi->mode bits understood by this driver: */ |
1339 | 1132 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
1340 | 1133 | master->auto_runtime_pm = true; |
1134 | + if (!is_polling(sdd)) | |
1135 | + master->can_dma = s3c64xx_spi_can_dma; | |
1341 | 1136 | |
1342 | 1137 | sdd->regs = devm_ioremap_resource(&pdev->dev, mem_res); |
1343 | 1138 | if (IS_ERR(sdd->regs)) { |
drivers/spi/spi-sc18is602.c
... | ... | @@ -183,17 +183,9 @@ |
183 | 183 | static int sc18is602_check_transfer(struct spi_device *spi, |
184 | 184 | struct spi_transfer *t, int tlen) |
185 | 185 | { |
186 | - uint32_t hz; | |
187 | - | |
188 | 186 | if (t && t->len + tlen > SC18IS602_BUFSIZ) |
189 | 187 | return -EINVAL; |
190 | 188 | |
191 | - hz = spi->max_speed_hz; | |
192 | - if (t && t->speed_hz) | |
193 | - hz = t->speed_hz; | |
194 | - if (hz == 0) | |
195 | - return -EINVAL; | |
196 | - | |
197 | 189 | return 0; |
198 | 190 | } |
199 | 191 | |
200 | 192 | |
201 | 193 | |
... | ... | @@ -205,22 +197,15 @@ |
205 | 197 | struct spi_transfer *t; |
206 | 198 | int status = 0; |
207 | 199 | |
208 | - /* SC18IS602 does not support CS2 */ | |
209 | - if (hw->id == sc18is602 && spi->chip_select == 2) { | |
210 | - status = -ENXIO; | |
211 | - goto error; | |
212 | - } | |
213 | - | |
214 | 200 | hw->tlen = 0; |
215 | 201 | list_for_each_entry(t, &m->transfers, transfer_list) { |
216 | - u32 hz = t->speed_hz ? : spi->max_speed_hz; | |
217 | 202 | bool do_transfer; |
218 | 203 | |
219 | 204 | status = sc18is602_check_transfer(spi, t, hw->tlen); |
220 | 205 | if (status < 0) |
221 | 206 | break; |
222 | 207 | |
223 | - status = sc18is602_setup_transfer(hw, hz, spi->mode); | |
208 | + status = sc18is602_setup_transfer(hw, t->speed_hz, spi->mode); | |
224 | 209 | if (status < 0) |
225 | 210 | break; |
226 | 211 | |
... | ... | @@ -238,7 +223,6 @@ |
238 | 223 | if (t->delay_usecs) |
239 | 224 | udelay(t->delay_usecs); |
240 | 225 | } |
241 | -error: | |
242 | 226 | m->status = status; |
243 | 227 | spi_finalize_current_message(master); |
244 | 228 | |
245 | 229 | |
... | ... | @@ -247,10 +231,13 @@ |
247 | 231 | |
248 | 232 | static int sc18is602_setup(struct spi_device *spi) |
249 | 233 | { |
250 | - if (spi->mode & ~(SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST)) | |
251 | - return -EINVAL; | |
234 | + struct sc18is602 *hw = spi_master_get_devdata(spi->master); | |
252 | 235 | |
253 | - return sc18is602_check_transfer(spi, NULL, 0); | |
236 | + /* SC18IS602 does not support CS2 */ | |
237 | + if (hw->id == sc18is602 && spi->chip_select == 2) | |
238 | + return -ENXIO; | |
239 | + | |
240 | + return 0; | |
254 | 241 | } |
255 | 242 | |
256 | 243 | static int sc18is602_probe(struct i2c_client *client, |
... | ... | @@ -309,6 +296,8 @@ |
309 | 296 | master->setup = sc18is602_setup; |
310 | 297 | master->transfer_one_message = sc18is602_transfer_one; |
311 | 298 | master->dev.of_node = np; |
299 | + master->min_speed_hz = hw->freq / 128; | |
300 | + master->max_speed_hz = hw->freq / 4; | |
312 | 301 | |
313 | 302 | error = devm_spi_register_master(dev, master); |
314 | 303 | if (error) |
drivers/spi/spi-sh-hspi.c
... | ... | @@ -46,8 +46,6 @@ |
46 | 46 | /* SPSR */ |
47 | 47 | #define RXFL (1 << 2) |
48 | 48 | |
49 | -#define hspi2info(h) (h->dev->platform_data) | |
50 | - | |
51 | 49 | struct hspi_priv { |
52 | 50 | void __iomem *addr; |
53 | 51 | struct spi_master *master; |
54 | 52 | |
... | ... | @@ -113,14 +111,9 @@ |
113 | 111 | { |
114 | 112 | struct spi_device *spi = msg->spi; |
115 | 113 | struct device *dev = hspi->dev; |
116 | - u32 target_rate; | |
117 | 114 | u32 spcr, idiv_clk; |
118 | 115 | u32 rate, best_rate, min, tmp; |
119 | 116 | |
120 | - target_rate = t ? t->speed_hz : 0; | |
121 | - if (!target_rate) | |
122 | - target_rate = spi->max_speed_hz; | |
123 | - | |
124 | 117 | /* |
125 | 118 | * find best IDIV/CLKCx settings |
126 | 119 | */ |
... | ... | @@ -140,7 +133,7 @@ |
140 | 133 | rate /= (((idiv_clk & 0x1F) + 1) * 2); |
141 | 134 | |
142 | 135 | /* save best settings */ |
143 | - tmp = abs(target_rate - rate); | |
136 | + tmp = abs(t->speed_hz - rate); | |
144 | 137 | if (tmp < min) { |
145 | 138 | min = tmp; |
146 | 139 | spcr = idiv_clk; |
... | ... | @@ -153,7 +146,7 @@ |
153 | 146 | if (spi->mode & SPI_CPOL) |
154 | 147 | spcr |= 1 << 6; |
155 | 148 | |
156 | - dev_dbg(dev, "speed %d/%d\n", target_rate, best_rate); | |
149 | + dev_dbg(dev, "speed %d/%d\n", t->speed_hz, best_rate); | |
157 | 150 | |
158 | 151 | hspi_write(hspi, SPCR, spcr); |
159 | 152 | hspi_write(hspi, SPSR, 0x0); |
... | ... | @@ -230,29 +223,6 @@ |
230 | 223 | return ret; |
231 | 224 | } |
232 | 225 | |
233 | -static int hspi_setup(struct spi_device *spi) | |
234 | -{ | |
235 | - struct hspi_priv *hspi = spi_master_get_devdata(spi->master); | |
236 | - struct device *dev = hspi->dev; | |
237 | - | |
238 | - if (8 != spi->bits_per_word) { | |
239 | - dev_err(dev, "bits_per_word should be 8\n"); | |
240 | - return -EIO; | |
241 | - } | |
242 | - | |
243 | - dev_dbg(dev, "%s setup\n", spi->modalias); | |
244 | - | |
245 | - return 0; | |
246 | -} | |
247 | - | |
248 | -static void hspi_cleanup(struct spi_device *spi) | |
249 | -{ | |
250 | - struct hspi_priv *hspi = spi_master_get_devdata(spi->master); | |
251 | - struct device *dev = hspi->dev; | |
252 | - | |
253 | - dev_dbg(dev, "%s cleanup\n", spi->modalias); | |
254 | -} | |
255 | - | |
256 | 226 | static int hspi_probe(struct platform_device *pdev) |
257 | 227 | { |
258 | 228 | struct resource *res; |
259 | 229 | |
260 | 230 | |
261 | 231 | |
... | ... | @@ -299,20 +269,22 @@ |
299 | 269 | pm_runtime_enable(&pdev->dev); |
300 | 270 | |
301 | 271 | master->bus_num = pdev->id; |
302 | - master->setup = hspi_setup; | |
303 | - master->cleanup = hspi_cleanup; | |
304 | 272 | master->mode_bits = SPI_CPOL | SPI_CPHA; |
305 | 273 | master->dev.of_node = pdev->dev.of_node; |
306 | 274 | master->auto_runtime_pm = true; |
307 | 275 | master->transfer_one_message = hspi_transfer_one_message; |
276 | + master->bits_per_word_mask = SPI_BPW_MASK(8); | |
277 | + | |
308 | 278 | ret = devm_spi_register_master(&pdev->dev, master); |
309 | 279 | if (ret < 0) { |
310 | 280 | dev_err(&pdev->dev, "spi_register_master error.\n"); |
311 | - goto error1; | |
281 | + goto error2; | |
312 | 282 | } |
313 | 283 | |
314 | 284 | return 0; |
315 | 285 | |
286 | + error2: | |
287 | + pm_runtime_disable(&pdev->dev); | |
316 | 288 | error1: |
317 | 289 | clk_put(clk); |
318 | 290 | error0: |
drivers/spi/spi-sh-msiof.c
... | ... | @@ -20,54 +20,104 @@ |
20 | 20 | #include <linux/kernel.h> |
21 | 21 | #include <linux/module.h> |
22 | 22 | #include <linux/of.h> |
23 | +#include <linux/of_device.h> | |
23 | 24 | #include <linux/platform_device.h> |
24 | 25 | #include <linux/pm_runtime.h> |
25 | 26 | |
26 | 27 | #include <linux/spi/sh_msiof.h> |
27 | 28 | #include <linux/spi/spi.h> |
28 | -#include <linux/spi/spi_bitbang.h> | |
29 | 29 | |
30 | 30 | #include <asm/unaligned.h> |
31 | 31 | |
32 | + | |
33 | +struct sh_msiof_chipdata { | |
34 | + u16 tx_fifo_size; | |
35 | + u16 rx_fifo_size; | |
36 | + u16 master_flags; | |
37 | +}; | |
38 | + | |
32 | 39 | struct sh_msiof_spi_priv { |
33 | - struct spi_bitbang bitbang; /* must be first for spi_bitbang.c */ | |
34 | 40 | void __iomem *mapbase; |
35 | 41 | struct clk *clk; |
36 | 42 | struct platform_device *pdev; |
43 | + const struct sh_msiof_chipdata *chipdata; | |
37 | 44 | struct sh_msiof_spi_info *info; |
38 | 45 | struct completion done; |
39 | - unsigned long flags; | |
40 | 46 | int tx_fifo_size; |
41 | 47 | int rx_fifo_size; |
42 | 48 | }; |
43 | 49 | |
44 | -#define TMDR1 0x00 | |
45 | -#define TMDR2 0x04 | |
46 | -#define TMDR3 0x08 | |
47 | -#define RMDR1 0x10 | |
48 | -#define RMDR2 0x14 | |
49 | -#define RMDR3 0x18 | |
50 | -#define TSCR 0x20 | |
51 | -#define RSCR 0x22 | |
52 | -#define CTR 0x28 | |
53 | -#define FCTR 0x30 | |
54 | -#define STR 0x40 | |
55 | -#define IER 0x44 | |
56 | -#define TDR1 0x48 | |
57 | -#define TDR2 0x4c | |
58 | -#define TFDR 0x50 | |
59 | -#define RDR1 0x58 | |
60 | -#define RDR2 0x5c | |
61 | -#define RFDR 0x60 | |
50 | +#define TMDR1 0x00 /* Transmit Mode Register 1 */ | |
51 | +#define TMDR2 0x04 /* Transmit Mode Register 2 */ | |
52 | +#define TMDR3 0x08 /* Transmit Mode Register 3 */ | |
53 | +#define RMDR1 0x10 /* Receive Mode Register 1 */ | |
54 | +#define RMDR2 0x14 /* Receive Mode Register 2 */ | |
55 | +#define RMDR3 0x18 /* Receive Mode Register 3 */ | |
56 | +#define TSCR 0x20 /* Transmit Clock Select Register */ | |
57 | +#define RSCR 0x22 /* Receive Clock Select Register (SH, A1, APE6) */ | |
58 | +#define CTR 0x28 /* Control Register */ | |
59 | +#define FCTR 0x30 /* FIFO Control Register */ | |
60 | +#define STR 0x40 /* Status Register */ | |
61 | +#define IER 0x44 /* Interrupt Enable Register */ | |
62 | +#define TDR1 0x48 /* Transmit Control Data Register 1 (SH, A1) */ | |
63 | +#define TDR2 0x4c /* Transmit Control Data Register 2 (SH, A1) */ | |
64 | +#define TFDR 0x50 /* Transmit FIFO Data Register */ | |
65 | +#define RDR1 0x58 /* Receive Control Data Register 1 (SH, A1) */ | |
66 | +#define RDR2 0x5c /* Receive Control Data Register 2 (SH, A1) */ | |
67 | +#define RFDR 0x60 /* Receive FIFO Data Register */ | |
62 | 68 | |
63 | -#define CTR_TSCKE (1 << 15) | |
64 | -#define CTR_TFSE (1 << 14) | |
65 | -#define CTR_TXE (1 << 9) | |
66 | -#define CTR_RXE (1 << 8) | |
69 | +/* TMDR1 and RMDR1 */ | |
70 | +#define MDR1_TRMD 0x80000000 /* Transfer Mode (1 = Master mode) */ | |
71 | +#define MDR1_SYNCMD_MASK 0x30000000 /* SYNC Mode */ | |
72 | +#define MDR1_SYNCMD_SPI 0x20000000 /* Level mode/SPI */ | |
73 | +#define MDR1_SYNCMD_LR 0x30000000 /* L/R mode */ | |
74 | +#define MDR1_SYNCAC_SHIFT 25 /* Sync Polarity (1 = Active-low) */ | |
75 | +#define MDR1_BITLSB_SHIFT 24 /* MSB/LSB First (1 = LSB first) */ | |
76 | +#define MDR1_FLD_MASK 0x000000c0 /* Frame Sync Signal Interval (0-3) */ | |
77 | +#define MDR1_FLD_SHIFT 2 | |
78 | +#define MDR1_XXSTP 0x00000001 /* Transmission/Reception Stop on FIFO */ | |
79 | +/* TMDR1 */ | |
80 | +#define TMDR1_PCON 0x40000000 /* Transfer Signal Connection */ | |
67 | 81 | |
68 | -#define STR_TEOF (1 << 23) | |
69 | -#define STR_REOF (1 << 7) | |
82 | +/* TMDR2 and RMDR2 */ | |
83 | +#define MDR2_BITLEN1(i) (((i) - 1) << 24) /* Data Size (8-32 bits) */ | |
84 | +#define MDR2_WDLEN1(i) (((i) - 1) << 16) /* Word Count (1-64/256 (SH, A1))) */ | |
85 | +#define MDR2_GRPMASK1 0x00000001 /* Group Output Mask 1 (SH, A1) */ | |
70 | 86 | |
87 | +/* TSCR and RSCR */ | |
88 | +#define SCR_BRPS_MASK 0x1f00 /* Prescaler Setting (1-32) */ | |
89 | +#define SCR_BRPS(i) (((i) - 1) << 8) | |
90 | +#define SCR_BRDV_MASK 0x0007 /* Baud Rate Generator's Division Ratio */ | |
91 | +#define SCR_BRDV_DIV_2 0x0000 | |
92 | +#define SCR_BRDV_DIV_4 0x0001 | |
93 | +#define SCR_BRDV_DIV_8 0x0002 | |
94 | +#define SCR_BRDV_DIV_16 0x0003 | |
95 | +#define SCR_BRDV_DIV_32 0x0004 | |
96 | +#define SCR_BRDV_DIV_1 0x0007 | |
97 | + | |
98 | +/* CTR */ | |
99 | +#define CTR_TSCKIZ_MASK 0xc0000000 /* Transmit Clock I/O Polarity Select */ | |
100 | +#define CTR_TSCKIZ_SCK 0x80000000 /* Disable SCK when TX disabled */ | |
101 | +#define CTR_TSCKIZ_POL_SHIFT 30 /* Transmit Clock Polarity */ | |
102 | +#define CTR_RSCKIZ_MASK 0x30000000 /* Receive Clock Polarity Select */ | |
103 | +#define CTR_RSCKIZ_SCK 0x20000000 /* Must match CTR_TSCKIZ_SCK */ | |
104 | +#define CTR_RSCKIZ_POL_SHIFT 28 /* Receive Clock Polarity */ | |
105 | +#define CTR_TEDG_SHIFT 27 /* Transmit Timing (1 = falling edge) */ | |
106 | +#define CTR_REDG_SHIFT 26 /* Receive Timing (1 = falling edge) */ | |
107 | +#define CTR_TXDIZ_MASK 0x00c00000 /* Pin Output When TX is Disabled */ | |
108 | +#define CTR_TXDIZ_LOW 0x00000000 /* 0 */ | |
109 | +#define CTR_TXDIZ_HIGH 0x00400000 /* 1 */ | |
110 | +#define CTR_TXDIZ_HIZ 0x00800000 /* High-impedance */ | |
111 | +#define CTR_TSCKE 0x00008000 /* Transmit Serial Clock Output Enable */ | |
112 | +#define CTR_TFSE 0x00004000 /* Transmit Frame Sync Signal Output Enable */ | |
113 | +#define CTR_TXE 0x00000200 /* Transmit Enable */ | |
114 | +#define CTR_RXE 0x00000100 /* Receive Enable */ | |
115 | + | |
116 | +/* STR and IER */ | |
117 | +#define STR_TEOF 0x00800000 /* Frame Transmission End */ | |
118 | +#define STR_REOF 0x00000080 /* Frame Reception End */ | |
119 | + | |
120 | + | |
71 | 121 | static u32 sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs) |
72 | 122 | { |
73 | 123 | switch (reg_offs) { |
74 | 124 | |
... | ... | @@ -130,22 +180,21 @@ |
130 | 180 | unsigned short div; |
131 | 181 | unsigned short scr; |
132 | 182 | } const sh_msiof_spi_clk_table[] = { |
133 | - { 1, 0x0007 }, | |
134 | - { 2, 0x0000 }, | |
135 | - { 4, 0x0001 }, | |
136 | - { 8, 0x0002 }, | |
137 | - { 16, 0x0003 }, | |
138 | - { 32, 0x0004 }, | |
139 | - { 64, 0x1f00 }, | |
140 | - { 128, 0x1f01 }, | |
141 | - { 256, 0x1f02 }, | |
142 | - { 512, 0x1f03 }, | |
143 | - { 1024, 0x1f04 }, | |
183 | + { 1, SCR_BRPS( 1) | SCR_BRDV_DIV_1 }, | |
184 | + { 2, SCR_BRPS( 1) | SCR_BRDV_DIV_2 }, | |
185 | + { 4, SCR_BRPS( 1) | SCR_BRDV_DIV_4 }, | |
186 | + { 8, SCR_BRPS( 1) | SCR_BRDV_DIV_8 }, | |
187 | + { 16, SCR_BRPS( 1) | SCR_BRDV_DIV_16 }, | |
188 | + { 32, SCR_BRPS( 1) | SCR_BRDV_DIV_32 }, | |
189 | + { 64, SCR_BRPS(32) | SCR_BRDV_DIV_2 }, | |
190 | + { 128, SCR_BRPS(32) | SCR_BRDV_DIV_4 }, | |
191 | + { 256, SCR_BRPS(32) | SCR_BRDV_DIV_8 }, | |
192 | + { 512, SCR_BRPS(32) | SCR_BRDV_DIV_16 }, | |
193 | + { 1024, SCR_BRPS(32) | SCR_BRDV_DIV_32 }, | |
144 | 194 | }; |
145 | 195 | |
146 | 196 | static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, |
147 | - unsigned long parent_rate, | |
148 | - unsigned long spi_hz) | |
197 | + unsigned long parent_rate, u32 spi_hz) | |
149 | 198 | { |
150 | 199 | unsigned long div = 1024; |
151 | 200 | size_t k; |
... | ... | @@ -163,7 +212,8 @@ |
163 | 212 | k = min_t(int, k, ARRAY_SIZE(sh_msiof_spi_clk_table) - 1); |
164 | 213 | |
165 | 214 | sh_msiof_write(p, TSCR, sh_msiof_spi_clk_table[k].scr); |
166 | - sh_msiof_write(p, RSCR, sh_msiof_spi_clk_table[k].scr); | |
215 | + if (!(p->chipdata->master_flags & SPI_MASTER_MUST_TX)) | |
216 | + sh_msiof_write(p, RSCR, sh_msiof_spi_clk_table[k].scr); | |
167 | 217 | } |
168 | 218 | |
169 | 219 | static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, |
170 | 220 | |
171 | 221 | |
172 | 222 | |
... | ... | @@ -182,21 +232,25 @@ |
182 | 232 | */ |
183 | 233 | sh_msiof_write(p, FCTR, 0); |
184 | 234 | |
235 | + tmp = MDR1_SYNCMD_SPI | 1 << MDR1_FLD_SHIFT | MDR1_XXSTP; | |
236 | + tmp |= !cs_high << MDR1_SYNCAC_SHIFT; | |
237 | + tmp |= lsb_first << MDR1_BITLSB_SHIFT; | |
238 | + sh_msiof_write(p, TMDR1, tmp | MDR1_TRMD | TMDR1_PCON); | |
239 | + if (p->chipdata->master_flags & SPI_MASTER_MUST_TX) { | |
240 | + /* These bits are reserved if RX needs TX */ | |
241 | + tmp &= ~0x0000ffff; | |
242 | + } | |
243 | + sh_msiof_write(p, RMDR1, tmp); | |
244 | + | |
185 | 245 | tmp = 0; |
186 | - tmp |= !cs_high << 25; | |
187 | - tmp |= lsb_first << 24; | |
188 | - sh_msiof_write(p, TMDR1, 0xe0000005 | tmp); | |
189 | - sh_msiof_write(p, RMDR1, 0x20000005 | tmp); | |
246 | + tmp |= CTR_TSCKIZ_SCK | cpol << CTR_TSCKIZ_POL_SHIFT; | |
247 | + tmp |= CTR_RSCKIZ_SCK | cpol << CTR_RSCKIZ_POL_SHIFT; | |
190 | 248 | |
191 | - tmp = 0xa0000000; | |
192 | - tmp |= cpol << 30; /* TSCKIZ */ | |
193 | - tmp |= cpol << 28; /* RSCKIZ */ | |
194 | - | |
195 | 249 | edge = cpol ^ !cpha; |
196 | 250 | |
197 | - tmp |= edge << 27; /* TEDG */ | |
198 | - tmp |= edge << 26; /* REDG */ | |
199 | - tmp |= (tx_hi_z ? 2 : 0) << 22; /* TXDIZ */ | |
251 | + tmp |= edge << CTR_TEDG_SHIFT; | |
252 | + tmp |= edge << CTR_REDG_SHIFT; | |
253 | + tmp |= tx_hi_z ? CTR_TXDIZ_HIZ : CTR_TXDIZ_LOW; | |
200 | 254 | sh_msiof_write(p, CTR, tmp); |
201 | 255 | } |
202 | 256 | |
203 | 257 | |
204 | 258 | |
... | ... | @@ -204,12 +258,12 @@ |
204 | 258 | const void *tx_buf, void *rx_buf, |
205 | 259 | u32 bits, u32 words) |
206 | 260 | { |
207 | - u32 dr2 = ((bits - 1) << 24) | ((words - 1) << 16); | |
261 | + u32 dr2 = MDR2_BITLEN1(bits) | MDR2_WDLEN1(words); | |
208 | 262 | |
209 | - if (tx_buf) | |
263 | + if (tx_buf || (p->chipdata->master_flags & SPI_MASTER_MUST_TX)) | |
210 | 264 | sh_msiof_write(p, TMDR2, dr2); |
211 | 265 | else |
212 | - sh_msiof_write(p, TMDR2, dr2 | 1); | |
266 | + sh_msiof_write(p, TMDR2, dr2 | MDR2_GRPMASK1); | |
213 | 267 | |
214 | 268 | if (rx_buf) |
215 | 269 | sh_msiof_write(p, RMDR2, dr2); |
216 | 270 | |
217 | 271 | |
218 | 272 | |
219 | 273 | |
220 | 274 | |
221 | 275 | |
222 | 276 | |
223 | 277 | |
... | ... | @@ -362,77 +416,45 @@ |
362 | 416 | put_unaligned(swab32(sh_msiof_read(p, RFDR) >> fs), &buf_32[k]); |
363 | 417 | } |
364 | 418 | |
365 | -static int sh_msiof_spi_bits(struct spi_device *spi, struct spi_transfer *t) | |
419 | +static int sh_msiof_spi_setup(struct spi_device *spi) | |
366 | 420 | { |
367 | - int bits; | |
421 | + struct device_node *np = spi->master->dev.of_node; | |
422 | + struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master); | |
368 | 423 | |
369 | - bits = t ? t->bits_per_word : 0; | |
370 | - if (!bits) | |
371 | - bits = spi->bits_per_word; | |
372 | - return bits; | |
373 | -} | |
424 | + if (!np) { | |
425 | + /* | |
426 | + * Use spi->controller_data for CS (same strategy as spi_gpio), | |
427 | + * if any. otherwise let HW control CS | |
428 | + */ | |
429 | + spi->cs_gpio = (uintptr_t)spi->controller_data; | |
430 | + } | |
374 | 431 | |
375 | -static unsigned long sh_msiof_spi_hz(struct spi_device *spi, | |
376 | - struct spi_transfer *t) | |
377 | -{ | |
378 | - unsigned long hz; | |
432 | + /* Configure pins before deasserting CS */ | |
433 | + sh_msiof_spi_set_pin_regs(p, !!(spi->mode & SPI_CPOL), | |
434 | + !!(spi->mode & SPI_CPHA), | |
435 | + !!(spi->mode & SPI_3WIRE), | |
436 | + !!(spi->mode & SPI_LSB_FIRST), | |
437 | + !!(spi->mode & SPI_CS_HIGH)); | |
379 | 438 | |
380 | - hz = t ? t->speed_hz : 0; | |
381 | - if (!hz) | |
382 | - hz = spi->max_speed_hz; | |
383 | - return hz; | |
384 | -} | |
439 | + if (spi->cs_gpio >= 0) | |
440 | + gpio_set_value(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); | |
385 | 441 | |
386 | -static int sh_msiof_spi_setup_transfer(struct spi_device *spi, | |
387 | - struct spi_transfer *t) | |
388 | -{ | |
389 | - int bits; | |
390 | - | |
391 | - /* noting to check hz values against since parent clock is disabled */ | |
392 | - | |
393 | - bits = sh_msiof_spi_bits(spi, t); | |
394 | - if (bits < 8) | |
395 | - return -EINVAL; | |
396 | - if (bits > 32) | |
397 | - return -EINVAL; | |
398 | - | |
399 | - return spi_bitbang_setup_transfer(spi, t); | |
442 | + return 0; | |
400 | 443 | } |
401 | 444 | |
402 | -static void sh_msiof_spi_chipselect(struct spi_device *spi, int is_on) | |
445 | +static int sh_msiof_prepare_message(struct spi_master *master, | |
446 | + struct spi_message *msg) | |
403 | 447 | { |
404 | - struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master); | |
405 | - int value; | |
448 | + struct sh_msiof_spi_priv *p = spi_master_get_devdata(master); | |
449 | + const struct spi_device *spi = msg->spi; | |
406 | 450 | |
407 | - /* chip select is active low unless SPI_CS_HIGH is set */ | |
408 | - if (spi->mode & SPI_CS_HIGH) | |
409 | - value = (is_on == BITBANG_CS_ACTIVE) ? 1 : 0; | |
410 | - else | |
411 | - value = (is_on == BITBANG_CS_ACTIVE) ? 0 : 1; | |
412 | - | |
413 | - if (is_on == BITBANG_CS_ACTIVE) { | |
414 | - if (!test_and_set_bit(0, &p->flags)) { | |
415 | - pm_runtime_get_sync(&p->pdev->dev); | |
416 | - clk_enable(p->clk); | |
417 | - } | |
418 | - | |
419 | - /* Configure pins before asserting CS */ | |
420 | - sh_msiof_spi_set_pin_regs(p, !!(spi->mode & SPI_CPOL), | |
421 | - !!(spi->mode & SPI_CPHA), | |
422 | - !!(spi->mode & SPI_3WIRE), | |
423 | - !!(spi->mode & SPI_LSB_FIRST), | |
424 | - !!(spi->mode & SPI_CS_HIGH)); | |
425 | - } | |
426 | - | |
427 | - /* use spi->controller data for CS (same strategy as spi_gpio) */ | |
428 | - gpio_set_value((uintptr_t)spi->controller_data, value); | |
429 | - | |
430 | - if (is_on == BITBANG_CS_INACTIVE) { | |
431 | - if (test_and_clear_bit(0, &p->flags)) { | |
432 | - clk_disable(p->clk); | |
433 | - pm_runtime_put(&p->pdev->dev); | |
434 | - } | |
435 | - } | |
451 | + /* Configure pins before asserting CS */ | |
452 | + sh_msiof_spi_set_pin_regs(p, !!(spi->mode & SPI_CPOL), | |
453 | + !!(spi->mode & SPI_CPHA), | |
454 | + !!(spi->mode & SPI_3WIRE), | |
455 | + !!(spi->mode & SPI_LSB_FIRST), | |
456 | + !!(spi->mode & SPI_CS_HIGH)); | |
457 | + return 0; | |
436 | 458 | } |
437 | 459 | |
438 | 460 | static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, |
... | ... | @@ -486,7 +508,7 @@ |
486 | 508 | /* clear status bits */ |
487 | 509 | sh_msiof_reset_str(p); |
488 | 510 | |
489 | - /* shut down frame, tx/tx and clock signals */ | |
511 | + /* shut down frame, rx/tx and clock signals */ | |
490 | 512 | ret = sh_msiof_modify_ctr_wait(p, CTR_TFSE, 0); |
491 | 513 | ret = ret ? ret : sh_msiof_modify_ctr_wait(p, CTR_TXE, 0); |
492 | 514 | if (rx_buf) |
493 | 515 | |
... | ... | @@ -504,9 +526,11 @@ |
504 | 526 | return ret; |
505 | 527 | } |
506 | 528 | |
507 | -static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t) | |
529 | +static int sh_msiof_transfer_one(struct spi_master *master, | |
530 | + struct spi_device *spi, | |
531 | + struct spi_transfer *t) | |
508 | 532 | { |
509 | - struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master); | |
533 | + struct sh_msiof_spi_priv *p = spi_master_get_devdata(master); | |
510 | 534 | void (*tx_fifo)(struct sh_msiof_spi_priv *, const void *, int, int); |
511 | 535 | void (*rx_fifo)(struct sh_msiof_spi_priv *, void *, int, int); |
512 | 536 | int bits; |
... | ... | @@ -516,7 +540,7 @@ |
516 | 540 | int n; |
517 | 541 | bool swab; |
518 | 542 | |
519 | - bits = sh_msiof_spi_bits(spi, t); | |
543 | + bits = t->bits_per_word; | |
520 | 544 | |
521 | 545 | if (bits <= 8 && t->len > 15 && !(t->len & 3)) { |
522 | 546 | bits = 32; |
... | ... | @@ -566,8 +590,7 @@ |
566 | 590 | } |
567 | 591 | |
568 | 592 | /* setup clocks (clock already enabled in chipselect()) */ |
569 | - sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), | |
570 | - sh_msiof_spi_hz(spi, t)); | |
593 | + sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), t->speed_hz); | |
571 | 594 | |
572 | 595 | /* transfer in fifo sized chunks */ |
573 | 596 | words = t->len / bytes_per_word; |
574 | 597 | |
575 | 598 | |
... | ... | @@ -587,22 +610,36 @@ |
587 | 610 | words -= n; |
588 | 611 | } |
589 | 612 | |
590 | - return bytes_done; | |
591 | -} | |
592 | - | |
593 | -static u32 sh_msiof_spi_txrx_word(struct spi_device *spi, unsigned nsecs, | |
594 | - u32 word, u8 bits) | |
595 | -{ | |
596 | - BUG(); /* unused but needed by bitbang code */ | |
597 | 613 | return 0; |
598 | 614 | } |
599 | 615 | |
616 | +static const struct sh_msiof_chipdata sh_data = { | |
617 | + .tx_fifo_size = 64, | |
618 | + .rx_fifo_size = 64, | |
619 | + .master_flags = 0, | |
620 | +}; | |
621 | + | |
622 | +static const struct sh_msiof_chipdata r8a779x_data = { | |
623 | + .tx_fifo_size = 64, | |
624 | + .rx_fifo_size = 256, | |
625 | + .master_flags = SPI_MASTER_MUST_TX, | |
626 | +}; | |
627 | + | |
628 | +static const struct of_device_id sh_msiof_match[] = { | |
629 | + { .compatible = "renesas,sh-msiof", .data = &sh_data }, | |
630 | + { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data }, | |
631 | + { .compatible = "renesas,msiof-r8a7790", .data = &r8a779x_data }, | |
632 | + { .compatible = "renesas,msiof-r8a7791", .data = &r8a779x_data }, | |
633 | + {}, | |
634 | +}; | |
635 | +MODULE_DEVICE_TABLE(of, sh_msiof_match); | |
636 | + | |
600 | 637 | #ifdef CONFIG_OF |
601 | 638 | static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev) |
602 | 639 | { |
603 | 640 | struct sh_msiof_spi_info *info; |
604 | 641 | struct device_node *np = dev->of_node; |
605 | - u32 num_cs = 0; | |
642 | + u32 num_cs = 1; | |
606 | 643 | |
607 | 644 | info = devm_kzalloc(dev, sizeof(struct sh_msiof_spi_info), GFP_KERNEL); |
608 | 645 | if (!info) { |
... | ... | @@ -632,6 +669,7 @@ |
632 | 669 | { |
633 | 670 | struct resource *r; |
634 | 671 | struct spi_master *master; |
672 | + const struct of_device_id *of_id; | |
635 | 673 | struct sh_msiof_spi_priv *p; |
636 | 674 | int i; |
637 | 675 | int ret; |
638 | 676 | |
639 | 677 | |
... | ... | @@ -645,10 +683,15 @@ |
645 | 683 | p = spi_master_get_devdata(master); |
646 | 684 | |
647 | 685 | platform_set_drvdata(pdev, p); |
648 | - if (pdev->dev.of_node) | |
686 | + | |
687 | + of_id = of_match_device(sh_msiof_match, &pdev->dev); | |
688 | + if (of_id) { | |
689 | + p->chipdata = of_id->data; | |
649 | 690 | p->info = sh_msiof_spi_parse_dt(&pdev->dev); |
650 | - else | |
691 | + } else { | |
692 | + p->chipdata = (const void *)pdev->id_entry->driver_data; | |
651 | 693 | p->info = dev_get_platdata(&pdev->dev); |
694 | + } | |
652 | 695 | |
653 | 696 | if (!p->info) { |
654 | 697 | dev_err(&pdev->dev, "failed to obtain device info\n"); |
655 | 698 | |
656 | 699 | |
657 | 700 | |
658 | 701 | |
659 | 702 | |
660 | 703 | |
661 | 704 | |
662 | 705 | |
663 | 706 | |
664 | 707 | |
... | ... | @@ -686,49 +729,40 @@ |
686 | 729 | goto err1; |
687 | 730 | } |
688 | 731 | |
689 | - ret = clk_prepare(p->clk); | |
690 | - if (ret < 0) { | |
691 | - dev_err(&pdev->dev, "unable to prepare clock\n"); | |
692 | - goto err1; | |
693 | - } | |
694 | - | |
695 | 732 | p->pdev = pdev; |
696 | 733 | pm_runtime_enable(&pdev->dev); |
697 | 734 | |
698 | - /* The standard version of MSIOF use 64 word FIFOs */ | |
699 | - p->tx_fifo_size = 64; | |
700 | - p->rx_fifo_size = 64; | |
701 | - | |
702 | 735 | /* Platform data may override FIFO sizes */ |
736 | + p->tx_fifo_size = p->chipdata->tx_fifo_size; | |
737 | + p->rx_fifo_size = p->chipdata->rx_fifo_size; | |
703 | 738 | if (p->info->tx_fifo_override) |
704 | 739 | p->tx_fifo_size = p->info->tx_fifo_override; |
705 | 740 | if (p->info->rx_fifo_override) |
706 | 741 | p->rx_fifo_size = p->info->rx_fifo_override; |
707 | 742 | |
708 | - /* init master and bitbang code */ | |
743 | + /* init master code */ | |
709 | 744 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
710 | 745 | master->mode_bits |= SPI_LSB_FIRST | SPI_3WIRE; |
711 | - master->flags = 0; | |
746 | + master->flags = p->chipdata->master_flags; | |
712 | 747 | master->bus_num = pdev->id; |
748 | + master->dev.of_node = pdev->dev.of_node; | |
713 | 749 | master->num_chipselect = p->info->num_chipselect; |
714 | - master->setup = spi_bitbang_setup; | |
715 | - master->cleanup = spi_bitbang_cleanup; | |
750 | + master->setup = sh_msiof_spi_setup; | |
751 | + master->prepare_message = sh_msiof_prepare_message; | |
752 | + master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32); | |
753 | + master->auto_runtime_pm = true; | |
754 | + master->transfer_one = sh_msiof_transfer_one; | |
716 | 755 | |
717 | - p->bitbang.master = master; | |
718 | - p->bitbang.chipselect = sh_msiof_spi_chipselect; | |
719 | - p->bitbang.setup_transfer = sh_msiof_spi_setup_transfer; | |
720 | - p->bitbang.txrx_bufs = sh_msiof_spi_txrx; | |
721 | - p->bitbang.txrx_word[SPI_MODE_0] = sh_msiof_spi_txrx_word; | |
722 | - p->bitbang.txrx_word[SPI_MODE_1] = sh_msiof_spi_txrx_word; | |
723 | - p->bitbang.txrx_word[SPI_MODE_2] = sh_msiof_spi_txrx_word; | |
724 | - p->bitbang.txrx_word[SPI_MODE_3] = sh_msiof_spi_txrx_word; | |
756 | + ret = devm_spi_register_master(&pdev->dev, master); | |
757 | + if (ret < 0) { | |
758 | + dev_err(&pdev->dev, "spi_register_master error.\n"); | |
759 | + goto err2; | |
760 | + } | |
725 | 761 | |
726 | - ret = spi_bitbang_start(&p->bitbang); | |
727 | - if (ret == 0) | |
728 | - return 0; | |
762 | + return 0; | |
729 | 763 | |
764 | + err2: | |
730 | 765 | pm_runtime_disable(&pdev->dev); |
731 | - clk_unprepare(p->clk); | |
732 | 766 | err1: |
733 | 767 | spi_master_put(master); |
734 | 768 | return ret; |
735 | 769 | |
736 | 770 | |
737 | 771 | |
... | ... | @@ -736,30 +770,22 @@ |
736 | 770 | |
737 | 771 | static int sh_msiof_spi_remove(struct platform_device *pdev) |
738 | 772 | { |
739 | - struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev); | |
740 | - int ret; | |
741 | - | |
742 | - ret = spi_bitbang_stop(&p->bitbang); | |
743 | - if (!ret) { | |
744 | - pm_runtime_disable(&pdev->dev); | |
745 | - clk_unprepare(p->clk); | |
746 | - spi_master_put(p->bitbang.master); | |
747 | - } | |
748 | - return ret; | |
773 | + pm_runtime_disable(&pdev->dev); | |
774 | + return 0; | |
749 | 775 | } |
750 | 776 | |
751 | -#ifdef CONFIG_OF | |
752 | -static const struct of_device_id sh_msiof_match[] = { | |
753 | - { .compatible = "renesas,sh-msiof", }, | |
754 | - { .compatible = "renesas,sh-mobile-msiof", }, | |
777 | +static struct platform_device_id spi_driver_ids[] = { | |
778 | + { "spi_sh_msiof", (kernel_ulong_t)&sh_data }, | |
779 | + { "spi_r8a7790_msiof", (kernel_ulong_t)&r8a779x_data }, | |
780 | + { "spi_r8a7791_msiof", (kernel_ulong_t)&r8a779x_data }, | |
755 | 781 | {}, |
756 | 782 | }; |
757 | -MODULE_DEVICE_TABLE(of, sh_msiof_match); | |
758 | -#endif | |
783 | +MODULE_DEVICE_TABLE(platform, spi_driver_ids); | |
759 | 784 | |
760 | 785 | static struct platform_driver sh_msiof_spi_drv = { |
761 | 786 | .probe = sh_msiof_spi_probe, |
762 | 787 | .remove = sh_msiof_spi_remove, |
788 | + .id_table = spi_driver_ids, | |
763 | 789 | .driver = { |
764 | 790 | .name = "spi_sh_msiof", |
765 | 791 | .owner = THIS_MODULE, |
drivers/spi/spi-sh-sci.c
... | ... | @@ -108,7 +108,7 @@ |
108 | 108 | { |
109 | 109 | struct sh_sci_spi *sp = spi_master_get_devdata(dev->master); |
110 | 110 | |
111 | - if (sp->info && sp->info->chip_select) | |
111 | + if (sp->info->chip_select) | |
112 | 112 | (sp->info->chip_select)(sp->info, dev->chip_select, value); |
113 | 113 | } |
114 | 114 | |
... | ... | @@ -130,6 +130,11 @@ |
130 | 130 | |
131 | 131 | platform_set_drvdata(dev, sp); |
132 | 132 | sp->info = dev_get_platdata(&dev->dev); |
133 | + if (!sp->info) { | |
134 | + dev_err(&dev->dev, "platform data is missing\n"); | |
135 | + ret = -ENOENT; | |
136 | + goto err1; | |
137 | + } | |
133 | 138 | |
134 | 139 | /* setup spi bitbang adaptor */ |
135 | 140 | sp->bitbang.master = master; |
drivers/spi/spi-sirf.c
... | ... | @@ -22,7 +22,6 @@ |
22 | 22 | #include <linux/dmaengine.h> |
23 | 23 | #include <linux/dma-direction.h> |
24 | 24 | #include <linux/dma-mapping.h> |
25 | -#include <linux/sirfsoc_dma.h> | |
26 | 25 | |
27 | 26 | #define DRIVER_NAME "sirfsoc_spi" |
28 | 27 | |
... | ... | @@ -132,6 +131,8 @@ |
132 | 131 | #define IS_DMA_VALID(x) (x && ALIGNED(x->tx_buf) && ALIGNED(x->rx_buf) && \ |
133 | 132 | ALIGNED(x->len) && (x->len < 2 * PAGE_SIZE)) |
134 | 133 | |
134 | +#define SIRFSOC_MAX_CMD_BYTES 4 | |
135 | + | |
135 | 136 | struct sirfsoc_spi { |
136 | 137 | struct spi_bitbang bitbang; |
137 | 138 | struct completion rx_done; |
... | ... | @@ -162,6 +163,12 @@ |
162 | 163 | void *dummypage; |
163 | 164 | int word_width; /* in bytes */ |
164 | 165 | |
166 | + /* | |
167 | + * if tx size is not more than 4 and rx size is NULL, use | |
168 | + * command model | |
169 | + */ | |
170 | + bool tx_by_cmd; | |
171 | + | |
165 | 172 | int chipselect[0]; |
166 | 173 | }; |
167 | 174 | |
... | ... | @@ -260,6 +267,12 @@ |
260 | 267 | |
261 | 268 | writel(spi_stat, sspi->base + SIRFSOC_SPI_INT_STATUS); |
262 | 269 | |
270 | + if (sspi->tx_by_cmd && (spi_stat & SIRFSOC_SPI_FRM_END)) { | |
271 | + complete(&sspi->tx_done); | |
272 | + writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN); | |
273 | + return IRQ_HANDLED; | |
274 | + } | |
275 | + | |
263 | 276 | /* Error Conditions */ |
264 | 277 | if (spi_stat & SIRFSOC_SPI_RX_OFLOW || |
265 | 278 | spi_stat & SIRFSOC_SPI_TX_UFLOW) { |
... | ... | @@ -310,6 +323,34 @@ |
310 | 323 | |
311 | 324 | writel(SIRFSOC_SPI_INT_MASK_ALL, sspi->base + SIRFSOC_SPI_INT_STATUS); |
312 | 325 | |
326 | + /* | |
327 | + * fill tx_buf into command register and wait for its completion | |
328 | + */ | |
329 | + if (sspi->tx_by_cmd) { | |
330 | + u32 cmd; | |
331 | + memcpy(&cmd, sspi->tx, t->len); | |
332 | + | |
333 | + if (sspi->word_width == 1 && !(spi->mode & SPI_LSB_FIRST)) | |
334 | + cmd = cpu_to_be32(cmd) >> | |
335 | + ((SIRFSOC_MAX_CMD_BYTES - t->len) * 8); | |
336 | + if (sspi->word_width == 2 && t->len == 4 && | |
337 | + (!(spi->mode & SPI_LSB_FIRST))) | |
338 | + cmd = ((cmd & 0xffff) << 16) | (cmd >> 16); | |
339 | + | |
340 | + writel(cmd, sspi->base + SIRFSOC_SPI_CMD); | |
341 | + writel(SIRFSOC_SPI_FRM_END_INT_EN, | |
342 | + sspi->base + SIRFSOC_SPI_INT_EN); | |
343 | + writel(SIRFSOC_SPI_CMD_TX_EN, | |
344 | + sspi->base + SIRFSOC_SPI_TX_RX_EN); | |
345 | + | |
346 | + if (wait_for_completion_timeout(&sspi->tx_done, timeout) == 0) { | |
347 | + dev_err(&spi->dev, "transfer timeout\n"); | |
348 | + return 0; | |
349 | + } | |
350 | + | |
351 | + return t->len; | |
352 | + } | |
353 | + | |
313 | 354 | if (sspi->left_tx_word == 1) { |
314 | 355 | writel(readl(sspi->base + SIRFSOC_SPI_CTRL) | |
315 | 356 | SIRFSOC_SPI_ENA_AUTO_CLR, |
... | ... | @@ -459,11 +500,6 @@ |
459 | 500 | regval |= SIRFSOC_SPI_TRAN_DAT_FORMAT_8; |
460 | 501 | sspi->rx_word = spi_sirfsoc_rx_word_u8; |
461 | 502 | sspi->tx_word = spi_sirfsoc_tx_word_u8; |
462 | - txfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | | |
463 | - SIRFSOC_SPI_FIFO_WIDTH_BYTE; | |
464 | - rxfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | | |
465 | - SIRFSOC_SPI_FIFO_WIDTH_BYTE; | |
466 | - sspi->word_width = 1; | |
467 | 503 | break; |
468 | 504 | case 12: |
469 | 505 | case 16: |
470 | 506 | |
471 | 507 | |
... | ... | @@ -471,26 +507,22 @@ |
471 | 507 | SIRFSOC_SPI_TRAN_DAT_FORMAT_16; |
472 | 508 | sspi->rx_word = spi_sirfsoc_rx_word_u16; |
473 | 509 | sspi->tx_word = spi_sirfsoc_tx_word_u16; |
474 | - txfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | | |
475 | - SIRFSOC_SPI_FIFO_WIDTH_WORD; | |
476 | - rxfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | | |
477 | - SIRFSOC_SPI_FIFO_WIDTH_WORD; | |
478 | - sspi->word_width = 2; | |
479 | 510 | break; |
480 | 511 | case 32: |
481 | 512 | regval |= SIRFSOC_SPI_TRAN_DAT_FORMAT_32; |
482 | 513 | sspi->rx_word = spi_sirfsoc_rx_word_u32; |
483 | 514 | sspi->tx_word = spi_sirfsoc_tx_word_u32; |
484 | - txfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | | |
485 | - SIRFSOC_SPI_FIFO_WIDTH_DWORD; | |
486 | - rxfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | | |
487 | - SIRFSOC_SPI_FIFO_WIDTH_DWORD; | |
488 | - sspi->word_width = 4; | |
489 | 515 | break; |
490 | 516 | default: |
491 | 517 | BUG(); |
492 | 518 | } |
493 | 519 | |
520 | + sspi->word_width = DIV_ROUND_UP(bits_per_word, 8); | |
521 | + txfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | | |
522 | + sspi->word_width; | |
523 | + rxfifo_ctrl = SIRFSOC_SPI_FIFO_THD(SIRFSOC_SPI_FIFO_SIZE / 2) | | |
524 | + sspi->word_width; | |
525 | + | |
494 | 526 | if (!(spi->mode & SPI_CS_HIGH)) |
495 | 527 | regval |= SIRFSOC_SPI_CS_IDLE_STAT; |
496 | 528 | if (!(spi->mode & SPI_LSB_FIRST)) |
... | ... | @@ -519,6 +551,14 @@ |
519 | 551 | writel(txfifo_ctrl, sspi->base + SIRFSOC_SPI_TXFIFO_CTRL); |
520 | 552 | writel(rxfifo_ctrl, sspi->base + SIRFSOC_SPI_RXFIFO_CTRL); |
521 | 553 | |
554 | + if (t && t->tx_buf && !t->rx_buf && (t->len <= SIRFSOC_MAX_CMD_BYTES)) { | |
555 | + regval |= (SIRFSOC_SPI_CMD_BYTE_NUM((t->len - 1)) | | |
556 | + SIRFSOC_SPI_CMD_MODE); | |
557 | + sspi->tx_by_cmd = true; | |
558 | + } else { | |
559 | + regval &= ~SIRFSOC_SPI_CMD_MODE; | |
560 | + sspi->tx_by_cmd = false; | |
561 | + } | |
522 | 562 | writel(regval, sspi->base + SIRFSOC_SPI_CTRL); |
523 | 563 | |
524 | 564 | if (IS_DMA_VALID(t)) { |
... | ... | @@ -548,8 +588,6 @@ |
548 | 588 | struct spi_master *master; |
549 | 589 | struct resource *mem_res; |
550 | 590 | int num_cs, cs_gpio, irq; |
551 | - u32 rx_dma_ch, tx_dma_ch; | |
552 | - dma_cap_mask_t dma_cap_mask; | |
553 | 591 | int i; |
554 | 592 | int ret; |
555 | 593 | |
... | ... | @@ -560,20 +598,6 @@ |
560 | 598 | goto err_cs; |
561 | 599 | } |
562 | 600 | |
563 | - ret = of_property_read_u32(pdev->dev.of_node, | |
564 | - "sirf,spi-dma-rx-channel", &rx_dma_ch); | |
565 | - if (ret < 0) { | |
566 | - dev_err(&pdev->dev, "Unable to get rx dma channel\n"); | |
567 | - goto err_cs; | |
568 | - } | |
569 | - | |
570 | - ret = of_property_read_u32(pdev->dev.of_node, | |
571 | - "sirf,spi-dma-tx-channel", &tx_dma_ch); | |
572 | - if (ret < 0) { | |
573 | - dev_err(&pdev->dev, "Unable to get tx dma channel\n"); | |
574 | - goto err_cs; | |
575 | - } | |
576 | - | |
577 | 601 | master = spi_alloc_master(&pdev->dev, sizeof(*sspi) + sizeof(int) * num_cs); |
578 | 602 | if (!master) { |
579 | 603 | dev_err(&pdev->dev, "Unable to allocate SPI master\n"); |
580 | 604 | |
... | ... | @@ -637,18 +661,13 @@ |
637 | 661 | sspi->bitbang.master->dev.of_node = pdev->dev.of_node; |
638 | 662 | |
639 | 663 | /* request DMA channels */ |
640 | - dma_cap_zero(dma_cap_mask); | |
641 | - dma_cap_set(DMA_INTERLEAVE, dma_cap_mask); | |
642 | - | |
643 | - sspi->rx_chan = dma_request_channel(dma_cap_mask, (dma_filter_fn)sirfsoc_dma_filter_id, | |
644 | - (void *)rx_dma_ch); | |
664 | + sspi->rx_chan = dma_request_slave_channel(&pdev->dev, "rx"); | |
645 | 665 | if (!sspi->rx_chan) { |
646 | 666 | dev_err(&pdev->dev, "can not allocate rx dma channel\n"); |
647 | 667 | ret = -ENODEV; |
648 | 668 | goto free_master; |
649 | 669 | } |
650 | - sspi->tx_chan = dma_request_channel(dma_cap_mask, (dma_filter_fn)sirfsoc_dma_filter_id, | |
651 | - (void *)tx_dma_ch); | |
670 | + sspi->tx_chan = dma_request_slave_channel(&pdev->dev, "tx"); | |
652 | 671 | if (!sspi->tx_chan) { |
653 | 672 | dev_err(&pdev->dev, "can not allocate tx dma channel\n"); |
654 | 673 | ret = -ENODEV; |
655 | 674 | |
656 | 675 | |
... | ... | @@ -724,12 +743,17 @@ |
724 | 743 | return 0; |
725 | 744 | } |
726 | 745 | |
727 | -#ifdef CONFIG_PM | |
746 | +#ifdef CONFIG_PM_SLEEP | |
728 | 747 | static int spi_sirfsoc_suspend(struct device *dev) |
729 | 748 | { |
730 | 749 | struct spi_master *master = dev_get_drvdata(dev); |
731 | 750 | struct sirfsoc_spi *sspi = spi_master_get_devdata(master); |
751 | + int ret; | |
732 | 752 | |
753 | + ret = spi_master_suspend(master); | |
754 | + if (ret) | |
755 | + return ret; | |
756 | + | |
733 | 757 | clk_disable(sspi->clk); |
734 | 758 | return 0; |
735 | 759 | } |
736 | 760 | |
737 | 761 | |
... | ... | @@ -745,15 +769,13 @@ |
745 | 769 | writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_RXFIFO_OP); |
746 | 770 | writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_TXFIFO_OP); |
747 | 771 | |
748 | - return 0; | |
772 | + return spi_master_resume(master); | |
749 | 773 | } |
750 | - | |
751 | -static const struct dev_pm_ops spi_sirfsoc_pm_ops = { | |
752 | - .suspend = spi_sirfsoc_suspend, | |
753 | - .resume = spi_sirfsoc_resume, | |
754 | -}; | |
755 | 774 | #endif |
756 | 775 | |
776 | +static SIMPLE_DEV_PM_OPS(spi_sirfsoc_pm_ops, spi_sirfsoc_suspend, | |
777 | + spi_sirfsoc_resume); | |
778 | + | |
757 | 779 | static const struct of_device_id spi_sirfsoc_of_match[] = { |
758 | 780 | { .compatible = "sirf,prima2-spi", }, |
759 | 781 | { .compatible = "sirf,marco-spi", }, |
760 | 782 | |
... | ... | @@ -765,9 +787,7 @@ |
765 | 787 | .driver = { |
766 | 788 | .name = DRIVER_NAME, |
767 | 789 | .owner = THIS_MODULE, |
768 | -#ifdef CONFIG_PM | |
769 | 790 | .pm = &spi_sirfsoc_pm_ops, |
770 | -#endif | |
771 | 791 | .of_match_table = spi_sirfsoc_of_match, |
772 | 792 | }, |
773 | 793 | .probe = spi_sirfsoc_probe, |
drivers/spi/spidev.c
... | ... | @@ -73,7 +73,8 @@ |
73 | 73 | */ |
74 | 74 | #define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \ |
75 | 75 | | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \ |
76 | - | SPI_NO_CS | SPI_READY) | |
76 | + | SPI_NO_CS | SPI_READY | SPI_TX_DUAL \ | |
77 | + | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD) | |
77 | 78 | |
78 | 79 | struct spidev_data { |
79 | 80 | dev_t devt; |
... | ... | @@ -265,6 +266,8 @@ |
265 | 266 | buf += k_tmp->len; |
266 | 267 | |
267 | 268 | k_tmp->cs_change = !!u_tmp->cs_change; |
269 | + k_tmp->tx_nbits = u_tmp->tx_nbits; | |
270 | + k_tmp->rx_nbits = u_tmp->rx_nbits; | |
268 | 271 | k_tmp->bits_per_word = u_tmp->bits_per_word; |
269 | 272 | k_tmp->delay_usecs = u_tmp->delay_usecs; |
270 | 273 | k_tmp->speed_hz = u_tmp->speed_hz; |
... | ... | @@ -359,6 +362,10 @@ |
359 | 362 | retval = __put_user(spi->mode & SPI_MODE_MASK, |
360 | 363 | (__u8 __user *)arg); |
361 | 364 | break; |
365 | + case SPI_IOC_RD_MODE32: | |
366 | + retval = __put_user(spi->mode & SPI_MODE_MASK, | |
367 | + (__u32 __user *)arg); | |
368 | + break; | |
362 | 369 | case SPI_IOC_RD_LSB_FIRST: |
363 | 370 | retval = __put_user((spi->mode & SPI_LSB_FIRST) ? 1 : 0, |
364 | 371 | (__u8 __user *)arg); |
365 | 372 | |
... | ... | @@ -372,9 +379,13 @@ |
372 | 379 | |
373 | 380 | /* write requests */ |
374 | 381 | case SPI_IOC_WR_MODE: |
375 | - retval = __get_user(tmp, (u8 __user *)arg); | |
382 | + case SPI_IOC_WR_MODE32: | |
383 | + if (cmd == SPI_IOC_WR_MODE) | |
384 | + retval = __get_user(tmp, (u8 __user *)arg); | |
385 | + else | |
386 | + retval = __get_user(tmp, (u32 __user *)arg); | |
376 | 387 | if (retval == 0) { |
377 | - u8 save = spi->mode; | |
388 | + u32 save = spi->mode; | |
378 | 389 | |
379 | 390 | if (tmp & ~SPI_MODE_MASK) { |
380 | 391 | retval = -EINVAL; |
381 | 392 | |
382 | 393 | |
... | ... | @@ -382,18 +393,18 @@ |
382 | 393 | } |
383 | 394 | |
384 | 395 | tmp |= spi->mode & ~SPI_MODE_MASK; |
385 | - spi->mode = (u8)tmp; | |
396 | + spi->mode = (u16)tmp; | |
386 | 397 | retval = spi_setup(spi); |
387 | 398 | if (retval < 0) |
388 | 399 | spi->mode = save; |
389 | 400 | else |
390 | - dev_dbg(&spi->dev, "spi mode %02x\n", tmp); | |
401 | + dev_dbg(&spi->dev, "spi mode %x\n", tmp); | |
391 | 402 | } |
392 | 403 | break; |
393 | 404 | case SPI_IOC_WR_LSB_FIRST: |
394 | 405 | retval = __get_user(tmp, (__u8 __user *)arg); |
395 | 406 | if (retval == 0) { |
396 | - u8 save = spi->mode; | |
407 | + u32 save = spi->mode; | |
397 | 408 | |
398 | 409 | if (tmp) |
399 | 410 | spi->mode |= SPI_LSB_FIRST; |
include/linux/platform_data/spi-s3c64xx.h
1 | -/* linux/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h | |
2 | - * | |
1 | +/* | |
3 | 2 | * Copyright (C) 2009 Samsung Electronics Ltd. |
4 | 3 | * Jaswinder Singh <jassi.brar@samsung.com> |
5 | 4 | * |
... | ... | @@ -8,8 +7,8 @@ |
8 | 7 | * published by the Free Software Foundation. |
9 | 8 | */ |
10 | 9 | |
11 | -#ifndef __S3C64XX_PLAT_SPI_H | |
12 | -#define __S3C64XX_PLAT_SPI_H | |
10 | +#ifndef __SPI_S3C64XX_H | |
11 | +#define __SPI_S3C64XX_H | |
13 | 12 | |
14 | 13 | #include <linux/dmaengine.h> |
15 | 14 | |
... | ... | @@ -68,5 +67,5 @@ |
68 | 67 | extern struct s3c64xx_spi_info s3c64xx_spi0_pdata; |
69 | 68 | extern struct s3c64xx_spi_info s3c64xx_spi1_pdata; |
70 | 69 | extern struct s3c64xx_spi_info s3c64xx_spi2_pdata; |
71 | -#endif /* __S3C64XX_PLAT_SPI_H */ | |
70 | +#endif /*__SPI_S3C64XX_H */ |
include/uapi/linux/spi/spidev.h
... | ... | @@ -42,6 +42,10 @@ |
42 | 42 | #define SPI_LOOP 0x20 |
43 | 43 | #define SPI_NO_CS 0x40 |
44 | 44 | #define SPI_READY 0x80 |
45 | +#define SPI_TX_DUAL 0x100 | |
46 | +#define SPI_TX_QUAD 0x200 | |
47 | +#define SPI_RX_DUAL 0x400 | |
48 | +#define SPI_RX_QUAD 0x800 | |
45 | 49 | |
46 | 50 | /*---------------------------------------------------------------------------*/ |
47 | 51 | |
... | ... | @@ -92,7 +96,9 @@ |
92 | 96 | __u16 delay_usecs; |
93 | 97 | __u8 bits_per_word; |
94 | 98 | __u8 cs_change; |
95 | - __u32 pad; | |
99 | + __u8 tx_nbits; | |
100 | + __u8 rx_nbits; | |
101 | + __u16 pad; | |
96 | 102 | |
97 | 103 | /* If the contents of 'struct spi_ioc_transfer' ever change |
98 | 104 | * incompatibly, then the ioctl number (currently 0) must change; |
... | ... | @@ -110,7 +116,7 @@ |
110 | 116 | #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) |
111 | 117 | |
112 | 118 | |
113 | -/* Read / Write of SPI mode (SPI_MODE_0..SPI_MODE_3) */ | |
119 | +/* Read / Write of SPI mode (SPI_MODE_0..SPI_MODE_3) (limited to 8 bits) */ | |
114 | 120 | #define SPI_IOC_RD_MODE _IOR(SPI_IOC_MAGIC, 1, __u8) |
115 | 121 | #define SPI_IOC_WR_MODE _IOW(SPI_IOC_MAGIC, 1, __u8) |
116 | 122 | |
... | ... | @@ -125,6 +131,10 @@ |
125 | 131 | /* Read / Write SPI device default max speed hz */ |
126 | 132 | #define SPI_IOC_RD_MAX_SPEED_HZ _IOR(SPI_IOC_MAGIC, 4, __u32) |
127 | 133 | #define SPI_IOC_WR_MAX_SPEED_HZ _IOW(SPI_IOC_MAGIC, 4, __u32) |
134 | + | |
135 | +/* Read / Write of the SPI mode field */ | |
136 | +#define SPI_IOC_RD_MODE32 _IOR(SPI_IOC_MAGIC, 5, __u32) | |
137 | +#define SPI_IOC_WR_MODE32 _IOW(SPI_IOC_MAGIC, 5, __u32) | |
128 | 138 | |
129 | 139 | |
130 | 140 |