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);