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