2 * linux/arch/arm/mach-footbridge/netwinder-hw.c
4 * Netwinder machine fixup
6 * Copyright (C) 1998, 1999 Russell King, Phil Blundell
8 #include <linux/config.h>
9 #include <linux/module.h>
10 #include <linux/ioport.h>
11 #include <linux/kernel.h>
12 #include <linux/delay.h>
13 #include <linux/init.h>
15 #include <asm/hardware/dec21285.h>
18 #include <asm/mach-types.h>
19 #include <asm/setup.h>
21 #include <asm/mach/arch.h>
25 #define IRDA_IO_BASE 0x180
26 #define GP1_IO_BASE 0x338
27 #define GP2_IO_BASE 0x33a
31 #define DEFAULT_LEDS 0
33 #define DEFAULT_LEDS GPIO_GREEN_LED
37 * Winbond WB83977F accessibility stuff
39 static inline void wb977_open(void)
45 static inline void wb977_close(void)
50 static inline void wb977_wb(int reg
, int val
)
56 static inline void wb977_ww(int reg
, int val
)
59 outb(val
>> 8, 0x371);
61 outb(val
& 255, 0x371);
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)
69 * This is a lock for accessing ports GP1_IO_BASE and GP2_IO_BASE
71 DEFINE_SPINLOCK(gpio_lock
);
73 static unsigned int current_gpio_op
;
74 static unsigned int current_gpio_io
;
75 static unsigned int current_cpld
;
77 void gpio_modify_op(int mask
, int set
)
79 unsigned int new_gpio
, changed
;
81 new_gpio
= (current_gpio_op
& ~mask
) | set
;
82 changed
= new_gpio
^ current_gpio_op
;
83 current_gpio_op
= new_gpio
;
86 outb(new_gpio
, GP1_IO_BASE
);
88 outb(new_gpio
>> 8, GP2_IO_BASE
);
91 static inline void __gpio_modify_io(int mask
, int in
)
93 unsigned int new_gpio
, changed
;
96 new_gpio
= (current_gpio_io
& ~mask
) | in
;
97 changed
= new_gpio
^ current_gpio_io
;
98 current_gpio_io
= new_gpio
;
103 wb977_device_select(7);
105 for (port
= 0xe1; changed
&& port
< 0xe8; changed
>>= 1) {
106 wb977_wb(port
, new_gpio
& 1);
112 wb977_device_select(8);
114 for (port
= 0xe8; changed
&& port
< 0xec; changed
>>= 1) {
115 wb977_wb(port
, new_gpio
& 1);
122 void gpio_modify_io(int mask
, int in
)
124 /* Open up the SuperIO chip */
127 __gpio_modify_io(mask
, in
);
129 /* Close up the EFER gate */
135 return inb(GP1_IO_BASE
) | inb(GP2_IO_BASE
) << 8;
139 * Initialise the Winbond W83977F global registers
141 static inline void wb977_init_global(void)
144 * Enable R/W config registers
146 wb977_wb(0x26, 0x40);
149 * Power down FDC (not used)
151 wb977_wb(0x22, 0xfe);
154 * GP12, GP11, CIRRX, IRRXH, GP10
156 wb977_wb(0x2a, 0xc1);
159 * GP23, GP22, GP21, GP20, GP13
161 wb977_wb(0x2b, 0x6b);
164 * GP17, GP16, GP15, GP14
166 wb977_wb(0x2c, 0x55);
170 * Initialise the Winbond W83977F printer port
172 static inline void wb977_init_printer(void)
174 wb977_device_select(1);
179 wb977_wb(0xf0, 0x01);
183 * Initialise the Winbond W83977F keyboard controller
185 static inline void wb977_init_keyboard(void)
187 wb977_device_select(5);
190 * Keyboard controller address
192 wb977_ww(0x60, 0x0060);
193 wb977_ww(0x62, 0x0064);
196 * Keyboard IRQ 1, active high, edge trigger
199 wb977_wb(0x71, 0x02);
202 * Mouse IRQ 5, active high, edge trigger
205 wb977_wb(0x73, 0x02);
210 wb977_wb(0xf0, 0x40);
215 wb977_device_enable();
219 * Initialise the Winbond W83977F Infra-Red device
221 static inline void wb977_init_irda(void)
223 wb977_device_select(6);
228 wb977_ww(0x60, IRDA_IO_BASE
);
231 * IRDA IRQ 6, active high, edge trigger
234 wb977_wb(0x71, 0x02);
239 wb977_wb(0x74, 0x00);
242 * TX DMA - Disable Tx DMA
244 wb977_wb(0x75, 0x04);
247 * Append CRC, Enable bank selection
249 wb977_wb(0xf0, 0x03);
254 wb977_device_enable();
258 * Initialise Winbond W83977F general purpose IO
260 static inline void wb977_init_gpio(void)
265 * Set up initial I/O definitions
267 current_gpio_io
= -1;
268 __gpio_modify_io(-1, GPIO_DONE
| GPIO_WDTIMER
);
270 wb977_device_select(7);
273 * Group1 base address
275 wb977_ww(0x60, GP1_IO_BASE
);
280 * GP10 (Orage button) IRQ 10, active high, edge trigger
283 wb977_wb(0x71, 0x02);
286 * GP10: Debounce filter enabled, IRQ, input
288 wb977_wb(0xe0, 0x19);
293 wb977_device_enable();
295 wb977_device_select(8);
298 * Group2 base address
300 wb977_ww(0x60, GP2_IO_BASE
);
303 * Clear watchdog timer regs
306 wb977_wb(0xf2, 0x00);
309 * - disable LED, no mouse nor keyboard IRQ
311 wb977_wb(0xf3, 0x00);
314 * - timer counting, disable power LED, disable timeouot
316 wb977_wb(0xf4, 0x00);
321 wb977_device_enable();
324 * Set Group1/Group2 outputs
326 spin_lock_irqsave(&gpio_lock
, flags
);
327 gpio_modify_op(-1, GPIO_RED_LED
| GPIO_FAN
);
328 spin_unlock_irqrestore(&gpio_lock
, flags
);
332 * Initialise the Winbond W83977F chip.
334 static void __init
wb977_init(void)
336 request_region(0x370, 2, "W83977AF configuration");
339 * Open up the SuperIO chip
344 * Initialise the global registers
349 * Initialise the various devices in
352 wb977_init_printer();
353 wb977_init_keyboard();
358 * Close up the EFER gate
363 void cpld_modify(int mask
, int set
)
367 current_cpld
= (current_cpld
& ~mask
) | set
;
369 gpio_modify_io(GPIO_DATA
| GPIO_IOCLK
| GPIO_IOLOAD
, 0);
370 gpio_modify_op(GPIO_IOLOAD
, 0);
372 for (msk
= 8; msk
; msk
>>= 1) {
373 int bit
= current_cpld
& msk
;
375 gpio_modify_op(GPIO_DATA
| GPIO_IOCLK
, bit
? GPIO_DATA
: 0);
376 gpio_modify_op(GPIO_IOCLK
, GPIO_IOCLK
);
379 gpio_modify_op(GPIO_IOCLK
|GPIO_DATA
, 0);
380 gpio_modify_op(GPIO_IOLOAD
|GPIO_DSCLK
, GPIO_IOLOAD
|GPIO_DSCLK
);
381 gpio_modify_op(GPIO_IOLOAD
, 0);
384 static void __init
cpld_init(void)
388 spin_lock_irqsave(&gpio_lock
, flags
);
389 cpld_modify(-1, CPLD_UNMUTE
| CPLD_7111_DISABLE
);
390 spin_unlock_irqrestore(&gpio_lock
, flags
);
393 static unsigned char rwa_unlock
[] __initdata
=
394 { 0x00, 0x00, 0x6a, 0xb5, 0xda, 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b,
395 0x0d, 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, 0xd1, 0xe8, 0x74,
396 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39 };
399 #define dprintk(x...)
401 #define dprintk(x...) printk(x)
404 #define WRITE_RWA(r,v) do { outb((r), 0x279); udelay(10); outb((v), 0xa79); } while (0)
406 static inline void rwa010_unlock(void)
413 for (i
= 0; i
< sizeof(rwa_unlock
); i
++) {
414 outb(rwa_unlock
[i
], 0x279);
419 static inline void rwa010_read_ident(void)
431 dprintk("Identifier: ");
432 for (i
= 0; i
< 9; i
++) {
434 for (j
= 0; j
< 8; j
++) {
440 dprintk("%02X ", bit
);
441 bit
= (bit
== 0xaa) ? 1 : 0;
444 dprintk("(%02X) ", si
[i
]);
449 static inline void rwa010_global_init(void)
451 WRITE_RWA(6, 2); // Assign a card no = 2
453 dprintk("Card no = %d\n", inb(0x203));
455 /* disable the modem section of the chip */
459 /* disable the cdrom section of the chip */
463 /* disable the MPU-401 section of the chip */
468 static inline void rwa010_game_port_init(void)
474 dprintk("Slider base: ");
479 dprintk("%02X%02X (201)\n", inb(0x203), i
);
484 static inline void rwa010_waveartist_init(int base
, int irq
, int dma
)
490 dprintk("WaveArtist base: ");
491 WRITE_RWA(0x61, base
& 255);
494 WRITE_RWA(0x60, base
>> 8);
495 dprintk("%02X%02X (%X),", inb(0x203), i
, base
);
497 WRITE_RWA(0x70, irq
);
498 dprintk(" irq: %d (%d),", inb(0x203), irq
);
500 WRITE_RWA(0x74, dma
);
501 dprintk(" dma: %d (%d)\n", inb(0x203), dma
);
506 static inline void rwa010_soundblaster_init(int sb_base
, int al_base
, int irq
, int dma
)
512 dprintk("SoundBlaster base: ");
513 WRITE_RWA(0x61, sb_base
& 255);
516 WRITE_RWA(0x60, sb_base
>> 8);
517 dprintk("%02X%02X (%X),", inb(0x203), i
, sb_base
);
520 WRITE_RWA(0x70, irq
);
521 dprintk("%d (%d),", inb(0x203), irq
);
523 dprintk(" 8-bit DMA: ");
524 WRITE_RWA(0x74, dma
);
525 dprintk("%d (%d)\n", inb(0x203), dma
);
527 dprintk("AdLib base: ");
528 WRITE_RWA(0x63, al_base
& 255);
531 WRITE_RWA(0x62, al_base
>> 8);
532 dprintk("%02X%02X (%X)\n", inb(0x203), i
, al_base
);
537 static void rwa010_soundblaster_reset(void)
545 for (i
= 0; i
< 5; i
++) {
546 if (inb(0x22e) & 0x80)
551 printk("SoundBlaster: DSP reset failed\n");
553 dprintk("SoundBlaster DSP reset: %02X (AA)\n", inb(0x22a));
555 for (i
= 0; i
< 5; i
++) {
556 if ((inb(0x22c) & 0x80) == 0)
562 printk("SoundBlaster: DSP not ready\n");
566 dprintk("SoundBlaster DSP id: ");
569 i
|= inb(0x22a) << 8;
570 dprintk("%04X\n", i
);
572 for (i
= 0; i
< 5; i
++) {
573 if ((inb(0x22c) & 0x80) == 0)
579 printk("SoundBlaster: could not turn speaker off\n");
589 static void __init
rwa010_init(void)
593 rwa010_global_init();
594 rwa010_game_port_init();
595 rwa010_waveartist_init(0x250, 3, 7);
596 rwa010_soundblaster_init(0x220, 0x388, 3, 1);
597 rwa010_soundblaster_reset();
600 EXPORT_SYMBOL(gpio_lock
);
601 EXPORT_SYMBOL(gpio_modify_op
);
602 EXPORT_SYMBOL(gpio_modify_io
);
603 EXPORT_SYMBOL(cpld_modify
);
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
610 static int __init
nw_hw_init(void)
612 if (machine_is_netwinder()) {
619 spin_lock_irqsave(&gpio_lock
, flags
);
620 gpio_modify_op(GPIO_RED_LED
|GPIO_GREEN_LED
, DEFAULT_LEDS
);
621 spin_unlock_irqrestore(&gpio_lock
, flags
);
626 __initcall(nw_hw_init
);
629 * Older NeTTroms either do not provide a parameters
630 * page, or they don't supply correct information in
631 * the parameter page.
634 fixup_netwinder(struct machine_desc
*desc
, struct tag
*tags
,
635 char **cmdline
, struct meminfo
*mi
)
638 extern int isapnp_disable
;
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.
649 MACHINE_START(NETWINDER
, "Rebel-NetWinder")
650 MAINTAINER("Russell King/Rebel.com")
651 BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE
, 0xfe000000)
652 BOOT_PARAMS(0x00000100)
653 VIDEO(0x000a0000, 0x000bffff)
656 FIXUP(fixup_netwinder
)
657 MAPIO(footbridge_map_io
)
658 INITIRQ(footbridge_init_irq
)