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