RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / arch / alpha / kernel / smc37c669.c
blob536768dc8b8a07fce92c54e589049a5c208551e0
1 /*
2 * SMC 37C669 initialization code
3 */
4 #include <linux/kernel.h>
6 #include <linux/mm.h>
7 #include <linux/init.h>
8 #include <linux/delay.h>
9 #include <linux/spinlock.h>
11 #include <asm/hwrpb.h>
12 #include <asm/io.h>
13 #include <asm/segment.h>
15 # define DBG_DEVS(args)
17 #define KB 1024
18 #define MB (1024*KB)
19 #define GB (1024*MB)
21 #define SMC_DEBUG 0
23 /* File: smcc669_def.h
25 * Copyright (C) 1997 by
26 * Digital Equipment Corporation, Maynard, Massachusetts.
27 * All rights reserved.
29 * This software is furnished under a license and may be used and copied
30 * only in accordance of the terms of such license and with the
31 * inclusion of the above copyright notice. This software or any other
32 * copies thereof may not be provided or otherwise made available to any
33 * other person. No title to and ownership of the software is hereby
34 * transferred.
36 * The information in this software is subject to change without notice
37 * and should not be construed as a commitment by Digital Equipment
38 * Corporation.
40 * Digital assumes no responsibility for the use or reliability of its
41 * software on equipment which is not supplied by Digital.
44 * Abstract:
46 * This file contains header definitions for the SMC37c669
47 * Super I/O controller.
49 * Author:
51 * Eric Rasmussen
53 * Modification History:
55 * er 28-Jan-1997 Initial Entry
58 #ifndef __SMC37c669_H
59 #define __SMC37c669_H
62 ** Macros for handling device IRQs
64 ** The mask acts as a flag used in mapping actual ISA IRQs (0 - 15)
65 ** to device IRQs (A - H).
67 #define SMC37c669_DEVICE_IRQ_MASK 0x80000000
68 #define SMC37c669_DEVICE_IRQ( __i ) \
69 ((SMC37c669_DEVICE_IRQ_MASK) | (__i))
70 #define SMC37c669_IS_DEVICE_IRQ(__i) \
71 (((__i) & (SMC37c669_DEVICE_IRQ_MASK)) == (SMC37c669_DEVICE_IRQ_MASK))
72 #define SMC37c669_RAW_DEVICE_IRQ(__i) \
73 ((__i) & ~(SMC37c669_DEVICE_IRQ_MASK))
76 ** Macros for handling device DRQs
78 ** The mask acts as a flag used in mapping actual ISA DMA
79 ** channels to device DMA channels (A - C).
81 #define SMC37c669_DEVICE_DRQ_MASK 0x80000000
82 #define SMC37c669_DEVICE_DRQ(__d) \
83 ((SMC37c669_DEVICE_DRQ_MASK) | (__d))
84 #define SMC37c669_IS_DEVICE_DRQ(__d) \
85 (((__d) & (SMC37c669_DEVICE_DRQ_MASK)) == (SMC37c669_DEVICE_DRQ_MASK))
86 #define SMC37c669_RAW_DEVICE_DRQ(__d) \
87 ((__d) & ~(SMC37c669_DEVICE_DRQ_MASK))
89 #define SMC37c669_DEVICE_ID 0x3
92 ** SMC37c669 Device Function Definitions
94 #define SERIAL_0 0
95 #define SERIAL_1 1
96 #define PARALLEL_0 2
97 #define FLOPPY_0 3
98 #define IDE_0 4
99 #define NUM_FUNCS 5
102 ** Default Device Function Mappings
104 #define COM1_BASE 0x3F8
105 #define COM1_IRQ 4
106 #define COM2_BASE 0x2F8
107 #define COM2_IRQ 3
108 #define PARP_BASE 0x3BC
109 #define PARP_IRQ 7
110 #define PARP_DRQ 3
111 #define FDC_BASE 0x3F0
112 #define FDC_IRQ 6
113 #define FDC_DRQ 2
116 ** Configuration On/Off Key Definitions
118 #define SMC37c669_CONFIG_ON_KEY 0x55
119 #define SMC37c669_CONFIG_OFF_KEY 0xAA
122 ** SMC 37c669 Device IRQs
124 #define SMC37c669_DEVICE_IRQ_A ( SMC37c669_DEVICE_IRQ( 0x01 ) )
125 #define SMC37c669_DEVICE_IRQ_B ( SMC37c669_DEVICE_IRQ( 0x02 ) )
126 #define SMC37c669_DEVICE_IRQ_C ( SMC37c669_DEVICE_IRQ( 0x03 ) )
127 #define SMC37c669_DEVICE_IRQ_D ( SMC37c669_DEVICE_IRQ( 0x04 ) )
128 #define SMC37c669_DEVICE_IRQ_E ( SMC37c669_DEVICE_IRQ( 0x05 ) )
129 #define SMC37c669_DEVICE_IRQ_F ( SMC37c669_DEVICE_IRQ( 0x06 ) )
130 /* SMC37c669_DEVICE_IRQ_G *** RESERVED ***/
131 #define SMC37c669_DEVICE_IRQ_H ( SMC37c669_DEVICE_IRQ( 0x08 ) )
134 ** SMC 37c669 Device DMA Channel Definitions
136 #define SMC37c669_DEVICE_DRQ_A ( SMC37c669_DEVICE_DRQ( 0x01 ) )
137 #define SMC37c669_DEVICE_DRQ_B ( SMC37c669_DEVICE_DRQ( 0x02 ) )
138 #define SMC37c669_DEVICE_DRQ_C ( SMC37c669_DEVICE_DRQ( 0x03 ) )
141 ** Configuration Register Index Definitions
143 #define SMC37c669_CR00_INDEX 0x00
144 #define SMC37c669_CR01_INDEX 0x01
145 #define SMC37c669_CR02_INDEX 0x02
146 #define SMC37c669_CR03_INDEX 0x03
147 #define SMC37c669_CR04_INDEX 0x04
148 #define SMC37c669_CR05_INDEX 0x05
149 #define SMC37c669_CR06_INDEX 0x06
150 #define SMC37c669_CR07_INDEX 0x07
151 #define SMC37c669_CR08_INDEX 0x08
152 #define SMC37c669_CR09_INDEX 0x09
153 #define SMC37c669_CR0A_INDEX 0x0A
154 #define SMC37c669_CR0B_INDEX 0x0B
155 #define SMC37c669_CR0C_INDEX 0x0C
156 #define SMC37c669_CR0D_INDEX 0x0D
157 #define SMC37c669_CR0E_INDEX 0x0E
158 #define SMC37c669_CR0F_INDEX 0x0F
159 #define SMC37c669_CR10_INDEX 0x10
160 #define SMC37c669_CR11_INDEX 0x11
161 #define SMC37c669_CR12_INDEX 0x12
162 #define SMC37c669_CR13_INDEX 0x13
163 #define SMC37c669_CR14_INDEX 0x14
164 #define SMC37c669_CR15_INDEX 0x15
165 #define SMC37c669_CR16_INDEX 0x16
166 #define SMC37c669_CR17_INDEX 0x17
167 #define SMC37c669_CR18_INDEX 0x18
168 #define SMC37c669_CR19_INDEX 0x19
169 #define SMC37c669_CR1A_INDEX 0x1A
170 #define SMC37c669_CR1B_INDEX 0x1B
171 #define SMC37c669_CR1C_INDEX 0x1C
172 #define SMC37c669_CR1D_INDEX 0x1D
173 #define SMC37c669_CR1E_INDEX 0x1E
174 #define SMC37c669_CR1F_INDEX 0x1F
175 #define SMC37c669_CR20_INDEX 0x20
176 #define SMC37c669_CR21_INDEX 0x21
177 #define SMC37c669_CR22_INDEX 0x22
178 #define SMC37c669_CR23_INDEX 0x23
179 #define SMC37c669_CR24_INDEX 0x24
180 #define SMC37c669_CR25_INDEX 0x25
181 #define SMC37c669_CR26_INDEX 0x26
182 #define SMC37c669_CR27_INDEX 0x27
183 #define SMC37c669_CR28_INDEX 0x28
184 #define SMC37c669_CR29_INDEX 0x29
187 ** Configuration Register Alias Definitions
189 #define SMC37c669_DEVICE_ID_INDEX SMC37c669_CR0D_INDEX
190 #define SMC37c669_DEVICE_REVISION_INDEX SMC37c669_CR0E_INDEX
191 #define SMC37c669_FDC_BASE_ADDRESS_INDEX SMC37c669_CR20_INDEX
192 #define SMC37c669_IDE_BASE_ADDRESS_INDEX SMC37c669_CR21_INDEX
193 #define SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX SMC37c669_CR22_INDEX
194 #define SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX SMC37c669_CR23_INDEX
195 #define SMC37c669_SERIAL0_BASE_ADDRESS_INDEX SMC37c669_CR24_INDEX
196 #define SMC37c669_SERIAL1_BASE_ADDRESS_INDEX SMC37c669_CR25_INDEX
197 #define SMC37c669_PARALLEL_FDC_DRQ_INDEX SMC37c669_CR26_INDEX
198 #define SMC37c669_PARALLEL_FDC_IRQ_INDEX SMC37c669_CR27_INDEX
199 #define SMC37c669_SERIAL_IRQ_INDEX SMC37c669_CR28_INDEX
202 ** Configuration Register Definitions
204 ** The INDEX (write only) and DATA (read/write) ports are effective
205 ** only when the chip is in the Configuration State.
207 typedef struct _SMC37c669_CONFIG_REGS {
208 unsigned char index_port;
209 unsigned char data_port;
210 } SMC37c669_CONFIG_REGS;
213 ** CR00 - default value 0x28
215 ** IDE_EN (CR00<1:0>):
216 ** 0x - 30ua pull-ups on nIDEEN, nHDCS0, NHDCS1
217 ** 11 - IRQ_H available as IRQ output,
218 ** IRRX2, IRTX2 available as alternate IR pins
219 ** 10 - nIDEEN, nHDCS0, nHDCS1 used to control IDE
221 ** VALID (CR00<7>):
222 ** A high level on this software controlled bit can
223 ** be used to indicate that a valid configuration
224 ** cycle has occurred. The control software must
225 ** take care to set this bit at the appropriate times.
226 ** Set to zero after power up. This bit has no
227 ** effect on any other hardware in the chip.
230 typedef union _SMC37c669_CR00 {
231 unsigned char as_uchar;
232 struct {
233 unsigned ide_en : 2; /* See note above */
234 unsigned reserved1 : 1; /* RAZ */
235 unsigned fdc_pwr : 1; /* 1 = supply power to FDC */
236 unsigned reserved2 : 3; /* Read as 010b */
237 unsigned valid : 1; /* See note above */
238 } by_field;
239 } SMC37c669_CR00;
242 ** CR01 - default value 0x9C
244 typedef union _SMC37c669_CR01 {
245 unsigned char as_uchar;
246 struct {
247 unsigned reserved1 : 2; /* RAZ */
248 unsigned ppt_pwr : 1; /* 1 = supply power to PPT */
249 unsigned ppt_mode : 1; /* 1 = Printer mode, 0 = EPP */
250 unsigned reserved2 : 1; /* Read as 1 */
251 unsigned reserved3 : 2; /* RAZ */
252 unsigned lock_crx: 1; /* Lock CR00 - CR18 */
253 } by_field;
254 } SMC37c669_CR01;
257 ** CR02 - default value 0x88
259 typedef union _SMC37c669_CR02 {
260 unsigned char as_uchar;
261 struct {
262 unsigned reserved1 : 3; /* RAZ */
263 unsigned uart1_pwr : 1; /* 1 = supply power to UART1 */
264 unsigned reserved2 : 3; /* RAZ */
265 unsigned uart2_pwr : 1; /* 1 = supply power to UART2 */
266 } by_field;
267 } SMC37c669_CR02;
270 ** CR03 - default value 0x78
272 ** CR03<7> CR03<2> Pin 94
273 ** ------- ------- ------
274 ** 0 X DRV2 (input)
275 ** 1 0 ADRX
276 ** 1 1 IRQ_B
278 ** CR03<6> CR03<5> Op Mode
279 ** ------- ------- -------
280 ** 0 0 Model 30
281 ** 0 1 PS/2
282 ** 1 0 Reserved
283 ** 1 1 AT Mode
285 typedef union _SMC37c669_CR03 {
286 unsigned char as_uchar;
287 struct {
288 unsigned pwrgd_gamecs : 1; /* 1 = PWRGD, 0 = GAMECS */
289 unsigned fdc_mode2 : 1; /* 1 = Enhanced Mode 2 */
290 unsigned pin94_0 : 1; /* See note above */
291 unsigned reserved1 : 1; /* RAZ */
292 unsigned drvden : 1; /* 1 = high, 0 - output */
293 unsigned op_mode : 2; /* See note above */
294 unsigned pin94_1 : 1; /* See note above */
295 } by_field;
296 } SMC37c669_CR03;
299 ** CR04 - default value 0x00
301 ** PP_EXT_MODE:
302 ** If CR01<PP_MODE> = 0 and PP_EXT_MODE =
303 ** 00 - Standard and Bidirectional
304 ** 01 - EPP mode and SPP
305 ** 10 - ECP mode
306 ** In this mode, 2 drives can be supported
307 ** directly, 3 or 4 drives must use external
308 ** 4 drive support. SPP can be selected
309 ** through the ECR register of ECP as mode 000.
310 ** 11 - ECP mode and EPP mode
311 ** In this mode, 2 drives can be supported
312 ** directly, 3 or 4 drives must use external
313 ** 4 drive support. SPP can be selected
314 ** through the ECR register of ECP as mode 000.
315 ** In this mode, EPP can be selected through
316 ** the ECR register of ECP as mode 100.
318 ** PP_FDC:
319 ** 00 - Normal
320 ** 01 - PPFD1
321 ** 10 - PPFD2
322 ** 11 - Reserved
324 ** MIDI1:
325 ** Serial Clock Select:
326 ** A low level on this bit disables MIDI support,
327 ** clock = divide by 13. A high level on this
328 ** bit enables MIDI support, clock = divide by 12.
330 ** MIDI operates at 31.25 Kbps which can be derived
331 ** from 125 KHz (24 MHz / 12 = 2 MHz, 2 MHz / 16 = 125 KHz)
333 ** ALT_IO:
334 ** 0 - Use pins IRRX, IRTX
335 ** 1 - Use pins IRRX2, IRTX2
337 ** If this bit is set, the IR receive and transmit
338 ** functions will not be available on pins 25 and 26
339 ** unless CR00<IDE_EN> = 11.
341 typedef union _SMC37c669_CR04 {
342 unsigned char as_uchar;
343 struct {
344 unsigned ppt_ext_mode : 2; /* See note above */
345 unsigned ppt_fdc : 2; /* See note above */
346 unsigned midi1 : 1; /* See note above */
347 unsigned midi2 : 1; /* See note above */
348 unsigned epp_type : 1; /* 0 = EPP 1.9, 1 = EPP 1.7 */
349 unsigned alt_io : 1; /* See note above */
350 } by_field;
351 } SMC37c669_CR04;
354 ** CR05 - default value 0x00
356 ** DEN_SEL:
357 ** 00 - Densel output normal
358 ** 01 - Reserved
359 ** 10 - Densel output 1
360 ** 11 - Densel output 0
363 typedef union _SMC37c669_CR05 {
364 unsigned char as_uchar;
365 struct {
366 unsigned reserved1 : 2; /* RAZ */
367 unsigned fdc_dma_mode : 1; /* 0 = burst, 1 = non-burst */
368 unsigned den_sel : 2; /* See note above */
369 unsigned swap_drv : 1; /* Swap the FDC motor selects */
370 unsigned extx4 : 1; /* 0 = 2 drive, 1 = external 4 drive decode */
371 unsigned reserved2 : 1; /* RAZ */
372 } by_field;
373 } SMC37c669_CR05;
376 ** CR06 - default value 0xFF
378 typedef union _SMC37c669_CR06 {
379 unsigned char as_uchar;
380 struct {
381 unsigned floppy_a : 2; /* Type of floppy drive A */
382 unsigned floppy_b : 2; /* Type of floppy drive B */
383 unsigned floppy_c : 2; /* Type of floppy drive C */
384 unsigned floppy_d : 2; /* Type of floppy drive D */
385 } by_field;
386 } SMC37c669_CR06;
389 ** CR07 - default value 0x00
391 ** Auto Power Management CR07<7:4>:
392 ** 0 - Auto Powerdown disabled (default)
393 ** 1 - Auto Powerdown enabled
395 ** This bit is reset to the default state by POR or
396 ** a hardware reset.
399 typedef union _SMC37c669_CR07 {
400 unsigned char as_uchar;
401 struct {
402 unsigned floppy_boot : 2; /* 0 = A:, 1 = B: */
403 unsigned reserved1 : 2; /* RAZ */
404 unsigned ppt_en : 1; /* See note above */
405 unsigned uart1_en : 1; /* See note above */
406 unsigned uart2_en : 1; /* See note above */
407 unsigned fdc_en : 1; /* See note above */
408 } by_field;
409 } SMC37c669_CR07;
412 ** CR08 - default value 0x00
414 typedef union _SMC37c669_CR08 {
415 unsigned char as_uchar;
416 struct {
417 unsigned zero : 4; /* 0 */
418 unsigned addrx7_4 : 4; /* ADR<7:3> for ADRx decode */
419 } by_field;
420 } SMC37c669_CR08;
423 ** CR09 - default value 0x00
425 ** ADRx_CONFIG:
426 ** 00 - ADRx disabled
427 ** 01 - 1 byte decode A<3:0> = 0000b
428 ** 10 - 8 byte block decode A<3:0> = 0XXXb
429 ** 11 - 16 byte block decode A<3:0> = XXXXb
432 typedef union _SMC37c669_CR09 {
433 unsigned char as_uchar;
434 struct {
435 unsigned adra8 : 3; /* ADR<10:8> for ADRx decode */
436 unsigned reserved1 : 3;
437 unsigned adrx_config : 2; /* See note above */
438 } by_field;
439 } SMC37c669_CR09;
442 ** CR0A - default value 0x00
444 typedef union _SMC37c669_CR0A {
445 unsigned char as_uchar;
446 struct {
447 unsigned ecp_fifo_threshold : 4;
448 unsigned reserved1 : 4;
449 } by_field;
450 } SMC37c669_CR0A;
453 ** CR0B - default value 0x00
455 typedef union _SMC37c669_CR0B {
456 unsigned char as_uchar;
457 struct {
458 unsigned fdd0_drtx : 2; /* FDD0 Data Rate Table */
459 unsigned fdd1_drtx : 2; /* FDD1 Data Rate Table */
460 unsigned fdd2_drtx : 2; /* FDD2 Data Rate Table */
461 unsigned fdd3_drtx : 2; /* FDD3 Data Rate Table */
462 } by_field;
463 } SMC37c669_CR0B;
466 ** CR0C - default value 0x00
468 ** UART2_MODE:
469 ** 000 - Standard (default)
470 ** 001 - IrDA (HPSIR)
471 ** 010 - Amplitude Shift Keyed IR @500 KHz
472 ** 011 - Reserved
473 ** 1xx - Reserved
476 typedef union _SMC37c669_CR0C {
477 unsigned char as_uchar;
478 struct {
479 unsigned uart2_rcv_polarity : 1; /* 1 = invert RX */
480 unsigned uart2_xmit_polarity : 1; /* 1 = invert TX */
481 unsigned uart2_duplex : 1; /* 1 = full, 0 = half */
482 unsigned uart2_mode : 3; /* See note above */
483 unsigned uart1_speed : 1; /* 1 = high speed enabled */
484 unsigned uart2_speed : 1; /* 1 = high speed enabled */
485 } by_field;
486 } SMC37c669_CR0C;
489 ** CR0D - default value 0x03
491 ** Device ID Register - read only
493 typedef union _SMC37c669_CR0D {
494 unsigned char as_uchar;
495 struct {
496 unsigned device_id : 8; /* Returns 0x3 in this field */
497 } by_field;
498 } SMC37c669_CR0D;
501 ** CR0E - default value 0x02
503 ** Device Revision Register - read only
505 typedef union _SMC37c669_CR0E {
506 unsigned char as_uchar;
507 struct {
508 unsigned device_rev : 8; /* Returns 0x2 in this field */
509 } by_field;
510 } SMC37c669_CR0E;
513 ** CR0F - default value 0x00
515 typedef union _SMC37c669_CR0F {
516 unsigned char as_uchar;
517 struct {
518 unsigned test0 : 1; /* Reserved - set to 0 */
519 unsigned test1 : 1; /* Reserved - set to 0 */
520 unsigned test2 : 1; /* Reserved - set to 0 */
521 unsigned test3 : 1; /* Reserved - set t0 0 */
522 unsigned test4 : 1; /* Reserved - set to 0 */
523 unsigned test5 : 1; /* Reserved - set t0 0 */
524 unsigned test6 : 1; /* Reserved - set t0 0 */
525 unsigned test7 : 1; /* Reserved - set to 0 */
526 } by_field;
527 } SMC37c669_CR0F;
530 ** CR10 - default value 0x00
532 typedef union _SMC37c669_CR10 {
533 unsigned char as_uchar;
534 struct {
535 unsigned reserved1 : 3; /* RAZ */
536 unsigned pll_gain : 1; /* 1 = 3V, 2 = 5V operation */
537 unsigned pll_stop : 1; /* 1 = stop PLLs */
538 unsigned ace_stop : 1; /* 1 = stop UART clocks */
539 unsigned pll_clock_ctrl : 1; /* 0 = 14.318 MHz, 1 = 24 MHz */
540 unsigned ir_test : 1; /* Enable IR test mode */
541 } by_field;
542 } SMC37c669_CR10;
545 ** CR11 - default value 0x00
547 typedef union _SMC37c669_CR11 {
548 unsigned char as_uchar;
549 struct {
550 unsigned ir_loopback : 1; /* Internal IR loop back */
551 unsigned test_10ms : 1; /* Test 10ms autopowerdown FDC timeout */
552 unsigned reserved1 : 6; /* RAZ */
553 } by_field;
554 } SMC37c669_CR11;
557 ** CR12 - CR1D are reserved registers
561 ** CR1E - default value 0x80
563 ** GAMECS:
564 ** 00 - GAMECS disabled
565 ** 01 - 1 byte decode ADR<3:0> = 0001b
566 ** 10 - 8 byte block decode ADR<3:0> = 0XXXb
567 ** 11 - 16 byte block decode ADR<3:0> = XXXXb
570 typedef union _SMC37c66_CR1E {
571 unsigned char as_uchar;
572 struct {
573 unsigned gamecs_config: 2; /* See note above */
574 unsigned gamecs_addr9_4 : 6; /* GAMECS Addr<9:4> */
575 } by_field;
576 } SMC37c669_CR1E;
579 ** CR1F - default value 0x00
581 ** DT0 DT1 DRVDEN0 DRVDEN1 Drive Type
582 ** --- --- ------- ------- ----------
583 ** 0 0 DENSEL DRATE0 4/2/1 MB 3.5"
584 ** 2/1 MB 5.25"
585 ** 2/1.6/1 MB 3.5" (3-mode)
586 ** 0 1 DRATE1 DRATE0
587 ** 1 0 nDENSEL DRATE0 PS/2
588 ** 1 1 DRATE0 DRATE1
590 ** Note: DENSEL, DRATE1, and DRATE0 map onto two output
591 ** pins - DRVDEN0 and DRVDEN1.
594 typedef union _SMC37c669_CR1F {
595 unsigned char as_uchar;
596 struct {
597 unsigned fdd0_drive_type : 2; /* FDD0 drive type */
598 unsigned fdd1_drive_type : 2; /* FDD1 drive type */
599 unsigned fdd2_drive_type : 2; /* FDD2 drive type */
600 unsigned fdd3_drive_type : 2; /* FDD3 drive type */
601 } by_field;
602 } SMC37c669_CR1F;
605 ** CR20 - default value 0x3C
607 ** FDC Base Address Register
608 ** - To disable this decode set Addr<9:8> = 0
609 ** - A<10> = 0, A<3:0> = 0XXXb to access.
612 typedef union _SMC37c669_CR20 {
613 unsigned char as_uchar;
614 struct {
615 unsigned zero : 2; /* 0 */
616 unsigned addr9_4 : 6; /* FDC Addr<9:4> */
617 } by_field;
618 } SMC37c669_CR20;
621 ** CR21 - default value 0x3C
623 ** IDE Base Address Register
624 ** - To disable this decode set Addr<9:8> = 0
625 ** - A<10> = 0, A<3:0> = 0XXXb to access.
628 typedef union _SMC37c669_CR21 {
629 unsigned char as_uchar;
630 struct {
631 unsigned zero : 2; /* 0 */
632 unsigned addr9_4 : 6; /* IDE Addr<9:4> */
633 } by_field;
634 } SMC37c669_CR21;
637 ** CR22 - default value 0x3D
639 ** IDE Alternate Status Base Address Register
640 ** - To disable this decode set Addr<9:8> = 0
641 ** - A<10> = 0, A<3:0> = 0110b to access.
644 typedef union _SMC37c669_CR22 {
645 unsigned char as_uchar;
646 struct {
647 unsigned zero : 2; /* 0 */
648 unsigned addr9_4 : 6; /* IDE Alt Status Addr<9:4> */
649 } by_field;
650 } SMC37c669_CR22;
653 ** CR23 - default value 0x00
655 ** Parallel Port Base Address Register
656 ** - To disable this decode set Addr<9:8> = 0
657 ** - A<10> = 0 to access.
658 ** - If EPP is enabled, A<2:0> = XXXb to access.
659 ** If EPP is NOT enabled, A<1:0> = XXb to access
662 typedef union _SMC37c669_CR23 {
663 unsigned char as_uchar;
664 struct {
665 unsigned addr9_2 : 8; /* Parallel Port Addr<9:2> */
666 } by_field;
667 } SMC37c669_CR23;
670 ** CR24 - default value 0x00
672 ** UART1 Base Address Register
673 ** - To disable this decode set Addr<9:8> = 0
674 ** - A<10> = 0, A<2:0> = XXXb to access.
677 typedef union _SMC37c669_CR24 {
678 unsigned char as_uchar;
679 struct {
680 unsigned zero : 1; /* 0 */
681 unsigned addr9_3 : 7; /* UART1 Addr<9:3> */
682 } by_field;
683 } SMC37c669_CR24;
686 ** CR25 - default value 0x00
688 ** UART2 Base Address Register
689 ** - To disable this decode set Addr<9:8> = 0
690 ** - A<10> = 0, A<2:0> = XXXb to access.
693 typedef union _SMC37c669_CR25 {
694 unsigned char as_uchar;
695 struct {
696 unsigned zero : 1; /* 0 */
697 unsigned addr9_3 : 7; /* UART2 Addr<9:3> */
698 } by_field;
699 } SMC37c669_CR25;
702 ** CR26 - default value 0x00
704 ** Parallel Port / FDC DMA Select Register
706 ** D3 - D0 DMA
707 ** D7 - D4 Selected
708 ** ------- --------
709 ** 0000 None
710 ** 0001 DMA_A
711 ** 0010 DMA_B
712 ** 0011 DMA_C
715 typedef union _SMC37c669_CR26 {
716 unsigned char as_uchar;
717 struct {
718 unsigned ppt_drq : 4; /* See note above */
719 unsigned fdc_drq : 4; /* See note above */
720 } by_field;
721 } SMC37c669_CR26;
724 ** CR27 - default value 0x00
726 ** Parallel Port / FDC IRQ Select Register
728 ** D3 - D0 IRQ
729 ** D7 - D4 Selected
730 ** ------- --------
731 ** 0000 None
732 ** 0001 IRQ_A
733 ** 0010 IRQ_B
734 ** 0011 IRQ_C
735 ** 0100 IRQ_D
736 ** 0101 IRQ_E
737 ** 0110 IRQ_F
738 ** 0111 Reserved
739 ** 1000 IRQ_H
741 ** Any unselected IRQ REQ is in tristate
744 typedef union _SMC37c669_CR27 {
745 unsigned char as_uchar;
746 struct {
747 unsigned ppt_irq : 4; /* See note above */
748 unsigned fdc_irq : 4; /* See note above */
749 } by_field;
750 } SMC37c669_CR27;
753 ** CR28 - default value 0x00
755 ** UART IRQ Select Register
757 ** D3 - D0 IRQ
758 ** D7 - D4 Selected
759 ** ------- --------
760 ** 0000 None
761 ** 0001 IRQ_A
762 ** 0010 IRQ_B
763 ** 0011 IRQ_C
764 ** 0100 IRQ_D
765 ** 0101 IRQ_E
766 ** 0110 IRQ_F
767 ** 0111 Reserved
768 ** 1000 IRQ_H
769 ** 1111 share with UART1 (only for UART2)
771 ** Any unselected IRQ REQ is in tristate
773 ** To share an IRQ between UART1 and UART2, set
774 ** UART1 to use the desired IRQ and set UART2 to
775 ** 0xF to enable sharing mechanism.
778 typedef union _SMC37c669_CR28 {
779 unsigned char as_uchar;
780 struct {
781 unsigned uart2_irq : 4; /* See note above */
782 unsigned uart1_irq : 4; /* See note above */
783 } by_field;
784 } SMC37c669_CR28;
787 ** CR29 - default value 0x00
789 ** IRQIN IRQ Select Register
791 ** D3 - D0 IRQ
792 ** D7 - D4 Selected
793 ** ------- --------
794 ** 0000 None
795 ** 0001 IRQ_A
796 ** 0010 IRQ_B
797 ** 0011 IRQ_C
798 ** 0100 IRQ_D
799 ** 0101 IRQ_E
800 ** 0110 IRQ_F
801 ** 0111 Reserved
802 ** 1000 IRQ_H
804 ** Any unselected IRQ REQ is in tristate
807 typedef union _SMC37c669_CR29 {
808 unsigned char as_uchar;
809 struct {
810 unsigned irqin_irq : 4; /* See note above */
811 unsigned reserved1 : 4; /* RAZ */
812 } by_field;
813 } SMC37c669_CR29;
816 ** Aliases of Configuration Register formats (should match
817 ** the set of index aliases).
819 ** Note that CR24 and CR25 have the same format and are the
820 ** base address registers for UART1 and UART2. Because of
821 ** this we only define 1 alias here - for CR24 - as the serial
822 ** base address register.
824 ** Note that CR21 and CR22 have the same format and are the
825 ** base address and alternate status address registers for
826 ** the IDE controller. Because of this we only define 1 alias
827 ** here - for CR21 - as the IDE address register.
830 typedef SMC37c669_CR0D SMC37c669_DEVICE_ID_REGISTER;
831 typedef SMC37c669_CR0E SMC37c669_DEVICE_REVISION_REGISTER;
832 typedef SMC37c669_CR20 SMC37c669_FDC_BASE_ADDRESS_REGISTER;
833 typedef SMC37c669_CR21 SMC37c669_IDE_ADDRESS_REGISTER;
834 typedef SMC37c669_CR23 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER;
835 typedef SMC37c669_CR24 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER;
836 typedef SMC37c669_CR26 SMC37c669_PARALLEL_FDC_DRQ_REGISTER;
837 typedef SMC37c669_CR27 SMC37c669_PARALLEL_FDC_IRQ_REGISTER;
838 typedef SMC37c669_CR28 SMC37c669_SERIAL_IRQ_REGISTER;
841 ** ISA/Device IRQ Translation Table Entry Definition
843 typedef struct _SMC37c669_IRQ_TRANSLATION_ENTRY {
844 int device_irq;
845 int isa_irq;
846 } SMC37c669_IRQ_TRANSLATION_ENTRY;
849 ** ISA/Device DMA Translation Table Entry Definition
851 typedef struct _SMC37c669_DRQ_TRANSLATION_ENTRY {
852 int device_drq;
853 int isa_drq;
854 } SMC37c669_DRQ_TRANSLATION_ENTRY;
857 ** External Interface Function Prototype Declarations
860 SMC37c669_CONFIG_REGS *SMC37c669_detect(
864 unsigned int SMC37c669_enable_device(
865 unsigned int func
868 unsigned int SMC37c669_disable_device(
869 unsigned int func
872 unsigned int SMC37c669_configure_device(
873 unsigned int func,
874 int port,
875 int irq,
876 int drq
879 void SMC37c669_display_device_info(
880 void
883 #endif /* __SMC37c669_H */
885 /* file: smcc669.c
887 * Copyright (C) 1997 by
888 * Digital Equipment Corporation, Maynard, Massachusetts.
889 * All rights reserved.
891 * This software is furnished under a license and may be used and copied
892 * only in accordance of the terms of such license and with the
893 * inclusion of the above copyright notice. This software or any other
894 * copies thereof may not be provided or otherwise made available to any
895 * other person. No title to and ownership of the software is hereby
896 * transferred.
898 * The information in this software is subject to change without notice
899 * and should not be construed as a commitment by digital equipment
900 * corporation.
902 * Digital assumes no responsibility for the use or reliability of its
903 * software on equipment which is not supplied by digital.
908 * FACILITY:
910 * Alpha SRM Console Firmware
912 * MODULE DESCRIPTION:
914 * SMC37c669 Super I/O controller configuration routines.
916 * AUTHORS:
918 * Eric Rasmussen
920 * CREATION DATE:
922 * 28-Jan-1997
924 * MODIFICATION HISTORY:
926 * er 01-May-1997 Fixed pointer conversion errors in
927 * SMC37c669_get_device_config().
928 * er 28-Jan-1997 Initial version.
933 #ifndef TRUE
934 #define TRUE 1
935 #endif
936 #ifndef FALSE
937 #define FALSE 0
938 #endif
940 #define wb( _x_, _y_ ) outb( _y_, (unsigned int)((unsigned long)_x_) )
941 #define rb( _x_ ) inb( (unsigned int)((unsigned long)_x_) )
944 ** Local storage for device configuration information.
946 ** Since the SMC37c669 does not provide an explicit
947 ** mechanism for enabling/disabling individual device
948 ** functions, other than unmapping the device, local
949 ** storage for device configuration information is
950 ** allocated here for use in implementing our own
951 ** function enable/disable scheme.
953 static struct DEVICE_CONFIG {
954 unsigned int port1;
955 unsigned int port2;
956 int irq;
957 int drq;
958 } local_config [NUM_FUNCS];
961 ** List of all possible addresses for the Super I/O chip
963 static unsigned long SMC37c669_Addresses[] __initdata =
965 0x3F0UL, /* Primary address */
966 0x370UL, /* Secondary address */
967 0UL /* End of list */
971 ** Global Pointer to the Super I/O device
973 static SMC37c669_CONFIG_REGS *SMC37c669 __initdata = NULL;
976 ** IRQ Translation Table
978 ** The IRQ translation table is a list of SMC37c669 device
979 ** and standard ISA IRQs.
982 static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_table __initdata;
985 ** The following definition is for the default IRQ
986 ** translation table.
988 static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_default_irq_table[]
989 __initdata =
991 { SMC37c669_DEVICE_IRQ_A, -1 },
992 { SMC37c669_DEVICE_IRQ_B, -1 },
993 { SMC37c669_DEVICE_IRQ_C, 7 },
994 { SMC37c669_DEVICE_IRQ_D, 6 },
995 { SMC37c669_DEVICE_IRQ_E, 4 },
996 { SMC37c669_DEVICE_IRQ_F, 3 },
997 { SMC37c669_DEVICE_IRQ_H, -1 },
998 { -1, -1 } /* End of table */
1002 ** The following definition is for the MONET (XP1000) IRQ
1003 ** translation table.
1005 static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_monet_irq_table[]
1006 __initdata =
1008 { SMC37c669_DEVICE_IRQ_A, -1 },
1009 { SMC37c669_DEVICE_IRQ_B, -1 },
1010 { SMC37c669_DEVICE_IRQ_C, 6 },
1011 { SMC37c669_DEVICE_IRQ_D, 7 },
1012 { SMC37c669_DEVICE_IRQ_E, 4 },
1013 { SMC37c669_DEVICE_IRQ_F, 3 },
1014 { SMC37c669_DEVICE_IRQ_H, -1 },
1015 { -1, -1 } /* End of table */
1018 static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_tables[] __initdata =
1020 SMC37c669_default_irq_table,
1021 SMC37c669_monet_irq_table
1025 ** DRQ Translation Table
1027 ** The DRQ translation table is a list of SMC37c669 device and
1028 ** ISA DMA channels.
1031 static SMC37c669_DRQ_TRANSLATION_ENTRY *SMC37c669_drq_table __initdata;
1034 ** The following definition is the default DRQ
1035 ** translation table.
1037 static SMC37c669_DRQ_TRANSLATION_ENTRY SMC37c669_default_drq_table[]
1038 __initdata =
1040 { SMC37c669_DEVICE_DRQ_A, 2 },
1041 { SMC37c669_DEVICE_DRQ_B, 3 },
1042 { SMC37c669_DEVICE_DRQ_C, -1 },
1043 { -1, -1 } /* End of table */
1047 ** Local Function Prototype Declarations
1050 static unsigned int SMC37c669_is_device_enabled(
1051 unsigned int func
1055 static void SMC37c669_config_mode(
1056 unsigned int enable
1059 static unsigned char SMC37c669_read_config(
1060 unsigned char index
1063 static void SMC37c669_write_config(
1064 unsigned char index,
1065 unsigned char data
1068 static void SMC37c669_init_local_config( void );
1070 static struct DEVICE_CONFIG *SMC37c669_get_config(
1071 unsigned int func
1074 static int SMC37c669_xlate_irq(
1075 int irq
1078 static int SMC37c669_xlate_drq(
1079 int drq
1082 static __cacheline_aligned DEFINE_SPINLOCK(smc_lock);
1085 **++
1086 ** FUNCTIONAL DESCRIPTION:
1088 ** This function detects the presence of an SMC37c669 Super I/O
1089 ** controller.
1091 ** FORMAL PARAMETERS:
1093 ** None
1095 ** RETURN VALUE:
1097 ** Returns a pointer to the device if found, otherwise,
1098 ** the NULL pointer is returned.
1100 ** SIDE EFFECTS:
1102 ** None
1104 **--
1106 SMC37c669_CONFIG_REGS * __init SMC37c669_detect( int index )
1108 int i;
1109 SMC37c669_DEVICE_ID_REGISTER id;
1111 for ( i = 0; SMC37c669_Addresses[i] != 0; i++ ) {
1113 ** Initialize the device pointer even though we don't yet know if
1114 ** the controller is at this address. The support functions access
1115 ** the controller through this device pointer so we need to set it
1116 ** even when we are looking ...
1118 SMC37c669 = ( SMC37c669_CONFIG_REGS * )SMC37c669_Addresses[i];
1120 ** Enter configuration mode
1122 SMC37c669_config_mode( TRUE );
1124 ** Read the device id
1126 id.as_uchar = SMC37c669_read_config( SMC37c669_DEVICE_ID_INDEX );
1128 ** Exit configuration mode
1130 SMC37c669_config_mode( FALSE );
1132 ** Does the device id match? If so, assume we have found an
1133 ** SMC37c669 controller at this address.
1135 if ( id.by_field.device_id == SMC37c669_DEVICE_ID ) {
1137 ** Initialize the IRQ and DRQ translation tables.
1139 SMC37c669_irq_table = SMC37c669_irq_tables[ index ];
1140 SMC37c669_drq_table = SMC37c669_default_drq_table;
1142 ** erfix
1144 ** If the platform can't use the IRQ and DRQ defaults set up in this
1145 ** file, it should call a platform-specific external routine at this
1146 ** point to reset the IRQ and DRQ translation table pointers to point
1147 ** at the appropriate tables for the platform. If the defaults are
1148 ** acceptable, then the external routine should do nothing.
1152 ** Put the chip back into configuration mode
1154 SMC37c669_config_mode( TRUE );
1156 ** Initialize local storage for configuration information
1158 SMC37c669_init_local_config( );
1160 ** Exit configuration mode
1162 SMC37c669_config_mode( FALSE );
1164 ** SMC37c669 controller found, break out of search loop
1166 break;
1168 else {
1170 ** Otherwise, we did not find an SMC37c669 controller at this
1171 ** address so set the device pointer to NULL.
1173 SMC37c669 = NULL;
1176 return SMC37c669;
1181 **++
1182 ** FUNCTIONAL DESCRIPTION:
1184 ** This function enables an SMC37c669 device function.
1186 ** FORMAL PARAMETERS:
1188 ** func:
1189 ** Which device function to enable
1191 ** RETURN VALUE:
1193 ** Returns TRUE is the device function was enabled, otherwise, FALSE
1195 ** SIDE EFFECTS:
1197 ** {@description or none@}
1199 ** DESIGN:
1201 ** Enabling a device function in the SMC37c669 controller involves
1202 ** setting all of its mappings (port, irq, drq ...). A local
1203 ** "shadow" copy of the device configuration is kept so we can
1204 ** just set each mapping to what the local copy says.
1206 ** This function ALWAYS updates the local shadow configuration of
1207 ** the device function being enabled, even if the device is always
1208 ** enabled. To avoid replication of code, functions such as
1209 ** configure_device set up the local copy and then call this
1210 ** function to the update the real device.
1212 **--
1214 unsigned int __init SMC37c669_enable_device ( unsigned int func )
1216 unsigned int ret_val = FALSE;
1218 ** Put the device into configuration mode
1220 SMC37c669_config_mode( TRUE );
1221 switch ( func ) {
1222 case SERIAL_0:
1224 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1225 SMC37c669_SERIAL_IRQ_REGISTER irq;
1227 ** Enable the serial 1 IRQ mapping
1229 irq.as_uchar =
1230 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1232 irq.by_field.uart1_irq =
1233 SMC37c669_RAW_DEVICE_IRQ(
1234 SMC37c669_xlate_irq( local_config[ func ].irq )
1237 SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1239 ** Enable the serial 1 port base address mapping
1241 base_addr.as_uchar = 0;
1242 base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
1244 SMC37c669_write_config(
1245 SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
1246 base_addr.as_uchar
1248 ret_val = TRUE;
1249 break;
1251 case SERIAL_1:
1253 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1254 SMC37c669_SERIAL_IRQ_REGISTER irq;
1256 ** Enable the serial 2 IRQ mapping
1258 irq.as_uchar =
1259 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1261 irq.by_field.uart2_irq =
1262 SMC37c669_RAW_DEVICE_IRQ(
1263 SMC37c669_xlate_irq( local_config[ func ].irq )
1266 SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1268 ** Enable the serial 2 port base address mapping
1270 base_addr.as_uchar = 0;
1271 base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
1273 SMC37c669_write_config(
1274 SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
1275 base_addr.as_uchar
1277 ret_val = TRUE;
1278 break;
1280 case PARALLEL_0:
1282 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
1283 SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1284 SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1286 ** Enable the parallel port DMA channel mapping
1288 drq.as_uchar =
1289 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1291 drq.by_field.ppt_drq =
1292 SMC37c669_RAW_DEVICE_DRQ(
1293 SMC37c669_xlate_drq( local_config[ func ].drq )
1296 SMC37c669_write_config(
1297 SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1298 drq.as_uchar
1301 ** Enable the parallel port IRQ mapping
1303 irq.as_uchar =
1304 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1306 irq.by_field.ppt_irq =
1307 SMC37c669_RAW_DEVICE_IRQ(
1308 SMC37c669_xlate_irq( local_config[ func ].irq )
1311 SMC37c669_write_config(
1312 SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1313 irq.as_uchar
1316 ** Enable the parallel port base address mapping
1318 base_addr.as_uchar = 0;
1319 base_addr.by_field.addr9_2 = local_config[ func ].port1 >> 2;
1321 SMC37c669_write_config(
1322 SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
1323 base_addr.as_uchar
1325 ret_val = TRUE;
1326 break;
1328 case FLOPPY_0:
1330 SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
1331 SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1332 SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1334 ** Enable the floppy controller DMA channel mapping
1336 drq.as_uchar =
1337 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1339 drq.by_field.fdc_drq =
1340 SMC37c669_RAW_DEVICE_DRQ(
1341 SMC37c669_xlate_drq( local_config[ func ].drq )
1344 SMC37c669_write_config(
1345 SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1346 drq.as_uchar
1349 ** Enable the floppy controller IRQ mapping
1351 irq.as_uchar =
1352 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1354 irq.by_field.fdc_irq =
1355 SMC37c669_RAW_DEVICE_IRQ(
1356 SMC37c669_xlate_irq( local_config[ func ].irq )
1359 SMC37c669_write_config(
1360 SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1361 irq.as_uchar
1364 ** Enable the floppy controller base address mapping
1366 base_addr.as_uchar = 0;
1367 base_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
1369 SMC37c669_write_config(
1370 SMC37c669_FDC_BASE_ADDRESS_INDEX,
1371 base_addr.as_uchar
1373 ret_val = TRUE;
1374 break;
1376 case IDE_0:
1378 SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
1380 ** Enable the IDE alternate status base address mapping
1382 ide_addr.as_uchar = 0;
1383 ide_addr.by_field.addr9_4 = local_config[ func ].port2 >> 4;
1385 SMC37c669_write_config(
1386 SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
1387 ide_addr.as_uchar
1390 ** Enable the IDE controller base address mapping
1392 ide_addr.as_uchar = 0;
1393 ide_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
1395 SMC37c669_write_config(
1396 SMC37c669_IDE_BASE_ADDRESS_INDEX,
1397 ide_addr.as_uchar
1399 ret_val = TRUE;
1400 break;
1404 ** Exit configuration mode and return
1406 SMC37c669_config_mode( FALSE );
1408 return ret_val;
1413 **++
1414 ** FUNCTIONAL DESCRIPTION:
1416 ** This function disables a device function within the
1417 ** SMC37c669 Super I/O controller.
1419 ** FORMAL PARAMETERS:
1421 ** func:
1422 ** Which function to disable
1424 ** RETURN VALUE:
1426 ** Return TRUE if the device function was disabled, otherwise, FALSE
1428 ** SIDE EFFECTS:
1430 ** {@description or none@}
1432 ** DESIGN:
1434 ** Disabling a function in the SMC37c669 device involves
1435 ** disabling all the function's mappings (port, irq, drq ...).
1436 ** A shadow copy of the device configuration is maintained
1437 ** in local storage so we won't worry aboving saving the
1438 ** current configuration information.
1440 **--
1442 unsigned int __init SMC37c669_disable_device ( unsigned int func )
1444 unsigned int ret_val = FALSE;
1447 ** Put the device into configuration mode
1449 SMC37c669_config_mode( TRUE );
1450 switch ( func ) {
1451 case SERIAL_0:
1453 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1454 SMC37c669_SERIAL_IRQ_REGISTER irq;
1456 ** Disable the serial 1 IRQ mapping
1458 irq.as_uchar =
1459 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1461 irq.by_field.uart1_irq = 0;
1463 SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1465 ** Disable the serial 1 port base address mapping
1467 base_addr.as_uchar = 0;
1468 SMC37c669_write_config(
1469 SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
1470 base_addr.as_uchar
1472 ret_val = TRUE;
1473 break;
1475 case SERIAL_1:
1477 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
1478 SMC37c669_SERIAL_IRQ_REGISTER irq;
1480 ** Disable the serial 2 IRQ mapping
1482 irq.as_uchar =
1483 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
1485 irq.by_field.uart2_irq = 0;
1487 SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
1489 ** Disable the serial 2 port base address mapping
1491 base_addr.as_uchar = 0;
1493 SMC37c669_write_config(
1494 SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
1495 base_addr.as_uchar
1497 ret_val = TRUE;
1498 break;
1500 case PARALLEL_0:
1502 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
1503 SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1504 SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1506 ** Disable the parallel port DMA channel mapping
1508 drq.as_uchar =
1509 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1511 drq.by_field.ppt_drq = 0;
1513 SMC37c669_write_config(
1514 SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1515 drq.as_uchar
1518 ** Disable the parallel port IRQ mapping
1520 irq.as_uchar =
1521 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1523 irq.by_field.ppt_irq = 0;
1525 SMC37c669_write_config(
1526 SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1527 irq.as_uchar
1530 ** Disable the parallel port base address mapping
1532 base_addr.as_uchar = 0;
1534 SMC37c669_write_config(
1535 SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
1536 base_addr.as_uchar
1538 ret_val = TRUE;
1539 break;
1541 case FLOPPY_0:
1543 SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
1544 SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
1545 SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
1547 ** Disable the floppy controller DMA channel mapping
1549 drq.as_uchar =
1550 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
1552 drq.by_field.fdc_drq = 0;
1554 SMC37c669_write_config(
1555 SMC37c669_PARALLEL_FDC_DRQ_INDEX,
1556 drq.as_uchar
1559 ** Disable the floppy controller IRQ mapping
1561 irq.as_uchar =
1562 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
1564 irq.by_field.fdc_irq = 0;
1566 SMC37c669_write_config(
1567 SMC37c669_PARALLEL_FDC_IRQ_INDEX,
1568 irq.as_uchar
1571 ** Disable the floppy controller base address mapping
1573 base_addr.as_uchar = 0;
1575 SMC37c669_write_config(
1576 SMC37c669_FDC_BASE_ADDRESS_INDEX,
1577 base_addr.as_uchar
1579 ret_val = TRUE;
1580 break;
1582 case IDE_0:
1584 SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
1586 ** Disable the IDE alternate status base address mapping
1588 ide_addr.as_uchar = 0;
1590 SMC37c669_write_config(
1591 SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
1592 ide_addr.as_uchar
1595 ** Disable the IDE controller base address mapping
1597 ide_addr.as_uchar = 0;
1599 SMC37c669_write_config(
1600 SMC37c669_IDE_BASE_ADDRESS_INDEX,
1601 ide_addr.as_uchar
1603 ret_val = TRUE;
1604 break;
1608 ** Exit configuration mode and return
1610 SMC37c669_config_mode( FALSE );
1612 return ret_val;
1617 **++
1618 ** FUNCTIONAL DESCRIPTION:
1620 ** This function configures a device function within the
1621 ** SMC37c669 Super I/O controller.
1623 ** FORMAL PARAMETERS:
1625 ** func:
1626 ** Which device function
1628 ** port:
1629 ** I/O port for the function to use
1631 ** irq:
1632 ** IRQ for the device function to use
1634 ** drq:
1635 ** DMA channel for the device function to use
1637 ** RETURN VALUE:
1639 ** Returns TRUE if the device function was configured,
1640 ** otherwise, FALSE.
1642 ** SIDE EFFECTS:
1644 ** {@description or none@}
1646 ** DESIGN:
1648 ** If this function returns TRUE, the local shadow copy of
1649 ** the configuration is also updated. If the device function
1650 ** is currently disabled, only the local shadow copy is
1651 ** updated and the actual device function will be updated
1652 ** if/when it is enabled.
1654 **--
1656 unsigned int __init SMC37c669_configure_device (
1657 unsigned int func,
1658 int port,
1659 int irq,
1660 int drq )
1662 struct DEVICE_CONFIG *cp;
1665 ** Check for a valid configuration
1667 if ( ( cp = SMC37c669_get_config ( func ) ) != NULL ) {
1669 ** Configuration is valid, update the local shadow copy
1671 if ( ( drq & ~0xFF ) == 0 ) {
1672 cp->drq = drq;
1674 if ( ( irq & ~0xFF ) == 0 ) {
1675 cp->irq = irq;
1677 if ( ( port & ~0xFFFF ) == 0 ) {
1678 cp->port1 = port;
1681 ** If the device function is enabled, update the actual
1682 ** device configuration.
1684 if ( SMC37c669_is_device_enabled( func ) ) {
1685 SMC37c669_enable_device( func );
1687 return TRUE;
1689 return FALSE;
1694 **++
1695 ** FUNCTIONAL DESCRIPTION:
1697 ** This function determines whether a device function
1698 ** within the SMC37c669 controller is enabled.
1700 ** FORMAL PARAMETERS:
1702 ** func:
1703 ** Which device function
1705 ** RETURN VALUE:
1707 ** Returns TRUE if the device function is enabled, otherwise, FALSE
1709 ** SIDE EFFECTS:
1711 ** {@description or none@}
1713 ** DESIGN:
1715 ** To check whether a device is enabled we will only look at
1716 ** the port base address mapping. According to the SMC37c669
1717 ** specification, all of the port base address mappings are
1718 ** disabled if the addr<9:8> (bits <7:6> of the register) are
1719 ** zero.
1721 **--
1723 static unsigned int __init SMC37c669_is_device_enabled ( unsigned int func )
1725 unsigned char base_addr = 0;
1726 unsigned int dev_ok = FALSE;
1727 unsigned int ret_val = FALSE;
1729 ** Enter configuration mode
1731 SMC37c669_config_mode( TRUE );
1733 switch ( func ) {
1734 case SERIAL_0:
1735 base_addr =
1736 SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
1737 dev_ok = TRUE;
1738 break;
1739 case SERIAL_1:
1740 base_addr =
1741 SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
1742 dev_ok = TRUE;
1743 break;
1744 case PARALLEL_0:
1745 base_addr =
1746 SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
1747 dev_ok = TRUE;
1748 break;
1749 case FLOPPY_0:
1750 base_addr =
1751 SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
1752 dev_ok = TRUE;
1753 break;
1754 case IDE_0:
1755 base_addr =
1756 SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
1757 dev_ok = TRUE;
1758 break;
1761 ** If we have a valid device, check base_addr<7:6> to see if the
1762 ** device is enabled (mapped).
1764 if ( ( dev_ok ) && ( ( base_addr & 0xC0 ) != 0 ) ) {
1766 ** The mapping is not disabled, so assume that the function is
1767 ** enabled.
1769 ret_val = TRUE;
1772 ** Exit configuration mode
1774 SMC37c669_config_mode( FALSE );
1776 return ret_val;
1783 **++
1784 ** FUNCTIONAL DESCRIPTION:
1786 ** This function displays the current state of the SMC37c699
1787 ** Super I/O controller's device functions.
1789 ** FORMAL PARAMETERS:
1791 ** None
1793 ** RETURN VALUE:
1795 ** None
1797 ** SIDE EFFECTS:
1799 ** None
1801 **--
1803 void __init SMC37c669_display_device_info ( void )
1805 if ( SMC37c669_is_device_enabled( SERIAL_0 ) ) {
1806 printk( " Serial 0: Enabled [ Port 0x%x, IRQ %d ]\n",
1807 local_config[ SERIAL_0 ].port1,
1808 local_config[ SERIAL_0 ].irq
1811 else {
1812 printk( " Serial 0: Disabled\n" );
1815 if ( SMC37c669_is_device_enabled( SERIAL_1 ) ) {
1816 printk( " Serial 1: Enabled [ Port 0x%x, IRQ %d ]\n",
1817 local_config[ SERIAL_1 ].port1,
1818 local_config[ SERIAL_1 ].irq
1821 else {
1822 printk( " Serial 1: Disabled\n" );
1825 if ( SMC37c669_is_device_enabled( PARALLEL_0 ) ) {
1826 printk( " Parallel: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
1827 local_config[ PARALLEL_0 ].port1,
1828 local_config[ PARALLEL_0 ].irq,
1829 local_config[ PARALLEL_0 ].drq
1832 else {
1833 printk( " Parallel: Disabled\n" );
1836 if ( SMC37c669_is_device_enabled( FLOPPY_0 ) ) {
1837 printk( " Floppy Ctrl: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
1838 local_config[ FLOPPY_0 ].port1,
1839 local_config[ FLOPPY_0 ].irq,
1840 local_config[ FLOPPY_0 ].drq
1843 else {
1844 printk( " Floppy Ctrl: Disabled\n" );
1847 if ( SMC37c669_is_device_enabled( IDE_0 ) ) {
1848 printk( " IDE 0: Enabled [ Port 0x%x, IRQ %d ]\n",
1849 local_config[ IDE_0 ].port1,
1850 local_config[ IDE_0 ].irq
1853 else {
1854 printk( " IDE 0: Disabled\n" );
1860 **++
1861 ** FUNCTIONAL DESCRIPTION:
1863 ** This function puts the SMC37c669 Super I/O controller into,
1864 ** and takes it out of, configuration mode.
1866 ** FORMAL PARAMETERS:
1868 ** enable:
1869 ** TRUE to enter configuration mode, FALSE to exit.
1871 ** RETURN VALUE:
1873 ** None
1875 ** SIDE EFFECTS:
1877 ** The SMC37c669 controller may be left in configuration mode.
1879 **--
1881 static void __init SMC37c669_config_mode(
1882 unsigned int enable )
1884 if ( enable ) {
1886 ** To enter configuration mode, two writes in succession to the index
1887 ** port are required. If a write to another address or port occurs
1888 ** between these two writes, the chip does not enter configuration
1889 ** mode. Therefore, a spinlock is placed around the two writes to
1890 ** guarantee that they complete uninterrupted.
1892 spin_lock(&smc_lock);
1893 wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
1894 wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
1895 spin_unlock(&smc_lock);
1897 else {
1898 wb( &SMC37c669->index_port, SMC37c669_CONFIG_OFF_KEY );
1903 **++
1904 ** FUNCTIONAL DESCRIPTION:
1906 ** This function reads an SMC37c669 Super I/O controller
1907 ** configuration register. This function assumes that the
1908 ** device is already in configuration mode.
1910 ** FORMAL PARAMETERS:
1912 ** index:
1913 ** Index value of configuration register to read
1915 ** RETURN VALUE:
1917 ** Data read from configuration register
1919 ** SIDE EFFECTS:
1921 ** None
1923 **--
1925 static unsigned char __init SMC37c669_read_config(
1926 unsigned char index )
1928 unsigned char data;
1930 wb( &SMC37c669->index_port, index );
1931 data = rb( &SMC37c669->data_port );
1932 return data;
1936 **++
1937 ** FUNCTIONAL DESCRIPTION:
1939 ** This function writes an SMC37c669 Super I/O controller
1940 ** configuration register. This function assumes that the
1941 ** device is already in configuration mode.
1943 ** FORMAL PARAMETERS:
1945 ** index:
1946 ** Index of configuration register to write
1948 ** data:
1949 ** Data to be written
1951 ** RETURN VALUE:
1953 ** None
1955 ** SIDE EFFECTS:
1957 ** None
1959 **--
1961 static void __init SMC37c669_write_config(
1962 unsigned char index,
1963 unsigned char data )
1965 wb( &SMC37c669->index_port, index );
1966 wb( &SMC37c669->data_port, data );
1971 **++
1972 ** FUNCTIONAL DESCRIPTION:
1974 ** This function initializes the local device
1975 ** configuration storage. This function assumes
1976 ** that the device is already in configuration
1977 ** mode.
1979 ** FORMAL PARAMETERS:
1981 ** None
1983 ** RETURN VALUE:
1985 ** None
1987 ** SIDE EFFECTS:
1989 ** Local storage for device configuration information
1990 ** is initialized.
1992 **--
1994 static void __init SMC37c669_init_local_config ( void )
1996 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER uart_base;
1997 SMC37c669_SERIAL_IRQ_REGISTER uart_irqs;
1998 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER ppt_base;
1999 SMC37c669_PARALLEL_FDC_IRQ_REGISTER ppt_fdc_irqs;
2000 SMC37c669_PARALLEL_FDC_DRQ_REGISTER ppt_fdc_drqs;
2001 SMC37c669_FDC_BASE_ADDRESS_REGISTER fdc_base;
2002 SMC37c669_IDE_ADDRESS_REGISTER ide_base;
2003 SMC37c669_IDE_ADDRESS_REGISTER ide_alt;
2006 ** Get serial port 1 base address
2008 uart_base.as_uchar =
2009 SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
2011 ** Get IRQs for serial ports 1 & 2
2013 uart_irqs.as_uchar =
2014 SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
2016 ** Store local configuration information for serial port 1
2018 local_config[SERIAL_0].port1 = uart_base.by_field.addr9_3 << 3;
2019 local_config[SERIAL_0].irq =
2020 SMC37c669_xlate_irq(
2021 SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart1_irq )
2024 ** Get serial port 2 base address
2026 uart_base.as_uchar =
2027 SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
2029 ** Store local configuration information for serial port 2
2031 local_config[SERIAL_1].port1 = uart_base.by_field.addr9_3 << 3;
2032 local_config[SERIAL_1].irq =
2033 SMC37c669_xlate_irq(
2034 SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart2_irq )
2037 ** Get parallel port base address
2039 ppt_base.as_uchar =
2040 SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
2042 ** Get IRQs for parallel port and floppy controller
2044 ppt_fdc_irqs.as_uchar =
2045 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
2047 ** Get DRQs for parallel port and floppy controller
2049 ppt_fdc_drqs.as_uchar =
2050 SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
2052 ** Store local configuration information for parallel port
2054 local_config[PARALLEL_0].port1 = ppt_base.by_field.addr9_2 << 2;
2055 local_config[PARALLEL_0].irq =
2056 SMC37c669_xlate_irq(
2057 SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.ppt_irq )
2059 local_config[PARALLEL_0].drq =
2060 SMC37c669_xlate_drq(
2061 SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.ppt_drq )
2064 ** Get floppy controller base address
2066 fdc_base.as_uchar =
2067 SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
2069 ** Store local configuration information for floppy controller
2071 local_config[FLOPPY_0].port1 = fdc_base.by_field.addr9_4 << 4;
2072 local_config[FLOPPY_0].irq =
2073 SMC37c669_xlate_irq(
2074 SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.fdc_irq )
2076 local_config[FLOPPY_0].drq =
2077 SMC37c669_xlate_drq(
2078 SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.fdc_drq )
2081 ** Get IDE controller base address
2083 ide_base.as_uchar =
2084 SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
2086 ** Get IDE alternate status base address
2088 ide_alt.as_uchar =
2089 SMC37c669_read_config( SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX );
2091 ** Store local configuration information for IDE controller
2093 local_config[IDE_0].port1 = ide_base.by_field.addr9_4 << 4;
2094 local_config[IDE_0].port2 = ide_alt.by_field.addr9_4 << 4;
2095 local_config[IDE_0].irq = 14;
2100 **++
2101 ** FUNCTIONAL DESCRIPTION:
2103 ** This function returns a pointer to the local shadow
2104 ** configuration of the requested device function.
2106 ** FORMAL PARAMETERS:
2108 ** func:
2109 ** Which device function
2111 ** RETURN VALUE:
2113 ** Returns a pointer to the DEVICE_CONFIG structure for the
2114 ** requested function, otherwise, NULL.
2116 ** SIDE EFFECTS:
2118 ** {@description or none@}
2120 **--
2122 static struct DEVICE_CONFIG * __init SMC37c669_get_config( unsigned int func )
2124 struct DEVICE_CONFIG *cp = NULL;
2126 switch ( func ) {
2127 case SERIAL_0:
2128 cp = &local_config[ SERIAL_0 ];
2129 break;
2130 case SERIAL_1:
2131 cp = &local_config[ SERIAL_1 ];
2132 break;
2133 case PARALLEL_0:
2134 cp = &local_config[ PARALLEL_0 ];
2135 break;
2136 case FLOPPY_0:
2137 cp = &local_config[ FLOPPY_0 ];
2138 break;
2139 case IDE_0:
2140 cp = &local_config[ IDE_0 ];
2141 break;
2143 return cp;
2147 **++
2148 ** FUNCTIONAL DESCRIPTION:
2150 ** This function translates IRQs back and forth between ISA
2151 ** IRQs and SMC37c669 device IRQs.
2153 ** FORMAL PARAMETERS:
2155 ** irq:
2156 ** The IRQ to translate
2158 ** RETURN VALUE:
2160 ** Returns the translated IRQ, otherwise, returns -1.
2162 ** SIDE EFFECTS:
2164 ** {@description or none@}
2166 **--
2168 static int __init SMC37c669_xlate_irq ( int irq )
2170 int i, translated_irq = -1;
2172 if ( SMC37c669_IS_DEVICE_IRQ( irq ) ) {
2174 ** We are translating a device IRQ to an ISA IRQ
2176 for ( i = 0; ( SMC37c669_irq_table[i].device_irq != -1 ) || ( SMC37c669_irq_table[i].isa_irq != -1 ); i++ ) {
2177 if ( irq == SMC37c669_irq_table[i].device_irq ) {
2178 translated_irq = SMC37c669_irq_table[i].isa_irq;
2179 break;
2183 else {
2185 ** We are translating an ISA IRQ to a device IRQ
2187 for ( i = 0; ( SMC37c669_irq_table[i].isa_irq != -1 ) || ( SMC37c669_irq_table[i].device_irq != -1 ); i++ ) {
2188 if ( irq == SMC37c669_irq_table[i].isa_irq ) {
2189 translated_irq = SMC37c669_irq_table[i].device_irq;
2190 break;
2194 return translated_irq;
2199 **++
2200 ** FUNCTIONAL DESCRIPTION:
2202 ** This function translates DMA channels back and forth between
2203 ** ISA DMA channels and SMC37c669 device DMA channels.
2205 ** FORMAL PARAMETERS:
2207 ** drq:
2208 ** The DMA channel to translate
2210 ** RETURN VALUE:
2212 ** Returns the translated DMA channel, otherwise, returns -1
2214 ** SIDE EFFECTS:
2216 ** {@description or none@}
2218 **--
2220 static int __init SMC37c669_xlate_drq ( int drq )
2222 int i, translated_drq = -1;
2224 if ( SMC37c669_IS_DEVICE_DRQ( drq ) ) {
2226 ** We are translating a device DMA channel to an ISA DMA channel
2228 for ( i = 0; ( SMC37c669_drq_table[i].device_drq != -1 ) || ( SMC37c669_drq_table[i].isa_drq != -1 ); i++ ) {
2229 if ( drq == SMC37c669_drq_table[i].device_drq ) {
2230 translated_drq = SMC37c669_drq_table[i].isa_drq;
2231 break;
2235 else {
2237 ** We are translating an ISA DMA channel to a device DMA channel
2239 for ( i = 0; ( SMC37c669_drq_table[i].isa_drq != -1 ) || ( SMC37c669_drq_table[i].device_drq != -1 ); i++ ) {
2240 if ( drq == SMC37c669_drq_table[i].isa_drq ) {
2241 translated_drq = SMC37c669_drq_table[i].device_drq;
2242 break;
2246 return translated_drq;
2250 void __init
2251 SMC37c669_dump_registers(void)
2253 int i;
2254 for (i = 0; i <= 0x29; i++)
2255 printk("-- CR%02x : %02x\n", i, SMC37c669_read_config(i));
2258 * ============================================================================
2259 * = SMC_init - SMC37c669 Super I/O controller initialization =
2260 * ============================================================================
2262 * OVERVIEW:
2264 * This routine configures and enables device functions on the
2265 * SMC37c669 Super I/O controller.
2267 * FORM OF CALL:
2269 * SMC_init( );
2271 * RETURNS:
2273 * Nothing
2275 * ARGUMENTS:
2277 * None
2279 * SIDE EFFECTS:
2281 * None
2284 void __init SMC669_Init ( int index )
2286 SMC37c669_CONFIG_REGS *SMC_base;
2287 unsigned long flags;
2289 local_irq_save(flags);
2290 if ( ( SMC_base = SMC37c669_detect( index ) ) != NULL ) {
2291 #if SMC_DEBUG
2292 SMC37c669_config_mode( TRUE );
2293 SMC37c669_dump_registers( );
2294 SMC37c669_config_mode( FALSE );
2295 SMC37c669_display_device_info( );
2296 #endif
2297 SMC37c669_disable_device( SERIAL_0 );
2298 SMC37c669_configure_device(
2299 SERIAL_0,
2300 COM1_BASE,
2301 COM1_IRQ,
2304 SMC37c669_enable_device( SERIAL_0 );
2306 SMC37c669_disable_device( SERIAL_1 );
2307 SMC37c669_configure_device(
2308 SERIAL_1,
2309 COM2_BASE,
2310 COM2_IRQ,
2313 SMC37c669_enable_device( SERIAL_1 );
2315 SMC37c669_disable_device( PARALLEL_0 );
2316 SMC37c669_configure_device(
2317 PARALLEL_0,
2318 PARP_BASE,
2319 PARP_IRQ,
2320 PARP_DRQ
2322 SMC37c669_enable_device( PARALLEL_0 );
2324 SMC37c669_disable_device( FLOPPY_0 );
2325 SMC37c669_configure_device(
2326 FLOPPY_0,
2327 FDC_BASE,
2328 FDC_IRQ,
2329 FDC_DRQ
2331 SMC37c669_enable_device( FLOPPY_0 );
2333 /* Wake up sometimes forgotten floppy, especially on DP264. */
2334 outb(0xc, 0x3f2);
2336 SMC37c669_disable_device( IDE_0 );
2338 #if SMC_DEBUG
2339 SMC37c669_config_mode( TRUE );
2340 SMC37c669_dump_registers( );
2341 SMC37c669_config_mode( FALSE );
2342 SMC37c669_display_device_info( );
2343 #endif
2344 local_irq_restore(flags);
2345 printk( "SMC37c669 Super I/O Controller found @ 0x%p\n",
2346 SMC_base );
2348 else {
2349 local_irq_restore(flags);
2350 #if SMC_DEBUG
2351 printk( "No SMC37c669 Super I/O Controller found\n" );
2352 #endif