ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / arm / mach-sa1100 / h3600.c
1 /*
2  * Hardware definitions for Compaq iPAQ H3xxx Handheld Computers
3  *
4  * Copyright 2000,1 Compaq Computer Corporation.
5  *
6  * Use consistent with the GNU GPL is permitted,
7  * provided that this copyright notice is
8  * preserved in its entirety in all copies and derived works.
9  *
10  * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
11  * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
12  * FITNESS FOR ANY PARTICULAR PURPOSE.
13  *
14  * Author: Jamey Hicks.
15  *
16  * History:
17  *
18  * 2001-10-??   Andrew Christian   Added support for iPAQ H3800
19  *                                 and abstracted EGPIO interface.
20  *
21  */
22 #include <linux/config.h>
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/kernel.h>
26 #include <linux/tty.h>
27 #include <linux/pm.h>
28 #include <linux/serial_core.h>
29
30 #include <asm/irq.h>
31 #include <asm/hardware.h>
32 #include <asm/mach-types.h>
33 #include <asm/setup.h>
34
35 #include <asm/mach/irq.h>
36 #include <asm/mach/arch.h>
37 #include <asm/mach/map.h>
38 #include <asm/mach/serial_sa1100.h>
39
40 #include <asm/arch/h3600.h>
41
42 #if defined (CONFIG_SA1100_H3600) || defined (CONFIG_SA1100_H3100)
43 #include <asm/arch/h3600_gpio.h>
44 #endif
45
46 #ifdef CONFIG_SA1100_H3800
47 #include <asm/arch/h3600_asic.h>
48 #endif
49
50 #include "generic.h"
51
52 struct ipaq_model_ops ipaq_model_ops;
53 EXPORT_SYMBOL(ipaq_model_ops);
54
55 /*
56  * low-level UART features
57  */
58
59 static void h3600_uart_set_mctrl(struct uart_port *port, u_int mctrl)
60 {
61         if (port->mapbase == _Ser3UTCR0) {
62                 if (mctrl & TIOCM_RTS)
63                         GPCR = GPIO_H3600_COM_RTS;
64                 else
65                         GPSR = GPIO_H3600_COM_RTS;
66         }
67 }
68
69 static u_int h3600_uart_get_mctrl(struct uart_port *port)
70 {
71         u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
72
73         if (port->mapbase == _Ser3UTCR0) {
74                 int gplr = GPLR;
75                 /* DCD and CTS bits are inverted in GPLR by RS232 transceiver */
76                 if (gplr & GPIO_H3600_COM_DCD)
77                         ret &= ~TIOCM_CD;
78                 if (gplr & GPIO_H3600_COM_CTS)
79                         ret &= ~TIOCM_CTS;
80         }
81
82         return ret;
83 }
84
85 static void h3600_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
86 {
87         if (port->mapbase == _Ser2UTCR0) { /* TODO: REMOVE THIS */
88                 assign_h3600_egpio(IPAQ_EGPIO_IR_ON, !state);
89         } else if (port->mapbase == _Ser3UTCR0) {
90                 assign_h3600_egpio(IPAQ_EGPIO_RS232_ON, !state);
91         }
92 }
93
94 /*
95  * Enable/Disable wake up events for this serial port.
96  * Obviously, we only support this on the normal COM port.
97  */
98 static int h3600_uart_set_wake(struct uart_port *port, u_int enable)
99 {
100         int err = -EINVAL;
101
102         if (port->mapbase == _Ser3UTCR0) {
103                 if (enable)
104                         PWER |= PWER_GPIO23 | PWER_GPIO25; /* DCD and CTS */
105                 else
106                         PWER &= ~(PWER_GPIO23 | PWER_GPIO25); /* DCD and CTS */
107                 err = 0;
108         }
109         return err;
110 }
111
112 static struct sa1100_port_fns h3600_port_fns __initdata = {
113         .set_mctrl      = h3600_uart_set_mctrl,
114         .get_mctrl      = h3600_uart_get_mctrl,
115         .pm             = h3600_uart_pm,
116         .set_wake       = h3600_uart_set_wake,
117 };
118
119 /*
120  * helper for sa1100fb
121  */
122 static void h3xxx_lcd_power(int enable)
123 {
124         assign_h3600_egpio(IPAQ_EGPIO_LCD_POWER, enable);
125 }
126
127 static struct map_desc h3600_io_desc[] __initdata = {
128  /* virtual            physical           length      type */
129   { H3600_BANK_2_VIRT, SA1100_CS2_PHYS,   0x02800000, MT_DEVICE }, /* static memory bank 2  CS#2 */
130   { H3600_BANK_4_VIRT, SA1100_CS4_PHYS,   0x00800000, MT_DEVICE }, /* static memory bank 4  CS#4 */
131   { H3600_EGPIO_VIRT,  H3600_EGPIO_PHYS,  0x01000000, MT_DEVICE }, /* EGPIO 0           CS#5 */
132 };
133
134 /*
135  * Common map_io initialization
136  */
137
138 static void __init h3xxx_map_io(void)
139 {
140         sa1100_map_io();
141         iotable_init(h3600_io_desc, ARRAY_SIZE(h3600_io_desc));
142
143         sa1100_register_uart_fns(&h3600_port_fns);
144         sa1100_register_uart(0, 3); /* Common serial port */
145 //      sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */
146
147         /* Ensure those pins are outputs and driving low  */
148         PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
149         PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
150
151         /* Configure suspend conditions */
152         PGSR = 0;
153         PWER = PWER_GPIO0 | PWER_RTC;
154         PCFR = PCFR_OPDE;
155         PSDR = 0;
156
157         sa1100fb_lcd_power = h3xxx_lcd_power;
158 }
159
160 static __inline__ void do_blank(int setp)
161 {
162         if (ipaq_model_ops.blank_callback)
163                 ipaq_model_ops.blank_callback(1-setp);
164 }
165
166 /************************* H3100 *************************/
167
168 #ifdef CONFIG_SA1100_H3100
169
170 #define H3100_EGPIO     (*(volatile unsigned int *)H3600_EGPIO_VIRT)
171 static unsigned int h3100_egpio = 0;
172
173 static void h3100_control_egpio(enum ipaq_egpio_type x, int setp)
174 {
175         unsigned int egpio = 0;
176         long         gpio = 0;
177         unsigned long flags;
178
179         switch (x) {
180         case IPAQ_EGPIO_LCD_POWER:
181                 egpio |= EGPIO_H3600_LCD_ON;
182                 gpio  |= GPIO_H3100_LCD_3V_ON;
183                 do_blank(setp);
184                 break;
185         case IPAQ_EGPIO_LCD_ENABLE:
186                 break;
187         case IPAQ_EGPIO_CODEC_NRESET:
188                 egpio |= EGPIO_H3600_CODEC_NRESET;
189                 break;
190         case IPAQ_EGPIO_AUDIO_ON:
191                 gpio |= GPIO_H3100_AUD_PWR_ON
192                         | GPIO_H3100_AUD_ON;
193                 break;
194         case IPAQ_EGPIO_QMUTE:
195                 gpio |= GPIO_H3100_QMUTE;
196                 break;
197         case IPAQ_EGPIO_OPT_NVRAM_ON:
198                 egpio |= EGPIO_H3600_OPT_NVRAM_ON;
199                 break;
200         case IPAQ_EGPIO_OPT_ON:
201                 egpio |= EGPIO_H3600_OPT_ON;
202                 break;
203         case IPAQ_EGPIO_CARD_RESET:
204                 egpio |= EGPIO_H3600_CARD_RESET;
205                 break;
206         case IPAQ_EGPIO_OPT_RESET:
207                 egpio |= EGPIO_H3600_OPT_RESET;
208                 break;
209         case IPAQ_EGPIO_IR_ON:
210                 gpio |= GPIO_H3100_IR_ON;
211                 break;
212         case IPAQ_EGPIO_IR_FSEL:
213                 gpio |= GPIO_H3100_IR_FSEL;
214                 break;
215         case IPAQ_EGPIO_RS232_ON:
216                 egpio |= EGPIO_H3600_RS232_ON;
217                 break;
218         case IPAQ_EGPIO_VPP_ON:
219                 egpio |= EGPIO_H3600_VPP_ON;
220                 break;
221         }
222
223         if (egpio || gpio) {
224                 local_irq_save(flags);
225                 if (setp) {
226                         h3100_egpio |= egpio;
227                         GPSR = gpio;
228                 } else {
229                         h3100_egpio &= ~egpio;
230                         GPCR = gpio;
231                 }
232                 H3100_EGPIO = h3100_egpio;
233                 local_irq_restore(flags);
234         }
235 }
236
237 static unsigned long h3100_read_egpio(void)
238 {
239         return h3100_egpio;
240 }
241
242 static int h3100_pm_callback(int req)
243 {
244         if (ipaq_model_ops.pm_callback_aux)
245                 return ipaq_model_ops.pm_callback_aux(req);
246         return 0;
247 }
248
249 static struct ipaq_model_ops h3100_model_ops __initdata = {
250         .generic_name   = "3100",
251         .control        = h3100_control_egpio,
252         .read           = h3100_read_egpio,
253         .pm_callback    = h3100_pm_callback
254 };
255
256 #define H3100_DIRECT_EGPIO (GPIO_H3100_BT_ON      \
257                           | GPIO_H3100_GPIO3      \
258                           | GPIO_H3100_QMUTE      \
259                           | GPIO_H3100_LCD_3V_ON  \
260                           | GPIO_H3100_AUD_ON     \
261                           | GPIO_H3100_AUD_PWR_ON \
262                           | GPIO_H3100_IR_ON      \
263                           | GPIO_H3100_IR_FSEL)
264
265 static void __init h3100_map_io(void)
266 {
267         h3xxx_map_io();
268
269         /* Initialize h3100-specific values here */
270         GPCR = 0x0fffffff;       /* All outputs are set low by default */
271         GPDR = GPIO_H3600_COM_RTS  | GPIO_H3600_L3_CLOCK |
272                GPIO_H3600_L3_MODE  | GPIO_H3600_L3_DATA  |
273                GPIO_H3600_CLK_SET1 | GPIO_H3600_CLK_SET0 |
274                H3100_DIRECT_EGPIO;
275
276         /* Older bootldrs put GPIO2-9 in alternate mode on the
277            assumption that they are used for video */
278         GAFR &= ~H3100_DIRECT_EGPIO;
279
280         H3100_EGPIO = h3100_egpio;
281         ipaq_model_ops = h3100_model_ops;
282 }
283
284 MACHINE_START(H3100, "Compaq iPAQ H3100")
285         BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
286         BOOT_PARAMS(0xc0000100)
287         MAPIO(h3100_map_io)
288         INITIRQ(sa1100_init_irq)
289 MACHINE_END
290
291 #endif /* CONFIG_SA1100_H3100 */
292
293 /************************* H3600 *************************/
294
295 #ifdef CONFIG_SA1100_H3600
296
297 #define H3600_EGPIO     (*(volatile unsigned int *)H3600_EGPIO_VIRT)
298 static unsigned int h3600_egpio = EGPIO_H3600_RS232_ON;
299
300 static void h3600_control_egpio(enum ipaq_egpio_type x, int setp)
301 {
302         unsigned int egpio = 0;
303         unsigned long flags;
304
305         switch (x) {
306         case IPAQ_EGPIO_LCD_POWER:
307                 egpio |= EGPIO_H3600_LCD_ON |
308                          EGPIO_H3600_LCD_PCI |
309                          EGPIO_H3600_LCD_5V_ON |
310                          EGPIO_H3600_LVDD_ON;
311                 do_blank(setp);
312                 break;
313         case IPAQ_EGPIO_LCD_ENABLE:
314                 break;
315         case IPAQ_EGPIO_CODEC_NRESET:
316                 egpio |= EGPIO_H3600_CODEC_NRESET;
317                 break;
318         case IPAQ_EGPIO_AUDIO_ON:
319                 egpio |= EGPIO_H3600_AUD_AMP_ON |
320                          EGPIO_H3600_AUD_PWR_ON;
321                 break;
322         case IPAQ_EGPIO_QMUTE:
323                 egpio |= EGPIO_H3600_QMUTE;
324                 break;
325         case IPAQ_EGPIO_OPT_NVRAM_ON:
326                 egpio |= EGPIO_H3600_OPT_NVRAM_ON;
327                 break;
328         case IPAQ_EGPIO_OPT_ON:
329                 egpio |= EGPIO_H3600_OPT_ON;
330                 break;
331         case IPAQ_EGPIO_CARD_RESET:
332                 egpio |= EGPIO_H3600_CARD_RESET;
333                 break;
334         case IPAQ_EGPIO_OPT_RESET:
335                 egpio |= EGPIO_H3600_OPT_RESET;
336                 break;
337         case IPAQ_EGPIO_IR_ON:
338                 egpio |= EGPIO_H3600_IR_ON;
339                 break;
340         case IPAQ_EGPIO_IR_FSEL:
341                 egpio |= EGPIO_H3600_IR_FSEL;
342                 break;
343         case IPAQ_EGPIO_RS232_ON:
344                 egpio |= EGPIO_H3600_RS232_ON;
345                 break;
346         case IPAQ_EGPIO_VPP_ON:
347                 egpio |= EGPIO_H3600_VPP_ON;
348                 break;
349         }
350
351         if (egpio) {
352                 local_irq_save(flags);
353                 if (setp)
354                         h3600_egpio |= egpio;
355                 else
356                         h3600_egpio &= ~egpio;
357                 H3600_EGPIO = h3600_egpio;
358                 local_irq_restore(flags);
359         }
360 }
361
362 static unsigned long h3600_read_egpio(void)
363 {
364         return h3600_egpio;
365 }
366
367 static int h3600_pm_callback(int req)
368 {
369         if (ipaq_model_ops.pm_callback_aux)
370                 return ipaq_model_ops.pm_callback_aux(req);
371         return 0;
372 }
373
374 static struct ipaq_model_ops h3600_model_ops __initdata = {
375         .generic_name   = "3600",
376         .control        = h3600_control_egpio,
377         .read           = h3600_read_egpio,
378         .pm_callback    = h3600_pm_callback
379 };
380
381 static void __init h3600_map_io(void)
382 {
383         h3xxx_map_io();
384
385         /* Initialize h3600-specific values here */
386
387         GPCR = 0x0fffffff;       /* All outputs are set low by default */
388         GPDR = GPIO_H3600_COM_RTS  | GPIO_H3600_L3_CLOCK |
389                GPIO_H3600_L3_MODE  | GPIO_H3600_L3_DATA  |
390                GPIO_H3600_CLK_SET1 | GPIO_H3600_CLK_SET0 |
391                GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
392                GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
393
394         H3600_EGPIO = h3600_egpio;         /* Maintains across sleep? */
395         ipaq_model_ops = h3600_model_ops;
396 }
397
398 MACHINE_START(H3600, "Compaq iPAQ H3600")
399         BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
400         BOOT_PARAMS(0xc0000100)
401         MAPIO(h3600_map_io)
402         INITIRQ(sa1100_init_irq)
403 MACHINE_END
404
405 #endif /* CONFIG_SA1100_H3600 */
406
407 #ifdef CONFIG_SA1100_H3800
408
409 #define SET_ASIC1(x) \
410    do {if (setp) { H3800_ASIC1_GPIO_OUT |= (x); } else { H3800_ASIC1_GPIO_OUT &= ~(x); }} while(0)
411
412 #define SET_ASIC2(x) \
413    do {if (setp) { H3800_ASIC2_GPIOPIOD |= (x); } else { H3800_ASIC2_GPIOPIOD &= ~(x); }} while(0)
414
415 #define CLEAR_ASIC1(x) \
416    do {if (setp) { H3800_ASIC1_GPIO_OUT &= ~(x); } else { H3800_ASIC1_GPIO_OUT |= (x); }} while(0)
417
418 #define CLEAR_ASIC2(x) \
419    do {if (setp) { H3800_ASIC2_GPIOPIOD &= ~(x); } else { H3800_ASIC2_GPIOPIOD |= (x); }} while(0)
420
421
422 /*
423   On screen enable, we get
424
425      h3800_video_power_on(1)
426      LCD controller starts
427      h3800_video_lcd_enable(1)
428
429   On screen disable, we get
430
431      h3800_video_lcd_enable(0)
432      LCD controller stops
433      h3800_video_power_on(0)
434 */
435
436
437 static void h3800_video_power_on(int setp)
438 {
439         if (setp) {
440                 H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_ON;
441                 msleep(30);
442                 H3800_ASIC1_GPIO_OUT |= GPIO1_VGL_ON;
443                 msleep(5);
444                 H3800_ASIC1_GPIO_OUT |= GPIO1_VGH_ON;
445                 msleep(50);
446                 H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_5V_ON;
447                 msleep(5);
448         } else {
449                 msleep(5);
450                 H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_5V_ON;
451                 msleep(50);
452                 H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGL_ON;
453                 msleep(5);
454                 H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGH_ON;
455                 msleep(100);
456                 H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_ON;
457         }
458 }
459
460 static void h3800_video_lcd_enable(int setp)
461 {
462         if (setp) {
463                 msleep(17);     // Wait one from before turning on
464                 H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_PCI;
465         } else {
466                 H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_PCI;
467                 msleep(30);     // Wait before turning off
468         }
469 }
470
471
472 static void h3800_control_egpio(enum ipaq_egpio_type x, int setp)
473 {
474         switch (x) {
475         case IPAQ_EGPIO_LCD_POWER:
476                 h3800_video_power_on(setp);
477                 break;
478         case IPAQ_EGPIO_LCD_ENABLE:
479                 h3800_video_lcd_enable(setp);
480                 break;
481         case IPAQ_EGPIO_CODEC_NRESET:
482         case IPAQ_EGPIO_AUDIO_ON:
483         case IPAQ_EGPIO_QMUTE:
484                 printk("%s: error - should not be called\n", __FUNCTION__);
485                 break;
486         case IPAQ_EGPIO_OPT_NVRAM_ON:
487                 SET_ASIC2(GPIO2_OPT_ON_NVRAM);
488                 break;
489         case IPAQ_EGPIO_OPT_ON:
490                 SET_ASIC2(GPIO2_OPT_ON);
491                 break;
492         case IPAQ_EGPIO_CARD_RESET:
493                 SET_ASIC2(GPIO2_OPT_PCM_RESET);
494                 break;
495         case IPAQ_EGPIO_OPT_RESET:
496                 SET_ASIC2(GPIO2_OPT_RESET);
497                 break;
498         case IPAQ_EGPIO_IR_ON:
499                 CLEAR_ASIC1(GPIO1_IR_ON_N);
500                 break;
501         case IPAQ_EGPIO_IR_FSEL:
502                 break;
503         case IPAQ_EGPIO_RS232_ON:
504                 SET_ASIC1(GPIO1_RS232_ON);
505                 break;
506         case IPAQ_EGPIO_VPP_ON:
507                 H3800_ASIC2_FlashWP_VPP_ON = setp;
508                 break;
509         }
510 }
511
512 static unsigned long h3800_read_egpio(void)
513 {
514         return H3800_ASIC1_GPIO_OUT | (H3800_ASIC2_GPIOPIOD << 16);
515 }
516
517 /* We need to fix ASIC2 GPIO over suspend/resume.  At the moment,
518    it doesn't appear that ASIC1 GPIO has the same problem */
519
520 static int h3800_pm_callback(int req)
521 {
522         static u16 asic1_data;
523         static u16 asic2_data;
524         int result = 0;
525
526         printk("%s %d\n", __FUNCTION__, req);
527
528         switch (req) {
529         case PM_RESUME:
530                 MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000;  /* Set MSC2 correctly */
531
532                 H3800_ASIC2_GPIOPIOD = asic2_data;
533                 H3800_ASIC2_GPIODIR = GPIO2_PEN_IRQ
534                         | GPIO2_SD_DETECT
535                         | GPIO2_EAR_IN_N
536                         | GPIO2_USB_DETECT_N
537                         | GPIO2_SD_CON_SLT;
538
539                 H3800_ASIC1_GPIO_OUT = asic1_data;
540
541                 if (ipaq_model_ops.pm_callback_aux)
542                         result = ipaq_model_ops.pm_callback_aux(req);
543                 break;
544
545         case PM_SUSPEND:
546                 if (ipaq_model_ops.pm_callback_aux &&
547                      ((result = ipaq_model_ops.pm_callback_aux(req)) != 0))
548                         return result;
549
550                 asic1_data = H3800_ASIC1_GPIO_OUT;
551                 asic2_data = H3800_ASIC2_GPIOPIOD;
552                 break;
553         default:
554                 printk("%s: unrecognized PM callback\n", __FUNCTION__);
555                 break;
556         }
557         return result;
558 }
559
560 static struct ipaq_model_ops h3800_model_ops __initdata = {
561         .generic_name   = "3800",
562         .control        = h3800_control_egpio,
563         .read           = h3800_read_egpio,
564         .pm_callback    = h3800_pm_callback
565 };
566
567 #define MAX_ASIC_ISR_LOOPS    20
568
569 /* The order of these is important - see #include <asm/arch/irqs.h> */
570 static u32 kpio_irq_mask[] = {
571         KPIO_KEY_ALL,
572         KPIO_SPI_INT,
573         KPIO_OWM_INT,
574         KPIO_ADC_INT,
575         KPIO_UART_0_INT,
576         KPIO_UART_1_INT,
577         KPIO_TIMER_0_INT,
578         KPIO_TIMER_1_INT,
579         KPIO_TIMER_2_INT
580 };
581
582 static u32 gpio_irq_mask[] = {
583         GPIO2_PEN_IRQ,
584         GPIO2_SD_DETECT,
585         GPIO2_EAR_IN_N,
586         GPIO2_USB_DETECT_N,
587         GPIO2_SD_CON_SLT,
588 };
589
590 static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
591 {
592         int i;
593
594         if (0) printk("%s: interrupt received\n", __FUNCTION__);
595
596         desc->chip->ack(irq);
597
598         for (i = 0; i < MAX_ASIC_ISR_LOOPS && (GPLR & GPIO_H3800_ASIC); i++) {
599                 u32 irq;
600                 int j;
601
602                 /* KPIO */
603                 irq = H3800_ASIC2_KPIINTFLAG;
604                 if (0) printk("%s KPIO 0x%08X\n", __FUNCTION__, irq);
605                 for (j = 0; j < H3800_KPIO_IRQ_COUNT; j++)
606                         if (irq & kpio_irq_mask[j])
607                                 do_edge_IRQ(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j, regs);
608
609                 /* GPIO2 */
610                 irq = H3800_ASIC2_GPIINTFLAG;
611                 if (0) printk("%s GPIO 0x%08X\n", __FUNCTION__, irq);
612                 for (j = 0; j < H3800_GPIO_IRQ_COUNT; j++)
613                         if (irq & gpio_irq_mask[j])
614                                 do_edge_IRQ(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j , regs);
615         }
616
617         if (i >= MAX_ASIC_ISR_LOOPS)
618                 printk("%s: interrupt processing overrun\n", __FUNCTION__);
619
620         /* For level-based interrupts */
621         desc->chip->unmask(irq);
622
623 }
624
625 static struct irqaction h3800_irq = {
626         .name           = "h3800_asic",
627         .handler        = h3800_IRQ_demux,
628         .flags          = SA_INTERRUPT,
629 };
630
631 u32 kpio_int_shadow = 0;
632
633
634 /* mask_ack <- IRQ is first serviced.
635        mask <- IRQ is disabled.
636      unmask <- IRQ is enabled
637
638      The INTCLR registers are poorly documented.  I believe that writing
639      a "1" to the register clears the specific interrupt, but the documentation
640      indicates writing a "0" clears the interrupt.  In any case, they shouldn't
641      be read (that's the INTFLAG register)
642  */
643
644 static void h3800_mask_ack_kpio_irq(unsigned int irq)
645 {
646         u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
647         kpio_int_shadow &= ~mask;
648         H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
649         H3800_ASIC2_KPIINTCLR  = mask;
650 }
651
652 static void h3800_mask_kpio_irq(unsigned int irq)
653 {
654         u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
655         kpio_int_shadow &= ~mask;
656         H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
657 }
658
659 static void h3800_unmask_kpio_irq(unsigned int irq)
660 {
661         u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
662         kpio_int_shadow |= mask;
663         H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
664 }
665
666 static void h3800_mask_ack_gpio_irq(unsigned int irq)
667 {
668         u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
669         H3800_ASIC2_GPIINTSTAT &= ~mask;
670         H3800_ASIC2_GPIINTCLR   = mask;
671 }
672
673 static void h3800_mask_gpio_irq(unsigned int irq)
674 {
675         u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
676         H3800_ASIC2_GPIINTSTAT &= ~mask;
677         }
678
679 static void h3800_unmask_gpio_irq(unsigned int irq)
680 {
681         u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
682         H3800_ASIC2_GPIINTSTAT |= mask;
683 }
684
685 static void __init h3800_init_irq(void)
686 {
687         int i;
688
689         /* Initialize standard IRQs */
690         sa1100_init_irq();
691
692         /* Disable all IRQs and set up clock */
693         H3800_ASIC2_KPIINTSTAT     =  0;     /* Disable all interrupts */
694         H3800_ASIC2_GPIINTSTAT     =  0;
695
696         H3800_ASIC2_KPIINTCLR      =  0;     /* Clear all KPIO interrupts */
697         H3800_ASIC2_GPIINTCLR      =  0;     /* Clear all GPIO interrupts */
698
699 //      H3800_ASIC2_KPIINTCLR      =  0xffff;     /* Clear all KPIO interrupts */
700 //      H3800_ASIC2_GPIINTCLR      =  0xffff;     /* Clear all GPIO interrupts */
701
702         H3800_ASIC2_CLOCK_Enable       |= ASIC2_CLOCK_EX0;   /* 32 kHZ crystal on */
703         H3800_ASIC2_INTR_ClockPrescale |= ASIC2_INTCPS_SET;
704         H3800_ASIC2_INTR_ClockPrescale  = ASIC2_INTCPS_CPS(0x0e) | ASIC2_INTCPS_SET;
705         H3800_ASIC2_INTR_TimerSet       = 1;
706
707 #if 0
708         for (i = 0; i < H3800_KPIO_IRQ_COUNT; i++) {
709                 int irq = i + H3800_KPIO_IRQ_START;
710                 irq_desc[irq].valid    = 1;
711                 irq_desc[irq].probe_ok = 1;
712                 set_irq_chip(irq, &h3800_kpio_irqchip);
713         }
714
715         for (i = 0; i < H3800_GPIO_IRQ_COUNT; i++) {
716                 int irq = i + H3800_GPIO_IRQ_START;
717                 irq_desc[irq].valid    = 1;
718                 irq_desc[irq].probe_ok = 1;
719                 set_irq_chip(irq, &h3800_gpio_irqchip);
720         }
721 #endif
722         set_irq_type(IRQ_GPIO_H3800_ASIC, IRQT_RISING);
723         set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, &h3800_IRQ_demux);
724 }
725
726
727 #define ASIC1_OUTPUTS    0x7fff   /* First 15 bits are used */
728
729 static void __init h3800_map_io(void)
730 {
731         h3xxx_map_io();
732
733         /* Add wakeup on AC plug/unplug */
734         PWER  |= PWER_GPIO12;
735
736         /* Initialize h3800-specific values here */
737         GPCR = 0x0fffffff;       /* All outputs are set low by default */
738         GAFR =  GPIO_H3800_CLK_OUT |
739                 GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
740                 GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
741         GPDR =  GPIO_H3800_CLK_OUT |
742                 GPIO_H3600_COM_RTS  | GPIO_H3600_L3_CLOCK |
743                 GPIO_H3600_L3_MODE  | GPIO_H3600_L3_DATA  |
744                 GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
745                 GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
746         TUCR =  TUCR_3_6864MHz;   /* Seems to be used only for the Bluetooth UART */
747
748         /* Fix the memory bus */
749         MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000;
750
751         /* Set up ASIC #1 */
752         H3800_ASIC1_GPIO_DIR            = ASIC1_OUTPUTS;            /* All outputs */
753         H3800_ASIC1_GPIO_MASK           = ASIC1_OUTPUTS;            /* No interrupts */
754         H3800_ASIC1_GPIO_SLEEP_MASK     = ASIC1_OUTPUTS;
755         H3800_ASIC1_GPIO_SLEEP_DIR      = ASIC1_OUTPUTS;
756         H3800_ASIC1_GPIO_SLEEP_OUT      = GPIO1_EAR_ON_N;
757         H3800_ASIC1_GPIO_BATT_FAULT_DIR = ASIC1_OUTPUTS;
758         H3800_ASIC1_GPIO_BATT_FAULT_OUT = GPIO1_EAR_ON_N;
759
760         H3800_ASIC1_GPIO_OUT = GPIO1_IR_ON_N
761                                       | GPIO1_RS232_ON
762                                       | GPIO1_EAR_ON_N;
763
764         /* Set up ASIC #2 */
765         H3800_ASIC2_GPIOPIOD    = GPIO2_IN_Y1_N | GPIO2_IN_X1_N;
766         H3800_ASIC2_GPOBFSTAT   = GPIO2_IN_Y1_N | GPIO2_IN_X1_N;
767
768         H3800_ASIC2_GPIODIR     = GPIO2_PEN_IRQ
769                                       | GPIO2_SD_DETECT
770                                       | GPIO2_EAR_IN_N
771                                       | GPIO2_USB_DETECT_N
772                                       | GPIO2_SD_CON_SLT;
773
774         /* TODO : Set sleep states & battery fault states */
775
776         /* Clear VPP Enable */
777         H3800_ASIC2_FlashWP_VPP_ON = 0;
778         ipaq_model_ops = h3800_model_ops;
779 }
780
781 MACHINE_START(H3800, "Compaq iPAQ H3800")
782         BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
783         BOOT_PARAMS(0xc0000100)
784         MAPIO(h3800_map_io)
785         INITIRQ(h3800_init_irq)
786 MACHINE_END
787
788 #endif /* CONFIG_SA1100_H3800 */