aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2007-02-12 03:52:37 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-12 12:48:30 -0500
commitfdb3c18d639311287dc4675abe743847a1aa62a8 (patch)
treed5d05f7eab547d515a4fb89d74e556fc462c85b0 /drivers/spi
parent85abfaa78239e63f553cc446f8ae5b955282aa29 (diff)
[PATCH] SPI controller driver for OMAP Microwire
This adds a SPI driver for the Microwire controller on OMAP1 chips. This driver has been used in the Linux-OMAP tree for some time now, including with some of those displays using standardized 9-bit commands followed by data with 8-bit words. Microwire only supports half duplex transfers, but that's all that most SPI protocols need. When full duplex, or higher speeds, are needed there are several other controllers that can be used on OMAP. [akpm@osdl.org: cleanups] Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Imre Deak <imre.deak@solidboot.com> Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/Kconfig7
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/omap_uwire.c572
3 files changed, 580 insertions, 0 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 43d41f50b84a..2a2f44d1367d 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -87,6 +87,13 @@ config SPI_MPC83xx
87 family of PowerPC processors. The MPC83xx uses a simple set of shift 87 family of PowerPC processors. The MPC83xx uses a simple set of shift
88 registers for data (opposed to the CPM based descriptor model). 88 registers for data (opposed to the CPM based descriptor model).
89 89
90config SPI_OMAP_UWIRE
91 tristate "OMAP1 MicroWire"
92 depends on SPI_MASTER && ARCH_OMAP1
93 select SPI_BITBANG
94 help
95 This hooks up to the MicroWire controller on OMAP1 chips.
96
90config SPI_PXA2XX 97config SPI_PXA2XX
91 tristate "PXA2xx SSP SPI master" 98 tristate "PXA2xx SSP SPI master"
92 depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL 99 depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 8f4cb67997b3..f1a3b96b2a63 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_SPI_MASTER) += spi.o
14obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o 14obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
15obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o 15obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
16obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o 16obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
17obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o
17obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o 18obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o
18obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o 19obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
19obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o 20obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
new file mode 100644
index 000000000000..366af4959a0f
--- /dev/null
+++ b/drivers/spi/omap_uwire.c
@@ -0,0 +1,572 @@
1/*
2 * omap_uwire.c -- MicroWire interface driver for OMAP
3 *
4 * Copyright 2003 MontaVista Software Inc. <source@mvista.com>
5 *
6 * Ported to 2.6 OMAP uwire interface.
7 * Copyright (C) 2004 Texas Instruments.
8 *
9 * Generalization patches by Juha Yrjola <juha.yrjola@nokia.com>
10 *
11 * Copyright (C) 2005 David Brownell (ported to 2.6 SPI interface)
12 * Copyright (C) 2006 Nokia
13 *
14 * Many updates by Imre Deak <imre.deak@nokia.com>
15 *
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 2 of the License, or (at your
19 * option) any later version.
20 *
21 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * You should have received a copy of the GNU General Public License along
33 * with this program; if not, write to the Free Software Foundation, Inc.,
34 * 675 Mass Ave, Cambridge, MA 02139, USA.
35 */
36#include <linux/kernel.h>
37#include <linux/init.h>
38#include <linux/delay.h>
39#include <linux/platform_device.h>
40#include <linux/workqueue.h>
41#include <linux/interrupt.h>
42#include <linux/err.h>
43#include <linux/clk.h>
44
45#include <linux/spi/spi.h>
46#include <linux/spi/spi_bitbang.h>
47
48#include <asm/system.h>
49#include <asm/irq.h>
50#include <asm/hardware.h>
51#include <asm/io.h>
52#include <asm/mach-types.h>
53
54#include <asm/arch/mux.h>
55#include <asm/arch/omap730.h> /* OMAP730_IO_CONF registers */
56
57
58/* FIXME address is now a platform device resource,
59 * and irqs should show there too...
60 */
61#define UWIRE_BASE_PHYS 0xFFFB3000
62#define UWIRE_BASE ((void *__iomem)IO_ADDRESS(UWIRE_BASE_PHYS))
63
64/* uWire Registers: */
65#define UWIRE_IO_SIZE 0x20
66#define UWIRE_TDR 0x00
67#define UWIRE_RDR 0x00
68#define UWIRE_CSR 0x01
69#define UWIRE_SR1 0x02
70#define UWIRE_SR2 0x03
71#define UWIRE_SR3 0x04
72#define UWIRE_SR4 0x05
73#define UWIRE_SR5 0x06
74
75/* CSR bits */
76#define RDRB (1 << 15)
77#define CSRB (1 << 14)
78#define START (1 << 13)
79#define CS_CMD (1 << 12)
80
81/* SR1 or SR2 bits */
82#define UWIRE_READ_FALLING_EDGE 0x0001
83#define UWIRE_READ_RISING_EDGE 0x0000
84#define UWIRE_WRITE_FALLING_EDGE 0x0000
85#define UWIRE_WRITE_RISING_EDGE 0x0002
86#define UWIRE_CS_ACTIVE_LOW 0x0000
87#define UWIRE_CS_ACTIVE_HIGH 0x0004
88#define UWIRE_FREQ_DIV_2 0x0000
89#define UWIRE_FREQ_DIV_4 0x0008
90#define UWIRE_FREQ_DIV_8 0x0010
91#define UWIRE_CHK_READY 0x0020
92#define UWIRE_CLK_INVERTED 0x0040
93
94
95struct uwire_spi {
96 struct spi_bitbang bitbang;
97 struct clk *ck;
98};
99
100struct uwire_state {
101 unsigned bits_per_word;
102 unsigned div1_idx;
103};
104
105/* REVISIT compile time constant for idx_shift? */
106static unsigned int uwire_idx_shift;
107
108static inline void uwire_write_reg(int idx, u16 val)
109{
110 __raw_writew(val, UWIRE_BASE + (idx << uwire_idx_shift));
111}
112
113static inline u16 uwire_read_reg(int idx)
114{
115 return __raw_readw(UWIRE_BASE + (idx << uwire_idx_shift));
116}
117
118static inline void omap_uwire_configure_mode(u8 cs, unsigned long flags)
119{
120 u16 w, val = 0;
121 int shift, reg;
122
123 if (flags & UWIRE_CLK_INVERTED)
124 val ^= 0x03;
125 val = flags & 0x3f;
126 if (cs & 1)
127 shift = 6;
128 else
129 shift = 0;
130 if (cs <= 1)
131 reg = UWIRE_SR1;
132 else
133 reg = UWIRE_SR2;
134
135 w = uwire_read_reg(reg);
136 w &= ~(0x3f << shift);
137 w |= val << shift;
138 uwire_write_reg(reg, w);
139}
140
141static int wait_uwire_csr_flag(u16 mask, u16 val, int might_not_catch)
142{
143 u16 w;
144 int c = 0;
145 unsigned long max_jiffies = jiffies + HZ;
146
147 for (;;) {
148 w = uwire_read_reg(UWIRE_CSR);
149 if ((w & mask) == val)
150 break;
151 if (time_after(jiffies, max_jiffies)) {
152 printk(KERN_ERR "%s: timeout. reg=%#06x "
153 "mask=%#06x val=%#06x\n",
154 __FUNCTION__, w, mask, val);
155 return -1;
156 }
157 c++;
158 if (might_not_catch && c > 64)
159 break;
160 }
161 return 0;
162}
163
164static void uwire_set_clk1_div(int div1_idx)
165{
166 u16 w;
167
168 w = uwire_read_reg(UWIRE_SR3);
169 w &= ~(0x03 << 1);
170 w |= div1_idx << 1;
171 uwire_write_reg(UWIRE_SR3, w);
172}
173
174static void uwire_chipselect(struct spi_device *spi, int value)
175{
176 struct uwire_state *ust = spi->controller_state;
177 u16 w;
178 int old_cs;
179
180
181 BUG_ON(wait_uwire_csr_flag(CSRB, 0, 0));
182
183 w = uwire_read_reg(UWIRE_CSR);
184 old_cs = (w >> 10) & 0x03;
185 if (value == BITBANG_CS_INACTIVE || old_cs != spi->chip_select) {
186 /* Deselect this CS, or the previous CS */
187 w &= ~CS_CMD;
188 uwire_write_reg(UWIRE_CSR, w);
189 }
190 /* activate specfied chipselect */
191 if (value == BITBANG_CS_ACTIVE) {
192 uwire_set_clk1_div(ust->div1_idx);
193 /* invert clock? */
194 if (spi->mode & SPI_CPOL)
195 uwire_write_reg(UWIRE_SR4, 1);
196 else
197 uwire_write_reg(UWIRE_SR4, 0);
198
199 w = spi->chip_select << 10;
200 w |= CS_CMD;
201 uwire_write_reg(UWIRE_CSR, w);
202 }
203}
204
205static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
206{
207 struct uwire_state *ust = spi->controller_state;
208 unsigned len = t->len;
209 unsigned bits = ust->bits_per_word;
210 unsigned bytes;
211 u16 val, w;
212 int status = 0;;
213
214 if (!t->tx_buf && !t->rx_buf)
215 return 0;
216
217 /* Microwire doesn't read and write concurrently */
218 if (t->tx_buf && t->rx_buf)
219 return -EPERM;
220
221 w = spi->chip_select << 10;
222 w |= CS_CMD;
223
224 if (t->tx_buf) {
225 const u8 *buf = t->tx_buf;
226
227 /* NOTE: DMA could be used for TX transfers */
228
229 /* write one or two bytes at a time */
230 while (len >= 1) {
231 /* tx bit 15 is first sent; we byteswap multibyte words
232 * (msb-first) on the way out from memory.
233 */
234 val = *buf++;
235 if (bits > 8) {
236 bytes = 2;
237 val |= *buf++ << 8;
238 } else
239 bytes = 1;
240 val <<= 16 - bits;
241
242#ifdef VERBOSE
243 pr_debug("%s: write-%d =%04x\n",
244 spi->dev.bus_id, bits, val);
245#endif
246 if (wait_uwire_csr_flag(CSRB, 0, 0))
247 goto eio;
248
249 uwire_write_reg(UWIRE_TDR, val);
250
251 /* start write */
252 val = START | w | (bits << 5);
253
254 uwire_write_reg(UWIRE_CSR, val);
255 len -= bytes;
256
257 /* Wait till write actually starts.
258 * This is needed with MPU clock 60+ MHz.
259 * REVISIT: we may not have time to catch it...
260 */
261 if (wait_uwire_csr_flag(CSRB, CSRB, 1))
262 goto eio;
263
264 status += bytes;
265 }
266
267 /* REVISIT: save this for later to get more i/o overlap */
268 if (wait_uwire_csr_flag(CSRB, 0, 0))
269 goto eio;
270
271 } else if (t->rx_buf) {
272 u8 *buf = t->rx_buf;
273
274 /* read one or two bytes at a time */
275 while (len) {
276 if (bits > 8) {
277 bytes = 2;
278 } else
279 bytes = 1;
280
281 /* start read */
282 val = START | w | (bits << 0);
283 uwire_write_reg(UWIRE_CSR, val);
284 len -= bytes;
285
286 /* Wait till read actually starts */
287 (void) wait_uwire_csr_flag(CSRB, CSRB, 1);
288
289 if (wait_uwire_csr_flag(RDRB | CSRB,
290 RDRB, 0))
291 goto eio;
292
293 /* rx bit 0 is last received; multibyte words will
294 * be properly byteswapped on the way to memory.
295 */
296 val = uwire_read_reg(UWIRE_RDR);
297 val &= (1 << bits) - 1;
298 *buf++ = (u8) val;
299 if (bytes == 2)
300 *buf++ = val >> 8;
301 status += bytes;
302#ifdef VERBOSE
303 pr_debug("%s: read-%d =%04x\n",
304 spi->dev.bus_id, bits, val);
305#endif
306
307 }
308 }
309 return status;
310eio:
311 return -EIO;
312}
313
314static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
315{
316 struct uwire_state *ust = spi->controller_state;
317 struct uwire_spi *uwire;
318 unsigned flags = 0;
319 unsigned bits;
320 unsigned hz;
321 unsigned long rate;
322 int div1_idx;
323 int div1;
324 int div2;
325 int status;
326
327 uwire = spi_master_get_devdata(spi->master);
328
329 if (spi->chip_select > 3) {
330 pr_debug("%s: cs%d?\n", spi->dev.bus_id, spi->chip_select);
331 status = -ENODEV;
332 goto done;
333 }
334
335 bits = spi->bits_per_word;
336 if (t != NULL && t->bits_per_word)
337 bits = t->bits_per_word;
338 if (!bits)
339 bits = 8;
340
341 if (bits > 16) {
342 pr_debug("%s: wordsize %d?\n", spi->dev.bus_id, bits);
343 status = -ENODEV;
344 goto done;
345 }
346 ust->bits_per_word = bits;
347
348 /* mode 0..3, clock inverted separately;
349 * standard nCS signaling;
350 * don't treat DI=high as "not ready"
351 */
352 if (spi->mode & SPI_CS_HIGH)
353 flags |= UWIRE_CS_ACTIVE_HIGH;
354
355 if (spi->mode & SPI_CPOL)
356 flags |= UWIRE_CLK_INVERTED;
357
358 switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
359 case SPI_MODE_0:
360 case SPI_MODE_3:
361 flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE;
362 break;
363 case SPI_MODE_1:
364 case SPI_MODE_2:
365 flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE;
366 break;
367 }
368
369 /* assume it's already enabled */
370 rate = clk_get_rate(uwire->ck);
371
372 hz = spi->max_speed_hz;
373 if (t != NULL && t->speed_hz)
374 hz = t->speed_hz;
375
376 if (!hz) {
377 pr_debug("%s: zero speed?\n", spi->dev.bus_id);
378 status = -EINVAL;
379 goto done;
380 }
381
382 /* F_INT = mpu_xor_clk / DIV1 */
383 for (div1_idx = 0; div1_idx < 4; div1_idx++) {
384 switch (div1_idx) {
385 case 0:
386 div1 = 2;
387 break;
388 case 1:
389 div1 = 4;
390 break;
391 case 2:
392 div1 = 7;
393 break;
394 default:
395 case 3:
396 div1 = 10;
397 break;
398 }
399 div2 = (rate / div1 + hz - 1) / hz;
400 if (div2 <= 8)
401 break;
402 }
403 if (div1_idx == 4) {
404 pr_debug("%s: lowest clock %ld, need %d\n",
405 spi->dev.bus_id, rate / 10 / 8, hz);
406 status = -EDOM;
407 goto done;
408 }
409
410 /* we have to cache this and reset in uwire_chipselect as this is a
411 * global parameter and another uwire device can change it under
412 * us */
413 ust->div1_idx = div1_idx;
414 uwire_set_clk1_div(div1_idx);
415
416 rate /= div1;
417
418 switch (div2) {
419 case 0:
420 case 1:
421 case 2:
422 flags |= UWIRE_FREQ_DIV_2;
423 rate /= 2;
424 break;
425 case 3:
426 case 4:
427 flags |= UWIRE_FREQ_DIV_4;
428 rate /= 4;
429 break;
430 case 5:
431 case 6:
432 case 7:
433 case 8:
434 flags |= UWIRE_FREQ_DIV_8;
435 rate /= 8;
436 break;
437 }
438 omap_uwire_configure_mode(spi->chip_select, flags);
439 pr_debug("%s: uwire flags %02x, armxor %lu KHz, SCK %lu KHz\n",
440 __FUNCTION__, flags,
441 clk_get_rate(uwire->ck) / 1000,
442 rate / 1000);
443 status = 0;
444done:
445 return status;
446}
447
448static int uwire_setup(struct spi_device *spi)
449{
450 struct uwire_state *ust = spi->controller_state;
451
452 if (ust == NULL) {
453 ust = kzalloc(sizeof(*ust), GFP_KERNEL);
454 if (ust == NULL)
455 return -ENOMEM;
456 spi->controller_state = ust;
457 }
458
459 return uwire_setup_transfer(spi, NULL);
460}
461
462static void uwire_cleanup(const struct spi_device *spi)
463{
464 kfree(spi->controller_state);
465}
466
467static void uwire_off(struct uwire_spi *uwire)
468{
469 uwire_write_reg(UWIRE_SR3, 0);
470 clk_disable(uwire->ck);
471 clk_put(uwire->ck);
472 spi_master_put(uwire->bitbang.master);
473}
474
475static int uwire_probe(struct platform_device *pdev)
476{
477 struct spi_master *master;
478 struct uwire_spi *uwire;
479 int status;
480
481 master = spi_alloc_master(&pdev->dev, sizeof *uwire);
482 if (!master)
483 return -ENODEV;
484
485 uwire = spi_master_get_devdata(master);
486 dev_set_drvdata(&pdev->dev, uwire);
487
488 uwire->ck = clk_get(&pdev->dev, "armxor_ck");
489 if (!uwire->ck || IS_ERR(uwire->ck)) {
490 dev_dbg(&pdev->dev, "no mpu_xor_clk ?\n");
491 spi_master_put(master);
492 return -ENODEV;
493 }
494 clk_enable(uwire->ck);
495
496 if (cpu_is_omap730())
497 uwire_idx_shift = 1;
498 else
499 uwire_idx_shift = 2;
500
501 uwire_write_reg(UWIRE_SR3, 1);
502
503 master->bus_num = 2; /* "official" */
504 master->num_chipselect = 4;
505 master->setup = uwire_setup;
506 master->cleanup = uwire_cleanup;
507
508 uwire->bitbang.master = master;
509 uwire->bitbang.chipselect = uwire_chipselect;
510 uwire->bitbang.setup_transfer = uwire_setup_transfer;
511 uwire->bitbang.txrx_bufs = uwire_txrx;
512
513 status = spi_bitbang_start(&uwire->bitbang);
514 if (status < 0)
515 uwire_off(uwire);
516 return status;
517}
518
519static int uwire_remove(struct platform_device *pdev)
520{
521 struct uwire_spi *uwire = dev_get_drvdata(&pdev->dev);
522 int status;
523
524 // FIXME remove all child devices, somewhere ...
525
526 status = spi_bitbang_stop(&uwire->bitbang);
527 uwire_off(uwire);
528 return status;
529}
530
531static struct platform_driver uwire_driver = {
532 .driver = {
533 .name = "omap_uwire",
534 .bus = &platform_bus_type,
535 .owner = THIS_MODULE,
536 },
537 .probe = uwire_probe,
538 .remove = uwire_remove,
539 // suspend ... unuse ck
540 // resume ... use ck
541};
542
543static int __init omap_uwire_init(void)
544{
545 /* FIXME move these into the relevant board init code. also, include
546 * H3 support; it uses tsc2101 like H2 (on a different chipselect).
547 */
548
549 if (machine_is_omap_h2()) {
550 /* defaults: W21 SDO, U18 SDI, V19 SCL */
551 omap_cfg_reg(N14_1610_UWIRE_CS0);
552 omap_cfg_reg(N15_1610_UWIRE_CS1);
553 }
554 if (machine_is_omap_perseus2()) {
555 /* configure pins: MPU_UW_nSCS1, MPU_UW_SDO, MPU_UW_SCLK */
556 int val = omap_readl(OMAP730_IO_CONF_9) & ~0x00EEE000;
557 omap_writel(val | 0x00AAA000, OMAP730_IO_CONF_9);
558 }
559
560 return platform_driver_register(&uwire_driver);
561}
562
563static void __exit omap_uwire_exit(void)
564{
565 platform_driver_unregister(&uwire_driver);
566}
567
568subsys_initcall(omap_uwire_init);
569module_exit(omap_uwire_exit);
570
571MODULE_LICENSE("GPL");
572