diff options
author | Purna Chandra Mandal <purna.mandal@microchip.com> | 2016-04-01 07:18:50 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-04-04 13:04:29 -0400 |
commit | 1bcb9f8ceb67803960871ecf4ed2d365a2a919c8 (patch) | |
tree | 893122cc6815e8d6957bc249870cffe15947ea52 | |
parent | 120e8989ebac7c7c702e351046c20e9918912aca (diff) |
spi: spi-pic32: Add PIC32 SPI master driver
The PIC32 SPI driver is capable of performing SPI transfers
using PIO or external DMA engine. GPIO controlled /CS support
is made default in the driver for correct operation of the
controller. This can be enabled by adding "cs-gpios" property
of the SPI node in board dts file.
Signed-off-by: Purna Chandra Mandal <purna.mandal@microchip.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | drivers/spi/Kconfig | 6 | ||||
-rw-r--r-- | drivers/spi/Makefile | 1 | ||||
-rw-r--r-- | drivers/spi/spi-pic32.c | 888 |
3 files changed, 895 insertions, 0 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 9d8c84bb1544..8a8ff5051c64 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -436,6 +436,12 @@ config SPI_ORION | |||
436 | help | 436 | help |
437 | This enables using the SPI master controller on the Orion chips. | 437 | This enables using the SPI master controller on the Orion chips. |
438 | 438 | ||
439 | config SPI_PIC32 | ||
440 | tristate "Microchip PIC32 series SPI" | ||
441 | depends on MACH_PIC32 || COMPILE_TEST | ||
442 | help | ||
443 | SPI driver for Microchip PIC32 SPI master controller. | ||
444 | |||
439 | config SPI_PL022 | 445 | config SPI_PL022 |
440 | tristate "ARM AMBA PL022 SSP controller" | 446 | tristate "ARM AMBA PL022 SSP controller" |
441 | depends on ARM_AMBA | 447 | depends on ARM_AMBA |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index fbb255c5a608..06019ed11fac 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -62,6 +62,7 @@ obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o | |||
62 | obj-$(CONFIG_SPI_OMAP24XX) += spi-omap2-mcspi.o | 62 | obj-$(CONFIG_SPI_OMAP24XX) += spi-omap2-mcspi.o |
63 | obj-$(CONFIG_SPI_TI_QSPI) += spi-ti-qspi.o | 63 | obj-$(CONFIG_SPI_TI_QSPI) += spi-ti-qspi.o |
64 | obj-$(CONFIG_SPI_ORION) += spi-orion.o | 64 | obj-$(CONFIG_SPI_ORION) += spi-orion.o |
65 | obj-$(CONFIG_SPI_PIC32) += spi-pic32.o | ||
65 | obj-$(CONFIG_SPI_PL022) += spi-pl022.o | 66 | obj-$(CONFIG_SPI_PL022) += spi-pl022.o |
66 | obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o | 67 | obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o |
67 | spi-pxa2xx-platform-objs := spi-pxa2xx.o spi-pxa2xx-dma.o | 68 | spi-pxa2xx-platform-objs := spi-pxa2xx.o spi-pxa2xx-dma.o |
diff --git a/drivers/spi/spi-pic32.c b/drivers/spi/spi-pic32.c new file mode 100644 index 000000000000..f8313ea11a34 --- /dev/null +++ b/drivers/spi/spi-pic32.c | |||
@@ -0,0 +1,888 @@ | |||
1 | /* | ||
2 | * Microchip PIC32 SPI controller driver. | ||
3 | * | ||
4 | * Purna Chandra Mandal <purna.mandal@microchip.com> | ||
5 | * Copyright (c) 2016, Microchip Technology Inc. | ||
6 | * | ||
7 | * This program is free software; you can distribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk.h> | ||
18 | #include <linux/clkdev.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/dmaengine.h> | ||
21 | #include <linux/dma-mapping.h> | ||
22 | #include <linux/highmem.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/of.h> | ||
27 | #include <linux/of_irq.h> | ||
28 | #include <linux/of_gpio.h> | ||
29 | #include <linux/of_address.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/spi/spi.h> | ||
32 | |||
33 | /* SPI controller registers */ | ||
34 | struct pic32_spi_regs { | ||
35 | u32 ctrl; | ||
36 | u32 ctrl_clr; | ||
37 | u32 ctrl_set; | ||
38 | u32 ctrl_inv; | ||
39 | u32 status; | ||
40 | u32 status_clr; | ||
41 | u32 status_set; | ||
42 | u32 status_inv; | ||
43 | u32 buf; | ||
44 | u32 dontuse[3]; | ||
45 | u32 baud; | ||
46 | u32 dontuse2[3]; | ||
47 | u32 ctrl2; | ||
48 | u32 ctrl2_clr; | ||
49 | u32 ctrl2_set; | ||
50 | u32 ctrl2_inv; | ||
51 | }; | ||
52 | |||
53 | /* Bit fields of SPI Control Register */ | ||
54 | #define CTRL_RX_INT_SHIFT 0 /* Rx interrupt generation */ | ||
55 | #define RX_FIFO_EMTPY 0 | ||
56 | #define RX_FIFO_NOT_EMPTY 1 /* not empty */ | ||
57 | #define RX_FIFO_HALF_FULL 2 /* full by half or more */ | ||
58 | #define RX_FIFO_FULL 3 /* completely full */ | ||
59 | |||
60 | #define CTRL_TX_INT_SHIFT 2 /* TX interrupt generation */ | ||
61 | #define TX_FIFO_ALL_EMPTY 0 /* completely empty */ | ||
62 | #define TX_FIFO_EMTPY 1 /* empty */ | ||
63 | #define TX_FIFO_HALF_EMPTY 2 /* empty by half or more */ | ||
64 | #define TX_FIFO_NOT_FULL 3 /* atleast one empty */ | ||
65 | |||
66 | #define CTRL_MSTEN BIT(5) /* enable master mode */ | ||
67 | #define CTRL_CKP BIT(6) /* active low */ | ||
68 | #define CTRL_CKE BIT(8) /* Tx on falling edge */ | ||
69 | #define CTRL_SMP BIT(9) /* Rx at middle or end of tx */ | ||
70 | #define CTRL_BPW_MASK 0x03 /* bits per word/sample */ | ||
71 | #define CTRL_BPW_SHIFT 10 | ||
72 | #define PIC32_BPW_8 0 | ||
73 | #define PIC32_BPW_16 1 | ||
74 | #define PIC32_BPW_32 2 | ||
75 | #define CTRL_SIDL BIT(13) /* sleep when idle */ | ||
76 | #define CTRL_ON BIT(15) /* enable macro */ | ||
77 | #define CTRL_ENHBUF BIT(16) /* enable enhanced buffering */ | ||
78 | #define CTRL_MCLKSEL BIT(23) /* select clock source */ | ||
79 | #define CTRL_MSSEN BIT(28) /* macro driven /SS */ | ||
80 | #define CTRL_FRMEN BIT(31) /* enable framing mode */ | ||
81 | |||
82 | /* Bit fields of SPI Status Register */ | ||
83 | #define STAT_RF_EMPTY BIT(5) /* RX Fifo empty */ | ||
84 | #define STAT_RX_OV BIT(6) /* err, s/w needs to clear */ | ||
85 | #define STAT_TX_UR BIT(8) /* UR in Framed SPI modes */ | ||
86 | #define STAT_FRM_ERR BIT(12) /* Multiple Frame Sync pulse */ | ||
87 | #define STAT_TF_LVL_MASK 0x1F | ||
88 | #define STAT_TF_LVL_SHIFT 16 | ||
89 | #define STAT_RF_LVL_MASK 0x1F | ||
90 | #define STAT_RF_LVL_SHIFT 24 | ||
91 | |||
92 | /* Bit fields of SPI Baud Register */ | ||
93 | #define BAUD_MASK 0x1ff | ||
94 | |||
95 | /* Bit fields of SPI Control2 Register */ | ||
96 | #define CTRL2_TX_UR_EN BIT(10) /* Enable int on Tx under-run */ | ||
97 | #define CTRL2_RX_OV_EN BIT(11) /* Enable int on Rx over-run */ | ||
98 | #define CTRL2_FRM_ERR_EN BIT(12) /* Enable frame err int */ | ||
99 | |||
100 | /* Minimum DMA transfer size */ | ||
101 | #define PIC32_DMA_LEN_MIN 64 | ||
102 | |||
103 | struct pic32_spi { | ||
104 | dma_addr_t dma_base; | ||
105 | struct pic32_spi_regs __iomem *regs; | ||
106 | int fault_irq; | ||
107 | int rx_irq; | ||
108 | int tx_irq; | ||
109 | u32 fifo_n_byte; /* FIFO depth in bytes */ | ||
110 | struct clk *clk; | ||
111 | struct spi_master *master; | ||
112 | /* Current controller setting */ | ||
113 | u32 speed_hz; /* spi-clk rate */ | ||
114 | u32 mode; | ||
115 | u32 bits_per_word; | ||
116 | u32 fifo_n_elm; /* FIFO depth in words */ | ||
117 | #define PIC32F_DMA_PREP 0 /* DMA chnls configured */ | ||
118 | unsigned long flags; | ||
119 | /* Current transfer state */ | ||
120 | struct completion xfer_done; | ||
121 | /* PIO transfer specific */ | ||
122 | const void *tx; | ||
123 | const void *tx_end; | ||
124 | const void *rx; | ||
125 | const void *rx_end; | ||
126 | int len; | ||
127 | void (*rx_fifo)(struct pic32_spi *); | ||
128 | void (*tx_fifo)(struct pic32_spi *); | ||
129 | }; | ||
130 | |||
131 | static inline void pic32_spi_enable(struct pic32_spi *pic32s) | ||
132 | { | ||
133 | writel(CTRL_ON | CTRL_SIDL, &pic32s->regs->ctrl_set); | ||
134 | } | ||
135 | |||
136 | static inline void pic32_spi_disable(struct pic32_spi *pic32s) | ||
137 | { | ||
138 | writel(CTRL_ON | CTRL_SIDL, &pic32s->regs->ctrl_clr); | ||
139 | |||
140 | /* avoid SPI registers read/write at immediate next CPU clock */ | ||
141 | ndelay(20); | ||
142 | } | ||
143 | |||
144 | static void pic32_spi_set_clk_rate(struct pic32_spi *pic32s, u32 spi_ck) | ||
145 | { | ||
146 | u32 div; | ||
147 | |||
148 | /* div = (clk_in / 2 * spi_ck) - 1 */ | ||
149 | div = DIV_ROUND_CLOSEST(clk_get_rate(pic32s->clk), 2 * spi_ck) - 1; | ||
150 | |||
151 | writel(div & BAUD_MASK, &pic32s->regs->baud); | ||
152 | } | ||
153 | |||
154 | static inline u32 pic32_rx_fifo_level(struct pic32_spi *pic32s) | ||
155 | { | ||
156 | u32 sr = readl(&pic32s->regs->status); | ||
157 | |||
158 | return (sr >> STAT_RF_LVL_SHIFT) & STAT_RF_LVL_MASK; | ||
159 | } | ||
160 | |||
161 | static inline u32 pic32_tx_fifo_level(struct pic32_spi *pic32s) | ||
162 | { | ||
163 | u32 sr = readl(&pic32s->regs->status); | ||
164 | |||
165 | return (sr >> STAT_TF_LVL_SHIFT) & STAT_TF_LVL_MASK; | ||
166 | } | ||
167 | |||
168 | /* Return the max entries we can fill into tx fifo */ | ||
169 | static u32 pic32_tx_max(struct pic32_spi *pic32s, int n_bytes) | ||
170 | { | ||
171 | u32 tx_left, tx_room, rxtx_gap; | ||
172 | |||
173 | tx_left = (pic32s->tx_end - pic32s->tx) / n_bytes; | ||
174 | tx_room = pic32s->fifo_n_elm - pic32_tx_fifo_level(pic32s); | ||
175 | |||
176 | /* | ||
177 | * Another concern is about the tx/rx mismatch, we | ||
178 | * though to use (pic32s->fifo_n_byte - rxfl - txfl) as | ||
179 | * one maximum value for tx, but it doesn't cover the | ||
180 | * data which is out of tx/rx fifo and inside the | ||
181 | * shift registers. So a ctrl from sw point of | ||
182 | * view is taken. | ||
183 | */ | ||
184 | rxtx_gap = ((pic32s->rx_end - pic32s->rx) - | ||
185 | (pic32s->tx_end - pic32s->tx)) / n_bytes; | ||
186 | return min3(tx_left, tx_room, (u32)(pic32s->fifo_n_elm - rxtx_gap)); | ||
187 | } | ||
188 | |||
189 | /* Return the max entries we should read out of rx fifo */ | ||
190 | static u32 pic32_rx_max(struct pic32_spi *pic32s, int n_bytes) | ||
191 | { | ||
192 | u32 rx_left = (pic32s->rx_end - pic32s->rx) / n_bytes; | ||
193 | |||
194 | return min_t(u32, rx_left, pic32_rx_fifo_level(pic32s)); | ||
195 | } | ||
196 | |||
197 | #define BUILD_SPI_FIFO_RW(__name, __type, __bwl) \ | ||
198 | static void pic32_spi_rx_##__name(struct pic32_spi *pic32s) \ | ||
199 | { \ | ||
200 | __type v; \ | ||
201 | u32 mx = pic32_rx_max(pic32s, sizeof(__type)); \ | ||
202 | for (; mx; mx--) { \ | ||
203 | v = read##__bwl(&pic32s->regs->buf); \ | ||
204 | if (pic32s->rx_end - pic32s->len) \ | ||
205 | *(__type *)(pic32s->rx) = v; \ | ||
206 | pic32s->rx += sizeof(__type); \ | ||
207 | } \ | ||
208 | } \ | ||
209 | \ | ||
210 | static void pic32_spi_tx_##__name(struct pic32_spi *pic32s) \ | ||
211 | { \ | ||
212 | __type v; \ | ||
213 | u32 mx = pic32_tx_max(pic32s, sizeof(__type)); \ | ||
214 | for (; mx ; mx--) { \ | ||
215 | v = (__type)~0U; \ | ||
216 | if (pic32s->tx_end - pic32s->len) \ | ||
217 | v = *(__type *)(pic32s->tx); \ | ||
218 | write##__bwl(v, &pic32s->regs->buf); \ | ||
219 | pic32s->tx += sizeof(__type); \ | ||
220 | } \ | ||
221 | } | ||
222 | |||
223 | BUILD_SPI_FIFO_RW(byte, u8, b); | ||
224 | BUILD_SPI_FIFO_RW(word, u16, w); | ||
225 | BUILD_SPI_FIFO_RW(dword, u32, l); | ||
226 | |||
227 | static void pic32_err_stop(struct pic32_spi *pic32s, const char *msg) | ||
228 | { | ||
229 | /* disable all interrupts */ | ||
230 | disable_irq_nosync(pic32s->fault_irq); | ||
231 | disable_irq_nosync(pic32s->rx_irq); | ||
232 | disable_irq_nosync(pic32s->tx_irq); | ||
233 | |||
234 | /* Show err message and abort xfer with err */ | ||
235 | dev_err(&pic32s->master->dev, "%s\n", msg); | ||
236 | if (pic32s->master->cur_msg) | ||
237 | pic32s->master->cur_msg->status = -EIO; | ||
238 | complete(&pic32s->xfer_done); | ||
239 | } | ||
240 | |||
241 | static irqreturn_t pic32_spi_fault_irq(int irq, void *dev_id) | ||
242 | { | ||
243 | struct pic32_spi *pic32s = dev_id; | ||
244 | u32 status; | ||
245 | |||
246 | status = readl(&pic32s->regs->status); | ||
247 | |||
248 | /* Error handling */ | ||
249 | if (status & (STAT_RX_OV | STAT_TX_UR)) { | ||
250 | writel(STAT_RX_OV, &pic32s->regs->status_clr); | ||
251 | writel(STAT_TX_UR, &pic32s->regs->status_clr); | ||
252 | pic32_err_stop(pic32s, "err_irq: fifo ov/ur-run\n"); | ||
253 | return IRQ_HANDLED; | ||
254 | } | ||
255 | |||
256 | if (status & STAT_FRM_ERR) { | ||
257 | pic32_err_stop(pic32s, "err_irq: frame error"); | ||
258 | return IRQ_HANDLED; | ||
259 | } | ||
260 | |||
261 | if (!pic32s->master->cur_msg) { | ||
262 | pic32_err_stop(pic32s, "err_irq: no mesg"); | ||
263 | return IRQ_NONE; | ||
264 | } | ||
265 | |||
266 | return IRQ_NONE; | ||
267 | } | ||
268 | |||
269 | static irqreturn_t pic32_spi_rx_irq(int irq, void *dev_id) | ||
270 | { | ||
271 | struct pic32_spi *pic32s = dev_id; | ||
272 | |||
273 | pic32s->rx_fifo(pic32s); | ||
274 | |||
275 | /* rx complete ? */ | ||
276 | if (pic32s->rx_end == pic32s->rx) { | ||
277 | /* disable all interrupts */ | ||
278 | disable_irq_nosync(pic32s->fault_irq); | ||
279 | disable_irq_nosync(pic32s->rx_irq); | ||
280 | |||
281 | /* complete current xfer */ | ||
282 | complete(&pic32s->xfer_done); | ||
283 | } | ||
284 | |||
285 | return IRQ_HANDLED; | ||
286 | } | ||
287 | |||
288 | static irqreturn_t pic32_spi_tx_irq(int irq, void *dev_id) | ||
289 | { | ||
290 | struct pic32_spi *pic32s = dev_id; | ||
291 | |||
292 | pic32s->tx_fifo(pic32s); | ||
293 | |||
294 | /* tx complete? disable tx interrupt */ | ||
295 | if (pic32s->tx_end == pic32s->tx) | ||
296 | disable_irq_nosync(pic32s->tx_irq); | ||
297 | |||
298 | return IRQ_HANDLED; | ||
299 | } | ||
300 | |||
301 | static void pic32_spi_dma_rx_notify(void *data) | ||
302 | { | ||
303 | struct pic32_spi *pic32s = data; | ||
304 | |||
305 | complete(&pic32s->xfer_done); | ||
306 | } | ||
307 | |||
308 | static int pic32_spi_dma_transfer(struct pic32_spi *pic32s, | ||
309 | struct spi_transfer *xfer) | ||
310 | { | ||
311 | struct spi_master *master = pic32s->master; | ||
312 | struct dma_async_tx_descriptor *desc_rx; | ||
313 | struct dma_async_tx_descriptor *desc_tx; | ||
314 | dma_cookie_t cookie; | ||
315 | int ret; | ||
316 | |||
317 | if (!master->dma_rx || !master->dma_tx) | ||
318 | return -ENODEV; | ||
319 | |||
320 | desc_rx = dmaengine_prep_slave_sg(master->dma_rx, | ||
321 | xfer->rx_sg.sgl, | ||
322 | xfer->rx_sg.nents, | ||
323 | DMA_FROM_DEVICE, | ||
324 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
325 | if (!desc_rx) { | ||
326 | ret = -EINVAL; | ||
327 | goto err_dma; | ||
328 | } | ||
329 | |||
330 | desc_tx = dmaengine_prep_slave_sg(master->dma_tx, | ||
331 | xfer->tx_sg.sgl, | ||
332 | xfer->tx_sg.nents, | ||
333 | DMA_TO_DEVICE, | ||
334 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
335 | if (!desc_tx) { | ||
336 | ret = -EINVAL; | ||
337 | goto err_dma; | ||
338 | } | ||
339 | |||
340 | /* Put callback on the RX transfer, that should finish last */ | ||
341 | desc_rx->callback = pic32_spi_dma_rx_notify; | ||
342 | desc_rx->callback_param = pic32s; | ||
343 | |||
344 | cookie = dmaengine_submit(desc_rx); | ||
345 | ret = dma_submit_error(cookie); | ||
346 | if (ret) | ||
347 | goto err_dma; | ||
348 | |||
349 | cookie = dmaengine_submit(desc_tx); | ||
350 | ret = dma_submit_error(cookie); | ||
351 | if (ret) | ||
352 | goto err_dma_tx; | ||
353 | |||
354 | dma_async_issue_pending(master->dma_rx); | ||
355 | dma_async_issue_pending(master->dma_tx); | ||
356 | |||
357 | return 0; | ||
358 | |||
359 | err_dma_tx: | ||
360 | dmaengine_terminate_all(master->dma_rx); | ||
361 | err_dma: | ||
362 | return ret; | ||
363 | } | ||
364 | |||
365 | static int pic32_spi_dma_config(struct pic32_spi *pic32s, u32 dma_width) | ||
366 | { | ||
367 | int buf_offset = offsetof(struct pic32_spi_regs, buf); | ||
368 | struct spi_master *master = pic32s->master; | ||
369 | struct dma_slave_config cfg; | ||
370 | int ret; | ||
371 | |||
372 | cfg.device_fc = true; | ||
373 | cfg.src_addr = pic32s->dma_base + buf_offset; | ||
374 | cfg.dst_addr = pic32s->dma_base + buf_offset; | ||
375 | cfg.src_maxburst = pic32s->fifo_n_elm / 2; /* fill one-half */ | ||
376 | cfg.dst_maxburst = pic32s->fifo_n_elm / 2; /* drain one-half */ | ||
377 | cfg.src_addr_width = dma_width; | ||
378 | cfg.dst_addr_width = dma_width; | ||
379 | /* tx channel */ | ||
380 | cfg.slave_id = pic32s->tx_irq; | ||
381 | cfg.direction = DMA_MEM_TO_DEV; | ||
382 | ret = dmaengine_slave_config(master->dma_tx, &cfg); | ||
383 | if (ret) { | ||
384 | dev_err(&master->dev, "tx channel setup failed\n"); | ||
385 | return ret; | ||
386 | } | ||
387 | /* rx channel */ | ||
388 | cfg.slave_id = pic32s->rx_irq; | ||
389 | cfg.direction = DMA_DEV_TO_MEM; | ||
390 | ret = dmaengine_slave_config(master->dma_rx, &cfg); | ||
391 | if (ret) | ||
392 | dev_err(&master->dev, "rx channel setup failed\n"); | ||
393 | |||
394 | return ret; | ||
395 | } | ||
396 | |||
397 | static int pic32_spi_set_word_size(struct pic32_spi *pic32s, u8 bits_per_word) | ||
398 | { | ||
399 | enum dma_slave_buswidth dmawidth; | ||
400 | u32 buswidth, v; | ||
401 | |||
402 | switch (bits_per_word) { | ||
403 | case 8: | ||
404 | pic32s->rx_fifo = pic32_spi_rx_byte; | ||
405 | pic32s->tx_fifo = pic32_spi_tx_byte; | ||
406 | buswidth = PIC32_BPW_8; | ||
407 | dmawidth = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
408 | break; | ||
409 | case 16: | ||
410 | pic32s->rx_fifo = pic32_spi_rx_word; | ||
411 | pic32s->tx_fifo = pic32_spi_tx_word; | ||
412 | buswidth = PIC32_BPW_16; | ||
413 | dmawidth = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
414 | break; | ||
415 | case 32: | ||
416 | pic32s->rx_fifo = pic32_spi_rx_dword; | ||
417 | pic32s->tx_fifo = pic32_spi_tx_dword; | ||
418 | buswidth = PIC32_BPW_32; | ||
419 | dmawidth = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
420 | break; | ||
421 | default: | ||
422 | /* not supported */ | ||
423 | return -EINVAL; | ||
424 | } | ||
425 | |||
426 | /* calculate maximum number of words fifos can hold */ | ||
427 | pic32s->fifo_n_elm = DIV_ROUND_UP(pic32s->fifo_n_byte, | ||
428 | bits_per_word / 8); | ||
429 | /* set word size */ | ||
430 | v = readl(&pic32s->regs->ctrl); | ||
431 | v &= ~(CTRL_BPW_MASK << CTRL_BPW_SHIFT); | ||
432 | v |= buswidth << CTRL_BPW_SHIFT; | ||
433 | writel(v, &pic32s->regs->ctrl); | ||
434 | |||
435 | /* re-configure dma width, if required */ | ||
436 | if (test_bit(PIC32F_DMA_PREP, &pic32s->flags)) | ||
437 | pic32_spi_dma_config(pic32s, dmawidth); | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | static int pic32_spi_prepare_hardware(struct spi_master *master) | ||
443 | { | ||
444 | struct pic32_spi *pic32s = spi_master_get_devdata(master); | ||
445 | |||
446 | pic32_spi_enable(pic32s); | ||
447 | |||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static int pic32_spi_prepare_message(struct spi_master *master, | ||
452 | struct spi_message *msg) | ||
453 | { | ||
454 | struct pic32_spi *pic32s = spi_master_get_devdata(master); | ||
455 | struct spi_device *spi = msg->spi; | ||
456 | u32 val; | ||
457 | |||
458 | /* set device specific bits_per_word */ | ||
459 | if (pic32s->bits_per_word != spi->bits_per_word) { | ||
460 | pic32_spi_set_word_size(pic32s, spi->bits_per_word); | ||
461 | pic32s->bits_per_word = spi->bits_per_word; | ||
462 | } | ||
463 | |||
464 | /* device specific speed change */ | ||
465 | if (pic32s->speed_hz != spi->max_speed_hz) { | ||
466 | pic32_spi_set_clk_rate(pic32s, spi->max_speed_hz); | ||
467 | pic32s->speed_hz = spi->max_speed_hz; | ||
468 | } | ||
469 | |||
470 | /* device specific mode change */ | ||
471 | if (pic32s->mode != spi->mode) { | ||
472 | val = readl(&pic32s->regs->ctrl); | ||
473 | /* active low */ | ||
474 | if (spi->mode & SPI_CPOL) | ||
475 | val |= CTRL_CKP; | ||
476 | else | ||
477 | val &= ~CTRL_CKP; | ||
478 | /* tx on rising edge */ | ||
479 | if (spi->mode & SPI_CPHA) | ||
480 | val &= ~CTRL_CKE; | ||
481 | else | ||
482 | val |= CTRL_CKE; | ||
483 | |||
484 | /* rx at end of tx */ | ||
485 | val |= CTRL_SMP; | ||
486 | writel(val, &pic32s->regs->ctrl); | ||
487 | pic32s->mode = spi->mode; | ||
488 | } | ||
489 | |||
490 | return 0; | ||
491 | } | ||
492 | |||
493 | static bool pic32_spi_can_dma(struct spi_master *master, | ||
494 | struct spi_device *spi, | ||
495 | struct spi_transfer *xfer) | ||
496 | { | ||
497 | struct pic32_spi *pic32s = spi_master_get_devdata(master); | ||
498 | |||
499 | /* skip using DMA on small size transfer to avoid overhead.*/ | ||
500 | return (xfer->len >= PIC32_DMA_LEN_MIN) && | ||
501 | test_bit(PIC32F_DMA_PREP, &pic32s->flags); | ||
502 | } | ||
503 | |||
504 | static int pic32_spi_one_transfer(struct spi_master *master, | ||
505 | struct spi_device *spi, | ||
506 | struct spi_transfer *transfer) | ||
507 | { | ||
508 | struct pic32_spi *pic32s; | ||
509 | bool dma_issued = false; | ||
510 | int ret; | ||
511 | |||
512 | pic32s = spi_master_get_devdata(master); | ||
513 | |||
514 | /* handle transfer specific word size change */ | ||
515 | if (transfer->bits_per_word && | ||
516 | (transfer->bits_per_word != pic32s->bits_per_word)) { | ||
517 | ret = pic32_spi_set_word_size(pic32s, transfer->bits_per_word); | ||
518 | if (ret) | ||
519 | return ret; | ||
520 | pic32s->bits_per_word = transfer->bits_per_word; | ||
521 | } | ||
522 | |||
523 | /* handle transfer specific speed change */ | ||
524 | if (transfer->speed_hz && (transfer->speed_hz != pic32s->speed_hz)) { | ||
525 | pic32_spi_set_clk_rate(pic32s, transfer->speed_hz); | ||
526 | pic32s->speed_hz = transfer->speed_hz; | ||
527 | } | ||
528 | |||
529 | reinit_completion(&pic32s->xfer_done); | ||
530 | |||
531 | /* transact by DMA mode */ | ||
532 | if (transfer->rx_sg.nents && transfer->tx_sg.nents) { | ||
533 | ret = pic32_spi_dma_transfer(pic32s, transfer); | ||
534 | if (ret) { | ||
535 | dev_err(&spi->dev, "dma submit error\n"); | ||
536 | return ret; | ||
537 | } | ||
538 | |||
539 | /* DMA issued */ | ||
540 | dma_issued = true; | ||
541 | } else { | ||
542 | /* set current transfer information */ | ||
543 | pic32s->tx = (const void *)transfer->tx_buf; | ||
544 | pic32s->rx = (const void *)transfer->rx_buf; | ||
545 | pic32s->tx_end = pic32s->tx + transfer->len; | ||
546 | pic32s->rx_end = pic32s->rx + transfer->len; | ||
547 | pic32s->len = transfer->len; | ||
548 | |||
549 | /* transact by interrupt driven PIO */ | ||
550 | enable_irq(pic32s->fault_irq); | ||
551 | enable_irq(pic32s->rx_irq); | ||
552 | enable_irq(pic32s->tx_irq); | ||
553 | } | ||
554 | |||
555 | /* wait for completion */ | ||
556 | ret = wait_for_completion_timeout(&pic32s->xfer_done, 2 * HZ); | ||
557 | if (ret <= 0) { | ||
558 | dev_err(&spi->dev, "wait error/timedout\n"); | ||
559 | if (dma_issued) { | ||
560 | dmaengine_terminate_all(master->dma_rx); | ||
561 | dmaengine_terminate_all(master->dma_rx); | ||
562 | } | ||
563 | ret = -ETIMEDOUT; | ||
564 | } else { | ||
565 | ret = 0; | ||
566 | } | ||
567 | |||
568 | return ret; | ||
569 | } | ||
570 | |||
571 | static int pic32_spi_unprepare_message(struct spi_master *master, | ||
572 | struct spi_message *msg) | ||
573 | { | ||
574 | /* nothing to do */ | ||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | static int pic32_spi_unprepare_hardware(struct spi_master *master) | ||
579 | { | ||
580 | struct pic32_spi *pic32s = spi_master_get_devdata(master); | ||
581 | |||
582 | pic32_spi_disable(pic32s); | ||
583 | |||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | /* This may be called multiple times by same spi dev */ | ||
588 | static int pic32_spi_setup(struct spi_device *spi) | ||
589 | { | ||
590 | if (!spi->max_speed_hz) { | ||
591 | dev_err(&spi->dev, "No max speed HZ parameter\n"); | ||
592 | return -EINVAL; | ||
593 | } | ||
594 | |||
595 | switch (spi->bits_per_word) { | ||
596 | case 8: | ||
597 | case 16: | ||
598 | case 32: | ||
599 | break; | ||
600 | default: | ||
601 | dev_err(&spi->dev, "Invalid bits_per_word defined\n"); | ||
602 | return -EINVAL; | ||
603 | } | ||
604 | |||
605 | /* PIC32 spi controller can drive /CS during transfer depending | ||
606 | * on tx fifo fill-level. /CS will stay asserted as long as TX | ||
607 | * fifo is non-empty, else will be deasserted indicating | ||
608 | * completion of the ongoing transfer. This might result into | ||
609 | * unreliable/erroneous SPI transactions. | ||
610 | * To avoid that we will always handle /CS by toggling GPIO. | ||
611 | */ | ||
612 | if (!gpio_is_valid(spi->cs_gpio)) | ||
613 | return -EINVAL; | ||
614 | |||
615 | gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); | ||
616 | |||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | static void pic32_spi_cleanup(struct spi_device *spi) | ||
621 | { | ||
622 | /* de-activate cs-gpio */ | ||
623 | gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); | ||
624 | } | ||
625 | |||
626 | static void pic32_spi_dma_prep(struct pic32_spi *pic32s, struct device *dev) | ||
627 | { | ||
628 | struct spi_master *master = pic32s->master; | ||
629 | dma_cap_mask_t mask; | ||
630 | |||
631 | dma_cap_zero(mask); | ||
632 | dma_cap_set(DMA_SLAVE, mask); | ||
633 | |||
634 | master->dma_rx = dma_request_slave_channel_compat(mask, NULL, NULL, | ||
635 | dev, "spi-rx"); | ||
636 | if (!master->dma_rx) { | ||
637 | dev_warn(dev, "RX channel not found.\n"); | ||
638 | goto out_err; | ||
639 | } | ||
640 | |||
641 | master->dma_tx = dma_request_slave_channel_compat(mask, NULL, NULL, | ||
642 | dev, "spi-tx"); | ||
643 | if (!master->dma_tx) { | ||
644 | dev_warn(dev, "TX channel not found.\n"); | ||
645 | goto out_err; | ||
646 | } | ||
647 | |||
648 | if (pic32_spi_dma_config(pic32s, DMA_SLAVE_BUSWIDTH_1_BYTE)) | ||
649 | goto out_err; | ||
650 | |||
651 | /* DMA chnls allocated and prepared */ | ||
652 | set_bit(PIC32F_DMA_PREP, &pic32s->flags); | ||
653 | |||
654 | return; | ||
655 | |||
656 | out_err: | ||
657 | if (master->dma_rx) | ||
658 | dma_release_channel(master->dma_rx); | ||
659 | |||
660 | if (master->dma_tx) | ||
661 | dma_release_channel(master->dma_tx); | ||
662 | } | ||
663 | |||
664 | static void pic32_spi_dma_unprep(struct pic32_spi *pic32s) | ||
665 | { | ||
666 | if (!test_bit(PIC32F_DMA_PREP, &pic32s->flags)) | ||
667 | return; | ||
668 | |||
669 | clear_bit(PIC32F_DMA_PREP, &pic32s->flags); | ||
670 | if (pic32s->master->dma_rx) | ||
671 | dma_release_channel(pic32s->master->dma_rx); | ||
672 | |||
673 | if (pic32s->master->dma_tx) | ||
674 | dma_release_channel(pic32s->master->dma_tx); | ||
675 | } | ||
676 | |||
677 | static void pic32_spi_hw_init(struct pic32_spi *pic32s) | ||
678 | { | ||
679 | u32 ctrl; | ||
680 | |||
681 | /* disable hardware */ | ||
682 | pic32_spi_disable(pic32s); | ||
683 | |||
684 | ctrl = readl(&pic32s->regs->ctrl); | ||
685 | /* enable enhanced fifo of 128bit deep */ | ||
686 | ctrl |= CTRL_ENHBUF; | ||
687 | pic32s->fifo_n_byte = 16; | ||
688 | |||
689 | /* disable framing mode */ | ||
690 | ctrl &= ~CTRL_FRMEN; | ||
691 | |||
692 | /* enable master mode while disabled */ | ||
693 | ctrl |= CTRL_MSTEN; | ||
694 | |||
695 | /* set tx fifo threshold interrupt */ | ||
696 | ctrl &= ~(0x3 << CTRL_TX_INT_SHIFT); | ||
697 | ctrl |= (TX_FIFO_HALF_EMPTY << CTRL_TX_INT_SHIFT); | ||
698 | |||
699 | /* set rx fifo threshold interrupt */ | ||
700 | ctrl &= ~(0x3 << CTRL_RX_INT_SHIFT); | ||
701 | ctrl |= (RX_FIFO_NOT_EMPTY << CTRL_RX_INT_SHIFT); | ||
702 | |||
703 | /* select clk source */ | ||
704 | ctrl &= ~CTRL_MCLKSEL; | ||
705 | |||
706 | /* set manual /CS mode */ | ||
707 | ctrl &= ~CTRL_MSSEN; | ||
708 | |||
709 | writel(ctrl, &pic32s->regs->ctrl); | ||
710 | |||
711 | /* enable error reporting */ | ||
712 | ctrl = CTRL2_TX_UR_EN | CTRL2_RX_OV_EN | CTRL2_FRM_ERR_EN; | ||
713 | writel(ctrl, &pic32s->regs->ctrl2_set); | ||
714 | } | ||
715 | |||
716 | static int pic32_spi_hw_probe(struct platform_device *pdev, | ||
717 | struct pic32_spi *pic32s) | ||
718 | { | ||
719 | struct resource *mem; | ||
720 | int ret; | ||
721 | |||
722 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
723 | pic32s->regs = devm_ioremap_resource(&pdev->dev, mem); | ||
724 | if (!pic32s->regs) { | ||
725 | dev_err(&pdev->dev, "ioremap() failed\n"); | ||
726 | return -ENOMEM; | ||
727 | } | ||
728 | pic32s->dma_base = mem->start; | ||
729 | |||
730 | /* get irq resources: err-irq, rx-irq, tx-irq */ | ||
731 | pic32s->fault_irq = platform_get_irq_byname(pdev, "fault"); | ||
732 | if (pic32s->fault_irq < 0) { | ||
733 | dev_err(&pdev->dev, "fault-irq not found\n"); | ||
734 | return pic32s->fault_irq; | ||
735 | } | ||
736 | |||
737 | pic32s->rx_irq = platform_get_irq_byname(pdev, "rx"); | ||
738 | if (pic32s->rx_irq < 0) { | ||
739 | dev_err(&pdev->dev, "rx-irq not found\n"); | ||
740 | return pic32s->rx_irq; | ||
741 | } | ||
742 | |||
743 | pic32s->tx_irq = platform_get_irq_byname(pdev, "tx"); | ||
744 | if (pic32s->tx_irq < 0) { | ||
745 | dev_err(&pdev->dev, "tx-irq not found\n"); | ||
746 | return pic32s->tx_irq; | ||
747 | } | ||
748 | |||
749 | /* get clock */ | ||
750 | pic32s->clk = devm_clk_get(&pdev->dev, "mck0"); | ||
751 | if (IS_ERR(pic32s->clk)) { | ||
752 | dev_err(&pdev->dev, "clk not found\n"); | ||
753 | ret = PTR_ERR(pic32s->clk); | ||
754 | goto err_unmap_mem; | ||
755 | } | ||
756 | |||
757 | ret = clk_prepare_enable(pic32s->clk); | ||
758 | if (ret) | ||
759 | goto err_unmap_mem; | ||
760 | |||
761 | pic32_spi_hw_init(pic32s); | ||
762 | |||
763 | return 0; | ||
764 | |||
765 | err_unmap_mem: | ||
766 | dev_err(&pdev->dev, "%s failed, err %d\n", __func__, ret); | ||
767 | return ret; | ||
768 | } | ||
769 | |||
770 | static int pic32_spi_probe(struct platform_device *pdev) | ||
771 | { | ||
772 | struct spi_master *master; | ||
773 | struct pic32_spi *pic32s; | ||
774 | int ret; | ||
775 | |||
776 | master = spi_alloc_master(&pdev->dev, sizeof(*pic32s)); | ||
777 | if (!master) | ||
778 | return -ENOMEM; | ||
779 | |||
780 | pic32s = spi_master_get_devdata(master); | ||
781 | pic32s->master = master; | ||
782 | |||
783 | ret = pic32_spi_hw_probe(pdev, pic32s); | ||
784 | if (ret) | ||
785 | goto err_master; | ||
786 | |||
787 | master->dev.of_node = of_node_get(pdev->dev.of_node); | ||
788 | master->mode_bits = SPI_MODE_3 | SPI_MODE_0 | SPI_CS_HIGH; | ||
789 | master->num_chipselect = 1; /* single chip-select */ | ||
790 | master->max_speed_hz = clk_get_rate(pic32s->clk); | ||
791 | master->setup = pic32_spi_setup; | ||
792 | master->cleanup = pic32_spi_cleanup; | ||
793 | master->flags = SPI_MASTER_MUST_TX | SPI_MASTER_MUST_RX; | ||
794 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32); | ||
795 | master->transfer_one = pic32_spi_one_transfer; | ||
796 | master->prepare_message = pic32_spi_prepare_message; | ||
797 | master->unprepare_message = pic32_spi_unprepare_message; | ||
798 | master->prepare_transfer_hardware = pic32_spi_prepare_hardware; | ||
799 | master->unprepare_transfer_hardware = pic32_spi_unprepare_hardware; | ||
800 | |||
801 | /* optional DMA support */ | ||
802 | pic32_spi_dma_prep(pic32s, &pdev->dev); | ||
803 | if (test_bit(PIC32F_DMA_PREP, &pic32s->flags)) | ||
804 | master->can_dma = pic32_spi_can_dma; | ||
805 | |||
806 | init_completion(&pic32s->xfer_done); | ||
807 | pic32s->mode = -1; | ||
808 | |||
809 | /* install irq handlers (with irq-disabled) */ | ||
810 | irq_set_status_flags(pic32s->fault_irq, IRQ_NOAUTOEN); | ||
811 | ret = devm_request_irq(&pdev->dev, pic32s->fault_irq, | ||
812 | pic32_spi_fault_irq, IRQF_NO_THREAD, | ||
813 | dev_name(&pdev->dev), pic32s); | ||
814 | if (ret < 0) { | ||
815 | dev_err(&pdev->dev, "request fault-irq %d\n", pic32s->rx_irq); | ||
816 | goto err_bailout; | ||
817 | } | ||
818 | |||
819 | /* receive interrupt handler */ | ||
820 | irq_set_status_flags(pic32s->rx_irq, IRQ_NOAUTOEN); | ||
821 | ret = devm_request_irq(&pdev->dev, pic32s->rx_irq, | ||
822 | pic32_spi_rx_irq, IRQF_NO_THREAD, | ||
823 | dev_name(&pdev->dev), pic32s); | ||
824 | if (ret < 0) { | ||
825 | dev_err(&pdev->dev, "request rx-irq %d\n", pic32s->rx_irq); | ||
826 | goto err_bailout; | ||
827 | } | ||
828 | |||
829 | /* transmit interrupt handler */ | ||
830 | irq_set_status_flags(pic32s->tx_irq, IRQ_NOAUTOEN); | ||
831 | ret = devm_request_irq(&pdev->dev, pic32s->tx_irq, | ||
832 | pic32_spi_tx_irq, IRQF_NO_THREAD, | ||
833 | dev_name(&pdev->dev), pic32s); | ||
834 | if (ret < 0) { | ||
835 | dev_err(&pdev->dev, "request tx-irq %d\n", pic32s->tx_irq); | ||
836 | goto err_bailout; | ||
837 | } | ||
838 | |||
839 | /* register master */ | ||
840 | ret = devm_spi_register_master(&pdev->dev, master); | ||
841 | if (ret) { | ||
842 | dev_err(&master->dev, "failed registering spi master\n"); | ||
843 | goto err_bailout; | ||
844 | } | ||
845 | |||
846 | platform_set_drvdata(pdev, pic32s); | ||
847 | |||
848 | return 0; | ||
849 | |||
850 | err_bailout: | ||
851 | clk_disable_unprepare(pic32s->clk); | ||
852 | err_master: | ||
853 | spi_master_put(master); | ||
854 | return ret; | ||
855 | } | ||
856 | |||
857 | static int pic32_spi_remove(struct platform_device *pdev) | ||
858 | { | ||
859 | struct pic32_spi *pic32s; | ||
860 | |||
861 | pic32s = platform_get_drvdata(pdev); | ||
862 | pic32_spi_disable(pic32s); | ||
863 | clk_disable_unprepare(pic32s->clk); | ||
864 | pic32_spi_dma_unprep(pic32s); | ||
865 | |||
866 | return 0; | ||
867 | } | ||
868 | |||
869 | static const struct of_device_id pic32_spi_of_match[] = { | ||
870 | {.compatible = "microchip,pic32mzda-spi",}, | ||
871 | {}, | ||
872 | }; | ||
873 | MODULE_DEVICE_TABLE(of, pic32_spi_of_match); | ||
874 | |||
875 | static struct platform_driver pic32_spi_driver = { | ||
876 | .driver = { | ||
877 | .name = "spi-pic32", | ||
878 | .of_match_table = of_match_ptr(pic32_spi_of_match), | ||
879 | }, | ||
880 | .probe = pic32_spi_probe, | ||
881 | .remove = pic32_spi_remove, | ||
882 | }; | ||
883 | |||
884 | module_platform_driver(pic32_spi_driver); | ||
885 | |||
886 | MODULE_AUTHOR("Purna Chandra Mandal <purna.mandal@microchip.com>"); | ||
887 | MODULE_DESCRIPTION("Microchip SPI driver for PIC32 SPI controller."); | ||
888 | MODULE_LICENSE("GPL v2"); | ||