1 /* 2 * linux/arch/arm/mach-footbridge/netwinder-hw.c 3 * 4 * Netwinder machine fixup 5 * 6 * Copyright (C) 1998, 1999 Russell King, Phil Blundell 7 */ 8 #include <linux/module.h> 9 #include <linux/ioport.h> 10 #include <linux/kernel.h> 11 #include <linux/delay.h> 12 #include <linux/init.h> 13 #include <linux/io.h> 14 #include <linux/spinlock.h> 15 16 #include <asm/hardware/dec21285.h> 17 #include <asm/leds.h> 18 #include <asm/mach-types.h> 19 #include <asm/setup.h> 20 21 #include <asm/mach/arch.h> 22 23 #include "common.h" 24 25 #define IRDA_IO_BASE 0x180 26 #define GP1_IO_BASE 0x338 27 #define GP2_IO_BASE 0x33a 28 29 30 #ifdef CONFIG_LEDS 31 #define DEFAULT_LEDS 0 32 #else 33 #define DEFAULT_LEDS GPIO_GREEN_LED 34 #endif 35 36 /* 37 * Winbond WB83977F accessibility stuff 38 */ 39 static inline void wb977_open(void) 40 { 41 outb(0x87, 0x370); 42 outb(0x87, 0x370); 43 } 44 45 static inline void wb977_close(void) 46 { 47 outb(0xaa, 0x370); 48 } 49 50 static inline void wb977_wb(int reg, int val) 51 { 52 outb(reg, 0x370); 53 outb(val, 0x371); 54 } 55 56 static inline void wb977_ww(int reg, int val) 57 { 58 outb(reg, 0x370); 59 outb(val >> 8, 0x371); 60 outb(reg + 1, 0x370); 61 outb(val & 255, 0x371); 62 } 63 64 #define wb977_device_select(dev) wb977_wb(0x07, dev) 65 #define wb977_device_disable() wb977_wb(0x30, 0x00) 66 #define wb977_device_enable() wb977_wb(0x30, 0x01) 67 68 /* 69 * This is a lock for accessing ports GP1_IO_BASE and GP2_IO_BASE 70 */ 71 DEFINE_SPINLOCK(nw_gpio_lock); 72 EXPORT_SYMBOL(nw_gpio_lock); 73 74 static unsigned int current_gpio_op; 75 static unsigned int current_gpio_io; 76 static unsigned int current_cpld; 77 78 void nw_gpio_modify_op(unsigned int mask, unsigned int set) 79 { 80 unsigned int new_gpio, changed; 81 82 new_gpio = (current_gpio_op & ~mask) | set; 83 changed = new_gpio ^ current_gpio_op; 84 current_gpio_op = new_gpio; 85 86 if (changed & 0xff) 87 outb(new_gpio, GP1_IO_BASE); 88 if (changed & 0xff00) 89 outb(new_gpio >> 8, GP2_IO_BASE); 90 } 91 EXPORT_SYMBOL(nw_gpio_modify_op); 92 93 static inline void __gpio_modify_io(int mask, int in) 94 { 95 unsigned int new_gpio, changed; 96 int port; 97 98 new_gpio = (current_gpio_io & ~mask) | in; 99 changed = new_gpio ^ current_gpio_io; 100 current_gpio_io = new_gpio; 101 102 changed >>= 1; 103 new_gpio >>= 1; 104 105 wb977_device_select(7); 106 107 for (port = 0xe1; changed && port < 0xe8; changed >>= 1) { 108 wb977_wb(port, new_gpio & 1); 109 110 port += 1; 111 new_gpio >>= 1; 112 } 113 114 wb977_device_select(8); 115 116 for (port = 0xe8; changed && port < 0xec; changed >>= 1) { 117 wb977_wb(port, new_gpio & 1); 118 119 port += 1; 120 new_gpio >>= 1; 121 } 122 } 123 124 void nw_gpio_modify_io(unsigned int mask, unsigned int in) 125 { 126 /* Open up the SuperIO chip */ 127 wb977_open(); 128 129 __gpio_modify_io(mask, in); 130 131 /* Close up the EFER gate */ 132 wb977_close(); 133 } 134 EXPORT_SYMBOL(nw_gpio_modify_io); 135 136 unsigned int nw_gpio_read(void) 137 { 138 return inb(GP1_IO_BASE) | inb(GP2_IO_BASE) << 8; 139 } 140 EXPORT_SYMBOL(nw_gpio_read); 141 142 /* 143 * Initialise the Winbond W83977F global registers 144 */ 145 static inline void wb977_init_global(void) 146 { 147 /* 148 * Enable R/W config registers 149 */ 150 wb977_wb(0x26, 0x40); 151 152 /* 153 * Power down FDC (not used) 154 */ 155 wb977_wb(0x22, 0xfe); 156 157 /* 158 * GP12, GP11, CIRRX, IRRXH, GP10 159 */ 160 wb977_wb(0x2a, 0xc1); 161 162 /* 163 * GP23, GP22, GP21, GP20, GP13 164 */ 165 wb977_wb(0x2b, 0x6b); 166 167 /* 168 * GP17, GP16, GP15, GP14 169 */ 170 wb977_wb(0x2c, 0x55); 171 } 172 173 /* 174 * Initialise the Winbond W83977F printer port 175 */ 176 static inline void wb977_init_printer(void) 177 { 178 wb977_device_select(1); 179 180 /* 181 * mode 1 == EPP 182 */ 183 wb977_wb(0xf0, 0x01); 184 } 185 186 /* 187 * Initialise the Winbond W83977F keyboard controller 188 */ 189 static inline void wb977_init_keyboard(void) 190 { 191 wb977_device_select(5); 192 193 /* 194 * Keyboard controller address 195 */ 196 wb977_ww(0x60, 0x0060); 197 wb977_ww(0x62, 0x0064); 198 199 /* 200 * Keyboard IRQ 1, active high, edge trigger 201 */ 202 wb977_wb(0x70, 1); 203 wb977_wb(0x71, 0x02); 204 205 /* 206 * Mouse IRQ 5, active high, edge trigger 207 */ 208 wb977_wb(0x72, 5); 209 wb977_wb(0x73, 0x02); 210 211 /* 212 * KBC 8MHz 213 */ 214 wb977_wb(0xf0, 0x40); 215 216 /* 217 * Enable device 218 */ 219 wb977_device_enable(); 220 } 221 222 /* 223 * Initialise the Winbond W83977F Infra-Red device 224 */ 225 static inline void wb977_init_irda(void) 226 { 227 wb977_device_select(6); 228 229 /* 230 * IR base address 231 */ 232 wb977_ww(0x60, IRDA_IO_BASE); 233 234 /* 235 * IRDA IRQ 6, active high, edge trigger 236 */ 237 wb977_wb(0x70, 6); 238 wb977_wb(0x71, 0x02); 239 240 /* 241 * RX DMA - ISA DMA 0 242 */ 243 wb977_wb(0x74, 0x00); 244 245 /* 246 * TX DMA - Disable Tx DMA 247 */ 248 wb977_wb(0x75, 0x04); 249 250 /* 251 * Append CRC, Enable bank selection 252 */ 253 wb977_wb(0xf0, 0x03); 254 255 /* 256 * Enable device 257 */ 258 wb977_device_enable(); 259 } 260 261 /* 262 * Initialise Winbond W83977F general purpose IO 263 */ 264 static inline void wb977_init_gpio(void) 265 { 266 unsigned long flags; 267 268 /* 269 * Set up initial I/O definitions 270 */ 271 current_gpio_io = -1; 272 __gpio_modify_io(-1, GPIO_DONE | GPIO_WDTIMER); 273 274 wb977_device_select(7); 275 276 /* 277 * Group1 base address 278 */ 279 wb977_ww(0x60, GP1_IO_BASE); 280 wb977_ww(0x62, 0); 281 wb977_ww(0x64, 0); 282 283 /* 284 * GP10 (Orage button) IRQ 10, active high, edge trigger 285 */ 286 wb977_wb(0x70, 10); 287 wb977_wb(0x71, 0x02); 288 289 /* 290 * GP10: Debounce filter enabled, IRQ, input 291 */ 292 wb977_wb(0xe0, 0x19); 293 294 /* 295 * Enable Group1 296 */ 297 wb977_device_enable(); 298 299 wb977_device_select(8); 300 301 /* 302 * Group2 base address 303 */ 304 wb977_ww(0x60, GP2_IO_BASE); 305 306 /* 307 * Clear watchdog timer regs 308 * - timer disable 309 */ 310 wb977_wb(0xf2, 0x00); 311 312 /* 313 * - disable LED, no mouse nor keyboard IRQ 314 */ 315 wb977_wb(0xf3, 0x00); 316 317 /* 318 * - timer counting, disable power LED, disable timeouot 319 */ 320 wb977_wb(0xf4, 0x00); 321 322 /* 323 * Enable group2 324 */ 325 wb977_device_enable(); 326 327 /* 328 * Set Group1/Group2 outputs 329 */ 330 spin_lock_irqsave(&nw_gpio_lock, flags); 331 nw_gpio_modify_op(-1, GPIO_RED_LED | GPIO_FAN); 332 spin_unlock_irqrestore(&nw_gpio_lock, flags); 333 } 334 335 /* 336 * Initialise the Winbond W83977F chip. 337 */ 338 static void __init wb977_init(void) 339 { 340 request_region(0x370, 2, "W83977AF configuration"); 341 342 /* 343 * Open up the SuperIO chip 344 */ 345 wb977_open(); 346 347 /* 348 * Initialise the global registers 349 */ 350 wb977_init_global(); 351 352 /* 353 * Initialise the various devices in 354 * the multi-IO chip. 355 */ 356 wb977_init_printer(); 357 wb977_init_keyboard(); 358 wb977_init_irda(); 359 wb977_init_gpio(); 360 361 /* 362 * Close up the EFER gate 363 */ 364 wb977_close(); 365 } 366 367 void nw_cpld_modify(unsigned int mask, unsigned int set) 368 { 369 int msk; 370 371 current_cpld = (current_cpld & ~mask) | set; 372 373 nw_gpio_modify_io(GPIO_DATA | GPIO_IOCLK | GPIO_IOLOAD, 0); 374 nw_gpio_modify_op(GPIO_IOLOAD, 0); 375 376 for (msk = 8; msk; msk >>= 1) { 377 int bit = current_cpld & msk; 378 379 nw_gpio_modify_op(GPIO_DATA | GPIO_IOCLK, bit ? GPIO_DATA : 0); 380 nw_gpio_modify_op(GPIO_IOCLK, GPIO_IOCLK); 381 } 382 383 nw_gpio_modify_op(GPIO_IOCLK|GPIO_DATA, 0); 384 nw_gpio_modify_op(GPIO_IOLOAD|GPIO_DSCLK, GPIO_IOLOAD|GPIO_DSCLK); 385 nw_gpio_modify_op(GPIO_IOLOAD, 0); 386 } 387 EXPORT_SYMBOL(nw_cpld_modify); 388 389 static void __init cpld_init(void) 390 { 391 unsigned long flags; 392 393 spin_lock_irqsave(&nw_gpio_lock, flags); 394 nw_cpld_modify(-1, CPLD_UNMUTE | CPLD_7111_DISABLE); 395 spin_unlock_irqrestore(&nw_gpio_lock, flags); 396 } 397 398 static unsigned char rwa_unlock[] __initdata = 399 { 0x00, 0x00, 0x6a, 0xb5, 0xda, 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b, 400 0x0d, 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, 0xd1, 0xe8, 0x74, 401 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39 }; 402 403 #ifndef DEBUG 404 #define dprintk(x...) 405 #else 406 #define dprintk(x...) printk(x) 407 #endif 408 409 #define WRITE_RWA(r,v) do { outb((r), 0x279); udelay(10); outb((v), 0xa79); } while (0) 410 411 static inline void rwa010_unlock(void) 412 { 413 int i; 414 415 WRITE_RWA(2, 2); 416 mdelay(10); 417 418 for (i = 0; i < sizeof(rwa_unlock); i++) { 419 outb(rwa_unlock[i], 0x279); 420 udelay(10); 421 } 422 } 423 424 static inline void rwa010_read_ident(void) 425 { 426 unsigned char si[9]; 427 int i, j; 428 429 WRITE_RWA(3, 0); 430 WRITE_RWA(0, 128); 431 432 outb(1, 0x279); 433 434 mdelay(1); 435 436 dprintk("Identifier: "); 437 for (i = 0; i < 9; i++) { 438 si[i] = 0; 439 for (j = 0; j < 8; j++) { 440 int bit; 441 udelay(250); 442 inb(0x203); 443 udelay(250); 444 bit = inb(0x203); 445 dprintk("%02X ", bit); 446 bit = (bit == 0xaa) ? 1 : 0; 447 si[i] |= bit << j; 448 } 449 dprintk("(%02X) ", si[i]); 450 } 451 dprintk("\n"); 452 } 453 454 static inline void rwa010_global_init(void) 455 { 456 WRITE_RWA(6, 2); // Assign a card no = 2 457 458 dprintk("Card no = %d\n", inb(0x203)); 459 460 /* disable the modem section of the chip */ 461 WRITE_RWA(7, 3); 462 WRITE_RWA(0x30, 0); 463 464 /* disable the cdrom section of the chip */ 465 WRITE_RWA(7, 4); 466 WRITE_RWA(0x30, 0); 467 468 /* disable the MPU-401 section of the chip */ 469 WRITE_RWA(7, 2); 470 WRITE_RWA(0x30, 0); 471 } 472 473 static inline void rwa010_game_port_init(void) 474 { 475 int i; 476 477 WRITE_RWA(7, 5); 478 479 dprintk("Slider base: "); 480 WRITE_RWA(0x61, 1); 481 i = inb(0x203); 482 483 WRITE_RWA(0x60, 2); 484 dprintk("%02X%02X (201)\n", inb(0x203), i); 485 486 WRITE_RWA(0x30, 1); 487 } 488 489 static inline void rwa010_waveartist_init(int base, int irq, int dma) 490 { 491 int i; 492 493 WRITE_RWA(7, 0); 494 495 dprintk("WaveArtist base: "); 496 WRITE_RWA(0x61, base & 255); 497 i = inb(0x203); 498 499 WRITE_RWA(0x60, base >> 8); 500 dprintk("%02X%02X (%X),", inb(0x203), i, base); 501 502 WRITE_RWA(0x70, irq); 503 dprintk(" irq: %d (%d),", inb(0x203), irq); 504 505 WRITE_RWA(0x74, dma); 506 dprintk(" dma: %d (%d)\n", inb(0x203), dma); 507 508 WRITE_RWA(0x30, 1); 509 } 510 511 static inline void rwa010_soundblaster_init(int sb_base, int al_base, int irq, int dma) 512 { 513 int i; 514 515 WRITE_RWA(7, 1); 516 517 dprintk("SoundBlaster base: "); 518 WRITE_RWA(0x61, sb_base & 255); 519 i = inb(0x203); 520 521 WRITE_RWA(0x60, sb_base >> 8); 522 dprintk("%02X%02X (%X),", inb(0x203), i, sb_base); 523 524 dprintk(" irq: "); 525 WRITE_RWA(0x70, irq); 526 dprintk("%d (%d),", inb(0x203), irq); 527 528 dprintk(" 8-bit DMA: "); 529 WRITE_RWA(0x74, dma); 530 dprintk("%d (%d)\n", inb(0x203), dma); 531 532 dprintk("AdLib base: "); 533 WRITE_RWA(0x63, al_base & 255); 534 i = inb(0x203); 535 536 WRITE_RWA(0x62, al_base >> 8); 537 dprintk("%02X%02X (%X)\n", inb(0x203), i, al_base); 538 539 WRITE_RWA(0x30, 1); 540 } 541 542 static void rwa010_soundblaster_reset(void) 543 { 544 int i; 545 546 outb(1, 0x226); 547 udelay(3); 548 outb(0, 0x226); 549 550 for (i = 0; i < 5; i++) { 551 if (inb(0x22e) & 0x80) 552 break; 553 mdelay(1); 554 } 555 if (i == 5) 556 printk("SoundBlaster: DSP reset failed\n"); 557 558 dprintk("SoundBlaster DSP reset: %02X (AA)\n", inb(0x22a)); 559 560 for (i = 0; i < 5; i++) { 561 if ((inb(0x22c) & 0x80) == 0) 562 break; 563 mdelay(1); 564 } 565 566 if (i == 5) 567 printk("SoundBlaster: DSP not ready\n"); 568 else { 569 outb(0xe1, 0x22c); 570 571 dprintk("SoundBlaster DSP id: "); 572 i = inb(0x22a); 573 udelay(1); 574 i |= inb(0x22a) << 8; 575 dprintk("%04X\n", i); 576 577 for (i = 0; i < 5; i++) { 578 if ((inb(0x22c) & 0x80) == 0) 579 break; 580 mdelay(1); 581 } 582 583 if (i == 5) 584 printk("SoundBlaster: could not turn speaker off\n"); 585 586 outb(0xd3, 0x22c); 587 } 588 589 /* turn on OPL3 */ 590 outb(5, 0x38a); 591 outb(1, 0x38b); 592 } 593 594 static void __init rwa010_init(void) 595 { 596 rwa010_unlock(); 597 rwa010_read_ident(); 598 rwa010_global_init(); 599 rwa010_game_port_init(); 600 rwa010_waveartist_init(0x250, 3, 7); 601 rwa010_soundblaster_init(0x220, 0x388, 3, 1); 602 rwa010_soundblaster_reset(); 603 } 604 605 /* 606 * Initialise any other hardware after we've got the PCI bus 607 * initialised. We may need the PCI bus to talk to this other 608 * hardware. 609 */ 610 static int __init nw_hw_init(void) 611 { 612 if (machine_is_netwinder()) { 613 unsigned long flags; 614 615 wb977_init(); 616 cpld_init(); 617 rwa010_init(); 618 619 spin_lock_irqsave(&nw_gpio_lock, flags); 620 nw_gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, DEFAULT_LEDS); 621 spin_unlock_irqrestore(&nw_gpio_lock, flags); 622 } 623 return 0; 624 } 625 626 __initcall(nw_hw_init); 627 628 /* 629 * Older NeTTroms either do not provide a parameters 630 * page, or they don't supply correct information in 631 * the parameter page. 632 */ 633 static void __init 634 fixup_netwinder(struct machine_desc *desc, struct tag *tags, 635 char **cmdline, struct meminfo *mi) 636 { 637 #ifdef CONFIG_ISAPNP 638 extern int isapnp_disable; 639 640 /* 641 * We must not use the kernels ISAPnP code 642 * on the NetWinder - it will reset the settings 643 * for the WaveArtist chip and render it inoperable. 644 */ 645 isapnp_disable = 1; 646 #endif 647 } 648 649 MACHINE_START(NETWINDER, "Rebel-NetWinder") 650 /* Maintainer: Russell King/Rebel.com */ 651 .boot_params = 0x00000100, 652 .video_start = 0x000a0000, 653 .video_end = 0x000bffff, 654 .reserve_lp0 = 1, 655 .reserve_lp2 = 1, 656 .fixup = fixup_netwinder, 657 .map_io = footbridge_map_io, 658 .init_irq = footbridge_init_irq, 659 .timer = &isa_timer, 660 MACHINE_END 661