VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[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         INITTIME(sa1100_init_time)
290 MACHINE_END
291
292 #endif /* CONFIG_SA1100_H3100 */
293
294 /************************* H3600 *************************/
295
296 #ifdef CONFIG_SA1100_H3600
297
298 #define H3600_EGPIO     (*(volatile unsigned int *)H3600_EGPIO_VIRT)
299 static unsigned int h3600_egpio = EGPIO_H3600_RS232_ON;
300
301 static void h3600_control_egpio(enum ipaq_egpio_type x, int setp)
302 {
303         unsigned int egpio = 0;
304         unsigned long flags;
305
306         switch (x) {
307         case IPAQ_EGPIO_LCD_POWER:
308                 egpio |= EGPIO_H3600_LCD_ON |
309                          EGPIO_H3600_LCD_PCI |
310                          EGPIO_H3600_LCD_5V_ON |
311                          EGPIO_H3600_LVDD_ON;
312                 do_blank(setp);
313                 break;
314         case IPAQ_EGPIO_LCD_ENABLE:
315                 break;
316         case IPAQ_EGPIO_CODEC_NRESET:
317                 egpio |= EGPIO_H3600_CODEC_NRESET;
318                 break;
319         case IPAQ_EGPIO_AUDIO_ON:
320                 egpio |= EGPIO_H3600_AUD_AMP_ON |
321                          EGPIO_H3600_AUD_PWR_ON;
322                 break;
323         case IPAQ_EGPIO_QMUTE:
324                 egpio |= EGPIO_H3600_QMUTE;
325                 break;
326         case IPAQ_EGPIO_OPT_NVRAM_ON:
327                 egpio |= EGPIO_H3600_OPT_NVRAM_ON;
328                 break;
329         case IPAQ_EGPIO_OPT_ON:
330                 egpio |= EGPIO_H3600_OPT_ON;
331                 break;
332         case IPAQ_EGPIO_CARD_RESET:
333                 egpio |= EGPIO_H3600_CARD_RESET;
334                 break;
335         case IPAQ_EGPIO_OPT_RESET:
336                 egpio |= EGPIO_H3600_OPT_RESET;
337                 break;
338         case IPAQ_EGPIO_IR_ON:
339                 egpio |= EGPIO_H3600_IR_ON;
340                 break;
341         case IPAQ_EGPIO_IR_FSEL:
342                 egpio |= EGPIO_H3600_IR_FSEL;
343                 break;
344         case IPAQ_EGPIO_RS232_ON:
345                 egpio |= EGPIO_H3600_RS232_ON;
346                 break;
347         case IPAQ_EGPIO_VPP_ON:
348                 egpio |= EGPIO_H3600_VPP_ON;
349                 break;
350         }
351
352         if (egpio) {
353                 local_irq_save(flags);
354                 if (setp)
355                         h3600_egpio |= egpio;
356                 else
357                         h3600_egpio &= ~egpio;
358                 H3600_EGPIO = h3600_egpio;
359                 local_irq_restore(flags);
360         }
361 }
362
363 static unsigned long h3600_read_egpio(void)
364 {
365         return h3600_egpio;
366 }
367
368 static int h3600_pm_callback(int req)
369 {
370         if (ipaq_model_ops.pm_callback_aux)
371                 return ipaq_model_ops.pm_callback_aux(req);
372         return 0;
373 }
374
375 static struct ipaq_model_ops h3600_model_ops __initdata = {
376         .generic_name   = "3600",
377         .control        = h3600_control_egpio,
378         .read           = h3600_read_egpio,
379         .pm_callback    = h3600_pm_callback
380 };
381
382 static void __init h3600_map_io(void)
383 {
384         h3xxx_map_io();
385
386         /* Initialize h3600-specific values here */
387
388         GPCR = 0x0fffffff;       /* All outputs are set low by default */
389         GPDR = GPIO_H3600_COM_RTS  | GPIO_H3600_L3_CLOCK |
390                GPIO_H3600_L3_MODE  | GPIO_H3600_L3_DATA  |
391                GPIO_H3600_CLK_SET1 | GPIO_H3600_CLK_SET0 |
392                GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
393                GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
394
395         H3600_EGPIO = h3600_egpio;         /* Maintains across sleep? */
396         ipaq_model_ops = h3600_model_ops;
397 }
398
399 MACHINE_START(H3600, "Compaq iPAQ H3600")
400         BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
401         BOOT_PARAMS(0xc0000100)
402         MAPIO(h3600_map_io)
403         INITIRQ(sa1100_init_irq)
404         INITTIME(sa1100_init_time)
405 MACHINE_END
406
407 #endif /* CONFIG_SA1100_H3600 */
408
409 #ifdef CONFIG_SA1100_H3800
410
411 #define SET_ASIC1(x) \
412    do {if (setp) { H3800_ASIC1_GPIO_OUT |= (x); } else { H3800_ASIC1_GPIO_OUT &= ~(x); }} while(0)
413
414 #define SET_ASIC2(x) \
415    do {if (setp) { H3800_ASIC2_GPIOPIOD |= (x); } else { H3800_ASIC2_GPIOPIOD &= ~(x); }} while(0)
416
417 #define CLEAR_ASIC1(x) \
418    do {if (setp) { H3800_ASIC1_GPIO_OUT &= ~(x); } else { H3800_ASIC1_GPIO_OUT |= (x); }} while(0)
419
420 #define CLEAR_ASIC2(x) \
421    do {if (setp) { H3800_ASIC2_GPIOPIOD &= ~(x); } else { H3800_ASIC2_GPIOPIOD |= (x); }} while(0)
422
423
424 /*
425   On screen enable, we get
426
427      h3800_video_power_on(1)
428      LCD controller starts
429      h3800_video_lcd_enable(1)
430
431   On screen disable, we get
432
433      h3800_video_lcd_enable(0)
434      LCD controller stops
435      h3800_video_power_on(0)
436 */
437
438
439 static void h3800_video_power_on(int setp)
440 {
441         if (setp) {
442                 H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_ON;
443                 msleep(30);
444                 H3800_ASIC1_GPIO_OUT |= GPIO1_VGL_ON;
445                 msleep(5);
446                 H3800_ASIC1_GPIO_OUT |= GPIO1_VGH_ON;
447                 msleep(50);
448                 H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_5V_ON;
449                 msleep(5);
450         } else {
451                 msleep(5);
452                 H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_5V_ON;
453                 msleep(50);
454                 H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGL_ON;
455                 msleep(5);
456                 H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGH_ON;
457                 msleep(100);
458                 H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_ON;
459         }
460 }
461
462 static void h3800_video_lcd_enable(int setp)
463 {
464         if (setp) {
465                 msleep(17);     // Wait one from before turning on
466                 H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_PCI;
467         } else {
468                 H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_PCI;
469                 msleep(30);     // Wait before turning off
470         }
471 }
472
473
474 static void h3800_control_egpio(enum ipaq_egpio_type x, int setp)
475 {
476         switch (x) {
477         case IPAQ_EGPIO_LCD_POWER:
478                 h3800_video_power_on(setp);
479                 break;
480         case IPAQ_EGPIO_LCD_ENABLE:
481                 h3800_video_lcd_enable(setp);
482                 break;
483         case IPAQ_EGPIO_CODEC_NRESET:
484         case IPAQ_EGPIO_AUDIO_ON:
485         case IPAQ_EGPIO_QMUTE:
486                 printk("%s: error - should not be called\n", __FUNCTION__);
487                 break;
488         case IPAQ_EGPIO_OPT_NVRAM_ON:
489                 SET_ASIC2(GPIO2_OPT_ON_NVRAM);
490                 break;
491         case IPAQ_EGPIO_OPT_ON:
492                 SET_ASIC2(GPIO2_OPT_ON);
493                 break;
494         case IPAQ_EGPIO_CARD_RESET:
495                 SET_ASIC2(GPIO2_OPT_PCM_RESET);
496                 break;
497         case IPAQ_EGPIO_OPT_RESET:
498                 SET_ASIC2(GPIO2_OPT_RESET);
499                 break;
500         case IPAQ_EGPIO_IR_ON:
501                 CLEAR_ASIC1(GPIO1_IR_ON_N);
502                 break;
503         case IPAQ_EGPIO_IR_FSEL:
504                 break;
505         case IPAQ_EGPIO_RS232_ON:
506                 SET_ASIC1(GPIO1_RS232_ON);
507                 break;
508         case IPAQ_EGPIO_VPP_ON:
509                 H3800_ASIC2_FlashWP_VPP_ON = setp;
510                 break;
511         }
512 }
513
514 static unsigned long h3800_read_egpio(void)
515 {
516         return H3800_ASIC1_GPIO_OUT | (H3800_ASIC2_GPIOPIOD << 16);
517 }
518
519 /* We need to fix ASIC2 GPIO over suspend/resume.  At the moment,
520    it doesn't appear that ASIC1 GPIO has the same problem */
521
522 static int h3800_pm_callback(int req)
523 {
524         static u16 asic1_data;
525         static u16 asic2_data;
526         int result = 0;
527
528         printk("%s %d\n", __FUNCTION__, req);
529
530         switch (req) {
531         case PM_RESUME:
532                 MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000;  /* Set MSC2 correctly */
533
534                 H3800_ASIC2_GPIOPIOD = asic2_data;
535                 H3800_ASIC2_GPIODIR = GPIO2_PEN_IRQ
536                         | GPIO2_SD_DETECT
537                         | GPIO2_EAR_IN_N
538                         | GPIO2_USB_DETECT_N
539                         | GPIO2_SD_CON_SLT;
540
541                 H3800_ASIC1_GPIO_OUT = asic1_data;
542
543                 if (ipaq_model_ops.pm_callback_aux)
544                         result = ipaq_model_ops.pm_callback_aux(req);
545                 break;
546
547         case PM_SUSPEND:
548                 if (ipaq_model_ops.pm_callback_aux &&
549                      ((result = ipaq_model_ops.pm_callback_aux(req)) != 0))
550                         return result;
551
552                 asic1_data = H3800_ASIC1_GPIO_OUT;
553                 asic2_data = H3800_ASIC2_GPIOPIOD;
554                 break;
555         default:
556                 printk("%s: unrecognized PM callback\n", __FUNCTION__);
557                 break;
558         }
559         return result;
560 }
561
562 static struct ipaq_model_ops h3800_model_ops __initdata = {
563         .generic_name   = "3800",
564         .control        = h3800_control_egpio,
565         .read           = h3800_read_egpio,
566         .pm_callback    = h3800_pm_callback
567 };
568
569 #define MAX_ASIC_ISR_LOOPS    20
570
571 /* The order of these is important - see #include <asm/arch/irqs.h> */
572 static u32 kpio_irq_mask[] = {
573         KPIO_KEY_ALL,
574         KPIO_SPI_INT,
575         KPIO_OWM_INT,
576         KPIO_ADC_INT,
577         KPIO_UART_0_INT,
578         KPIO_UART_1_INT,
579         KPIO_TIMER_0_INT,
580         KPIO_TIMER_1_INT,
581         KPIO_TIMER_2_INT
582 };
583
584 static u32 gpio_irq_mask[] = {
585         GPIO2_PEN_IRQ,
586         GPIO2_SD_DETECT,
587         GPIO2_EAR_IN_N,
588         GPIO2_USB_DETECT_N,
589         GPIO2_SD_CON_SLT,
590 };
591
592 static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
593 {
594         int i;
595
596         if (0) printk("%s: interrupt received\n", __FUNCTION__);
597
598         desc->chip->ack(irq);
599
600         for (i = 0; i < MAX_ASIC_ISR_LOOPS && (GPLR & GPIO_H3800_ASIC); i++) {
601                 u32 irq;
602                 int j;
603
604                 /* KPIO */
605                 irq = H3800_ASIC2_KPIINTFLAG;
606                 if (0) printk("%s KPIO 0x%08X\n", __FUNCTION__, irq);
607                 for (j = 0; j < H3800_KPIO_IRQ_COUNT; j++)
608                         if (irq & kpio_irq_mask[j])
609                                 do_edge_IRQ(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j, regs);
610
611                 /* GPIO2 */
612                 irq = H3800_ASIC2_GPIINTFLAG;
613                 if (0) printk("%s GPIO 0x%08X\n", __FUNCTION__, irq);
614                 for (j = 0; j < H3800_GPIO_IRQ_COUNT; j++)
615                         if (irq & gpio_irq_mask[j])
616                                 do_edge_IRQ(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j , regs);
617         }
618
619         if (i >= MAX_ASIC_ISR_LOOPS)
620                 printk("%s: interrupt processing overrun\n", __FUNCTION__);
621
622         /* For level-based interrupts */
623         desc->chip->unmask(irq);
624
625 }
626
627 static struct irqaction h3800_irq = {
628         .name           = "h3800_asic",
629         .handler        = h3800_IRQ_demux,
630         .flags          = SA_INTERRUPT,
631 };
632
633 u32 kpio_int_shadow = 0;
634
635
636 /* mask_ack <- IRQ is first serviced.
637        mask <- IRQ is disabled.
638      unmask <- IRQ is enabled
639
640      The INTCLR registers are poorly documented.  I believe that writing
641      a "1" to the register clears the specific interrupt, but the documentation
642      indicates writing a "0" clears the interrupt.  In any case, they shouldn't
643      be read (that's the INTFLAG register)
644  */
645
646 static void h3800_mask_ack_kpio_irq(unsigned int irq)
647 {
648         u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
649         kpio_int_shadow &= ~mask;
650         H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
651         H3800_ASIC2_KPIINTCLR  = mask;
652 }
653
654 static void h3800_mask_kpio_irq(unsigned int irq)
655 {
656         u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
657         kpio_int_shadow &= ~mask;
658         H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
659 }
660
661 static void h3800_unmask_kpio_irq(unsigned int irq)
662 {
663         u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
664         kpio_int_shadow |= mask;
665         H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
666 }
667
668 static void h3800_mask_ack_gpio_irq(unsigned int irq)
669 {
670         u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
671         H3800_ASIC2_GPIINTSTAT &= ~mask;
672         H3800_ASIC2_GPIINTCLR   = mask;
673 }
674
675 static void h3800_mask_gpio_irq(unsigned int irq)
676 {
677         u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
678         H3800_ASIC2_GPIINTSTAT &= ~mask;
679         }
680
681 static void h3800_unmask_gpio_irq(unsigned int irq)
682 {
683         u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
684         H3800_ASIC2_GPIINTSTAT |= mask;
685 }
686
687 static void __init h3800_init_irq(void)
688 {
689         int i;
690
691         /* Initialize standard IRQs */
692         sa1100_init_irq();
693
694         /* Disable all IRQs and set up clock */
695         H3800_ASIC2_KPIINTSTAT     =  0;     /* Disable all interrupts */
696         H3800_ASIC2_GPIINTSTAT     =  0;
697
698         H3800_ASIC2_KPIINTCLR      =  0;     /* Clear all KPIO interrupts */
699         H3800_ASIC2_GPIINTCLR      =  0;     /* Clear all GPIO interrupts */
700
701 //      H3800_ASIC2_KPIINTCLR      =  0xffff;     /* Clear all KPIO interrupts */
702 //      H3800_ASIC2_GPIINTCLR      =  0xffff;     /* Clear all GPIO interrupts */
703
704         H3800_ASIC2_CLOCK_Enable       |= ASIC2_CLOCK_EX0;   /* 32 kHZ crystal on */
705         H3800_ASIC2_INTR_ClockPrescale |= ASIC2_INTCPS_SET;
706         H3800_ASIC2_INTR_ClockPrescale  = ASIC2_INTCPS_CPS(0x0e) | ASIC2_INTCPS_SET;
707         H3800_ASIC2_INTR_TimerSet       = 1;
708
709 #if 0
710         for (i = 0; i < H3800_KPIO_IRQ_COUNT; i++) {
711                 int irq = i + H3800_KPIO_IRQ_START;
712                 irq_desc[irq].valid    = 1;
713                 irq_desc[irq].probe_ok = 1;
714                 set_irq_chip(irq, &h3800_kpio_irqchip);
715         }
716
717         for (i = 0; i < H3800_GPIO_IRQ_COUNT; i++) {
718                 int irq = i + H3800_GPIO_IRQ_START;
719                 irq_desc[irq].valid    = 1;
720                 irq_desc[irq].probe_ok = 1;
721                 set_irq_chip(irq, &h3800_gpio_irqchip);
722         }
723 #endif
724         set_irq_type(IRQ_GPIO_H3800_ASIC, IRQT_RISING);
725         set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, &h3800_IRQ_demux);
726 }
727
728
729 #define ASIC1_OUTPUTS    0x7fff   /* First 15 bits are used */
730
731 static void __init h3800_map_io(void)
732 {
733         h3xxx_map_io();
734
735         /* Add wakeup on AC plug/unplug */
736         PWER  |= PWER_GPIO12;
737
738         /* Initialize h3800-specific values here */
739         GPCR = 0x0fffffff;       /* All outputs are set low by default */
740         GAFR =  GPIO_H3800_CLK_OUT |
741                 GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
742                 GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
743         GPDR =  GPIO_H3800_CLK_OUT |
744                 GPIO_H3600_COM_RTS  | GPIO_H3600_L3_CLOCK |
745                 GPIO_H3600_L3_MODE  | GPIO_H3600_L3_DATA  |
746                 GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
747                 GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
748         TUCR =  TUCR_3_6864MHz;   /* Seems to be used only for the Bluetooth UART */
749
750         /* Fix the memory bus */
751         MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000;
752
753         /* Set up ASIC #1 */
754         H3800_ASIC1_GPIO_DIR            = ASIC1_OUTPUTS;            /* All outputs */
755         H3800_ASIC1_GPIO_MASK           = ASIC1_OUTPUTS;            /* No interrupts */
756         H3800_ASIC1_GPIO_SLEEP_MASK     = ASIC1_OUTPUTS;
757         H3800_ASIC1_GPIO_SLEEP_DIR      = ASIC1_OUTPUTS;
758         H3800_ASIC1_GPIO_SLEEP_OUT      = GPIO1_EAR_ON_N;
759         H3800_ASIC1_GPIO_BATT_FAULT_DIR = ASIC1_OUTPUTS;
760         H3800_ASIC1_GPIO_BATT_FAULT_OUT = GPIO1_EAR_ON_N;
761
762         H3800_ASIC1_GPIO_OUT = GPIO1_IR_ON_N
763                                       | GPIO1_RS232_ON
764                                       | GPIO1_EAR_ON_N;
765
766         /* Set up ASIC #2 */
767         H3800_ASIC2_GPIOPIOD    = GPIO2_IN_Y1_N | GPIO2_IN_X1_N;
768         H3800_ASIC2_GPOBFSTAT   = GPIO2_IN_Y1_N | GPIO2_IN_X1_N;
769
770         H3800_ASIC2_GPIODIR     = GPIO2_PEN_IRQ
771                                       | GPIO2_SD_DETECT
772                                       | GPIO2_EAR_IN_N
773                                       | GPIO2_USB_DETECT_N
774                                       | GPIO2_SD_CON_SLT;
775
776         /* TODO : Set sleep states & battery fault states */
777
778         /* Clear VPP Enable */
779         H3800_ASIC2_FlashWP_VPP_ON = 0;
780         ipaq_model_ops = h3800_model_ops;
781 }
782
783 MACHINE_START(H3800, "Compaq iPAQ H3800")
784         BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
785         BOOT_PARAMS(0xc0000100)
786         MAPIO(h3800_map_io)
787         INITIRQ(h3800_init_irq)
788         INITTIME(sa1100_init_time)
789 MACHINE_END
790
791 #endif /* CONFIG_SA1100_H3800 */