aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Konovalov <akonovalov@ru.mvista.com>2007-07-17 07:04:11 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:05 -0400
commitae918c02d365c884bccb193960db41364868bb7b (patch)
tree5de1aea4e976c01e50e8bd0640835f719297c464
parent447aef1a19135a69bfd725c33f7e753740cb8447 (diff)
SPI master driver for Xilinx virtex
Simple SPI master driver for Xilinx SPI controller. No support for multiple masters. Not using level 1 drivers from EDK. [akpm@linux-foundation.org: uninlining] Signed-off-by: Yuri Frolov <yfrolov@ru.mvista.com> Signed-off-by: Andrei Konovalov <akonovalov@ru.mvista.com> Cc: Kumar Gala <galak@gate.crashing.org> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/ppc/syslib/virtex_devices.h7
-rw-r--r--drivers/spi/Kconfig11
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/xilinx_spi.c434
4 files changed, 453 insertions, 0 deletions
diff --git a/arch/ppc/syslib/virtex_devices.h b/arch/ppc/syslib/virtex_devices.h
index 3d4be1412f60..9f38d92ae536 100644
--- a/arch/ppc/syslib/virtex_devices.h
+++ b/arch/ppc/syslib/virtex_devices.h
@@ -31,4 +31,11 @@ void __init virtex_early_serial_map(void);
31 */ 31 */
32int virtex_device_fixup(struct platform_device *dev); 32int virtex_device_fixup(struct platform_device *dev);
33 33
34/* SPI Controller IP */
35struct xspi_platform_data {
36 s16 bus_num;
37 u16 num_chipselect;
38 u32 speed_hz;
39};
40
34#endif /* __ASM_VIRTEX_DEVICES_H__ */ 41#endif /* __ASM_VIRTEX_DEVICES_H__ */
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index a49270eae660..22feb3c8de55 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -167,6 +167,17 @@ config SPI_S3C24XX_GPIO
167 GPIO lines to provide the SPI bus. This can be used where 167 GPIO lines to provide the SPI bus. This can be used where
168 the inbuilt hardware cannot provide the transfer mode, or 168 the inbuilt hardware cannot provide the transfer mode, or
169 where the board is using non hardware connected pins. 169 where the board is using non hardware connected pins.
170
171config SPI_XILINX
172 tristate "Xilinx SPI controller"
173 depends on SPI_MASTER && XILINX_VIRTEX && EXPERIMENTAL
174 select SPI_BITBANG
175 help
176 This exposes the SPI controller IP from the Xilinx EDK.
177
178 See the "OPB Serial Peripheral Interface (SPI) (v1.00e)"
179 Product Specification document (DS464) for hardware details.
180
170# 181#
171# Add new SPI master controllers in alphabetical order above this line 182# Add new SPI master controllers in alphabetical order above this line
172# 183#
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index d9bd7f605d6a..9c95db2b6bbd 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_SPI_MPC52xx_PSC) += mpc52xx_psc_spi.o
24obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o 24obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o
25obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o 25obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
26obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o 26obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
27obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o
27# ... add above this line ... 28# ... add above this line ...
28 29
29# SPI protocol drivers (device/link on bus) 30# SPI protocol drivers (device/link on bus)
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
new file mode 100644
index 000000000000..f0bf9a68e96b
--- /dev/null
+++ b/drivers/spi/xilinx_spi.c
@@ -0,0 +1,434 @@
1/*
2 * xilinx_spi.c
3 *
4 * Xilinx SPI controller driver (master mode only)
5 *
6 * Author: MontaVista Software, Inc.
7 * source@mvista.com
8 *
9 * 2002-2007 (c) MontaVista Software, Inc. This file is licensed under the
10 * terms of the GNU General Public License version 2. This program is licensed
11 * "as is" without any warranty of any kind, whether express or implied.
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/interrupt.h>
17#include <linux/platform_device.h>
18#include <linux/spi/spi.h>
19#include <linux/spi/spi_bitbang.h>
20#include <linux/io.h>
21
22#include <syslib/virtex_devices.h>
23
24#define XILINX_SPI_NAME "xspi"
25
26/* Register definitions as per "OPB Serial Peripheral Interface (SPI) (v1.00e)
27 * Product Specification", DS464
28 */
29#define XSPI_CR_OFFSET 0x62 /* 16-bit Control Register */
30
31#define XSPI_CR_ENABLE 0x02
32#define XSPI_CR_MASTER_MODE 0x04
33#define XSPI_CR_CPOL 0x08
34#define XSPI_CR_CPHA 0x10
35#define XSPI_CR_MODE_MASK (XSPI_CR_CPHA | XSPI_CR_CPOL)
36#define XSPI_CR_TXFIFO_RESET 0x20
37#define XSPI_CR_RXFIFO_RESET 0x40
38#define XSPI_CR_MANUAL_SSELECT 0x80
39#define XSPI_CR_TRANS_INHIBIT 0x100
40
41#define XSPI_SR_OFFSET 0x67 /* 8-bit Status Register */
42
43#define XSPI_SR_RX_EMPTY_MASK 0x01 /* Receive FIFO is empty */
44#define XSPI_SR_RX_FULL_MASK 0x02 /* Receive FIFO is full */
45#define XSPI_SR_TX_EMPTY_MASK 0x04 /* Transmit FIFO is empty */
46#define XSPI_SR_TX_FULL_MASK 0x08 /* Transmit FIFO is full */
47#define XSPI_SR_MODE_FAULT_MASK 0x10 /* Mode fault error */
48
49#define XSPI_TXD_OFFSET 0x6b /* 8-bit Data Transmit Register */
50#define XSPI_RXD_OFFSET 0x6f /* 8-bit Data Receive Register */
51
52#define XSPI_SSR_OFFSET 0x70 /* 32-bit Slave Select Register */
53
54/* Register definitions as per "OPB IPIF (v3.01c) Product Specification", DS414
55 * IPIF registers are 32 bit
56 */
57#define XIPIF_V123B_DGIER_OFFSET 0x1c /* IPIF global int enable reg */
58#define XIPIF_V123B_GINTR_ENABLE 0x80000000
59
60#define XIPIF_V123B_IISR_OFFSET 0x20 /* IPIF interrupt status reg */
61#define XIPIF_V123B_IIER_OFFSET 0x28 /* IPIF interrupt enable reg */
62
63#define XSPI_INTR_MODE_FAULT 0x01 /* Mode fault error */
64#define XSPI_INTR_SLAVE_MODE_FAULT 0x02 /* Selected as slave while
65 * disabled */
66#define XSPI_INTR_TX_EMPTY 0x04 /* TxFIFO is empty */
67#define XSPI_INTR_TX_UNDERRUN 0x08 /* TxFIFO was underrun */
68#define XSPI_INTR_RX_FULL 0x10 /* RxFIFO is full */
69#define XSPI_INTR_RX_OVERRUN 0x20 /* RxFIFO was overrun */
70
71#define XIPIF_V123B_RESETR_OFFSET 0x40 /* IPIF reset register */
72#define XIPIF_V123B_RESET_MASK 0x0a /* the value to write */
73
74struct xilinx_spi {
75 /* bitbang has to be first */
76 struct spi_bitbang bitbang;
77 struct completion done;
78
79 void __iomem *regs; /* virt. address of the control registers */
80
81 u32 irq;
82
83 u32 speed_hz; /* SCK has a fixed frequency of speed_hz Hz */
84
85 u8 *rx_ptr; /* pointer in the Tx buffer */
86 const u8 *tx_ptr; /* pointer in the Rx buffer */
87 int remaining_bytes; /* the number of bytes left to transfer */
88};
89
90static void xspi_init_hw(void __iomem *regs_base)
91{
92 /* Reset the SPI device */
93 out_be32(regs_base + XIPIF_V123B_RESETR_OFFSET,
94 XIPIF_V123B_RESET_MASK);
95 /* Disable all the interrupts just in case */
96 out_be32(regs_base + XIPIF_V123B_IIER_OFFSET, 0);
97 /* Enable the global IPIF interrupt */
98 out_be32(regs_base + XIPIF_V123B_DGIER_OFFSET,
99 XIPIF_V123B_GINTR_ENABLE);
100 /* Deselect the slave on the SPI bus */
101 out_be32(regs_base + XSPI_SSR_OFFSET, 0xffff);
102 /* Disable the transmitter, enable Manual Slave Select Assertion,
103 * put SPI controller into master mode, and enable it */
104 out_be16(regs_base + XSPI_CR_OFFSET,
105 XSPI_CR_TRANS_INHIBIT | XSPI_CR_MANUAL_SSELECT
106 | XSPI_CR_MASTER_MODE | XSPI_CR_ENABLE);
107}
108
109static void xilinx_spi_chipselect(struct spi_device *spi, int is_on)
110{
111 struct xilinx_spi *xspi = spi_master_get_devdata(spi->master);
112
113 if (is_on == BITBANG_CS_INACTIVE) {
114 /* Deselect the slave on the SPI bus */
115 out_be32(xspi->regs + XSPI_SSR_OFFSET, 0xffff);
116 } else if (is_on == BITBANG_CS_ACTIVE) {
117 /* Set the SPI clock phase and polarity */
118 u16 cr = in_be16(xspi->regs + XSPI_CR_OFFSET)
119 & ~XSPI_CR_MODE_MASK;
120 if (spi->mode & SPI_CPHA)
121 cr |= XSPI_CR_CPHA;
122 if (spi->mode & SPI_CPOL)
123 cr |= XSPI_CR_CPOL;
124 out_be16(xspi->regs + XSPI_CR_OFFSET, cr);
125
126 /* We do not check spi->max_speed_hz here as the SPI clock
127 * frequency is not software programmable (the IP block design
128 * parameter)
129 */
130
131 /* Activate the chip select */
132 out_be32(xspi->regs + XSPI_SSR_OFFSET,
133 ~(0x0001 << spi->chip_select));
134 }
135}
136
137/* spi_bitbang requires custom setup_transfer() to be defined if there is a
138 * custom txrx_bufs(). We have nothing to setup here as the SPI IP block
139 * supports just 8 bits per word, and SPI clock can't be changed in software.
140 * Check for 8 bits per word. Chip select delay calculations could be
141 * added here as soon as bitbang_work() can be made aware of the delay value.
142 */
143static int xilinx_spi_setup_transfer(struct spi_device *spi,
144 struct spi_transfer *t)
145{
146 u8 bits_per_word;
147 u32 hz;
148 struct xilinx_spi *xspi = spi_master_get_devdata(spi->master);
149
150 bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
151 hz = (t) ? t->speed_hz : spi->max_speed_hz;
152 if (bits_per_word != 8) {
153 dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
154 __FUNCTION__, bits_per_word);
155 return -EINVAL;
156 }
157
158 if (hz && xspi->speed_hz > hz) {
159 dev_err(&spi->dev, "%s, unsupported clock rate %uHz\n",
160 __FUNCTION__, hz);
161 return -EINVAL;
162 }
163
164 return 0;
165}
166
167/* the spi->mode bits understood by this driver: */
168#define MODEBITS (SPI_CPOL | SPI_CPHA)
169
170static int xilinx_spi_setup(struct spi_device *spi)
171{
172 struct spi_bitbang *bitbang;
173 struct xilinx_spi *xspi;
174 int retval;
175
176 xspi = spi_master_get_devdata(spi->master);
177 bitbang = &xspi->bitbang;
178
179 if (!spi->bits_per_word)
180 spi->bits_per_word = 8;
181
182 if (spi->mode & ~MODEBITS) {
183 dev_err(&spi->dev, "%s, unsupported mode bits %x\n",
184 __FUNCTION__, spi->mode & ~MODEBITS);
185 return -EINVAL;
186 }
187
188 retval = xilinx_spi_setup_transfer(spi, NULL);
189 if (retval < 0)
190 return retval;
191
192 dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n",
193 __FUNCTION__, spi->mode & MODEBITS, spi->bits_per_word, 0);
194
195 return 0;
196}
197
198static void xilinx_spi_fill_tx_fifo(struct xilinx_spi *xspi)
199{
200 u8 sr;
201
202 /* Fill the Tx FIFO with as many bytes as possible */
203 sr = in_8(xspi->regs + XSPI_SR_OFFSET);
204 while ((sr & XSPI_SR_TX_FULL_MASK) == 0 && xspi->remaining_bytes > 0) {
205 if (xspi->tx_ptr) {
206 out_8(xspi->regs + XSPI_TXD_OFFSET, *xspi->tx_ptr++);
207 } else {
208 out_8(xspi->regs + XSPI_TXD_OFFSET, 0);
209 }
210 xspi->remaining_bytes--;
211 sr = in_8(xspi->regs + XSPI_SR_OFFSET);
212 }
213}
214
215static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
216{
217 struct xilinx_spi *xspi = spi_master_get_devdata(spi->master);
218 u32 ipif_ier;
219 u16 cr;
220
221 /* We get here with transmitter inhibited */
222
223 xspi->tx_ptr = t->tx_buf;
224 xspi->rx_ptr = t->rx_buf;
225 xspi->remaining_bytes = t->len;
226 INIT_COMPLETION(xspi->done);
227
228 xilinx_spi_fill_tx_fifo(xspi);
229
230 /* Enable the transmit empty interrupt, which we use to determine
231 * progress on the transmission.
232 */
233 ipif_ier = in_be32(xspi->regs + XIPIF_V123B_IIER_OFFSET);
234 out_be32(xspi->regs + XIPIF_V123B_IIER_OFFSET,
235 ipif_ier | XSPI_INTR_TX_EMPTY);
236
237 /* Start the transfer by not inhibiting the transmitter any longer */
238 cr = in_be16(xspi->regs + XSPI_CR_OFFSET) & ~XSPI_CR_TRANS_INHIBIT;
239 out_be16(xspi->regs + XSPI_CR_OFFSET, cr);
240
241 wait_for_completion(&xspi->done);
242
243 /* Disable the transmit empty interrupt */
244 out_be32(xspi->regs + XIPIF_V123B_IIER_OFFSET, ipif_ier);
245
246 return t->len - xspi->remaining_bytes;
247}
248
249
250/* This driver supports single master mode only. Hence Tx FIFO Empty
251 * is the only interrupt we care about.
252 * Receive FIFO Overrun, Transmit FIFO Underrun, Mode Fault, and Slave Mode
253 * Fault are not to happen.
254 */
255static irqreturn_t xilinx_spi_irq(int irq, void *dev_id)
256{
257 struct xilinx_spi *xspi = dev_id;
258 u32 ipif_isr;
259
260 /* Get the IPIF interrupts, and clear them immediately */
261 ipif_isr = in_be32(xspi->regs + XIPIF_V123B_IISR_OFFSET);
262 out_be32(xspi->regs + XIPIF_V123B_IISR_OFFSET, ipif_isr);
263
264 if (ipif_isr & XSPI_INTR_TX_EMPTY) { /* Transmission completed */
265 u16 cr;
266 u8 sr;
267
268 /* A transmit has just completed. Process received data and
269 * check for more data to transmit. Always inhibit the
270 * transmitter while the Isr refills the transmit register/FIFO,
271 * or make sure it is stopped if we're done.
272 */
273 cr = in_be16(xspi->regs + XSPI_CR_OFFSET);
274 out_be16(xspi->regs + XSPI_CR_OFFSET,
275 cr | XSPI_CR_TRANS_INHIBIT);
276
277 /* Read out all the data from the Rx FIFO */
278 sr = in_8(xspi->regs + XSPI_SR_OFFSET);
279 while ((sr & XSPI_SR_RX_EMPTY_MASK) == 0) {
280 u8 data;
281
282 data = in_8(xspi->regs + XSPI_RXD_OFFSET);
283 if (xspi->rx_ptr) {
284 *xspi->rx_ptr++ = data;
285 }
286 sr = in_8(xspi->regs + XSPI_SR_OFFSET);
287 }
288
289 /* See if there is more data to send */
290 if (xspi->remaining_bytes > 0) {
291 xilinx_spi_fill_tx_fifo(xspi);
292 /* Start the transfer by not inhibiting the
293 * transmitter any longer
294 */
295 out_be16(xspi->regs + XSPI_CR_OFFSET, cr);
296 } else {
297 /* No more data to send.
298 * Indicate the transfer is completed.
299 */
300 complete(&xspi->done);
301 }
302 }
303
304 return IRQ_HANDLED;
305}
306
307static int __init xilinx_spi_probe(struct platform_device *dev)
308{
309 int ret = 0;
310 struct spi_master *master;
311 struct xilinx_spi *xspi;
312 struct xspi_platform_data *pdata;
313 struct resource *r;
314
315 /* Get resources(memory, IRQ) associated with the device */
316 master = spi_alloc_master(&dev->dev, sizeof(struct xilinx_spi));
317
318 if (master == NULL) {
319 return -ENOMEM;
320 }
321
322 platform_set_drvdata(dev, master);
323 pdata = dev->dev.platform_data;
324
325 if (pdata == NULL) {
326 ret = -ENODEV;
327 goto put_master;
328 }
329
330 r = platform_get_resource(dev, IORESOURCE_MEM, 0);
331 if (r == NULL) {
332 ret = -ENODEV;
333 goto put_master;
334 }
335
336 xspi = spi_master_get_devdata(master);
337 xspi->bitbang.master = spi_master_get(master);
338 xspi->bitbang.chipselect = xilinx_spi_chipselect;
339 xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
340 xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;
341 xspi->bitbang.master->setup = xilinx_spi_setup;
342 init_completion(&xspi->done);
343
344 if (!request_mem_region(r->start,
345 r->end - r->start + 1, XILINX_SPI_NAME)) {
346 ret = -ENXIO;
347 goto put_master;
348 }
349
350 xspi->regs = ioremap(r->start, r->end - r->start + 1);
351 if (xspi->regs == NULL) {
352 ret = -ENOMEM;
353 goto put_master;
354 }
355
356 xspi->irq = platform_get_irq(dev, 0);
357 if (xspi->irq < 0) {
358 ret = -ENXIO;
359 goto unmap_io;
360 }
361
362 master->bus_num = pdata->bus_num;
363 master->num_chipselect = pdata->num_chipselect;
364 xspi->speed_hz = pdata->speed_hz;
365
366 /* SPI controller initializations */
367 xspi_init_hw(xspi->regs);
368
369 /* Register for SPI Interrupt */
370 ret = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi);
371 if (ret != 0)
372 goto unmap_io;
373
374 ret = spi_bitbang_start(&xspi->bitbang);
375 if (ret != 0) {
376 dev_err(&dev->dev, "spi_bitbang_start FAILED\n");
377 goto free_irq;
378 }
379
380 dev_info(&dev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n",
381 r->start, (u32)xspi->regs, xspi->irq);
382
383 return ret;
384
385free_irq:
386 free_irq(xspi->irq, xspi);
387unmap_io:
388 iounmap(xspi->regs);
389put_master:
390 spi_master_put(master);
391 return ret;
392}
393
394static int __devexit xilinx_spi_remove(struct platform_device *dev)
395{
396 struct xilinx_spi *xspi;
397 struct spi_master *master;
398
399 master = platform_get_drvdata(dev);
400 xspi = spi_master_get_devdata(master);
401
402 spi_bitbang_stop(&xspi->bitbang);
403 free_irq(xspi->irq, xspi);
404 iounmap(xspi->regs);
405 platform_set_drvdata(dev, 0);
406 spi_master_put(xspi->bitbang.master);
407
408 return 0;
409}
410
411static struct platform_driver xilinx_spi_driver = {
412 .probe = xilinx_spi_probe,
413 .remove = __devexit_p(xilinx_spi_remove),
414 .driver = {
415 .name = XILINX_SPI_NAME,
416 .owner = THIS_MODULE,
417 },
418};
419
420static int __init xilinx_spi_init(void)
421{
422 return platform_driver_register(&xilinx_spi_driver);
423}
424module_init(xilinx_spi_init);
425
426static void __exit xilinx_spi_exit(void)
427{
428 platform_driver_unregister(&xilinx_spi_driver);
429}
430module_exit(xilinx_spi_exit);
431
432MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
433MODULE_DESCRIPTION("Xilinx SPI driver");
434MODULE_LICENSE("GPL");