MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / arch / arm / mach-sa1100 / stork.c
blobf3b3a6eb8c09d5eee8a0f27bcc91cf633b12c3f5
1 /*
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>
26 #include "generic.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 */
37 static int debug = 0;
39 static int storkLatchA = 0;
40 static int storkLatchB = 0;
41 static int storkLCDCPLD[4] = { 0, 0, 0, 0};
43 int
44 storkSetLatchA(int bits)
46 int ret = storkLatchA;
47 volatile unsigned int *latch = (unsigned int *)(STORK_LATCH_A_ADDR+STORK_VM_ADJUST_CS1);
49 storkLatchA |= bits;
50 *latch = storkLatchA;
51 return ret;
54 int
55 storkClearLatchA(int bits)
57 int ret = storkLatchA;
58 volatile unsigned int *latch = (unsigned int *)(STORK_LATCH_A_ADDR+STORK_VM_ADJUST_CS1);
60 storkLatchA &= ~bits;
61 *latch = storkLatchA;
62 return ret;
65 int
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];
73 return ret;
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 */
80 int
81 storkGetLCDCPLD(int which)
83 volatile unsigned int *latch = (unsigned int *)(STORK_LCDCPLD_BASE_ADDR+STORK_VM_ADJUST_CS2 + 0x20*which);
84 return *latch;
87 int
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];
95 return ret;
98 int
99 storkSetLatchB(int bits)
101 int ret = storkLatchB;
102 char buf[100];
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);
108 storkLatchB |= bits;
109 *latch = storkLatchB;
110 return ret;
114 storkClearLatchB(int bits)
116 int ret = storkLatchB;
117 char buf[100];
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;
125 return ret;
128 void
129 storkSetGPIO(int bits)
131 char buf[100];
133 sprintf(buf, "%s: bits %04x\n", __FUNCTION__, bits);
134 if (debug) printk(buf);
135 GPSR = bits;
138 void
139 storkClearGPIO(int bits)
141 char buf[100];
143 sprintf(buf, "%s: bits %04x\n", __FUNCTION__, bits);
144 if (debug) printk(buf);
145 GPCR = bits;
149 storkGetGPIO()
151 char buf[100];
153 int bits = GPLR;
155 sprintf(buf, "%s: bits %04x\n", __FUNCTION__, bits);
156 if (debug) printk(buf);
158 return bits;
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();
168 char buf[100];
170 sprintf(buf, "%s: bits %04x val %04x\n", __FUNCTION__, bits, val);
171 if (debug) printk(buf);
173 return (val & bits);
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);
184 udelay(10);
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 */
192 int bit;
193 int result = 0;
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)
201 break;
203 if (timeout < 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);
214 else
215 storkSetLatchB(STORK_TOUCH_SCREEN_DIN);
217 storkClockTS();
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)
224 break;
226 if (timeout < 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))
236 result |= bit;
238 storkClockTS();
241 storkSetLatchB(STORK_TOUCH_SCREEN_CS); /* unselect touch screen */
243 return result;
246 void
247 storkClockShortToDtoA(int word)
249 int bit;
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);
259 else
260 storkSetLatchB(STORK_TOUCH_SCREEN_DIN);
262 storkClockTS();
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);
274 void
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)
286 if (on) {
287 storkSetLCDCPLD(0, 1);
288 storkSetLatchA(STORK_LCD_BACKLIGHT_INVERTER_ON);
289 } else {
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 */
302 int __init
303 stork_map_io(void)
305 sa1100_map_io();
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;
325 return 0;
329 MACHINE_START(STORK, "Stork Technologies prototype")
330 BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
331 BOOT_PARAMS(0xc0000100)
332 MAPIO(stork_map_io)
333 INITIRQ(sa1100_init_irq)
334 INITTIME(sa1100_init_time)
335 MACHINE_END
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);