2 * linux/arch/arm/mach-sa1100/stork.c
4 * Copyright (C) 2001 Ken Gordon
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/module.h>
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/tty.h>
15 #include <linux/delay.h>
17 #include <asm/hardware.h>
18 #include <asm/setup.h>
19 #include <asm/keyboard.h>
21 #include <asm/mach/arch.h>
22 #include <asm/mach/map.h>
23 #include <asm/mach/serial_sa1100.h>
24 #include <linux/serial_core.h>
29 #define STORK_VM_BASE_CS1 0xf0000000 /* where we get mapped (virtual) */
30 #define STORK_VM_OFF_CS1 0x08000000 /* where we started mapping (physical) */
31 #define STORK_VM_ADJUST_CS1 (STORK_VM_BASE_CS1-STORK_VM_OFF_CS1) /* add to the phys to get virt */
33 #define STORK_VM_BASE_CS2 0xf1000000 /* where we get mapped (virtual) */
34 #define STORK_VM_OFF_CS2 0x10000000 /* where we started mapping (physical) */
35 #define STORK_VM_ADJUST_CS2 (STORK_VM_BASE_CS2-STORK_VM_OFF_CS2) /* add to the phys to get virt */
39 static int storkLatchA
= 0;
40 static int storkLatchB
= 0;
41 static int storkLCDCPLD
[4] = { 0, 0, 0, 0};
44 storkSetLatchA(int bits
)
46 int ret
= storkLatchA
;
47 volatile unsigned int *latch
= (unsigned int *)(STORK_LATCH_A_ADDR
+STORK_VM_ADJUST_CS1
);
55 storkClearLatchA(int bits
)
57 int ret
= storkLatchA
;
58 volatile unsigned int *latch
= (unsigned int *)(STORK_LATCH_A_ADDR
+STORK_VM_ADJUST_CS1
);
66 storkSetLCDCPLD(int which
, int bits
)
68 int ret
= storkLCDCPLD
[which
];
69 volatile unsigned int *latch
= (unsigned int *)(STORK_LCDCPLD_BASE_ADDR
+STORK_VM_ADJUST_CS2
+ 0x20*which
);
71 storkLCDCPLD
[which
] |= bits
;
72 *latch
= storkLCDCPLD
[which
];
77 /* NB we don't shadow these 'cos there is no relation between the data written and the data read */
78 /* ie the read registers are read only and the write registers write only */
81 storkGetLCDCPLD(int which
)
83 volatile unsigned int *latch
= (unsigned int *)(STORK_LCDCPLD_BASE_ADDR
+STORK_VM_ADJUST_CS2
+ 0x20*which
);
88 storkClearLCDCPLD(int which
, int bits
)
90 int ret
= storkLCDCPLD
[which
];
91 volatile unsigned int *latch
= (unsigned int *)(STORK_LCDCPLD_BASE_ADDR
+STORK_VM_ADJUST_CS2
+ 0x20*which
);
93 storkLCDCPLD
[which
] &= ~bits
;
94 *latch
= storkLCDCPLD
[which
];
99 storkSetLatchB(int bits
)
101 int ret
= storkLatchB
;
104 volatile unsigned int *latch
= (unsigned int *)(STORK_LATCH_B_ADDR
+STORK_VM_ADJUST_CS1
);
105 sprintf(buf
, "%s: bits %04x\n", __FUNCTION__
, bits
);
106 if (debug
) printk(buf
);
109 *latch
= storkLatchB
;
114 storkClearLatchB(int bits
)
116 int ret
= storkLatchB
;
119 volatile unsigned int *latch
= (unsigned int *)(STORK_LATCH_B_ADDR
+STORK_VM_ADJUST_CS1
);
120 sprintf(buf
, "%s: bits %04x\n", __FUNCTION__
, bits
);
121 if (debug
) printk(buf
);
123 storkLatchB
&= ~bits
;
124 *latch
= storkLatchB
;
129 storkSetGPIO(int bits
)
133 sprintf(buf
, "%s: bits %04x\n", __FUNCTION__
, bits
);
134 if (debug
) printk(buf
);
139 storkClearGPIO(int bits
)
143 sprintf(buf
, "%s: bits %04x\n", __FUNCTION__
, bits
);
144 if (debug
) printk(buf
);
155 sprintf(buf
, "%s: bits %04x\n", __FUNCTION__
, bits
);
156 if (debug
) printk(buf
);
161 /* this will return the current state of the hardware ANDED with the given bits
162 so NE => at least one bit was set, but maybe not all of them! */
165 storkTestGPIO(int bits
)
167 int val
= storkGetGPIO();
170 sprintf(buf
, "%s: bits %04x val %04x\n", __FUNCTION__
, bits
, val
);
171 if (debug
) printk(buf
);
176 /* NB the touch screen and the d to a use the same data and clock out pins */
178 static void storkClockTS(void)
180 storkSetLatchB(STORK_TOUCH_SCREEN_DCLK
);
181 udelay(10); /* hmm wait 200ns (min) - ok this ought to be udelay(1) but that doesn't get */
182 /* consistent values so I'm using 10 (urgh) */
183 storkClearLatchB(STORK_TOUCH_SCREEN_DCLK
);
188 int /* there is always a 12 bit read after the write! */
189 storkClockByteToTS(int byte
)
191 int timeout
= 10000; /* stuff is meant to happen in 60ns */
195 if (debug
) printk("storkClockByteToTS: %02x\n", byte
);
197 storkClearLatchB(STORK_TOUCH_SCREEN_CS
); /* slect touch screen */
199 while (timeout
-- > 0)
200 if (storkTestGPIO(GPIO_STORK_TOUCH_SCREEN_BUSY
) == 0)
204 printk("storkClockBitToTS: GPIO_STORK_TOUCH_SCREEN_BUSY didn't go low!\n\r");
205 /* ignore error for now return; */
208 /* clock out the given byte */
210 for (bit
= 0x80; bit
> 0; bit
= bit
>> 1) {
212 if ((bit
& byte
) == 0)
213 storkClearLatchB(STORK_TOUCH_SCREEN_DIN
);
215 storkSetLatchB(STORK_TOUCH_SCREEN_DIN
);
220 storkClockTS(); /* will be busy for at a clock (at least) */
222 for (timeout
= 10000; timeout
>= 0; timeout
--)
223 if (storkTestGPIO(GPIO_STORK_TOUCH_SCREEN_BUSY
) == 0)
227 printk("storkClockBitToTS: 2nd GPIO_STORK_TOUCH_SCREEN_BUSY didn't go low!\n\r");
228 /* ignore error for now return; */
231 /* clock in the result */
233 for (bit
= 0x0800; bit
> 0; bit
= bit
>> 1) {
235 if (storkTestGPIO(GPIO_STORK_TOUCH_SCREEN_DATA
))
241 storkSetLatchB(STORK_TOUCH_SCREEN_CS
); /* unselect touch screen */
247 storkClockShortToDtoA(int word
)
251 storkClearLatchB(STORK_DA_CS
); /* select D to A */
253 /* clock out the given byte */
255 for (bit
= 0x8000; bit
> 0; bit
= bit
>> 1) {
257 if ((bit
& word
) == 0)
258 storkClearLatchB(STORK_TOUCH_SCREEN_DIN
);
260 storkSetLatchB(STORK_TOUCH_SCREEN_DIN
);
265 storkSetLatchB(STORK_DA_CS
); /* unselect D to A */
267 /* set DTOA#_LOAD low then high (min 20ns) to transfer value to D to A */
268 storkClearLatchB(STORK_DA_LD
);
269 storkSetLatchB(STORK_DA_LD
);
275 storkInitTSandDtoA(void)
277 storkClearLatchB(STORK_TOUCH_SCREEN_DCLK
| STORK_TOUCH_SCREEN_DIN
);
278 storkSetLatchB(STORK_TOUCH_SCREEN_CS
| STORK_DA_CS
| STORK_DA_LD
);
279 storkClockByteToTS(0xE2); /* turn on the reference */
280 storkClockShortToDtoA(0x8D00); /* turn on the contrast */
281 storkClockShortToDtoA(0x0A00); /* turn on the brightness */
284 static void stork_lcd_power(int on
)
287 storkSetLCDCPLD(0, 1);
288 storkSetLatchA(STORK_LCD_BACKLIGHT_INVERTER_ON
);
290 storkSetLCDCPLD(0, 0);
291 storkClearLatchA(STORK_LCD_BACKLIGHT_INVERTER_ON
);
295 struct map_desc stork_io_desc
[] __initdata
= {
296 /* virtual physical length type */
297 { STORK_VM_BASE_CS1
, STORK_VM_OFF_CS1
, 0x01000000, MT_DEVICE
}, /* EGPIO 0 */
298 { 0xf1000000, 0x10000000, 0x02800000, MT_DEVICE
}, /* static memory bank 2 */
299 { 0xf3800000, 0x40000000, 0x00800000, MT_DEVICE
} /* static memory bank 4 */
306 iotable_init(stork_io_desc
, ARRAY_SIZE(stork_io_desc
));
308 sa1100_register_uart(0, 1); /* com port */
309 sa1100_register_uart(1, 2);
310 sa1100_register_uart(2, 3);
312 printk("Stork driver initing latches\r\n");
314 storkClearLatchB(STORK_RED_LED
); /* let's have the red LED on please */
315 storkSetLatchB(STORK_YELLOW_LED
);
316 storkSetLatchB(STORK_GREEN_LED
);
317 storkSetLatchA(STORK_BATTERY_CHARGER_ON
);
318 storkSetLatchA(STORK_LCD_5V_POWER_ON
);
319 storkSetLatchA(STORK_LCD_3V3_POWER_ON
);
321 storkInitTSandDtoA();
323 sa1100fb_lcd_power
= stork_lcd_power
;
329 MACHINE_START(STORK
, "Stork Technologies prototype")
330 BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
331 BOOT_PARAMS(0xc0000100)
333 INITIRQ(sa1100_init_irq
)
334 INITTIME(sa1100_init_time
)
338 EXPORT_SYMBOL(storkTestGPIO
);
339 EXPORT_SYMBOL(storkSetGPIO
);
340 EXPORT_SYMBOL(storkClearGPIO
);
341 EXPORT_SYMBOL(storkSetLatchA
);
342 EXPORT_SYMBOL(storkClearLatchA
);
343 EXPORT_SYMBOL(storkSetLatchB
);
344 EXPORT_SYMBOL(storkClearLatchB
);
345 EXPORT_SYMBOL(storkClockByteToTS
);
346 EXPORT_SYMBOL(storkClockShortToDtoA
);
347 EXPORT_SYMBOL(storkGetLCDCPLD
);
348 EXPORT_SYMBOL(storkSetLCDCPLD
);