1 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
2 index c7ad324..daa2e0a 100644
5 @@ -998,7 +998,7 @@ config CPU_FREQ_SA1100
9 - depends on CPU_FREQ && (SA1100_ASSABET || SA1100_CERF || SA1100_PT_SYSTEM3)
10 + depends on CPU_FREQ && (SA1100_ASSABET || SA1100_CERF || SA1100_PT_SYSTEM3 || SA1100_COLLIE)
13 config CPU_FREQ_INTEGRATOR
14 diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c
15 index e508028..36f726c 100644
16 --- a/arch/arm/mach-sa1100/dma.c
17 +++ b/arch/arm/mach-sa1100/dma.c
18 @@ -39,7 +39,7 @@ typedef struct {
20 static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS];
22 -static spinlock_t dma_list_lock;
23 +static DEFINE_SPINLOCK(dma_list_lock);
26 static irqreturn_t dma_irq_handler(int irq, void *dev_id)
27 diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
28 index 9caed30..79e19bf 100644
29 --- a/drivers/input/keyboard/locomokbd.c
30 +++ b/drivers/input/keyboard/locomokbd.c
31 @@ -265,6 +265,7 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev)
32 for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
33 set_bit(locomokbd->keycode[i], input_dev->keybit);
34 clear_bit(0, input_dev->keybit);
35 + locomo_writel(0, locomokbd->base + LOCOMO_KSC);
37 /* attempt to get the interrupt */
38 err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
39 diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
40 index 9f93c29..33fc5d6 100644
41 --- a/drivers/mfd/Kconfig
42 +++ b/drivers/mfd/Kconfig
43 @@ -72,4 +72,10 @@ config MCP_UCB1200_TS
44 tristate "Touchscreen interface support"
45 depends on MCP_UCB1200 && INPUT
48 + tristate "Touchscreen collie support"
49 + depends on MCP_UCB1200 && INPUT && !MCP_UCB1200_TS
51 + Driver for touchscreen on collie - sharp sl-5500.
54 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
55 index 33daa2f..0885ccd 100644
56 --- a/drivers/mfd/Makefile
57 +++ b/drivers/mfd/Makefile
58 @@ -16,7 +16,7 @@ obj-$(CONFIG_MCP) += mcp-core.o
59 obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
60 obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
61 obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
63 +obj-$(CONFIG_MCP_COLLIE_TS) += collie-ts.o
64 ifeq ($(CONFIG_SA1100_ASSABET),y)
65 obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
67 diff --git a/drivers/mfd/collie-ts.c b/drivers/mfd/collie-ts.c
69 index 0000000..ddde5fc
71 +++ b/drivers/mfd/collie-ts.c
74 + * Touchscreen driver for UCB1x00-based touchscreens
76 + * Copyright (C) 2001 Russell King, All Rights Reserved.
77 + * Copyright (C) 2005 Pavel Machek
79 + * This program is free software; you can redistribute it and/or modify
80 + * it under the terms of the GNU General Public License version 2 as
81 + * published by the Free Software Foundation.
83 + * 21-Jan-2002 <jco@ict.es> :
85 + * Added support for synchronous A/D mode. This mode is useful to
86 + * avoid noise induced in the touchpanel by the LCD, provided that
87 + * the UCB1x00 has a valid LCD sync signal routed to its ADCSYNC pin.
88 + * It is important to note that the signal connected to the ADCSYNC
89 + * pin should provide pulses even when the LCD is blanked, otherwise
90 + * a pen touch needed to unblank the LCD will never be read.
92 +#include <linux/module.h>
93 +#include <linux/moduleparam.h>
94 +#include <linux/init.h>
95 +#include <linux/smp.h>
96 +#include <linux/smp_lock.h>
97 +#include <linux/sched.h>
98 +#include <linux/completion.h>
99 +#include <linux/delay.h>
100 +#include <linux/string.h>
101 +#include <linux/input.h>
102 +#include <linux/device.h>
103 +#include <linux/freezer.h>
104 +#include <linux/slab.h>
105 +#include <linux/kthread.h>
107 +#include <asm/dma.h>
108 +#include <asm/semaphore.h>
109 +#include <asm/arch/collie.h>
110 +#include <asm/mach-types.h>
112 +#include "ucb1x00.h"
115 + struct input_dev *idev;
116 + struct ucb1x00 *ucb;
118 + wait_queue_head_t irq_wait;
119 + struct task_struct *rtask;
123 + unsigned int adcsync:1;
128 +/**********************************
147 +**********************************/
150 +static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
152 + struct input_dev *idev = ts->idev;
154 + input_report_abs(idev, ABS_X, x);
155 + input_report_abs(idev, ABS_Y, y);
156 + input_report_abs(idev, ABS_PRESSURE, pressure);
157 + input_report_key(idev, BTN_TOUCH, 1);
161 +static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
163 + struct input_dev *idev = ts->idev;
165 + input_report_abs(idev, ABS_PRESSURE, 0);
166 + input_report_key(idev, BTN_TOUCH, 0);
171 + * Switch to interrupt mode. This set touchscreen to interrupt
172 + * mode, so that chip is able to send interrupt.
174 +static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
176 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
177 + UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
178 + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
179 + UCB_TS_CR_MODE_INT);
183 + * Switch to pressure mode, and read pressure. We don't need to wait
184 + * here, since both plates are being driven.
186 + * set_read_pressure() in sharp code
188 +static inline void ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
190 + ucb1x00_io_write(ts->ucb, COLLIE_TC35143_GPIO_TBL_CHK, 0);
191 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
192 + UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMX_POW |
193 + UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
195 + ucb1x00_reg_write(ts->ucb, UCB_ADC_CR, ts->ucb->adc_cr |
199 + ucb1x00_reg_write(ts->ucb, UCB_ADC_CR, ts->ucb->adc_cr |
201 + UCB_ADC_SYNC_ENA | UCB_ADC_START);
205 + * Switch to X position mode and measure Y plate. We switch the plate
206 + * configuration in pressure mode, then switch to position mode. This
207 + * gives a faster response time. Even so, we need to wait about 55us
208 + * for things to stabilise.
210 +static inline void ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
212 + ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
213 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
214 + UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
215 + UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
218 + ucb1x00_reg_write(ts->ucb, UCB_ADC_CR, ts->ucb->adc_cr |
219 + UCB_ADC_INP_TSPY | UCB_ADC_SYNC_ENA);
221 + ucb1x00_reg_write(ts->ucb, UCB_ADC_CR, ts->ucb->adc_cr |
222 + UCB_ADC_INP_TSPY | UCB_ADC_SYNC_ENA |
227 + * Switch to Y position mode and measure X plate. We switch the plate
228 + * configuration in pressure mode, then switch to position mode. This
229 + * gives a faster response time. Even so, we need to wait about 55us
230 + * for things to stabilise.
232 +static inline void ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
234 + ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
236 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
237 + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
238 + UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
241 + ucb1x00_reg_write(ts->ucb, UCB_ADC_CR, ts->ucb->adc_cr |
242 + UCB_ADC_INP_TSPX | UCB_ADC_SYNC_ENA);
244 + ucb1x00_reg_write(ts->ucb, UCB_ADC_CR, ts->ucb->adc_cr |
245 + UCB_ADC_INP_TSPX | UCB_ADC_SYNC_ENA |
250 + * Switch to X plate resistance mode. Set MX to ground, PX to
251 + * supply. Measure current.
253 +static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts)
255 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
256 + UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
257 + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
258 + return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
262 + * Switch to Y plate resistance mode. Set MY to ground, PY to
263 + * supply. Measure current.
265 +static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
267 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
268 + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
269 + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
270 + return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
274 + * This is a RT kernel thread that handles the ADC accesses
275 + * (mainly so we can use semaphores in the UCB1200 core code
276 + * to serialise accesses to the ADC).
278 +static int ucb1x00_thread(void *_ts)
280 + struct ucb1x00_ts *ts = _ts;
281 + struct task_struct *tsk = current;
282 + DECLARE_WAITQUEUE(wait, tsk);
286 + * We could run as a real-time thread. However, thus far
287 + * this doesn't seem to be necessary.
290 + add_wait_queue(&ts->irq_wait, &wait);
292 + while (!kthread_should_stop()) {
293 + unsigned int data[3];
295 + for (state=0; state<3; state++) {
297 + ucb1x00_adc_enable(ts->ucb);
298 + ucb1x00_enable_irq(ts->ucb, UCB_IRQ_ADC, UCB_FALLING);
300 + /* Order matters here; last measurement seems to be more noisy then the
301 + rest, and we care about pressure least */
302 + case 2: ucb1x00_ts_read_pressure(ts);
304 + case 0: ucb1x00_ts_read_ypos(ts);
306 + case 1: ucb1x00_ts_read_xpos(ts);
311 + schedule_timeout(1000 * HZ);
312 + ucb1x00_disable_irq(ts->ucb, UCB_IRQ_ADC, UCB_FALLING);
313 + data[state] = UCB_ADC_DAT(ucb1x00_reg_read(ts->ucb, UCB_ADC_DATA));
314 + ucb1x00_adc_disable(ts->ucb);
317 + /* If not pressed any more, try to sleep! */
318 + if (data[2] < 300) {
319 + set_task_state(tsk, TASK_INTERRUPTIBLE);
320 + ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_RISING);
321 + ucb1x00_ts_mode_int(ts);
322 + ucb1x00_disable(ts->ucb);
323 + ucb1x00_ts_event_release(ts);
325 + schedule_timeout(1000 * HZ);
326 + ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_RISING);
327 + ucb1x00_enable(ts->ucb);
329 + ucb1x00_ts_evt_add(ts, data[2], data[1], data[0]);
331 + ucb1x00_disable(ts->ucb);
333 + ucb1x00_enable(ts->ucb);
336 + remove_wait_queue(&ts->irq_wait, &wait);
343 + * We only detect touch screen _touches_ with this interrupt
344 + * handler, and even then we just schedule our task.
346 +static void ucb1x00_ts_irq(int idx, void *id)
348 + struct ucb1x00_ts *ts = id;
349 + wake_up(&ts->irq_wait);
352 +static void ucb1x00_adc_irq(int idx, void *id)
354 + struct ucb1x00_ts *ts = id;
355 + wake_up(&ts->irq_wait);
358 +static int ucb1x00_ts_open(struct input_dev *idev)
360 + struct ucb1x00_ts *ts = input_get_drvdata(idev);
365 + init_waitqueue_head(&ts->irq_wait);
367 + ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
371 + ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_ADC, ucb1x00_adc_irq, ts);
373 + ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
377 + ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_RISING);
380 + * If we do this at all, we should allow the user to
381 + * measure and read the X and Y resistance at any time.
383 + ucb1x00_adc_enable(ts->ucb);
384 + ts->x_res = ucb1x00_ts_read_xres(ts);
385 + ts->y_res = ucb1x00_ts_read_yres(ts);
386 + ucb1x00_adc_disable(ts->ucb);
388 + if (machine_is_collie()) {
389 + ucb1x00_io_set_dir(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
392 + ts->rtask = kthread_run(ucb1x00_thread, ts, "ktsd");
393 + if (!IS_ERR(ts->rtask)) {
396 + ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
405 + * Release touchscreen resources. Disable IRQs.
407 +static void ucb1x00_ts_close(struct input_dev *idev)
409 + struct ucb1x00_ts *ts = input_get_drvdata(idev);
412 + kthread_stop(ts->rtask);
414 + ucb1x00_enable(ts->ucb);
415 + ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
416 + ucb1x00_free_irq(ts->ucb, UCB_IRQ_ADC, ts);
417 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0);
418 + ucb1x00_disable(ts->ucb);
422 +static int ucb1x00_ts_resume(struct ucb1x00_dev *dev)
424 + struct ucb1x00_ts *ts = dev->priv;
426 + if (ts->rtask != NULL) {
428 + * Restart the TS thread to ensure the
429 + * TS interrupt mode is set up again
432 + wake_up(&ts->irq_wait);
437 +#define ucb1x00_ts_resume NULL
444 +static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
446 + struct ucb1x00_ts *ts;
447 + struct input_dev *idev;
450 + ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
451 + idev = input_allocate_device();
452 + if (!ts || !idev) {
457 + ts->ucb = dev->ucb;
459 + ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
461 + input_set_drvdata(idev, ts);
462 + idev->name = "Touchscreen panel";
463 + idev->id.product = ts->ucb->id;
464 + idev->open = ucb1x00_ts_open;
465 + idev->close = ucb1x00_ts_close;
467 + __set_bit(EV_ABS, idev->evbit);
468 + __set_bit(ABS_X, idev->absbit);
469 + __set_bit(ABS_Y, idev->absbit);
470 + __set_bit(ABS_PRESSURE, idev->absbit);
472 + input_set_abs_params(ts->idev, ABS_X, 0, 450, 0, 0);
473 + input_set_abs_params(ts->idev, ABS_Y, 200, 800, 0, 0);
474 + input_set_abs_params(ts->idev, ABS_PRESSURE, 400, 800, 0, 0);
477 + err = input_register_device(idev);
486 + input_free_device(idev);
491 +static void ucb1x00_ts_remove(struct ucb1x00_dev *dev)
493 + struct ucb1x00_ts *ts = dev->priv;
495 + input_unregister_device(ts->idev);
499 +static struct ucb1x00_driver ucb1x00_ts_driver = {
500 + .add = ucb1x00_ts_add,
501 + .remove = ucb1x00_ts_remove,
502 + .resume = ucb1x00_ts_resume,
505 +static int __init ucb1x00_ts_init(void)
507 + return ucb1x00_register_driver(&ucb1x00_ts_driver);
510 +static void __exit ucb1x00_ts_exit(void)
512 + ucb1x00_unregister_driver(&ucb1x00_ts_driver);
515 +module_param(adcsync, int, 0444);
516 +module_init(ucb1x00_ts_init);
517 +module_exit(ucb1x00_ts_exit);
519 +MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
520 +MODULE_DESCRIPTION("UCB1x00 touchscreen driver");
521 +MODULE_LICENSE("GPL");
522 diff --git a/drivers/mfd/ucb1x00.h b/drivers/mfd/ucb1x00.h
523 index a8ad8a0..137b043 100644
524 --- a/drivers/mfd/ucb1x00.h
525 +++ b/drivers/mfd/ucb1x00.h
527 #define UCB_IE_TCLIP (1 << 14)
528 #define UCB_IE_ACLIP (1 << 15)
531 +#define UCB_IRQ_ADC 11
532 #define UCB_IRQ_TSPX 12
533 +#define UCB_IRQ_TSMX 13
535 #define UCB_TC_A 0x05
536 #define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
537 diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
538 index c7d5a52..215bec2 100644
539 --- a/drivers/mtd/maps/sa1100-flash.c
540 +++ b/drivers/mtd/maps/sa1100-flash.c
541 @@ -210,6 +210,12 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r
544 subdev->mtd->owner = THIS_MODULE;
546 +#ifdef CONFIG_SA1100_COLLIE
547 + /* collie flash starts locked */
548 + if (subdev->mtd->unlock)
549 + subdev->mtd->unlock(subdev->mtd, 0xc0000, subdev->mtd->size - 0xc0000);
552 printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, "
553 "%d-bit\n", phys, subdev->mtd->size >> 20,
554 diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
555 index 3b4e55c..0ae741d 100644
556 --- a/drivers/net/wireless/hostap/hostap_cs.c
557 +++ b/drivers/net/wireless/hostap/hostap_cs.c
558 @@ -35,7 +35,7 @@ static int ignore_cis_vcc;
559 module_param(ignore_cis_vcc, int, 0444);
560 MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
564 /* struct local_info::hw_priv */
565 struct hostap_cs_priv {
567 @@ -499,11 +499,13 @@ static int hostap_cs_probe(struct pcmcia_device *p_dev)
569 PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info);
570 p_dev->conf.IntType = INT_MEMORY_AND_IO;
574 ret = prism2_config(p_dev);
576 PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
582 diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
583 index 13d5882..6f24d66 100644
584 --- a/drivers/net/wireless/hostap/hostap_hw.c
585 +++ b/drivers/net/wireless/hostap/hostap_hw.c
588 #include "hostap_ap.h"
592 /* #define final_version */
594 @@ -1497,6 +1498,8 @@ static int prism2_hw_config(struct net_device *dev, int initial)
595 if (local->hw_downloading)
600 if (prism2_hw_init(dev, initial)) {
601 return local->no_pri ? 0 : 1;
603 @@ -2628,8 +2631,15 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id)
607 - iface = netdev_priv(dev);
608 - local = iface->local;
610 + // Todos los parametros de entrada son correctos (no son nulos). De momento esta es la unica forma que conozco de detectar el problema.
612 + printk("hostap_hw.c: INTERRUPT BEFORE DEVICE INIT!\n");
613 + return IRQ_HANDLED;
616 + iface = netdev_priv(dev);
617 + local = iface->local;
619 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0);
621 diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
622 index 3a874fc..df58aa3 100644
623 --- a/drivers/net/wireless/hostap/hostap_pci.c
624 +++ b/drivers/net/wireless/hostap/hostap_pci.c
627 #include "hostap_wlan.h"
631 static char *dev_info = "hostap_pci";
633 diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
634 index cbf15d7..4475174 100644
635 --- a/drivers/net/wireless/hostap/hostap_plx.c
636 +++ b/drivers/net/wireless/hostap/hostap_plx.c
640 #include "hostap_wlan.h"
644 static char *dev_info = "hostap_plx";
646 diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
647 index c5b2a44..eecbe8c 100644
648 --- a/drivers/pcmcia/sa1100_generic.c
649 +++ b/drivers/pcmcia/sa1100_generic.c
650 @@ -81,13 +81,14 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
654 -static struct device_driver sa11x0_pcmcia_driver = {
655 - .probe = sa11x0_drv_pcmcia_probe,
656 - .remove = soc_common_drv_pcmcia_remove,
657 - .name = "sa11x0-pcmcia",
658 - .bus = &platform_bus_type,
659 - .suspend = pcmcia_socket_dev_suspend,
660 - .resume = pcmcia_socket_dev_resume,
661 +static struct platform_driver sa11x0_pcmcia_driver = {
663 + .name = "sa11x0-pcmcia",
664 + .probe = sa11x0_drv_pcmcia_probe,
665 + .remove = soc_common_drv_pcmcia_remove,
666 + .suspend= pcmcia_socket_dev_suspend,
667 + .resume = pcmcia_socket_dev_resume,
671 /* sa11x0_pcmcia_init()
672 @@ -100,7 +101,7 @@ static struct device_driver sa11x0_pcmcia_driver = {
674 static int __init sa11x0_pcmcia_init(void)
676 - return driver_register(&sa11x0_pcmcia_driver);
677 + return platform_driver_register(&sa11x0_pcmcia_driver);
680 /* sa11x0_pcmcia_exit()
681 @@ -110,7 +111,7 @@ static int __init sa11x0_pcmcia_init(void)
683 static void __exit sa11x0_pcmcia_exit(void)
685 - driver_unregister(&sa11x0_pcmcia_driver);
686 + platform_driver_unregister(&sa11x0_pcmcia_driver);
689 MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
690 diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
691 index 66ec5d8..aba38d7 100644
692 --- a/drivers/spi/Kconfig
693 +++ b/drivers/spi/Kconfig
694 @@ -123,6 +123,10 @@ config SPI_MPC52xx_PSC
695 This enables using the Freescale MPC52xx Programmable Serial
696 Controller in master SPI mode.
699 + tristate "Locomo SPI master"
700 + depends on SPI_MASTER && SHARP_LOCOMO && EXPERIMENTAL
703 tristate "Freescale MPC83xx/QUICC Engine SPI controller"
704 depends on SPI_MASTER && (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL
705 diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
706 index 7fca043..b89992b 100644
707 --- a/drivers/spi/Makefile
708 +++ b/drivers/spi/Makefile
709 @@ -28,6 +28,7 @@ obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
710 obj-$(CONFIG_SPI_TXX9) += spi_txx9.o
711 obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o
712 obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o
713 +obj-$(CONFIG_SPI_LOCOMO) += locomo_spi.o
714 # ... add above this line ...
716 # SPI protocol drivers (device/link on bus)
717 diff --git a/drivers/spi/locomo_spi.c b/drivers/spi/locomo_spi.c
719 index 0000000..d3a4bd9
721 +++ b/drivers/spi/locomo_spi.c
724 +#include <asm/irq.h>
725 +#include <linux/module.h>
726 +#include <linux/init.h>
727 +#include <linux/device.h>
728 +#include <linux/stat.h>
729 +#include <linux/delay.h>
730 +#include <linux/wait.h>
731 +#include <linux/interrupt.h>
732 +#include <asm/hardware/locomo.h>
733 +#include <asm/errno.h>
734 +#include <linux/mmc/host.h>
735 +#include <linux/spi/spi.h>
736 +#include <linux/spi/mmc_spi.h>
737 +#include <linux/workqueue.h>
738 +#include <linux/spinlock.h>
739 +#include <linux/list.h>
740 +#include "locomo_spi.h"
741 +static struct locomospi_dev * spidev;
742 +static struct work_struct transfer_wq;
745 +char* transtxbuf=(char*)NULL;
746 +char* transrxbuf=(char*)NULL;
747 +int transfercount=0, transfersize=0;
748 +static DECLARE_WAIT_QUEUE_HEAD(transferqueue);
749 +/* MMC_SPI functions *********************************************************/
751 +static int locomommcspi_init(struct device *dev, irqreturn_t (*isr)(int, void*), void *mmc)
754 + result=request_irq(IRQ_LOCOMO_CARDDETECT, isr, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "locomo-spi", mmc);
758 +static void locomommcspi_exit(struct device *dev, void* mmc)
760 + free_irq(IRQ_LOCOMO_CARDDETECT, mmc);
763 +static int locomommcspi_getro(struct device *dev)
765 + return locomo_gpio_read_level(spidev->ldev->dev.parent,LOCOMO_GPIO_WRITE_PROT) > 0 ? 1 : 0;
768 +static void locomommcspi_setpower(struct device *dev, unsigned int mask)
770 + if(!mask && spidev->card_power)
771 + locomospi_power(0);
772 + else if( !spidev->card_power )
773 + locomospi_power(1);
778 +static struct mmc_spi_platform_data colliemmc ={
779 + .init = locomommcspi_init,
780 + .exit = locomommcspi_exit,
781 + .detect_delay = 200,
782 + .get_ro = locomommcspi_getro,
783 + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
784 + .setpower = locomommcspi_setpower,
785 + .powerup_msecs = 200,
788 +/* Utility function **********************************************************/
790 +static void locomospi_power(int on)
792 + locomo_gpio_write(spidev->ldev->dev.parent, LOCOMO_GPIO_CARD_POWER, on);
793 + spidev->card_power=on;
794 + printk(KERN_DEBUG "locomospi: power %d\n",on);
797 +static void locomospi_setclock(unsigned int div, unsigned int clock)
799 + u16 r = ioread16(spidev->base+LOCOMO_SPIMD);
802 + if(clock != spidev->clock_base || div != spidev->clock_div){
803 + r &= ~(LOCOMO_SPI_XSEL | LOCOMO_SPI_CLKSEL | LOCOMO_SPI_XEN);
804 + iowrite16(r,spidev->base+LOCOMO_SPIMD);
805 + r |= (div | (clock <<3) | LOCOMO_SPI_XEN);
806 + iowrite16(r,spidev->base+LOCOMO_SPIMD);
807 + spidev->clock_div = div;
808 + spidev->clock_base = clock;
813 +// returns 1 if card ist present, 0 otherwise
814 +static int locomospi_carddetect()
816 + return (locomo_gpio_read_level(spidev->ldev->dev.parent,LOCOMO_GPIO_CARD_DETECT)>0)?0:1;
819 +static void locomospi_setcs(int high)
822 + printk(KERN_DEBUG "locomospi: cs %d\n",high);
823 + r = ioread16(spidev->base + LOCOMO_SPICT);
825 + r |= LOCOMO_SPI_CS;
827 + r &= ~LOCOMO_SPI_CS;
828 + iowrite16(r, spidev->base + LOCOMO_SPICT);
831 +static void locomospi_reg_open()
834 + spidev->clock_div = DIV_64;
835 + spidev->clock_base = CLOCK_18MHZ;
836 + locomospi_power(1);
838 +// iowrite16( 0xec00 | (CLOCK_18MHZ <<3)|DIV_64, spidev->base+LOCOMO_SPIMD);
839 + iowrite16( LOCOMO_SPI_MSB1ST | LOCOMO_SPI_DOSTAT | LOCOMO_SPI_RCPOL | LOCOMO_SPI_TCPOL
840 + |(CLOCK_18MHZ <<3) | DIV_64, spidev->base+LOCOMO_SPIMD);
841 +// if(locomospi_carddetect()){
842 + r = ioread16(spidev->base+LOCOMO_SPIMD);
843 + r |= LOCOMO_SPI_XON;
844 + iowrite16( r, spidev->base+LOCOMO_SPIMD);
845 + r = ioread16(spidev->base+LOCOMO_SPIMD);
846 + r |= LOCOMO_SPI_XEN;
847 + iowrite16( r, spidev->base+LOCOMO_SPIMD);
849 + iowrite16( LOCOMO_SPI_CS, spidev->base+LOCOMO_SPICT);
850 + r = ioread16(spidev->base+LOCOMO_SPICT);
851 + r |= (LOCOMO_SPI_CEN | LOCOMO_SPI_RXUEN | LOCOMO_SPI_ALIGNEN);
852 + iowrite16( r, spidev->base+LOCOMO_SPICT);
854 + r = ioread16(spidev->base+LOCOMO_SPICT);
855 + iowrite16(r, spidev->base+LOCOMO_SPICT);
856 + r = ioread16(spidev->base+LOCOMO_SPICT);
857 + r &= ~LOCOMO_SPI_CS;
858 + iowrite16(r, spidev->base+LOCOMO_SPICT);
861 +static void locomospi_reg_release()
864 + r = ioread16(spidev->base+LOCOMO_SPICT);
865 + r &= ~LOCOMO_SPI_CEN;
866 + iowrite16(r, spidev->base+LOCOMO_SPICT);
867 + r = ioread16(spidev->base+LOCOMO_SPIMD);
868 + r &= ~LOCOMO_SPI_XEN;
869 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
870 + r = ioread16(spidev->base+LOCOMO_SPIMD);
871 + r &= ~LOCOMO_SPI_XON;
872 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
873 + r = ioread16(spidev->base+LOCOMO_SPICT);
874 + r |= LOCOMO_SPI_XEN;
875 + iowrite16(r, spidev->base+LOCOMO_SPICT);
876 + locomospi_power(0);
879 +static int txrx(const char* txbuffer, char* rxbuffer, int size)
881 + u16 r = ioread16(spidev->base+LOCOMO_SPICT);
882 + r |= LOCOMO_SPI_ALIGNEN;
883 + iowrite16(r, spidev->base+LOCOMO_SPICT);
884 + printk(KERN_DEBUG "locomospi: %d bytes to prozess\n",size);
885 + /* initialize global vars for isr */
886 + transfercount=0; transfersize=size;
887 + transtxbuf=txbuffer; transrxbuf=rxbuffer;
889 + /* start transmit and go sleep isr will wake us*/
890 + enable_irq(IRQ_LOCOMO_SPI_TEND);
891 + iowrite8(txbuffer[0], spidev->base+LOCOMO_SPITD);
892 + wait_event(transferqueue, transfercount >= transfersize);
893 + disable_irq(IRQ_LOCOMO_SPI_TEND);
894 + transrxbuf=NULL; transtxbuf=NULL;
896 + r = ioread16(spidev->base+LOCOMO_SPICT);
897 + r &= ~LOCOMO_SPI_ALIGNEN;
898 + iowrite16(r, spidev->base+LOCOMO_SPICT);
900 + for(i=0; i< size; i++)
901 + printk(KERN_DEBUG "locomospi: sent: %x received: %x \n",txbuffer[i], rxbuffer[i]);
908 +static int tx(const char* txbuffer, int size)
910 + printk(KERN_DEBUG "locomospi: %d bytes to send\n",size);
911 + /* initialize global vars for isr */
912 + transfercount=0; transfersize=size;
913 + transtxbuf=txbuffer;
915 + /* start transmit and go sleep isr will wake us*/
916 + enable_irq(IRQ_LOCOMO_SPI_RFW);
917 + iowrite8(txbuffer[0], spidev->base+LOCOMO_SPITD);
918 + wait_event(transferqueue, transfercount >= transfersize);
919 + disable_irq(IRQ_LOCOMO_SPI_RFW);
923 + for(i=0; i< size; i++)
924 + printk(KERN_DEBUG "locomospi: sent: %x\n",txbuffer[i]);
930 +static int rx(char* rxbuffer, int size)
932 + printk(KERN_DEBUG "locomospi: %d bytes to read\n",size);
933 + /* initialize global vars for isr */
934 + transfercount=0; transfersize=size;
935 + transrxbuf=rxbuffer;
937 + /* start transmit and go sleep isr will wake us*/
938 + enable_irq(IRQ_LOCOMO_SPI_RFR);
939 + rxbuffer[0]=ioread8(spidev->base+LOCOMO_SPIRD);
940 + wait_event(transferqueue, transfercount >= transfersize);
941 + disable_irq(IRQ_LOCOMO_SPI_RFR);
945 + for(i=0; i< size; i++)
946 + printk(KERN_DEBUG "locomospi: received: %x \n", rxbuffer[i]);
953 +static int txrx(const char* txbuffer, char* rxbuffer, int size)
958 +/* char * txback = kmalloc(size * sizeof(char), GFP_KERNEL);
959 + memcpy(txback, txbuffer, size);
961 + if(spidev->clock_div == 4)
966 +// printk(KERN_DEBUG "locomospi: txrx %d bytes to prozess\n",size);
968 +// r = ioread16(spidev->base+LOCOMO_SPICT);
969 +// r |= LOCOMO_SPI_ALIGNEN;
970 +// iowrite16(r, spidev->base+LOCOMO_SPICT);
971 + //discard first bogus byte
973 + ioread8(spidev->base+LOCOMO_SPIRD);
974 + for(i=0; i<size; i++){
975 + for(j=0; j <= wait; j++){
976 + if(ioread16(spidev->base+LOCOMO_SPIST) & LOCOMO_SPI_RFW)
979 + iowrite8(txbuffer[i], spidev->base+LOCOMO_SPITD);
982 + for(j=0; j <= wait; j++){
983 + if(ioread16(spidev->base+LOCOMO_SPIST) & LOCOMO_SPI_RFR)
986 + rxbuffer[i] = ioread8(spidev->base+LOCOMO_SPIRD);
989 +// r = ioread16(spidev->base+LOCOMO_SPICT);
990 +// r &= ~LOCOMO_SPI_ALIGNEN;
991 +// iowrite16(r, spidev->base+LOCOMO_SPICT);
993 +/* for(j=0; j< size; j++)
994 + printk(KERN_DEBUG "locomospi: sent: %x received: %x \n",txback[j], rxbuffer[j]);
1000 +static int tx(const char* buffer, int size)
1005 + if(spidev->clock_div == 4)
1009 + r = ioread16(spidev->base+LOCOMO_SPICT);
1010 + r &= ~LOCOMO_SPI_ALIGNEN;
1011 + iowrite16(r, spidev->base+LOCOMO_SPICT);
1013 +// printk(KERN_DEBUG "locomospi: tx %d bytes to transmit\n",size);
1014 + for(i=0; i<size; i++){
1015 + for(j=0; j <= wait; j++){
1016 + if(ioread16(spidev->base+LOCOMO_SPIST) & LOCOMO_SPI_RFW)
1019 + iowrite8(buffer[i], spidev->base+LOCOMO_SPITD);
1023 + for(j=0; j <= wait; j++){
1024 + if(ioread16(spidev->base+LOCOMO_SPIST) & LOCOMO_SPI_TEND)
1028 + r = ioread16(spidev->base+LOCOMO_SPICT);
1029 + r |= LOCOMO_SPI_ALIGNEN;
1030 + iowrite16(r, spidev->base+LOCOMO_SPICT);
1032 +// for(j=0; j< size; j++)
1033 +// printk(KERN_DEBUG "locomospi: sent: %x \n", buffer[j]);
1034 +// printk(KERN_DEBUG "locomospi: tx %d bytes transmitted\n",i);
1038 +static int rx(char* buffer, int size)
1043 + printk(KERN_DEBUG "locomospi: rx %d bytes to receive\n",size);
1044 + if(spidev->clock_div == 4)
1048 + r = ioread16(spidev->base+LOCOMO_SPICT);
1049 + r &= ~LOCOMO_SPI_ALIGNEN;
1050 + iowrite16(r, spidev->base+LOCOMO_SPICT);
1052 + for(i=0; i<size; i++){
1054 + for(j=0; j <= wait; j++){
1055 + if(ioread16(spidev->base+LOCOMO_SPIST) & LOCOMO_SPI_RFR)
1058 + buffer[i]= ioread8(spidev->base+LOCOMO_SPIRD);
1062 + r = ioread16(spidev->base+LOCOMO_SPICT);
1063 + r |= LOCOMO_SPI_ALIGNEN;
1064 + iowrite16(r, spidev->base+LOCOMO_SPICT);
1066 + for(j=0; j< size; j++)
1067 + printk(KERN_DEBUG "locomospi: received: %x \n", buffer[j]);
1068 + printk(KERN_DEBUG "locomospi: rx %d bytes received\n",i);
1073 +static irqreturn_t locomospi_rwready(int irq, void *dev_id)
1075 + struct locomospi_dev* dev=(struct locomospi_dev*) dev_id;
1076 +// dev_dbg(&spidev->sdev->dev, "IRQ: %d\n", irq);
1077 +// printk(KERN_DEBUG "locomospi: IRQ: %d\n", irq);
1078 + wake_up_interruptible(&dev->waitqueue);
1079 + return IRQ_HANDLED;
1082 +static irqreturn_t locomospi_testisr(int irq, void *dev_id)
1086 + case IRQ_LOCOMO_SPI_RFR: buf="RFR";
1088 + case IRQ_LOCOMO_SPI_RFW: buf="RFW";
1090 + case IRQ_LOCOMO_SPI_REND:buf="REND";
1092 + case IRQ_LOCOMO_SPI_TEND:buf="TEND";
1094 + case IRQ_LOCOMO_CARDDETECT:
1095 + buf="CARD_DETECT";
1097 + default: return IRQ_NONE;
1099 + printk(KERN_DEBUG "locomospi: IRQ: %s\n",buf);
1100 +// dev_dbg(&spidev->sdev->dev, "IRQ: %s\n",buf);
1101 + return IRQ_HANDLED;
1103 +static irqreturn_t locomospi_txrxisr(int irq, void *dev_id)
1105 + if(transfercount < transfersize){
1106 + transrxbuf[transfercount++] = ioread8(spidev->base+LOCOMO_SPIRD);
1107 + iowrite8(transtxbuf[transfercount], spidev->base+LOCOMO_SPITD);
1110 + /* transfer complete. wake up txrx */
1111 + wake_up(&transferqueue);
1113 + return IRQ_HANDLED;
1116 +static irqreturn_t locomospi_txisr(int irq, void *dev_id)
1118 + if(transfercount < transfersize){
1119 + iowrite8(transtxbuf[transfercount++], spidev->base+LOCOMO_SPITD);
1122 + /* transfer complete. wake up txrx */
1123 + wake_up(&transferqueue);
1125 + return IRQ_HANDLED;
1128 +static irqreturn_t locomospi_rxisr(int irq, void *dev_id)
1130 + if(transfercount < transfersize){
1131 + transrxbuf[transfercount++] = ioread8(spidev->base+LOCOMO_SPIRD);
1134 + /* transfer complete. wake up txrx */
1135 + wake_up(&transferqueue);
1137 + return IRQ_HANDLED;
1140 +static void locomospi_clock(unsigned int Hz)
1143 + printk(KERN_DEBUG "locomospi: changing clock to: %d\n", Hz);
1145 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1146 + r &= ~LOCOMO_SPI_XON;
1147 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1149 + else if(Hz >= 24576000){
1150 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1151 + r |= LOCOMO_SPI_XON;
1152 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1153 + locomospi_setclock(DIV_1, CLOCK_25MHZ);
1156 + else if(Hz >= 22579200){
1157 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1158 + r |= LOCOMO_SPI_XON;
1159 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1160 + locomospi_setclock(DIV_1, CLOCK_22MHZ);
1163 + else if(Hz >= 18432000){
1164 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1165 + r |= LOCOMO_SPI_XON;
1166 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1167 + locomospi_setclock(DIV_1, CLOCK_18MHZ);
1170 + else if(Hz >= 12288000){
1171 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1172 + r |= LOCOMO_SPI_XON;
1173 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1174 + locomospi_setclock(DIV_2, CLOCK_25MHZ);
1177 + else if(Hz >= 11289600){
1178 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1179 + r |= LOCOMO_SPI_XON;
1180 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1181 + locomospi_setclock(DIV_2, CLOCK_22MHZ);
1184 + else if(Hz >= 9216000){
1185 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1186 + r |= LOCOMO_SPI_XON;
1187 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1188 + locomospi_setclock(DIV_2, CLOCK_18MHZ);
1191 + else if(Hz >= 6144000){
1192 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1193 + r |= LOCOMO_SPI_XON;
1194 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1195 + locomospi_setclock(DIV_4, CLOCK_25MHZ);
1198 + else if(Hz >= 5644800){
1199 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1200 + r |= LOCOMO_SPI_XON;
1201 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1202 + locomospi_setclock(DIV_4, CLOCK_22MHZ);
1205 + else if(Hz >= 4608000){
1206 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1207 + r |= LOCOMO_SPI_XON;
1208 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1209 + locomospi_setclock(DIV_4, CLOCK_18MHZ);
1212 + else if(Hz >= 3072000){
1213 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1214 + r |= LOCOMO_SPI_XON;
1215 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1216 + locomospi_setclock(DIV_8, CLOCK_25MHZ);
1219 + else if(Hz >= 2822400){
1220 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1221 + r |= LOCOMO_SPI_XON;
1222 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1223 + locomospi_setclock(DIV_8, CLOCK_22MHZ);
1226 + else if(Hz >= 2304000){
1227 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1228 + r |= LOCOMO_SPI_XON;
1229 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1230 + locomospi_setclock(DIV_8, CLOCK_18MHZ);
1233 + else if(Hz >= 384000){
1234 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1235 + r |= LOCOMO_SPI_XON;
1236 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1237 + locomospi_setclock(DIV_64, CLOCK_25MHZ);
1240 + else if(Hz >= 352800){
1241 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1242 + r |= LOCOMO_SPI_XON;
1243 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1244 + locomospi_setclock(DIV_64, CLOCK_22MHZ);
1247 + else{ /* set to 288 KHz */
1248 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1249 + r |= LOCOMO_SPI_XON;
1250 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1251 + locomospi_setclock(DIV_64, CLOCK_18MHZ);
1254 + spidev->clock = Hz;
1257 +/* sysfs attributes used for debug *******************************************/
1259 +/* SPI registers */
1260 +ssize_t locomospi_showspimd(struct device_driver *drv, char *buf)
1262 + return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPIMD));
1265 +ssize_t locomospi_storespimd(struct device_driver *drv, const char *buf, size_t count)
1267 + iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPIMD);
1270 +static DRIVER_ATTR(spimd, S_IWUSR | S_IRUGO, locomospi_showspimd, locomospi_storespimd);
1272 +ssize_t locomospi_showspict(struct device_driver *drv, char *buf)
1274 + return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPICT));
1277 +ssize_t locomospi_storespict(struct device_driver *drv, const char *buf, size_t count)
1279 + iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPICT);
1282 +static DRIVER_ATTR(spict, S_IWUSR | S_IRUGO, locomospi_showspict, locomospi_storespict);
1284 +ssize_t locomospi_showspist(struct device_driver *drv, char *buf)
1286 + return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPIST));
1289 +ssize_t locomospi_storespist(struct device_driver *drv, const char *buf, size_t count)
1291 + iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPIST);
1294 +static DRIVER_ATTR(spist, S_IWUSR | S_IRUGO, locomospi_showspist, locomospi_storespist);
1296 +ssize_t locomospi_showspitd(struct device_driver *drv, char *buf)
1298 + return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPITD));
1301 +ssize_t locomospi_storespitd(struct device_driver *drv, const char *buf, size_t count)
1303 + iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPITD);
1306 +static DRIVER_ATTR(spitd, S_IWUSR | S_IRUGO, locomospi_showspitd, locomospi_storespitd);
1308 +ssize_t locomospi_showspird(struct device_driver *drv, char *buf)
1310 + return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPIRD));
1313 +ssize_t locomospi_storespird(struct device_driver *drv, const char *buf, size_t count)
1315 + iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPIRD);
1318 +static DRIVER_ATTR(spird, S_IWUSR | S_IRUGO, locomospi_showspird, locomospi_storespird);
1320 +ssize_t locomospi_showspits(struct device_driver *drv, char *buf)
1322 + return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPITS));
1325 +ssize_t locomospi_storespits(struct device_driver *drv, const char *buf, size_t count)
1327 + iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPITS);
1330 +static DRIVER_ATTR(spits, S_IWUSR | S_IRUGO, locomospi_showspits, locomospi_storespits);
1332 +ssize_t locomospi_showspirs(struct device_driver *drv, char *buf)
1334 + return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPIRS));
1337 +ssize_t locomospi_storespirs(struct device_driver *drv, const char *buf, size_t count)
1339 + iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPIRS);
1342 +static DRIVER_ATTR(spirs, S_IWUSR | S_IRUGO, locomospi_showspirs, locomospi_storespirs);
1344 +/* MMC Card status */
1346 +ssize_t locomospi_showpower(struct device_driver *drv, char *buf)
1348 + return sprintf(buf, "%d\n", spidev->card_power);
1351 +ssize_t locomospi_storepower(struct device_driver *drv, const char *buf, size_t count)
1353 + locomospi_power(simple_strtoul(buf, NULL, 10));
1356 +static DRIVER_ATTR(cardpower, S_IWUSR | S_IRUGO, locomospi_showpower, locomospi_storepower);
1358 +ssize_t locomospi_detectcard(struct device_driver *drv, char *buf)
1360 + return sprintf(buf, "%d\n",(locomo_gpio_read_level(spidev->ldev->dev.parent,LOCOMO_GPIO_CARD_DETECT)>0)?0:1);
1362 +static DRIVER_ATTR(carddetect, S_IRUGO, locomospi_detectcard, NULL);
1364 +ssize_t locomospi_writeprotect(struct device_driver *drv, char *buf)
1366 + return sprintf(buf, "%d\n",(locomo_gpio_read_level(spidev->ldev->dev.parent,LOCOMO_GPIO_WRITE_PROT)>0)?1:0);
1368 +static DRIVER_ATTR(cardwriteprotect, S_IRUGO, locomospi_writeprotect, NULL);
1371 +ssize_t locomospi_showclock(struct device_driver *drv, char *buf)
1373 + return sprintf(buf, "%d\n", spidev->clock);
1376 +ssize_t locomospi_storeclock(struct device_driver *drv, const char *buf, size_t count)
1378 + locomospi_clock(simple_strtoul(buf, NULL, 10));
1381 +static DRIVER_ATTR(clock, S_IWUSR | S_IRUGO, locomospi_showclock, locomospi_storeclock);
1384 +ssize_t locomospi_showdelay(struct device_driver *drv, char *buf)
1386 + return sprintf(buf, "%d\n", delay);
1389 +ssize_t locomospi_storedelay(struct device_driver *drv, const char *buf, size_t count)
1391 + delay=simple_strtoul(buf,NULL,10);
1394 +static DRIVER_ATTR(delay, S_IWUSR | S_IRUGO, locomospi_showdelay, locomospi_storedelay);
1396 +ssize_t locomospi_reset(struct device_driver *drv, const char *buf, size_t count)
1398 + int choice = simple_strtoul(buf, NULL, 10);
1402 + case 0: locomospi_reg_release();
1403 + schedule_timeout(2*HZ);
1404 + locomospi_reg_open();
1407 + char b1[] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
1408 + char b2[] = "\xff\x40\x00\x00\x00\x00\x95\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
1409 + locomospi_setcs(1);
1411 + locomospi_setcs(0);
1416 + case 2: locomospi_setcs(1);
1417 + txrx("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",buff,18);
1418 + locomospi_setcs(0);
1419 + txrx("\xff\x40\x00\x00\x00\x00\x95\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",buff,17);
1422 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1423 + r |= LOCOMO_SPI_LOOPBACK;
1424 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1426 + txrx("abcdefghijklmnopqrstuvwxyz1234567890",buff,36);
1430 + schedule_timeout(HZ);
1431 + txrx("abcdefghijklmnopqrstuvwxyz1234567890",buff,36);
1433 + r = ioread16(spidev->base+LOCOMO_SPIMD);
1434 + r &= ~LOCOMO_SPI_LOOPBACK;
1435 + iowrite16(r, spidev->base+LOCOMO_SPIMD);
1437 + default: /* do nothing */;
1441 +static DRIVER_ATTR(reset, S_IWUSR, NULL, locomospi_reset);
1443 +typedef struct locomo_reg_entry {
1446 +} locomo_reg_entry_t;
1447 +#define LCM (sizeof(locomo_regs)/sizeof(locomo_reg_entry_t))
1448 +static locomo_reg_entry_t locomo_regs[] =
1450 +/* { addr, name, description } */
1455 + { 0x10, "MCSX0" },
1456 + { 0x14, "MCSX1" },
1457 + { 0x18, "MCSX2" },
1458 + { 0x1C, "MCSX3" },
1470 + { 0x60, "SPIMD" },
1471 + { 0x64, "SPICT" },
1472 + { 0x68, "SPIST" },
1473 + { 0x70, "SPIIS" },
1474 + { 0x74, "SPIWE" },
1475 + { 0x78, "SPIIE" },
1476 + { 0x7C, "SPIIR" },
1477 + { 0x80, "SPITD" },
1478 + { 0x84, "SPIRD" },
1479 + { 0x88, "SPITS" },
1480 + { 0x8C, "SPIRS" },
1495 + { 0xdc, "LTINT" },
1502 +static ssize_t lcm_show(struct device *dev, struct device_attribute *attr, char *buf)
1504 + int base = spidev->base - LOCOMO_SPI;
1508 + for(i=0; i<LCM; i++){
1509 + sprintf(c,"%s:\t\t 0x%x\n",locomo_regs[i].name, ioread16(base + locomo_regs[i].addr));
1512 + return sprintf(buf,"%s",b);
1515 +static DRIVER_ATTR(regs, 0444, lcm_show, NULL);
1518 +/* SPI functions *************************************************************/
1520 +static void locomospi_do_transfer(struct work_struct *wrk)
1522 + struct list_head *mptr, *tptr, *mptr2;
1523 + struct spi_transfer *entry;
1524 + struct spi_message *msg;
1526 + list_for_each_safe(mptr, mptr2, &spidev->message_list){
1527 + msg = list_entry(mptr, struct spi_message, queue);
1530 + msg->actual_length = 0;
1531 + list_for_each(tptr, &msg->transfers){
1532 + entry = list_entry(tptr, struct spi_transfer, transfer_list);
1533 + if(entry->tx_buf && entry->rx_buf){ //duplex
1534 + txrx((char*) entry->tx_buf, (char*) entry->rx_buf, entry->len);
1535 + msg->actual_length += entry->len;
1536 + } else if(entry->tx_buf && !entry->rx_buf){ //write
1537 + tx((char*) entry->tx_buf, entry->len);
1538 + msg->actual_length += entry->len;
1539 + } else if(!entry->tx_buf && entry->rx_buf){ //read
1540 + rx((char*) entry->rx_buf, entry->len);
1541 + msg->actual_length += entry->len;
1542 + } else if(!entry->tx_buf && !entry->rx_buf){ //error
1543 + dev_err(&spidev->sdev->dev, "do_transfer: no buffers allocated\n");
1544 + msg->status = -EFAULT;
1547 + spin_lock(&spidev->message_lock);
1549 + spin_unlock(&spidev->message_lock);
1550 + msg->complete(msg->context);
1554 +static int locomospi_setup(struct spi_device *spi)
1556 + if((spi->mode & SPI_CS_HIGH) != (spidev->spimode & SPI_CS_HIGH))
1557 + locomospi_setcs(spi->mode & SPI_CS_HIGH ? 1 : 0 );
1558 + if(spidev->clock != spi->max_speed_hz){
1559 + locomospi_clock(spi->max_speed_hz);
1561 + spidev->spimode = spi->mode;
1566 +static int locomospi_transfer(struct spi_device *spi, struct spi_message *msg)
1569 + spin_lock(&spidev->message_lock);
1570 + list_add_tail(&msg->queue, &spidev->message_list);
1571 + spin_unlock(&spidev->message_lock);
1572 + schedule_work(&transfer_wq);
1576 +static struct locomo_driver locomo_spi_driver = {
1578 + .name = "locomo-spi",
1580 + .devid = LOCOMO_DEVID_SPI,
1581 + .probe = locomospi_probe,
1582 + .remove = locomospi_remove,
1584 + .suspend = locomospi_suspend,
1585 + .resume = locomospi_resume,
1589 +static struct spi_board_info board = {
1590 + .modalias = "mmc_spi",
1591 + .platform_data = (void*) &colliemmc,
1592 + .controller_data= NULL,
1594 + .max_speed_hz = 25000000,
1601 +static int locomospi_suspend(struct locomo_dev *dev, pm_message_t state)
1603 + disable_irq(IRQ_LOCOMO_CARDDETECT);
1607 +static int locomospi_resume(struct locomo_dev *dev)
1609 + enable_irq(IRQ_LOCOMO_CARDDETECT);
1614 +static int locomospi_probe(struct locomo_dev *dev)
1617 + printk(KERN_DEBUG "Collie MMC over SPI Driver\n");
1618 + spidev=kmalloc(sizeof(struct locomospi_dev),GFP_KERNEL);
1622 + spidev->ldev = dev;
1623 + spidev->card_power = 1;
1624 + spidev->spimode = 0;
1626 + if(!request_mem_region((unsigned long) dev->mapbase, dev->length, LOCOMO_DRIVER_NAME(dev))) {
1627 + dev_err(&dev->dev, " Can't aquire access to io memory\n");
1630 + spidev->base=(unsigned long) dev->mapbase;
1631 + locomospi_reg_open();
1633 + locomo_gpio_set_dir(dev->dev.parent, LOCOMO_GPIO_CARD_POWER, 0);
1634 + locomo_gpio_set_dir(dev->dev.parent, LOCOMO_GPIO_CARD_DETECT, 1);
1635 + locomo_gpio_set_dir(dev->dev.parent, LOCOMO_GPIO_WRITE_PROT, 1);
1637 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_cardpower);
1639 + dev_err(&dev->dev, "error creating driver attribute\n");
1642 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_carddetect);
1644 + dev_err(&dev->dev,"error creating driver attribute\n");
1647 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_cardwriteprotect);
1649 + dev_err(&dev->dev, "error creating driver attribute\n");
1652 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spimd);
1654 + dev_err(&dev->dev, "error creating driver attribute\n");
1657 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spict);
1659 + dev_err(&dev->dev, "error creating driver attribute\n");
1662 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spist);
1664 + dev_err(&dev->dev, "error creating driver attribute\n");
1667 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spitd);
1669 + dev_err(&dev->dev, "error creating driver attribute\n");
1672 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spird);
1674 + dev_err(&dev->dev, "error creating driver attribute\n");
1677 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spits);
1679 + dev_err(&dev->dev, "error creating driver attribute\n");
1682 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spirs);
1684 + dev_err(&dev->dev, "error creating driver attribute\n");
1687 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_clock);
1689 + dev_err(&dev->dev, "error creating driver attribute\n");
1692 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_delay);
1694 + dev_err(&dev->dev, "error creating driver attribute\n");
1697 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_reset);
1699 + dev_err(&dev->dev, "error creating driver attribute\n");
1702 + result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_regs);
1704 + dev_err(&dev->dev, "error creating driver attribute\n");
1707 + INIT_WORK(&transfer_wq, locomospi_do_transfer);
1708 + INIT_LIST_HEAD(&spidev->message_list);
1709 + spin_lock_init(&spidev->message_lock);
1710 + init_waitqueue_head(&spidev->waitqueue);
1711 + spidev->master=spi_alloc_master(&dev->dev,0);
1712 + if(!spidev->master){
1716 + spidev->master->bus_num = 0;
1717 + spidev->master->num_chipselect = 1;
1718 + spidev->master->setup = locomospi_setup;
1719 + spidev->master->transfer = locomospi_transfer;
1720 + spidev->sdev = spi_new_device(spidev->master, &board);
1721 + if(!spidev->sdev){
1722 + dev_err(&dev->dev, "failed to register spi device\n");
1726 +/* result=request_irq(IRQ_LOCOMO_SPI_RFR, locomospi_testisr, IRQF_SHARED, "locomo-spi", (void*) spidev);
1728 + dev_err(&dev->dev, "Could not get IRQ: RFR\n");
1731 + //disable_irq(IRQ_LOCOMO_SPI_RFR);
1732 +*//* result=request_irq(IRQ_LOCOMO_SPI_RFW, locomospi_testisr, IRQF_SHARED, "locomo-spi", (void*) spidev);
1734 + dev_err(&dev->dev, "Could not get IRQ: RFW\n");
1737 + //disable_irq(IRQ_LOCOMO_SPI_RFW);
1738 +*//* result=request_irq(IRQ_LOCOMO_SPI_REND, locomospi_testisr, IRQF_SHARED, "locomo-spi", (void*) spidev);
1740 + dev_err(&dev->dev, "Could not get IRQ: REND\n");
1743 +*//* result=request_irq(IRQ_LOCOMO_SPI_TEND, locomospi_testisr, IRQF_SHARED, "locomo-spi", (void*) spidev);
1745 + dev_err(&dev->dev, "Could not get IRQ: TEND\n");
1748 + //disable_irq(IRQ_LOCOMO_SPI_TEND);
1749 +*/ spidev->workqueue = create_singlethread_workqueue("locomo-spi");
1750 + if(!spidev->workqueue){
1751 + dev_err(&dev->dev, "failed to create workqueue\n");
1754 + result=spi_register_master(spidev->master);
1756 + dev_err(&dev->dev, "failed to register spimaster\n");
1761 + destroy_workqueue(spidev->workqueue);
1763 +// free_irq(IRQ_LOCOMO_SPI_TEND, (void*) spidev);
1765 +// free_irq(IRQ_LOCOMO_SPI_REND, (void*) spidev);
1767 +// free_irq(IRQ_LOCOMO_SPI_RFW, (void*) spidev);
1769 +// free_irq(IRQ_LOCOMO_SPI_RFR, (void*) spidev);
1771 + spi_unregister_device(spidev->sdev);
1773 + spi_master_put(spidev->master);
1775 + release_mem_region((unsigned long) dev->mapbase, dev->length);
1781 +static int locomospi_remove(struct locomo_dev *dev)
1783 + spi_unregister_device(spidev->sdev);
1784 + spi_unregister_master(spidev->master);
1785 + destroy_workqueue(spidev->workqueue);
1786 + locomospi_reg_release();
1787 +// free_irq(IRQ_LOCOMO_SPI_TEND, (void*) spidev);
1788 +// free_irq(IRQ_LOCOMO_SPI_REND, (void*) spidev);
1789 +// free_irq(IRQ_LOCOMO_SPI_RFW, (void*) spidev);
1790 +// free_irq(IRQ_LOCOMO_SPI_RFR, (void*) spidev);
1791 + spi_master_put(spidev->master);
1792 + release_mem_region((unsigned long) dev->mapbase, dev->length);
1799 +static int __init locomospi_init(void)
1801 + int ret = locomo_driver_register(&locomo_spi_driver);
1809 +static void __exit locomospi_exit(void)
1811 + locomo_driver_unregister(&locomo_spi_driver);
1814 +module_init(locomospi_init);
1815 +module_exit(locomospi_exit);
1817 +MODULE_AUTHOR("Thomas Kunze thommy@tabao.de");
1818 +MODULE_DESCRIPTION("Collie mmc driver");
1819 +MODULE_LICENSE("GPL");
1820 diff --git a/drivers/spi/locomo_spi.h b/drivers/spi/locomo_spi.h
1821 new file mode 100644
1822 index 0000000..7e1c0ce
1824 +++ b/drivers/spi/locomo_spi.h
1826 +#include <asm/hardware/locomo.h>
1827 +#ifndef __LOCOMO_SPI_H__
1828 +#define __LOCOMO_SPI_H__
1830 +/* locomo-spi status register LOCOMO_SPIST */
1831 +#define LOCOMO_SPI_TEND (1 << 3) /* Transfer end bit */
1832 +#define LOCOMO_SPI_REND (1 << 2) /* Receive end bit */
1833 +#define LOCOMO_SPI_RFW (1 << 1) /* write buffer bit */
1834 +#define LOCOMO_SPI_RFR (1) /* read buffer bit */
1836 +/* locomo-spi mode register LOCOMO_SPIMD */
1837 +#define LOCOMO_SPI_LOOPBACK (1 << 15) /* loopback tx to rx */
1838 +#define LOCOMO_SPI_MSB1ST (1 << 14) /* send MSB first */
1839 +#define LOCOMO_SPI_DOSTAT (1 << 13) /* transmit line is idle high */
1840 +#define LOCOMO_SPI_TCPOL (1 << 11) /* transmit CPOL (maybe affects CPHA too) */
1841 +#define LOCOMO_SPI_RCPOL (1 << 10) /* receive CPOL (maybe affects CPHA too) */
1842 +#define LOCOMO_SPI_TDINV (1 << 9) /* invert transmit line */
1843 +#define LOCOMO_SPI_RDINV (1 << 8) /* invert receive line */
1844 +#define LOCOMO_SPI_XON (1 << 7) /* enable spi controller clock */
1845 +#define LOCOMO_SPI_XEN (1 << 6) /* clock bit write enable xon must be off, wait 300 us before xon->1 */
1846 +#define LOCOMO_SPI_XSEL 0x0018 /* clock select */
1847 +#define CLOCK_18MHZ 0 /* 18,432 MHz clock */
1848 +#define CLOCK_22MHZ 1 /* 22,5792 MHz clock */
1849 +#define CLOCK_25MHZ 2 /* 24,576 MHz clock */
1850 +#define LOCOMO_SPI_CLKSEL 0x7
1851 +#define DIV_1 0 /* don't divide clock */
1852 +#define DIV_2 1 /* divide clock by two */
1853 +#define DIV_4 2 /* divide clock by four */
1854 +#define DIV_8 3 /* divide clock by eight*/
1855 +#define DIV_64 4 /* divide clock by 64 */
1857 +/* locomo-spi control register LOCOMO_SPICT */
1858 +#define LOCOMO_SPI_CRC16_7_B (1 << 15) /* 0: crc16 1: crc7 */
1859 +#define LOCOMO_SPI_CRCRX_TX_B (1 << 14)
1860 +#define LOCOMO_SPI_CRCRESET_B (1 << 13)
1861 +#define LOCOMO_SPI_CEN (1 << 7) /* ?? enable */
1862 +#define LOCOMO_SPI_CS (1 << 6) /* chip select */
1863 +#define LOCOMO_SPI_UNIT16 (1 << 5) /* 0: 8 bit units, 1: 16 bit unit */
1864 +#define LOCOMO_SPI_ALIGNEN (1 << 2) /* align transfer enable */
1865 +#define LOCOMO_SPI_RXWEN (1 << 1) /* continous receive */
1866 +#define LOCOMO_SPI_RXUEN (1 << 0) /* aligned receive */
1868 +#define IRQ_LOCOMO_CARDDETECT IRQ_LOCOMO_GPIO13
1871 +struct locomospi_dev {
1872 + struct locomo_dev *ldev;
1873 + struct spi_master *master;
1874 + struct spi_device *sdev;
1879 + unsigned long base;
1881 + wait_queue_head_t waitqueue;
1882 + struct workqueue_struct *workqueue;
1883 + struct list_head message_list;
1884 + spinlock_t message_lock;
1888 +static irqreturn_t locomospi_cardisr(int, void*);
1889 +static int locomospi_probe(struct locomo_dev*);
1890 +static int locomospi_remove(struct locomo_dev*);
1891 +static int locomospi_carddetect(void);
1892 +static void locomospi_reg_open(void);
1893 +static void locomospi_reg_release(void);
1894 +static int tx(const char*, int);
1895 +static int rx(char *, int);
1896 +static void locomospi_power(int on);
1897 +static int locomospi_suspend(struct locomo_dev *dev, pm_message_t state);
1898 +static int locomospi_resume(struct locomo_dev *dev);
1899 +static void locomospi_setcs(int high);