xref: /openbmc/linux/arch/alpha/kernel/smc37c669.c (revision 5f0e3da6)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * SMC 37C669 initialization code
31da177e4SLinus Torvalds  */
41da177e4SLinus Torvalds #include <linux/kernel.h>
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds #include <linux/slab.h>
71da177e4SLinus Torvalds #include <linux/mm.h>
81da177e4SLinus Torvalds #include <linux/init.h>
91da177e4SLinus Torvalds #include <linux/delay.h>
101da177e4SLinus Torvalds #include <linux/spinlock.h>
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds #include <asm/hwrpb.h>
131da177e4SLinus Torvalds #include <asm/io.h>
141da177e4SLinus Torvalds #include <asm/segment.h>
151da177e4SLinus Torvalds 
161da177e4SLinus Torvalds #if 0
171da177e4SLinus Torvalds # define DBG_DEVS(args)         printk args
181da177e4SLinus Torvalds #else
191da177e4SLinus Torvalds # define DBG_DEVS(args)
201da177e4SLinus Torvalds #endif
211da177e4SLinus Torvalds 
221da177e4SLinus Torvalds #define KB              1024
231da177e4SLinus Torvalds #define MB              (1024*KB)
241da177e4SLinus Torvalds #define GB              (1024*MB)
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds #define SMC_DEBUG   0
271da177e4SLinus Torvalds 
281da177e4SLinus Torvalds /* File:	smcc669_def.h
291da177e4SLinus Torvalds  *
301da177e4SLinus Torvalds  * Copyright (C) 1997 by
311da177e4SLinus Torvalds  * Digital Equipment Corporation, Maynard, Massachusetts.
321da177e4SLinus Torvalds  * All rights reserved.
331da177e4SLinus Torvalds  *
341da177e4SLinus Torvalds  * This software is furnished under a license and may be used and copied
351da177e4SLinus Torvalds  * only  in  accordance  of  the  terms  of  such  license  and with the
361da177e4SLinus Torvalds  * inclusion of the above copyright notice. This software or  any  other
371da177e4SLinus Torvalds  * copies thereof may not be provided or otherwise made available to any
381da177e4SLinus Torvalds  * other person.  No title to and  ownership of the  software is  hereby
391da177e4SLinus Torvalds  * transferred.
401da177e4SLinus Torvalds  *
411da177e4SLinus Torvalds  * The information in this software is  subject to change without notice
421da177e4SLinus Torvalds  * and  should  not  be  construed  as a commitment by Digital Equipment
431da177e4SLinus Torvalds  * Corporation.
441da177e4SLinus Torvalds  *
451da177e4SLinus Torvalds  * Digital assumes no responsibility for the use  or  reliability of its
461da177e4SLinus Torvalds  * software on equipment which is not supplied by Digital.
471da177e4SLinus Torvalds  *
481da177e4SLinus Torvalds  *
491da177e4SLinus Torvalds  * Abstract:
501da177e4SLinus Torvalds  *
511da177e4SLinus Torvalds  *	This file contains header definitions for the SMC37c669
521da177e4SLinus Torvalds  *	Super I/O controller.
531da177e4SLinus Torvalds  *
541da177e4SLinus Torvalds  * Author:
551da177e4SLinus Torvalds  *
561da177e4SLinus Torvalds  *	Eric Rasmussen
571da177e4SLinus Torvalds  *
581da177e4SLinus Torvalds  * Modification History:
591da177e4SLinus Torvalds  *
601da177e4SLinus Torvalds  *	er	28-Jan-1997	Initial Entry
611da177e4SLinus Torvalds  */
621da177e4SLinus Torvalds 
631da177e4SLinus Torvalds #ifndef __SMC37c669_H
641da177e4SLinus Torvalds #define __SMC37c669_H
651da177e4SLinus Torvalds 
661da177e4SLinus Torvalds /*
671da177e4SLinus Torvalds ** Macros for handling device IRQs
681da177e4SLinus Torvalds **
691da177e4SLinus Torvalds ** The mask acts as a flag used in mapping actual ISA IRQs (0 - 15)
701da177e4SLinus Torvalds ** to device IRQs (A - H).
711da177e4SLinus Torvalds */
721da177e4SLinus Torvalds #define SMC37c669_DEVICE_IRQ_MASK	0x80000000
731da177e4SLinus Torvalds #define SMC37c669_DEVICE_IRQ( __i )	\
741da177e4SLinus Torvalds 	((SMC37c669_DEVICE_IRQ_MASK) | (__i))
751da177e4SLinus Torvalds #define SMC37c669_IS_DEVICE_IRQ(__i)	\
761da177e4SLinus Torvalds 	(((__i) & (SMC37c669_DEVICE_IRQ_MASK)) == (SMC37c669_DEVICE_IRQ_MASK))
771da177e4SLinus Torvalds #define SMC37c669_RAW_DEVICE_IRQ(__i)	\
781da177e4SLinus Torvalds 	((__i) & ~(SMC37c669_DEVICE_IRQ_MASK))
791da177e4SLinus Torvalds 
801da177e4SLinus Torvalds /*
811da177e4SLinus Torvalds ** Macros for handling device DRQs
821da177e4SLinus Torvalds **
831da177e4SLinus Torvalds ** The mask acts as a flag used in mapping actual ISA DMA
841da177e4SLinus Torvalds ** channels to device DMA channels (A - C).
851da177e4SLinus Torvalds */
861da177e4SLinus Torvalds #define SMC37c669_DEVICE_DRQ_MASK	0x80000000
871da177e4SLinus Torvalds #define SMC37c669_DEVICE_DRQ(__d)	\
881da177e4SLinus Torvalds 	((SMC37c669_DEVICE_DRQ_MASK) | (__d))
891da177e4SLinus Torvalds #define SMC37c669_IS_DEVICE_DRQ(__d)	\
901da177e4SLinus Torvalds 	(((__d) & (SMC37c669_DEVICE_DRQ_MASK)) == (SMC37c669_DEVICE_DRQ_MASK))
911da177e4SLinus Torvalds #define SMC37c669_RAW_DEVICE_DRQ(__d)	\
921da177e4SLinus Torvalds 	((__d) & ~(SMC37c669_DEVICE_DRQ_MASK))
931da177e4SLinus Torvalds 
941da177e4SLinus Torvalds #define SMC37c669_DEVICE_ID	0x3
951da177e4SLinus Torvalds 
961da177e4SLinus Torvalds /*
971da177e4SLinus Torvalds ** SMC37c669 Device Function Definitions
981da177e4SLinus Torvalds */
991da177e4SLinus Torvalds #define SERIAL_0	0
1001da177e4SLinus Torvalds #define SERIAL_1	1
1011da177e4SLinus Torvalds #define PARALLEL_0	2
1021da177e4SLinus Torvalds #define FLOPPY_0	3
1031da177e4SLinus Torvalds #define IDE_0		4
1041da177e4SLinus Torvalds #define NUM_FUNCS	5
1051da177e4SLinus Torvalds 
1061da177e4SLinus Torvalds /*
1071da177e4SLinus Torvalds ** Default Device Function Mappings
1081da177e4SLinus Torvalds */
1091da177e4SLinus Torvalds #define COM1_BASE	0x3F8
1101da177e4SLinus Torvalds #define COM1_IRQ	4
1111da177e4SLinus Torvalds #define COM2_BASE	0x2F8
1121da177e4SLinus Torvalds #define COM2_IRQ	3
1131da177e4SLinus Torvalds #define PARP_BASE	0x3BC
1141da177e4SLinus Torvalds #define PARP_IRQ	7
1151da177e4SLinus Torvalds #define PARP_DRQ	3
1161da177e4SLinus Torvalds #define FDC_BASE	0x3F0
1171da177e4SLinus Torvalds #define FDC_IRQ		6
1181da177e4SLinus Torvalds #define FDC_DRQ		2
1191da177e4SLinus Torvalds 
1201da177e4SLinus Torvalds /*
1211da177e4SLinus Torvalds ** Configuration On/Off Key Definitions
1221da177e4SLinus Torvalds */
1231da177e4SLinus Torvalds #define SMC37c669_CONFIG_ON_KEY		0x55
1241da177e4SLinus Torvalds #define SMC37c669_CONFIG_OFF_KEY	0xAA
1251da177e4SLinus Torvalds 
1261da177e4SLinus Torvalds /*
1271da177e4SLinus Torvalds ** SMC 37c669 Device IRQs
1281da177e4SLinus Torvalds */
1291da177e4SLinus Torvalds #define SMC37c669_DEVICE_IRQ_A	    ( SMC37c669_DEVICE_IRQ( 0x01 ) )
1301da177e4SLinus Torvalds #define SMC37c669_DEVICE_IRQ_B	    ( SMC37c669_DEVICE_IRQ( 0x02 ) )
1311da177e4SLinus Torvalds #define SMC37c669_DEVICE_IRQ_C	    ( SMC37c669_DEVICE_IRQ( 0x03 ) )
1321da177e4SLinus Torvalds #define SMC37c669_DEVICE_IRQ_D	    ( SMC37c669_DEVICE_IRQ( 0x04 ) )
1331da177e4SLinus Torvalds #define SMC37c669_DEVICE_IRQ_E	    ( SMC37c669_DEVICE_IRQ( 0x05 ) )
1341da177e4SLinus Torvalds #define SMC37c669_DEVICE_IRQ_F	    ( SMC37c669_DEVICE_IRQ( 0x06 ) )
1351da177e4SLinus Torvalds /*      SMC37c669_DEVICE_IRQ_G	    *** RESERVED ***/
1361da177e4SLinus Torvalds #define SMC37c669_DEVICE_IRQ_H	    ( SMC37c669_DEVICE_IRQ( 0x08 ) )
1371da177e4SLinus Torvalds 
1381da177e4SLinus Torvalds /*
1391da177e4SLinus Torvalds ** SMC 37c669 Device DMA Channel Definitions
1401da177e4SLinus Torvalds */
1411da177e4SLinus Torvalds #define SMC37c669_DEVICE_DRQ_A		    ( SMC37c669_DEVICE_DRQ( 0x01 ) )
1421da177e4SLinus Torvalds #define SMC37c669_DEVICE_DRQ_B		    ( SMC37c669_DEVICE_DRQ( 0x02 ) )
1431da177e4SLinus Torvalds #define SMC37c669_DEVICE_DRQ_C		    ( SMC37c669_DEVICE_DRQ( 0x03 ) )
1441da177e4SLinus Torvalds 
1451da177e4SLinus Torvalds /*
1461da177e4SLinus Torvalds ** Configuration Register Index Definitions
1471da177e4SLinus Torvalds */
1481da177e4SLinus Torvalds #define SMC37c669_CR00_INDEX	    0x00
1491da177e4SLinus Torvalds #define SMC37c669_CR01_INDEX	    0x01
1501da177e4SLinus Torvalds #define SMC37c669_CR02_INDEX	    0x02
1511da177e4SLinus Torvalds #define SMC37c669_CR03_INDEX	    0x03
1521da177e4SLinus Torvalds #define SMC37c669_CR04_INDEX	    0x04
1531da177e4SLinus Torvalds #define SMC37c669_CR05_INDEX	    0x05
1541da177e4SLinus Torvalds #define SMC37c669_CR06_INDEX	    0x06
1551da177e4SLinus Torvalds #define SMC37c669_CR07_INDEX	    0x07
1561da177e4SLinus Torvalds #define SMC37c669_CR08_INDEX	    0x08
1571da177e4SLinus Torvalds #define SMC37c669_CR09_INDEX	    0x09
1581da177e4SLinus Torvalds #define SMC37c669_CR0A_INDEX	    0x0A
1591da177e4SLinus Torvalds #define SMC37c669_CR0B_INDEX	    0x0B
1601da177e4SLinus Torvalds #define SMC37c669_CR0C_INDEX	    0x0C
1611da177e4SLinus Torvalds #define SMC37c669_CR0D_INDEX	    0x0D
1621da177e4SLinus Torvalds #define SMC37c669_CR0E_INDEX	    0x0E
1631da177e4SLinus Torvalds #define SMC37c669_CR0F_INDEX	    0x0F
1641da177e4SLinus Torvalds #define SMC37c669_CR10_INDEX	    0x10
1651da177e4SLinus Torvalds #define SMC37c669_CR11_INDEX	    0x11
1661da177e4SLinus Torvalds #define SMC37c669_CR12_INDEX	    0x12
1671da177e4SLinus Torvalds #define SMC37c669_CR13_INDEX	    0x13
1681da177e4SLinus Torvalds #define SMC37c669_CR14_INDEX	    0x14
1691da177e4SLinus Torvalds #define SMC37c669_CR15_INDEX	    0x15
1701da177e4SLinus Torvalds #define SMC37c669_CR16_INDEX	    0x16
1711da177e4SLinus Torvalds #define SMC37c669_CR17_INDEX	    0x17
1721da177e4SLinus Torvalds #define SMC37c669_CR18_INDEX	    0x18
1731da177e4SLinus Torvalds #define SMC37c669_CR19_INDEX	    0x19
1741da177e4SLinus Torvalds #define SMC37c669_CR1A_INDEX	    0x1A
1751da177e4SLinus Torvalds #define SMC37c669_CR1B_INDEX	    0x1B
1761da177e4SLinus Torvalds #define SMC37c669_CR1C_INDEX	    0x1C
1771da177e4SLinus Torvalds #define SMC37c669_CR1D_INDEX	    0x1D
1781da177e4SLinus Torvalds #define SMC37c669_CR1E_INDEX	    0x1E
1791da177e4SLinus Torvalds #define SMC37c669_CR1F_INDEX	    0x1F
1801da177e4SLinus Torvalds #define SMC37c669_CR20_INDEX	    0x20
1811da177e4SLinus Torvalds #define SMC37c669_CR21_INDEX	    0x21
1821da177e4SLinus Torvalds #define SMC37c669_CR22_INDEX	    0x22
1831da177e4SLinus Torvalds #define SMC37c669_CR23_INDEX	    0x23
1841da177e4SLinus Torvalds #define SMC37c669_CR24_INDEX	    0x24
1851da177e4SLinus Torvalds #define SMC37c669_CR25_INDEX	    0x25
1861da177e4SLinus Torvalds #define SMC37c669_CR26_INDEX	    0x26
1871da177e4SLinus Torvalds #define SMC37c669_CR27_INDEX	    0x27
1881da177e4SLinus Torvalds #define SMC37c669_CR28_INDEX	    0x28
1891da177e4SLinus Torvalds #define SMC37c669_CR29_INDEX	    0x29
1901da177e4SLinus Torvalds 
1911da177e4SLinus Torvalds /*
1921da177e4SLinus Torvalds ** Configuration Register Alias Definitions
1931da177e4SLinus Torvalds */
1941da177e4SLinus Torvalds #define SMC37c669_DEVICE_ID_INDEX		    SMC37c669_CR0D_INDEX
1951da177e4SLinus Torvalds #define SMC37c669_DEVICE_REVISION_INDEX		    SMC37c669_CR0E_INDEX
1961da177e4SLinus Torvalds #define SMC37c669_FDC_BASE_ADDRESS_INDEX	    SMC37c669_CR20_INDEX
1971da177e4SLinus Torvalds #define SMC37c669_IDE_BASE_ADDRESS_INDEX	    SMC37c669_CR21_INDEX
1981da177e4SLinus Torvalds #define SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX	    SMC37c669_CR22_INDEX
1991da177e4SLinus Torvalds #define SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX	    SMC37c669_CR23_INDEX
2001da177e4SLinus Torvalds #define SMC37c669_SERIAL0_BASE_ADDRESS_INDEX	    SMC37c669_CR24_INDEX
2011da177e4SLinus Torvalds #define SMC37c669_SERIAL1_BASE_ADDRESS_INDEX	    SMC37c669_CR25_INDEX
2021da177e4SLinus Torvalds #define SMC37c669_PARALLEL_FDC_DRQ_INDEX	    SMC37c669_CR26_INDEX
2031da177e4SLinus Torvalds #define SMC37c669_PARALLEL_FDC_IRQ_INDEX	    SMC37c669_CR27_INDEX
2041da177e4SLinus Torvalds #define SMC37c669_SERIAL_IRQ_INDEX		    SMC37c669_CR28_INDEX
2051da177e4SLinus Torvalds 
2061da177e4SLinus Torvalds /*
2071da177e4SLinus Torvalds ** Configuration Register Definitions
2081da177e4SLinus Torvalds **
2091da177e4SLinus Torvalds ** The INDEX (write only) and DATA (read/write) ports are effective
2101da177e4SLinus Torvalds ** only when the chip is in the Configuration State.
2111da177e4SLinus Torvalds */
2121da177e4SLinus Torvalds typedef struct _SMC37c669_CONFIG_REGS {
2131da177e4SLinus Torvalds     unsigned char index_port;
2141da177e4SLinus Torvalds     unsigned char data_port;
2151da177e4SLinus Torvalds } SMC37c669_CONFIG_REGS;
2161da177e4SLinus Torvalds 
2171da177e4SLinus Torvalds /*
2181da177e4SLinus Torvalds ** CR00 - default value 0x28
2191da177e4SLinus Torvalds **
2201da177e4SLinus Torvalds **  IDE_EN (CR00<1:0>):
2211da177e4SLinus Torvalds **	0x - 30ua pull-ups on nIDEEN, nHDCS0, NHDCS1
2221da177e4SLinus Torvalds **	11 - IRQ_H available as IRQ output,
2231da177e4SLinus Torvalds **	     IRRX2, IRTX2 available as alternate IR pins
2241da177e4SLinus Torvalds **	10 - nIDEEN, nHDCS0, nHDCS1 used to control IDE
2251da177e4SLinus Torvalds **
2261da177e4SLinus Torvalds **  VALID (CR00<7>):
2271da177e4SLinus Torvalds **	A high level on this software controlled bit can
2281da177e4SLinus Torvalds **	be used to indicate that a valid configuration
2291da177e4SLinus Torvalds **	cycle has occurred.  The control software must
2301da177e4SLinus Torvalds **	take care to set this bit at the appropriate times.
2311da177e4SLinus Torvalds **	Set to zero after power up.  This bit has no
2321da177e4SLinus Torvalds **	effect on any other hardware in the chip.
2331da177e4SLinus Torvalds **
2341da177e4SLinus Torvalds */
2351da177e4SLinus Torvalds typedef union _SMC37c669_CR00 {
2361da177e4SLinus Torvalds     unsigned char as_uchar;
2371da177e4SLinus Torvalds     struct {
2381da177e4SLinus Torvalds     	unsigned ide_en : 2;	    /* See note above		*/
2391da177e4SLinus Torvalds 	unsigned reserved1 : 1;	    /* RAZ			*/
2401da177e4SLinus Torvalds 	unsigned fdc_pwr : 1;	    /* 1 = supply power to FDC  */
2411da177e4SLinus Torvalds 	unsigned reserved2 : 3;	    /* Read as 010b		*/
2421da177e4SLinus Torvalds 	unsigned valid : 1;	    /* See note above		*/
2431da177e4SLinus Torvalds     }	by_field;
2441da177e4SLinus Torvalds } SMC37c669_CR00;
2451da177e4SLinus Torvalds 
2461da177e4SLinus Torvalds /*
2471da177e4SLinus Torvalds ** CR01 - default value 0x9C
2481da177e4SLinus Torvalds */
2491da177e4SLinus Torvalds typedef union _SMC37c669_CR01 {
2501da177e4SLinus Torvalds     unsigned char as_uchar;
2511da177e4SLinus Torvalds     struct {
2521da177e4SLinus Torvalds     	unsigned reserved1 : 2;	    /* RAZ			    */
2531da177e4SLinus Torvalds 	unsigned ppt_pwr : 1;	    /* 1 = supply power to PPT	    */
2541da177e4SLinus Torvalds 	unsigned ppt_mode : 1;	    /* 1 = Printer mode, 0 = EPP    */
2551da177e4SLinus Torvalds 	unsigned reserved2 : 1;	    /* Read as 1		    */
2561da177e4SLinus Torvalds 	unsigned reserved3 : 2;	    /* RAZ			    */
2571da177e4SLinus Torvalds 	unsigned lock_crx: 1;	    /* Lock CR00 - CR18		    */
2581da177e4SLinus Torvalds     }	by_field;
2591da177e4SLinus Torvalds } SMC37c669_CR01;
2601da177e4SLinus Torvalds 
2611da177e4SLinus Torvalds /*
2621da177e4SLinus Torvalds ** CR02 - default value 0x88
2631da177e4SLinus Torvalds */
2641da177e4SLinus Torvalds typedef union _SMC37c669_CR02 {
2651da177e4SLinus Torvalds     unsigned char as_uchar;
2661da177e4SLinus Torvalds     struct {
2671da177e4SLinus Torvalds     	unsigned reserved1 : 3;	    /* RAZ			    */
2681da177e4SLinus Torvalds 	unsigned uart1_pwr : 1;	    /* 1 = supply power to UART1    */
2691da177e4SLinus Torvalds 	unsigned reserved2 : 3;	    /* RAZ			    */
2701da177e4SLinus Torvalds 	unsigned uart2_pwr : 1;	    /* 1 = supply power to UART2    */
2711da177e4SLinus Torvalds     }	by_field;
2721da177e4SLinus Torvalds } SMC37c669_CR02;
2731da177e4SLinus Torvalds 
2741da177e4SLinus Torvalds /*
2751da177e4SLinus Torvalds ** CR03 - default value 0x78
2761da177e4SLinus Torvalds **
2771da177e4SLinus Torvalds **  CR03<7>	CR03<2>	    Pin 94
2781da177e4SLinus Torvalds **  -------	-------	    ------
2791da177e4SLinus Torvalds **     0	   X	    DRV2 (input)
2801da177e4SLinus Torvalds **     1	   0	    ADRX
2811da177e4SLinus Torvalds **     1	   1	    IRQ_B
2821da177e4SLinus Torvalds **
2831da177e4SLinus Torvalds **  CR03<6>	CR03<5>	    Op Mode
2841da177e4SLinus Torvalds **  -------	-------	    -------
2851da177e4SLinus Torvalds **     0	   0	    Model 30
2861da177e4SLinus Torvalds **     0	   1	    PS/2
2871da177e4SLinus Torvalds **     1	   0	    Reserved
2881da177e4SLinus Torvalds **     1	   1	    AT Mode
2891da177e4SLinus Torvalds */
2901da177e4SLinus Torvalds typedef union _SMC37c669_CR03 {
2911da177e4SLinus Torvalds     unsigned char as_uchar;
2921da177e4SLinus Torvalds     struct {
2931da177e4SLinus Torvalds     	unsigned pwrgd_gamecs : 1;  /* 1 = PWRGD, 0 = GAMECS	    */
2941da177e4SLinus Torvalds 	unsigned fdc_mode2 : 1;	    /* 1 = Enhanced Mode 2	    */
2951da177e4SLinus Torvalds 	unsigned pin94_0 : 1;	    /* See note above		    */
2961da177e4SLinus Torvalds 	unsigned reserved1 : 1;	    /* RAZ			    */
2971da177e4SLinus Torvalds 	unsigned drvden : 1;	    /* 1 = high, 0 - output	    */
2981da177e4SLinus Torvalds 	unsigned op_mode : 2;	    /* See note above		    */
2991da177e4SLinus Torvalds 	unsigned pin94_1 : 1;	    /* See note above		    */
3001da177e4SLinus Torvalds     }	by_field;
3011da177e4SLinus Torvalds } SMC37c669_CR03;
3021da177e4SLinus Torvalds 
3031da177e4SLinus Torvalds /*
3041da177e4SLinus Torvalds ** CR04 - default value 0x00
3051da177e4SLinus Torvalds **
3061da177e4SLinus Torvalds **  PP_EXT_MODE:
3071da177e4SLinus Torvalds **	If CR01<PP_MODE> = 0 and PP_EXT_MODE =
3081da177e4SLinus Torvalds **	    00 - Standard and Bidirectional
3091da177e4SLinus Torvalds **	    01 - EPP mode and SPP
3101da177e4SLinus Torvalds **	    10 - ECP mode
3111da177e4SLinus Torvalds **		 In this mode, 2 drives can be supported
3121da177e4SLinus Torvalds **		 directly, 3 or 4 drives must use external
3131da177e4SLinus Torvalds **		 4 drive support.  SPP can be selected
3141da177e4SLinus Torvalds **		 through the ECR register of ECP as mode 000.
3151da177e4SLinus Torvalds **	    11 - ECP mode and EPP mode
3161da177e4SLinus Torvalds **		 In this mode, 2 drives can be supported
3171da177e4SLinus Torvalds **		 directly, 3 or 4 drives must use external
3181da177e4SLinus Torvalds **		 4 drive support.  SPP can be selected
3191da177e4SLinus Torvalds **		 through the ECR register of ECP as mode 000.
3201da177e4SLinus Torvalds **		 In this mode, EPP can be selected through
3211da177e4SLinus Torvalds **		 the ECR register of ECP as mode 100.
3221da177e4SLinus Torvalds **
3231da177e4SLinus Torvalds **  PP_FDC:
3241da177e4SLinus Torvalds **	00 - Normal
3251da177e4SLinus Torvalds **	01 - PPFD1
3261da177e4SLinus Torvalds **	10 - PPFD2
3271da177e4SLinus Torvalds **	11 - Reserved
3281da177e4SLinus Torvalds **
3291da177e4SLinus Torvalds **  MIDI1:
3301da177e4SLinus Torvalds **	Serial Clock Select:
3311da177e4SLinus Torvalds **	    A low level on this bit disables MIDI support,
3321da177e4SLinus Torvalds **	    clock = divide by 13.  A high level on this
3331da177e4SLinus Torvalds **	    bit enables MIDI support, clock = divide by 12.
3341da177e4SLinus Torvalds **
3351da177e4SLinus Torvalds **	MIDI operates at 31.25 Kbps which can be derived
3361da177e4SLinus Torvalds **	from 125 KHz (24 MHz / 12 = 2 MHz, 2 MHz / 16 = 125 KHz)
3371da177e4SLinus Torvalds **
3381da177e4SLinus Torvalds **  ALT_IO:
3391da177e4SLinus Torvalds **	0 - Use pins IRRX, IRTX
3401da177e4SLinus Torvalds **	1 - Use pins IRRX2, IRTX2
3411da177e4SLinus Torvalds **
3421da177e4SLinus Torvalds **	If this bit is set, the IR receive and transmit
3431da177e4SLinus Torvalds **	functions will not be available on pins 25 and 26
3441da177e4SLinus Torvalds **	unless CR00<IDE_EN> = 11.
3451da177e4SLinus Torvalds */
3461da177e4SLinus Torvalds typedef union _SMC37c669_CR04 {
3471da177e4SLinus Torvalds     unsigned char as_uchar;
3481da177e4SLinus Torvalds     struct {
3491da177e4SLinus Torvalds     	unsigned ppt_ext_mode : 2;  /* See note above		    */
3501da177e4SLinus Torvalds 	unsigned ppt_fdc : 2;	    /* See note above		    */
3511da177e4SLinus Torvalds 	unsigned midi1 : 1;	    /* See note above		    */
3521da177e4SLinus Torvalds 	unsigned midi2 : 1;	    /* See note above		    */
3531da177e4SLinus Torvalds 	unsigned epp_type : 1;	    /* 0 = EPP 1.9, 1 = EPP 1.7	    */
3541da177e4SLinus Torvalds 	unsigned alt_io : 1;	    /* See note above		    */
3551da177e4SLinus Torvalds     }	by_field;
3561da177e4SLinus Torvalds } SMC37c669_CR04;
3571da177e4SLinus Torvalds 
3581da177e4SLinus Torvalds /*
3591da177e4SLinus Torvalds ** CR05 - default value 0x00
3601da177e4SLinus Torvalds **
3611da177e4SLinus Torvalds **  DEN_SEL:
3621da177e4SLinus Torvalds **	00 - Densel output normal
3631da177e4SLinus Torvalds **	01 - Reserved
3641da177e4SLinus Torvalds **	10 - Densel output 1
3651da177e4SLinus Torvalds **	11 - Densel output 0
3661da177e4SLinus Torvalds **
3671da177e4SLinus Torvalds */
3681da177e4SLinus Torvalds typedef union _SMC37c669_CR05 {
3691da177e4SLinus Torvalds     unsigned char as_uchar;
3701da177e4SLinus Torvalds     struct {
3711da177e4SLinus Torvalds     	unsigned reserved1 : 2;	    /* RAZ					*/
3721da177e4SLinus Torvalds 	unsigned fdc_dma_mode : 1;  /* 0 = burst, 1 = non-burst			*/
3731da177e4SLinus Torvalds 	unsigned den_sel : 2;	    /* See note above				*/
3741da177e4SLinus Torvalds 	unsigned swap_drv : 1;	    /* Swap the FDC motor selects		*/
3751da177e4SLinus Torvalds 	unsigned extx4 : 1;	    /* 0 = 2 drive, 1 = external 4 drive decode	*/
3761da177e4SLinus Torvalds 	unsigned reserved2 : 1;	    /* RAZ					*/
3771da177e4SLinus Torvalds     }	by_field;
3781da177e4SLinus Torvalds } SMC37c669_CR05;
3791da177e4SLinus Torvalds 
3801da177e4SLinus Torvalds /*
3811da177e4SLinus Torvalds ** CR06 - default value 0xFF
3821da177e4SLinus Torvalds */
3831da177e4SLinus Torvalds typedef union _SMC37c669_CR06 {
3841da177e4SLinus Torvalds     unsigned char as_uchar;
3851da177e4SLinus Torvalds     struct {
3861da177e4SLinus Torvalds     	unsigned floppy_a : 2;	    /* Type of floppy drive A	    */
3871da177e4SLinus Torvalds 	unsigned floppy_b : 2;	    /* Type of floppy drive B	    */
3881da177e4SLinus Torvalds 	unsigned floppy_c : 2;	    /* Type of floppy drive C	    */
3891da177e4SLinus Torvalds 	unsigned floppy_d : 2;	    /* Type of floppy drive D	    */
3901da177e4SLinus Torvalds     }	by_field;
3911da177e4SLinus Torvalds } SMC37c669_CR06;
3921da177e4SLinus Torvalds 
3931da177e4SLinus Torvalds /*
3941da177e4SLinus Torvalds ** CR07 - default value 0x00
3951da177e4SLinus Torvalds **
3961da177e4SLinus Torvalds **  Auto Power Management CR07<7:4>:
3971da177e4SLinus Torvalds **	0 - Auto Powerdown disabled (default)
3981da177e4SLinus Torvalds **	1 - Auto Powerdown enabled
3991da177e4SLinus Torvalds **
4001da177e4SLinus Torvalds **	This bit is reset to the default state by POR or
4011da177e4SLinus Torvalds **	a hardware reset.
4021da177e4SLinus Torvalds **
4031da177e4SLinus Torvalds */
4041da177e4SLinus Torvalds typedef union _SMC37c669_CR07 {
4051da177e4SLinus Torvalds     unsigned char as_uchar;
4061da177e4SLinus Torvalds     struct {
4071da177e4SLinus Torvalds     	unsigned floppy_boot : 2;   /* 0 = A:, 1 = B:		    */
4081da177e4SLinus Torvalds 	unsigned reserved1 : 2;	    /* RAZ			    */
4091da177e4SLinus Torvalds 	unsigned ppt_en : 1;	    /* See note above		    */
4101da177e4SLinus Torvalds 	unsigned uart1_en : 1;	    /* See note above		    */
4111da177e4SLinus Torvalds 	unsigned uart2_en : 1;	    /* See note above		    */
4121da177e4SLinus Torvalds 	unsigned fdc_en : 1;	    /* See note above		    */
4131da177e4SLinus Torvalds     }	by_field;
4141da177e4SLinus Torvalds } SMC37c669_CR07;
4151da177e4SLinus Torvalds 
4161da177e4SLinus Torvalds /*
4171da177e4SLinus Torvalds ** CR08 - default value 0x00
4181da177e4SLinus Torvalds */
4191da177e4SLinus Torvalds typedef union _SMC37c669_CR08 {
4201da177e4SLinus Torvalds     unsigned char as_uchar;
4211da177e4SLinus Torvalds     struct {
4221da177e4SLinus Torvalds     	unsigned zero : 4;	    /* 0			    */
4231da177e4SLinus Torvalds 	unsigned addrx7_4 : 4;	    /* ADR<7:3> for ADRx decode	    */
4241da177e4SLinus Torvalds     }	by_field;
4251da177e4SLinus Torvalds } SMC37c669_CR08;
4261da177e4SLinus Torvalds 
4271da177e4SLinus Torvalds /*
4281da177e4SLinus Torvalds ** CR09 - default value 0x00
4291da177e4SLinus Torvalds **
4301da177e4SLinus Torvalds **  ADRx_CONFIG:
4311da177e4SLinus Torvalds **	00 - ADRx disabled
4321da177e4SLinus Torvalds **	01 - 1 byte decode A<3:0> = 0000b
4331da177e4SLinus Torvalds **	10 - 8 byte block decode A<3:0> = 0XXXb
4341da177e4SLinus Torvalds **	11 - 16 byte block decode A<3:0> = XXXXb
4351da177e4SLinus Torvalds **
4361da177e4SLinus Torvalds */
4371da177e4SLinus Torvalds typedef union _SMC37c669_CR09 {
4381da177e4SLinus Torvalds     unsigned char as_uchar;
4391da177e4SLinus Torvalds     struct {
4401da177e4SLinus Torvalds     	unsigned adra8 : 3;	    /* ADR<10:8> for ADRx decode    */
4411da177e4SLinus Torvalds 	unsigned reserved1 : 3;
4421da177e4SLinus Torvalds 	unsigned adrx_config : 2;   /* See note above		    */
4431da177e4SLinus Torvalds     }	by_field;
4441da177e4SLinus Torvalds } SMC37c669_CR09;
4451da177e4SLinus Torvalds 
4461da177e4SLinus Torvalds /*
4471da177e4SLinus Torvalds ** CR0A - default value 0x00
4481da177e4SLinus Torvalds */
4491da177e4SLinus Torvalds typedef union _SMC37c669_CR0A {
4501da177e4SLinus Torvalds     unsigned char as_uchar;
4511da177e4SLinus Torvalds     struct {
4521da177e4SLinus Torvalds     	unsigned ecp_fifo_threshold : 4;
4531da177e4SLinus Torvalds 	unsigned reserved1 : 4;
4541da177e4SLinus Torvalds     }	by_field;
4551da177e4SLinus Torvalds } SMC37c669_CR0A;
4561da177e4SLinus Torvalds 
4571da177e4SLinus Torvalds /*
4581da177e4SLinus Torvalds ** CR0B - default value 0x00
4591da177e4SLinus Torvalds */
4601da177e4SLinus Torvalds typedef union _SMC37c669_CR0B {
4611da177e4SLinus Torvalds     unsigned char as_uchar;
4621da177e4SLinus Torvalds     struct {
4631da177e4SLinus Torvalds     	unsigned fdd0_drtx : 2;	    /* FDD0 Data Rate Table	    */
4641da177e4SLinus Torvalds 	unsigned fdd1_drtx : 2;	    /* FDD1 Data Rate Table	    */
4651da177e4SLinus Torvalds 	unsigned fdd2_drtx : 2;	    /* FDD2 Data Rate Table	    */
4661da177e4SLinus Torvalds 	unsigned fdd3_drtx : 2;	    /* FDD3 Data Rate Table	    */
4671da177e4SLinus Torvalds     }	by_field;
4681da177e4SLinus Torvalds } SMC37c669_CR0B;
4691da177e4SLinus Torvalds 
4701da177e4SLinus Torvalds /*
4711da177e4SLinus Torvalds ** CR0C - default value 0x00
4721da177e4SLinus Torvalds **
4731da177e4SLinus Torvalds **  UART2_MODE:
4741da177e4SLinus Torvalds **	000 - Standard (default)
4751da177e4SLinus Torvalds **	001 - IrDA (HPSIR)
4761da177e4SLinus Torvalds **	010 - Amplitude Shift Keyed IR @500 KHz
4771da177e4SLinus Torvalds **	011 - Reserved
4781da177e4SLinus Torvalds **	1xx - Reserved
4791da177e4SLinus Torvalds **
4801da177e4SLinus Torvalds */
4811da177e4SLinus Torvalds typedef union _SMC37c669_CR0C {
4821da177e4SLinus Torvalds     unsigned char as_uchar;
4831da177e4SLinus Torvalds     struct {
4841da177e4SLinus Torvalds     	unsigned uart2_rcv_polarity : 1;    /* 1 = invert RX		*/
4851da177e4SLinus Torvalds 	unsigned uart2_xmit_polarity : 1;   /* 1 = invert TX		*/
4861da177e4SLinus Torvalds 	unsigned uart2_duplex : 1;	    /* 1 = full, 0 = half	*/
4871da177e4SLinus Torvalds 	unsigned uart2_mode : 3;	    /* See note above		*/
4881da177e4SLinus Torvalds 	unsigned uart1_speed : 1;	    /* 1 = high speed enabled	*/
4891da177e4SLinus Torvalds 	unsigned uart2_speed : 1;	    /* 1 = high speed enabled	*/
4901da177e4SLinus Torvalds     }	by_field;
4911da177e4SLinus Torvalds } SMC37c669_CR0C;
4921da177e4SLinus Torvalds 
4931da177e4SLinus Torvalds /*
4941da177e4SLinus Torvalds ** CR0D - default value 0x03
4951da177e4SLinus Torvalds **
4961da177e4SLinus Torvalds **  Device ID Register - read only
4971da177e4SLinus Torvalds */
4981da177e4SLinus Torvalds typedef union _SMC37c669_CR0D {
4991da177e4SLinus Torvalds     unsigned char as_uchar;
5001da177e4SLinus Torvalds     struct {
5011da177e4SLinus Torvalds     	unsigned device_id : 8;	    /* Returns 0x3 in this field    */
5021da177e4SLinus Torvalds     }	by_field;
5031da177e4SLinus Torvalds } SMC37c669_CR0D;
5041da177e4SLinus Torvalds 
5051da177e4SLinus Torvalds /*
5061da177e4SLinus Torvalds ** CR0E - default value 0x02
5071da177e4SLinus Torvalds **
5081da177e4SLinus Torvalds **  Device Revision Register - read only
5091da177e4SLinus Torvalds */
5101da177e4SLinus Torvalds typedef union _SMC37c669_CR0E {
5111da177e4SLinus Torvalds     unsigned char as_uchar;
5121da177e4SLinus Torvalds     struct {
5131da177e4SLinus Torvalds     	unsigned device_rev : 8;    /* Returns 0x2 in this field    */
5141da177e4SLinus Torvalds     }	by_field;
5151da177e4SLinus Torvalds } SMC37c669_CR0E;
5161da177e4SLinus Torvalds 
5171da177e4SLinus Torvalds /*
5181da177e4SLinus Torvalds ** CR0F - default value 0x00
5191da177e4SLinus Torvalds */
5201da177e4SLinus Torvalds typedef union _SMC37c669_CR0F {
5211da177e4SLinus Torvalds     unsigned char as_uchar;
5221da177e4SLinus Torvalds     struct {
5231da177e4SLinus Torvalds     	unsigned test0 : 1;	    /* Reserved - set to 0	    */
5241da177e4SLinus Torvalds 	unsigned test1 : 1;	    /* Reserved - set to 0	    */
5251da177e4SLinus Torvalds 	unsigned test2 : 1;	    /* Reserved - set to 0	    */
5261da177e4SLinus Torvalds 	unsigned test3 : 1;	    /* Reserved - set t0 0	    */
5271da177e4SLinus Torvalds 	unsigned test4 : 1;	    /* Reserved - set to 0	    */
5281da177e4SLinus Torvalds 	unsigned test5 : 1;	    /* Reserved - set t0 0	    */
5291da177e4SLinus Torvalds 	unsigned test6 : 1;	    /* Reserved - set t0 0	    */
5301da177e4SLinus Torvalds 	unsigned test7 : 1;	    /* Reserved - set to 0	    */
5311da177e4SLinus Torvalds     }	by_field;
5321da177e4SLinus Torvalds } SMC37c669_CR0F;
5331da177e4SLinus Torvalds 
5341da177e4SLinus Torvalds /*
5351da177e4SLinus Torvalds ** CR10 - default value 0x00
5361da177e4SLinus Torvalds */
5371da177e4SLinus Torvalds typedef union _SMC37c669_CR10 {
5381da177e4SLinus Torvalds     unsigned char as_uchar;
5391da177e4SLinus Torvalds     struct {
5401da177e4SLinus Torvalds     	unsigned reserved1 : 3;	     /* RAZ			    */
5411da177e4SLinus Torvalds 	unsigned pll_gain : 1;	     /* 1 = 3V, 2 = 5V operation    */
5421da177e4SLinus Torvalds 	unsigned pll_stop : 1;	     /* 1 = stop PLLs		    */
5431da177e4SLinus Torvalds 	unsigned ace_stop : 1;	     /* 1 = stop UART clocks	    */
5441da177e4SLinus Torvalds 	unsigned pll_clock_ctrl : 1; /* 0 = 14.318 MHz, 1 = 24 MHz  */
5451da177e4SLinus Torvalds 	unsigned ir_test : 1;	     /* Enable IR test mode	    */
5461da177e4SLinus Torvalds     }	by_field;
5471da177e4SLinus Torvalds } SMC37c669_CR10;
5481da177e4SLinus Torvalds 
5491da177e4SLinus Torvalds /*
5501da177e4SLinus Torvalds ** CR11 - default value 0x00
5511da177e4SLinus Torvalds */
5521da177e4SLinus Torvalds typedef union _SMC37c669_CR11 {
5531da177e4SLinus Torvalds     unsigned char as_uchar;
5541da177e4SLinus Torvalds     struct {
5551da177e4SLinus Torvalds     	unsigned ir_loopback : 1;   /* Internal IR loop back		    */
5561da177e4SLinus Torvalds 	unsigned test_10ms : 1;	    /* Test 10ms autopowerdown FDC timeout  */
5571da177e4SLinus Torvalds 	unsigned reserved1 : 6;	    /* RAZ				    */
5581da177e4SLinus Torvalds     }	by_field;
5591da177e4SLinus Torvalds } SMC37c669_CR11;
5601da177e4SLinus Torvalds 
5611da177e4SLinus Torvalds /*
5621da177e4SLinus Torvalds ** CR12 - CR1D are reserved registers
5631da177e4SLinus Torvalds */
5641da177e4SLinus Torvalds 
5651da177e4SLinus Torvalds /*
5661da177e4SLinus Torvalds ** CR1E - default value 0x80
5671da177e4SLinus Torvalds **
5681da177e4SLinus Torvalds **  GAMECS:
5691da177e4SLinus Torvalds **	00 - GAMECS disabled
5701da177e4SLinus Torvalds **	01 - 1 byte decode ADR<3:0> = 0001b
5711da177e4SLinus Torvalds **	10 - 8 byte block decode ADR<3:0> = 0XXXb
5721da177e4SLinus Torvalds **	11 - 16 byte block decode ADR<3:0> = XXXXb
5731da177e4SLinus Torvalds **
5741da177e4SLinus Torvalds */
5751da177e4SLinus Torvalds typedef union _SMC37c66_CR1E {
5761da177e4SLinus Torvalds     unsigned char as_uchar;
5771da177e4SLinus Torvalds     struct {
5781da177e4SLinus Torvalds     	unsigned gamecs_config: 2;   /* See note above		    */
5791da177e4SLinus Torvalds 	unsigned gamecs_addr9_4 : 6; /* GAMECS Addr<9:4>	    */
5801da177e4SLinus Torvalds     }	by_field;
5811da177e4SLinus Torvalds } SMC37c669_CR1E;
5821da177e4SLinus Torvalds 
5831da177e4SLinus Torvalds /*
5841da177e4SLinus Torvalds ** CR1F - default value 0x00
5851da177e4SLinus Torvalds **
5861da177e4SLinus Torvalds **  DT0 DT1 DRVDEN0 DRVDEN1 Drive Type
5871da177e4SLinus Torvalds **  --- --- ------- ------- ----------
5881da177e4SLinus Torvalds **   0   0  DENSEL  DRATE0  4/2/1 MB 3.5"
5891da177e4SLinus Torvalds **                          2/1 MB 5.25"
5901da177e4SLinus Torvalds **                          2/1.6/1 MB 3.5" (3-mode)
5911da177e4SLinus Torvalds **   0   1  DRATE1  DRATE0
5921da177e4SLinus Torvalds **   1   0  nDENSEL DRATE0  PS/2
5931da177e4SLinus Torvalds **   1   1  DRATE0  DRATE1
5941da177e4SLinus Torvalds **
5951da177e4SLinus Torvalds **  Note: DENSEL, DRATE1, and DRATE0 map onto two output
5961da177e4SLinus Torvalds **	  pins - DRVDEN0 and DRVDEN1.
5971da177e4SLinus Torvalds **
5981da177e4SLinus Torvalds */
5991da177e4SLinus Torvalds typedef union _SMC37c669_CR1F {
6001da177e4SLinus Torvalds     unsigned char as_uchar;
6011da177e4SLinus Torvalds     struct {
6021da177e4SLinus Torvalds     	unsigned fdd0_drive_type : 2;	/* FDD0 drive type	    */
6031da177e4SLinus Torvalds 	unsigned fdd1_drive_type : 2;	/* FDD1 drive type	    */
6041da177e4SLinus Torvalds 	unsigned fdd2_drive_type : 2;	/* FDD2 drive type	    */
6051da177e4SLinus Torvalds 	unsigned fdd3_drive_type : 2;	/* FDD3 drive type	    */
6061da177e4SLinus Torvalds     }	by_field;
6071da177e4SLinus Torvalds } SMC37c669_CR1F;
6081da177e4SLinus Torvalds 
6091da177e4SLinus Torvalds /*
6101da177e4SLinus Torvalds ** CR20 - default value 0x3C
6111da177e4SLinus Torvalds **
6121da177e4SLinus Torvalds **  FDC Base Address Register
6131da177e4SLinus Torvalds **	- To disable this decode set Addr<9:8> = 0
6141da177e4SLinus Torvalds **	- A<10> = 0, A<3:0> = 0XXXb to access.
6151da177e4SLinus Torvalds **
6161da177e4SLinus Torvalds */
6171da177e4SLinus Torvalds typedef union _SMC37c669_CR20 {
6181da177e4SLinus Torvalds     unsigned char as_uchar;
6191da177e4SLinus Torvalds     struct {
6201da177e4SLinus Torvalds     	unsigned zero : 2;	    /* 0			    */
6211da177e4SLinus Torvalds 	unsigned addr9_4 : 6;	    /* FDC Addr<9:4>		    */
6221da177e4SLinus Torvalds     }	by_field;
6231da177e4SLinus Torvalds } SMC37c669_CR20;
6241da177e4SLinus Torvalds 
6251da177e4SLinus Torvalds /*
6261da177e4SLinus Torvalds ** CR21 - default value 0x3C
6271da177e4SLinus Torvalds **
6281da177e4SLinus Torvalds **  IDE Base Address Register
6291da177e4SLinus Torvalds **	- To disable this decode set Addr<9:8> = 0
6301da177e4SLinus Torvalds **	- A<10> = 0, A<3:0> = 0XXXb to access.
6311da177e4SLinus Torvalds **
6321da177e4SLinus Torvalds */
6331da177e4SLinus Torvalds typedef union _SMC37c669_CR21 {
6341da177e4SLinus Torvalds     unsigned char as_uchar;
6351da177e4SLinus Torvalds     struct {
6361da177e4SLinus Torvalds     	unsigned zero : 2;	    /* 0			    */
6371da177e4SLinus Torvalds 	unsigned addr9_4 : 6;	    /* IDE Addr<9:4>		    */
6381da177e4SLinus Torvalds     }	by_field;
6391da177e4SLinus Torvalds } SMC37c669_CR21;
6401da177e4SLinus Torvalds 
6411da177e4SLinus Torvalds /*
6421da177e4SLinus Torvalds ** CR22 - default value 0x3D
6431da177e4SLinus Torvalds **
6441da177e4SLinus Torvalds **  IDE Alternate Status Base Address Register
6451da177e4SLinus Torvalds **	- To disable this decode set Addr<9:8> = 0
6461da177e4SLinus Torvalds **	- A<10> = 0, A<3:0> = 0110b to access.
6471da177e4SLinus Torvalds **
6481da177e4SLinus Torvalds */
6491da177e4SLinus Torvalds typedef union _SMC37c669_CR22 {
6501da177e4SLinus Torvalds     unsigned char as_uchar;
6511da177e4SLinus Torvalds     struct {
6521da177e4SLinus Torvalds     	unsigned zero : 2;	    /* 0			    */
6531da177e4SLinus Torvalds 	unsigned addr9_4 : 6;	    /* IDE Alt Status Addr<9:4>	    */
6541da177e4SLinus Torvalds     }	by_field;
6551da177e4SLinus Torvalds } SMC37c669_CR22;
6561da177e4SLinus Torvalds 
6571da177e4SLinus Torvalds /*
6581da177e4SLinus Torvalds ** CR23 - default value 0x00
6591da177e4SLinus Torvalds **
6601da177e4SLinus Torvalds **  Parallel Port Base Address Register
6611da177e4SLinus Torvalds **	- To disable this decode set Addr<9:8> = 0
6621da177e4SLinus Torvalds **	- A<10> = 0 to access.
6631da177e4SLinus Torvalds **	- If EPP is enabled, A<2:0> = XXXb to access.
6641da177e4SLinus Torvalds **	  If EPP is NOT enabled, A<1:0> = XXb to access
6651da177e4SLinus Torvalds **
6661da177e4SLinus Torvalds */
6671da177e4SLinus Torvalds typedef union _SMC37c669_CR23 {
6681da177e4SLinus Torvalds     unsigned char as_uchar;
6691da177e4SLinus Torvalds     struct {
6701da177e4SLinus Torvalds 	unsigned addr9_2 : 8;	    /* Parallel Port Addr<9:2>	    */
6711da177e4SLinus Torvalds     }	by_field;
6721da177e4SLinus Torvalds } SMC37c669_CR23;
6731da177e4SLinus Torvalds 
6741da177e4SLinus Torvalds /*
6751da177e4SLinus Torvalds ** CR24 - default value 0x00
6761da177e4SLinus Torvalds **
6771da177e4SLinus Torvalds **  UART1 Base Address Register
6781da177e4SLinus Torvalds **	- To disable this decode set Addr<9:8> = 0
6791da177e4SLinus Torvalds **	- A<10> = 0, A<2:0> = XXXb to access.
6801da177e4SLinus Torvalds **
6811da177e4SLinus Torvalds */
6821da177e4SLinus Torvalds typedef union _SMC37c669_CR24 {
6831da177e4SLinus Torvalds     unsigned char as_uchar;
6841da177e4SLinus Torvalds     struct {
6851da177e4SLinus Torvalds     	unsigned zero : 1;	    /* 0			    */
6861da177e4SLinus Torvalds 	unsigned addr9_3 : 7;	    /* UART1 Addr<9:3>		    */
6871da177e4SLinus Torvalds     }	by_field;
6881da177e4SLinus Torvalds } SMC37c669_CR24;
6891da177e4SLinus Torvalds 
6901da177e4SLinus Torvalds /*
6911da177e4SLinus Torvalds ** CR25 - default value 0x00
6921da177e4SLinus Torvalds **
6931da177e4SLinus Torvalds **  UART2 Base Address Register
6941da177e4SLinus Torvalds **	- To disable this decode set Addr<9:8> = 0
6951da177e4SLinus Torvalds **	- A<10> = 0, A<2:0> = XXXb to access.
6961da177e4SLinus Torvalds **
6971da177e4SLinus Torvalds */
6981da177e4SLinus Torvalds typedef union _SMC37c669_CR25 {
6991da177e4SLinus Torvalds     unsigned char as_uchar;
7001da177e4SLinus Torvalds     struct {
7011da177e4SLinus Torvalds     	unsigned zero : 1;	    /* 0			    */
7021da177e4SLinus Torvalds 	unsigned addr9_3 : 7;	    /* UART2 Addr<9:3>		    */
7031da177e4SLinus Torvalds     }	by_field;
7041da177e4SLinus Torvalds } SMC37c669_CR25;
7051da177e4SLinus Torvalds 
7061da177e4SLinus Torvalds /*
7071da177e4SLinus Torvalds ** CR26 - default value 0x00
7081da177e4SLinus Torvalds **
7091da177e4SLinus Torvalds **  Parallel Port / FDC DMA Select Register
7101da177e4SLinus Torvalds **
7111da177e4SLinus Torvalds **  D3 - D0	  DMA
7121da177e4SLinus Torvalds **  D7 - D4	Selected
7131da177e4SLinus Torvalds **  -------	--------
7141da177e4SLinus Torvalds **   0000	 None
7151da177e4SLinus Torvalds **   0001	 DMA_A
7161da177e4SLinus Torvalds **   0010	 DMA_B
7171da177e4SLinus Torvalds **   0011	 DMA_C
7181da177e4SLinus Torvalds **
7191da177e4SLinus Torvalds */
7201da177e4SLinus Torvalds typedef union _SMC37c669_CR26 {
7211da177e4SLinus Torvalds     unsigned char as_uchar;
7221da177e4SLinus Torvalds     struct {
7231da177e4SLinus Torvalds     	unsigned ppt_drq : 4;	    /* See note above		    */
7241da177e4SLinus Torvalds 	unsigned fdc_drq : 4;	    /* See note above		    */
7251da177e4SLinus Torvalds     }	by_field;
7261da177e4SLinus Torvalds } SMC37c669_CR26;
7271da177e4SLinus Torvalds 
7281da177e4SLinus Torvalds /*
7291da177e4SLinus Torvalds ** CR27 - default value 0x00
7301da177e4SLinus Torvalds **
7311da177e4SLinus Torvalds **  Parallel Port / FDC IRQ Select Register
7321da177e4SLinus Torvalds **
7331da177e4SLinus Torvalds **  D3 - D0	  IRQ
7341da177e4SLinus Torvalds **  D7 - D4	Selected
7351da177e4SLinus Torvalds **  -------	--------
7361da177e4SLinus Torvalds **   0000	 None
7371da177e4SLinus Torvalds **   0001	 IRQ_A
7381da177e4SLinus Torvalds **   0010	 IRQ_B
7391da177e4SLinus Torvalds **   0011	 IRQ_C
7401da177e4SLinus Torvalds **   0100	 IRQ_D
7411da177e4SLinus Torvalds **   0101	 IRQ_E
7421da177e4SLinus Torvalds **   0110	 IRQ_F
7431da177e4SLinus Torvalds **   0111	 Reserved
7441da177e4SLinus Torvalds **   1000	 IRQ_H
7451da177e4SLinus Torvalds **
7461da177e4SLinus Torvalds **  Any unselected IRQ REQ is in tristate
7471da177e4SLinus Torvalds **
7481da177e4SLinus Torvalds */
7491da177e4SLinus Torvalds typedef union _SMC37c669_CR27 {
7501da177e4SLinus Torvalds     unsigned char as_uchar;
7511da177e4SLinus Torvalds     struct {
7521da177e4SLinus Torvalds     	unsigned ppt_irq : 4;	    /* See note above		    */
7531da177e4SLinus Torvalds 	unsigned fdc_irq : 4;	    /* See note above		    */
7541da177e4SLinus Torvalds     }	by_field;
7551da177e4SLinus Torvalds } SMC37c669_CR27;
7561da177e4SLinus Torvalds 
7571da177e4SLinus Torvalds /*
7581da177e4SLinus Torvalds ** CR28 - default value 0x00
7591da177e4SLinus Torvalds **
7601da177e4SLinus Torvalds **  UART IRQ Select Register
7611da177e4SLinus Torvalds **
7621da177e4SLinus Torvalds **  D3 - D0	  IRQ
7631da177e4SLinus Torvalds **  D7 - D4	Selected
7641da177e4SLinus Torvalds **  -------	--------
7651da177e4SLinus Torvalds **   0000	 None
7661da177e4SLinus Torvalds **   0001	 IRQ_A
7671da177e4SLinus Torvalds **   0010	 IRQ_B
7681da177e4SLinus Torvalds **   0011	 IRQ_C
7691da177e4SLinus Torvalds **   0100	 IRQ_D
7701da177e4SLinus Torvalds **   0101	 IRQ_E
7711da177e4SLinus Torvalds **   0110	 IRQ_F
7721da177e4SLinus Torvalds **   0111	 Reserved
7731da177e4SLinus Torvalds **   1000	 IRQ_H
7741da177e4SLinus Torvalds **   1111	 share with UART1 (only for UART2)
7751da177e4SLinus Torvalds **
7761da177e4SLinus Torvalds **  Any unselected IRQ REQ is in tristate
7771da177e4SLinus Torvalds **
7781da177e4SLinus Torvalds **  To share an IRQ between UART1 and UART2, set
7791da177e4SLinus Torvalds **  UART1 to use the desired IRQ and set UART2 to
7801da177e4SLinus Torvalds **  0xF to enable sharing mechanism.
7811da177e4SLinus Torvalds **
7821da177e4SLinus Torvalds */
7831da177e4SLinus Torvalds typedef union _SMC37c669_CR28 {
7841da177e4SLinus Torvalds     unsigned char as_uchar;
7851da177e4SLinus Torvalds     struct {
7861da177e4SLinus Torvalds     	unsigned uart2_irq : 4;	    /* See note above		    */
7871da177e4SLinus Torvalds 	unsigned uart1_irq : 4;	    /* See note above		    */
7881da177e4SLinus Torvalds     }	by_field;
7891da177e4SLinus Torvalds } SMC37c669_CR28;
7901da177e4SLinus Torvalds 
7911da177e4SLinus Torvalds /*
7921da177e4SLinus Torvalds ** CR29 - default value 0x00
7931da177e4SLinus Torvalds **
7941da177e4SLinus Torvalds **  IRQIN IRQ Select Register
7951da177e4SLinus Torvalds **
7961da177e4SLinus Torvalds **  D3 - D0	  IRQ
7971da177e4SLinus Torvalds **  D7 - D4	Selected
7981da177e4SLinus Torvalds **  -------	--------
7991da177e4SLinus Torvalds **   0000	 None
8001da177e4SLinus Torvalds **   0001	 IRQ_A
8011da177e4SLinus Torvalds **   0010	 IRQ_B
8021da177e4SLinus Torvalds **   0011	 IRQ_C
8031da177e4SLinus Torvalds **   0100	 IRQ_D
8041da177e4SLinus Torvalds **   0101	 IRQ_E
8051da177e4SLinus Torvalds **   0110	 IRQ_F
8061da177e4SLinus Torvalds **   0111	 Reserved
8071da177e4SLinus Torvalds **   1000	 IRQ_H
8081da177e4SLinus Torvalds **
8091da177e4SLinus Torvalds **  Any unselected IRQ REQ is in tristate
8101da177e4SLinus Torvalds **
8111da177e4SLinus Torvalds */
8121da177e4SLinus Torvalds typedef union _SMC37c669_CR29 {
8131da177e4SLinus Torvalds     unsigned char as_uchar;
8141da177e4SLinus Torvalds     struct {
8151da177e4SLinus Torvalds     	unsigned irqin_irq : 4;	    /* See note above		    */
8161da177e4SLinus Torvalds 	unsigned reserved1 : 4;	    /* RAZ			    */
8171da177e4SLinus Torvalds     }	by_field;
8181da177e4SLinus Torvalds } SMC37c669_CR29;
8191da177e4SLinus Torvalds 
8201da177e4SLinus Torvalds /*
8211da177e4SLinus Torvalds ** Aliases of Configuration Register formats (should match
8221da177e4SLinus Torvalds ** the set of index aliases).
8231da177e4SLinus Torvalds **
8241da177e4SLinus Torvalds ** Note that CR24 and CR25 have the same format and are the
8251da177e4SLinus Torvalds ** base address registers for UART1 and UART2.  Because of
8261da177e4SLinus Torvalds ** this we only define 1 alias here - for CR24 - as the serial
8271da177e4SLinus Torvalds ** base address register.
8281da177e4SLinus Torvalds **
8291da177e4SLinus Torvalds ** Note that CR21 and CR22 have the same format and are the
8301da177e4SLinus Torvalds ** base address and alternate status address registers for
8311da177e4SLinus Torvalds ** the IDE controller.  Because of this we only define 1 alias
8321da177e4SLinus Torvalds ** here - for CR21 - as the IDE address register.
8331da177e4SLinus Torvalds **
8341da177e4SLinus Torvalds */
8351da177e4SLinus Torvalds typedef SMC37c669_CR0D SMC37c669_DEVICE_ID_REGISTER;
8361da177e4SLinus Torvalds typedef SMC37c669_CR0E SMC37c669_DEVICE_REVISION_REGISTER;
8371da177e4SLinus Torvalds typedef SMC37c669_CR20 SMC37c669_FDC_BASE_ADDRESS_REGISTER;
8381da177e4SLinus Torvalds typedef SMC37c669_CR21 SMC37c669_IDE_ADDRESS_REGISTER;
8391da177e4SLinus Torvalds typedef SMC37c669_CR23 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER;
8401da177e4SLinus Torvalds typedef SMC37c669_CR24 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER;
8411da177e4SLinus Torvalds typedef SMC37c669_CR26 SMC37c669_PARALLEL_FDC_DRQ_REGISTER;
8421da177e4SLinus Torvalds typedef SMC37c669_CR27 SMC37c669_PARALLEL_FDC_IRQ_REGISTER;
8431da177e4SLinus Torvalds typedef SMC37c669_CR28 SMC37c669_SERIAL_IRQ_REGISTER;
8441da177e4SLinus Torvalds 
8451da177e4SLinus Torvalds /*
8461da177e4SLinus Torvalds ** ISA/Device IRQ Translation Table Entry Definition
8471da177e4SLinus Torvalds */
8481da177e4SLinus Torvalds typedef struct _SMC37c669_IRQ_TRANSLATION_ENTRY {
8491da177e4SLinus Torvalds     int device_irq;
8501da177e4SLinus Torvalds     int isa_irq;
8511da177e4SLinus Torvalds } SMC37c669_IRQ_TRANSLATION_ENTRY;
8521da177e4SLinus Torvalds 
8531da177e4SLinus Torvalds /*
8541da177e4SLinus Torvalds ** ISA/Device DMA Translation Table Entry Definition
8551da177e4SLinus Torvalds */
8561da177e4SLinus Torvalds typedef struct _SMC37c669_DRQ_TRANSLATION_ENTRY {
8571da177e4SLinus Torvalds     int device_drq;
8581da177e4SLinus Torvalds     int isa_drq;
8591da177e4SLinus Torvalds } SMC37c669_DRQ_TRANSLATION_ENTRY;
8601da177e4SLinus Torvalds 
8611da177e4SLinus Torvalds /*
8621da177e4SLinus Torvalds ** External Interface Function Prototype Declarations
8631da177e4SLinus Torvalds */
8641da177e4SLinus Torvalds 
8651da177e4SLinus Torvalds SMC37c669_CONFIG_REGS *SMC37c669_detect(
8661da177e4SLinus Torvalds     int
8671da177e4SLinus Torvalds );
8681da177e4SLinus Torvalds 
8691da177e4SLinus Torvalds unsigned int SMC37c669_enable_device(
8701da177e4SLinus Torvalds     unsigned int func
8711da177e4SLinus Torvalds );
8721da177e4SLinus Torvalds 
8731da177e4SLinus Torvalds unsigned int SMC37c669_disable_device(
8741da177e4SLinus Torvalds     unsigned int func
8751da177e4SLinus Torvalds );
8761da177e4SLinus Torvalds 
8771da177e4SLinus Torvalds unsigned int SMC37c669_configure_device(
8781da177e4SLinus Torvalds     unsigned int func,
8791da177e4SLinus Torvalds     int port,
8801da177e4SLinus Torvalds     int irq,
8811da177e4SLinus Torvalds     int drq
8821da177e4SLinus Torvalds );
8831da177e4SLinus Torvalds 
8841da177e4SLinus Torvalds void SMC37c669_display_device_info(
8851da177e4SLinus Torvalds     void
8861da177e4SLinus Torvalds );
8871da177e4SLinus Torvalds 
8881da177e4SLinus Torvalds #endif	/* __SMC37c669_H */
8891da177e4SLinus Torvalds 
8901da177e4SLinus Torvalds /* file:	smcc669.c
8911da177e4SLinus Torvalds  *
8921da177e4SLinus Torvalds  * Copyright (C) 1997 by
8931da177e4SLinus Torvalds  * Digital Equipment Corporation, Maynard, Massachusetts.
8941da177e4SLinus Torvalds  * All rights reserved.
8951da177e4SLinus Torvalds  *
8961da177e4SLinus Torvalds  * This software is furnished under a license and may be used and copied
8971da177e4SLinus Torvalds  * only  in  accordance  of  the  terms  of  such  license  and with the
8981da177e4SLinus Torvalds  * inclusion of the above copyright notice. This software or  any  other
8991da177e4SLinus Torvalds  * copies thereof may not be provided or otherwise made available to any
9001da177e4SLinus Torvalds  * other person.  No title to and  ownership of the  software is  hereby
9011da177e4SLinus Torvalds  * transferred.
9021da177e4SLinus Torvalds  *
9031da177e4SLinus Torvalds  * The information in this software is  subject to change without notice
9041da177e4SLinus Torvalds  * and  should  not  be  construed  as a commitment by digital equipment
9051da177e4SLinus Torvalds  * corporation.
9061da177e4SLinus Torvalds  *
9071da177e4SLinus Torvalds  * Digital assumes no responsibility for the use  or  reliability of its
9081da177e4SLinus Torvalds  * software on equipment which is not supplied by digital.
9091da177e4SLinus Torvalds  */
9101da177e4SLinus Torvalds 
9111da177e4SLinus Torvalds /*
9121da177e4SLinus Torvalds  *++
9131da177e4SLinus Torvalds  *  FACILITY:
9141da177e4SLinus Torvalds  *
9151da177e4SLinus Torvalds  *      Alpha SRM Console Firmware
9161da177e4SLinus Torvalds  *
9171da177e4SLinus Torvalds  *  MODULE DESCRIPTION:
9181da177e4SLinus Torvalds  *
9191da177e4SLinus Torvalds  *	SMC37c669 Super I/O controller configuration routines.
9201da177e4SLinus Torvalds  *
9211da177e4SLinus Torvalds  *  AUTHORS:
9221da177e4SLinus Torvalds  *
9231da177e4SLinus Torvalds  *	Eric Rasmussen
9241da177e4SLinus Torvalds  *
9251da177e4SLinus Torvalds  *  CREATION DATE:
9261da177e4SLinus Torvalds  *
9271da177e4SLinus Torvalds  *	28-Jan-1997
9281da177e4SLinus Torvalds  *
9291da177e4SLinus Torvalds  *  MODIFICATION HISTORY:
9301da177e4SLinus Torvalds  *
9311da177e4SLinus Torvalds  *	er	01-May-1997	Fixed pointer conversion errors in
9321da177e4SLinus Torvalds  *				SMC37c669_get_device_config().
9331da177e4SLinus Torvalds  *      er	28-Jan-1997	Initial version.
9341da177e4SLinus Torvalds  *
9351da177e4SLinus Torvalds  *--
9361da177e4SLinus Torvalds  */
9371da177e4SLinus Torvalds #if 0
9381da177e4SLinus Torvalds /* $INCLUDE_OPTIONS$ */
9391da177e4SLinus Torvalds #include    "cp$inc:platform_io.h"
9401da177e4SLinus Torvalds /* $INCLUDE_OPTIONS_END$ */
9411da177e4SLinus Torvalds #include    "cp$src:common.h"
9421da177e4SLinus Torvalds #include    "cp$inc:prototypes.h"
9431da177e4SLinus Torvalds #include    "cp$src:kernel_def.h"
9441da177e4SLinus Torvalds #include    "cp$src:msg_def.h"
9451da177e4SLinus Torvalds #include    "cp$src:smcc669_def.h"
9461da177e4SLinus Torvalds /* Platform-specific includes */
9471da177e4SLinus Torvalds #include    "cp$src:platform.h"
9481da177e4SLinus Torvalds #endif
9491da177e4SLinus Torvalds 
9501da177e4SLinus Torvalds #ifndef TRUE
9511da177e4SLinus Torvalds #define TRUE 1
9521da177e4SLinus Torvalds #endif
9531da177e4SLinus Torvalds #ifndef FALSE
9541da177e4SLinus Torvalds #define FALSE 0
9551da177e4SLinus Torvalds #endif
9561da177e4SLinus Torvalds 
9571da177e4SLinus Torvalds #define wb( _x_, _y_ )	outb( _y_, (unsigned int)((unsigned long)_x_) )
9581da177e4SLinus Torvalds #define rb( _x_ )	inb( (unsigned int)((unsigned long)_x_) )
9591da177e4SLinus Torvalds 
9601da177e4SLinus Torvalds /*
9611da177e4SLinus Torvalds ** Local storage for device configuration information.
9621da177e4SLinus Torvalds **
9631da177e4SLinus Torvalds ** Since the SMC37c669 does not provide an explicit
9641da177e4SLinus Torvalds ** mechanism for enabling/disabling individual device
9651da177e4SLinus Torvalds ** functions, other than unmapping the device, local
9661da177e4SLinus Torvalds ** storage for device configuration information is
9671da177e4SLinus Torvalds ** allocated here for use in implementing our own
9681da177e4SLinus Torvalds ** function enable/disable scheme.
9691da177e4SLinus Torvalds */
9701da177e4SLinus Torvalds static struct DEVICE_CONFIG {
9711da177e4SLinus Torvalds     unsigned int port1;
9721da177e4SLinus Torvalds     unsigned int port2;
9731da177e4SLinus Torvalds     int irq;
9741da177e4SLinus Torvalds     int drq;
9751da177e4SLinus Torvalds } local_config [NUM_FUNCS];
9761da177e4SLinus Torvalds 
9771da177e4SLinus Torvalds /*
9781da177e4SLinus Torvalds ** List of all possible addresses for the Super I/O chip
9791da177e4SLinus Torvalds */
9801da177e4SLinus Torvalds static unsigned long SMC37c669_Addresses[] __initdata =
9811da177e4SLinus Torvalds     {
9821da177e4SLinus Torvalds 	0x3F0UL,	    /* Primary address	    */
9831da177e4SLinus Torvalds 	0x370UL,	    /* Secondary address    */
9841da177e4SLinus Torvalds 	0UL		    /* End of list	    */
9851da177e4SLinus Torvalds     };
9861da177e4SLinus Torvalds 
9871da177e4SLinus Torvalds /*
9881da177e4SLinus Torvalds ** Global Pointer to the Super I/O device
9891da177e4SLinus Torvalds */
9901da177e4SLinus Torvalds static SMC37c669_CONFIG_REGS *SMC37c669 __initdata = NULL;
9911da177e4SLinus Torvalds 
9921da177e4SLinus Torvalds /*
9931da177e4SLinus Torvalds ** IRQ Translation Table
9941da177e4SLinus Torvalds **
9951da177e4SLinus Torvalds ** The IRQ translation table is a list of SMC37c669 device
9961da177e4SLinus Torvalds ** and standard ISA IRQs.
9971da177e4SLinus Torvalds **
9981da177e4SLinus Torvalds */
9991da177e4SLinus Torvalds static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_table __initdata;
10001da177e4SLinus Torvalds 
10011da177e4SLinus Torvalds /*
10021da177e4SLinus Torvalds ** The following definition is for the default IRQ
10031da177e4SLinus Torvalds ** translation table.
10041da177e4SLinus Torvalds */
10051da177e4SLinus Torvalds static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_default_irq_table[]
10061da177e4SLinus Torvalds __initdata =
10071da177e4SLinus Torvalds     {
10081da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_A, -1 },
10091da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_B, -1 },
10101da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_C, 7 },
10111da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_D, 6 },
10121da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_E, 4 },
10131da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_F, 3 },
10141da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_H, -1 },
10151da177e4SLinus Torvalds 	{ -1, -1 } /* End of table */
10161da177e4SLinus Torvalds     };
10171da177e4SLinus Torvalds 
10181da177e4SLinus Torvalds /*
10191da177e4SLinus Torvalds ** The following definition is for the MONET (XP1000) IRQ
10201da177e4SLinus Torvalds ** translation table.
10211da177e4SLinus Torvalds */
10221da177e4SLinus Torvalds static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_monet_irq_table[]
10231da177e4SLinus Torvalds __initdata =
10241da177e4SLinus Torvalds     {
10251da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_A, -1 },
10261da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_B, -1 },
10271da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_C, 6 },
10281da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_D, 7 },
10291da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_E, 4 },
10301da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_F, 3 },
10311da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_IRQ_H, -1 },
10321da177e4SLinus Torvalds 	{ -1, -1 } /* End of table */
10331da177e4SLinus Torvalds     };
10341da177e4SLinus Torvalds 
10351da177e4SLinus Torvalds static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_tables[] __initdata =
10361da177e4SLinus Torvalds     {
10371da177e4SLinus Torvalds 	SMC37c669_default_irq_table,
10381da177e4SLinus Torvalds 	SMC37c669_monet_irq_table
10391da177e4SLinus Torvalds     };
10401da177e4SLinus Torvalds 
10411da177e4SLinus Torvalds /*
10421da177e4SLinus Torvalds ** DRQ Translation Table
10431da177e4SLinus Torvalds **
10441da177e4SLinus Torvalds ** The DRQ translation table is a list of SMC37c669 device and
10451da177e4SLinus Torvalds ** ISA DMA channels.
10461da177e4SLinus Torvalds **
10471da177e4SLinus Torvalds */
10481da177e4SLinus Torvalds static SMC37c669_DRQ_TRANSLATION_ENTRY *SMC37c669_drq_table __initdata;
10491da177e4SLinus Torvalds 
10501da177e4SLinus Torvalds /*
10511da177e4SLinus Torvalds ** The following definition is the default DRQ
10521da177e4SLinus Torvalds ** translation table.
10531da177e4SLinus Torvalds */
10541da177e4SLinus Torvalds static SMC37c669_DRQ_TRANSLATION_ENTRY SMC37c669_default_drq_table[]
10551da177e4SLinus Torvalds __initdata =
10561da177e4SLinus Torvalds     {
10571da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_DRQ_A, 2 },
10581da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_DRQ_B, 3 },
10591da177e4SLinus Torvalds 	{ SMC37c669_DEVICE_DRQ_C, -1 },
10601da177e4SLinus Torvalds 	{ -1, -1 } /* End of table */
10611da177e4SLinus Torvalds     };
10621da177e4SLinus Torvalds 
10631da177e4SLinus Torvalds /*
10641da177e4SLinus Torvalds ** Local Function Prototype Declarations
10651da177e4SLinus Torvalds */
10661da177e4SLinus Torvalds 
10671da177e4SLinus Torvalds static unsigned int SMC37c669_is_device_enabled(
10681da177e4SLinus Torvalds     unsigned int func
10691da177e4SLinus Torvalds );
10701da177e4SLinus Torvalds 
10711da177e4SLinus Torvalds #if 0
10721da177e4SLinus Torvalds static unsigned int SMC37c669_get_device_config(
10731da177e4SLinus Torvalds     unsigned int func,
10741da177e4SLinus Torvalds     int *port,
10751da177e4SLinus Torvalds     int *irq,
10761da177e4SLinus Torvalds     int *drq
10771da177e4SLinus Torvalds );
10781da177e4SLinus Torvalds #endif
10791da177e4SLinus Torvalds 
10801da177e4SLinus Torvalds static void SMC37c669_config_mode(
10811da177e4SLinus Torvalds     unsigned int enable
10821da177e4SLinus Torvalds );
10831da177e4SLinus Torvalds 
10841da177e4SLinus Torvalds static unsigned char SMC37c669_read_config(
10851da177e4SLinus Torvalds     unsigned char index
10861da177e4SLinus Torvalds );
10871da177e4SLinus Torvalds 
10881da177e4SLinus Torvalds static void SMC37c669_write_config(
10891da177e4SLinus Torvalds     unsigned char index,
10901da177e4SLinus Torvalds     unsigned char data
10911da177e4SLinus Torvalds );
10921da177e4SLinus Torvalds 
10931da177e4SLinus Torvalds static void SMC37c669_init_local_config( void );
10941da177e4SLinus Torvalds 
10951da177e4SLinus Torvalds static struct DEVICE_CONFIG *SMC37c669_get_config(
10961da177e4SLinus Torvalds     unsigned int func
10971da177e4SLinus Torvalds );
10981da177e4SLinus Torvalds 
10991da177e4SLinus Torvalds static int SMC37c669_xlate_irq(
11001da177e4SLinus Torvalds     int irq
11011da177e4SLinus Torvalds );
11021da177e4SLinus Torvalds 
11031da177e4SLinus Torvalds static int SMC37c669_xlate_drq(
11041da177e4SLinus Torvalds     int drq
11051da177e4SLinus Torvalds );
11061da177e4SLinus Torvalds 
11071da177e4SLinus Torvalds static  __cacheline_aligned DEFINE_SPINLOCK(smc_lock);
11081da177e4SLinus Torvalds 
11091da177e4SLinus Torvalds /*
11101da177e4SLinus Torvalds **++
11111da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
11121da177e4SLinus Torvalds **
11131da177e4SLinus Torvalds **      This function detects the presence of an SMC37c669 Super I/O
11141da177e4SLinus Torvalds **	controller.
11151da177e4SLinus Torvalds **
11161da177e4SLinus Torvalds **  FORMAL PARAMETERS:
11171da177e4SLinus Torvalds **
11181da177e4SLinus Torvalds **	None
11191da177e4SLinus Torvalds **
11201da177e4SLinus Torvalds **  RETURN VALUE:
11211da177e4SLinus Torvalds **
11221da177e4SLinus Torvalds **      Returns a pointer to the device if found, otherwise,
11231da177e4SLinus Torvalds **	the NULL pointer is returned.
11241da177e4SLinus Torvalds **
11251da177e4SLinus Torvalds **  SIDE EFFECTS:
11261da177e4SLinus Torvalds **
11271da177e4SLinus Torvalds **      None
11281da177e4SLinus Torvalds **
11291da177e4SLinus Torvalds **--
11301da177e4SLinus Torvalds */
11311da177e4SLinus Torvalds SMC37c669_CONFIG_REGS * __init SMC37c669_detect( int index )
11321da177e4SLinus Torvalds {
11331da177e4SLinus Torvalds     int i;
11341da177e4SLinus Torvalds     SMC37c669_DEVICE_ID_REGISTER id;
11351da177e4SLinus Torvalds 
11361da177e4SLinus Torvalds     for ( i = 0;  SMC37c669_Addresses[i] != 0;  i++ ) {
11371da177e4SLinus Torvalds /*
11381da177e4SLinus Torvalds ** Initialize the device pointer even though we don't yet know if
11391da177e4SLinus Torvalds ** the controller is at this address.  The support functions access
11401da177e4SLinus Torvalds ** the controller through this device pointer so we need to set it
11411da177e4SLinus Torvalds ** even when we are looking ...
11421da177e4SLinus Torvalds */
11431da177e4SLinus Torvalds     	SMC37c669 = ( SMC37c669_CONFIG_REGS * )SMC37c669_Addresses[i];
11441da177e4SLinus Torvalds /*
11451da177e4SLinus Torvalds ** Enter configuration mode
11461da177e4SLinus Torvalds */
11471da177e4SLinus Torvalds 	SMC37c669_config_mode( TRUE );
11481da177e4SLinus Torvalds /*
11491da177e4SLinus Torvalds ** Read the device id
11501da177e4SLinus Torvalds */
11511da177e4SLinus Torvalds 	id.as_uchar = SMC37c669_read_config( SMC37c669_DEVICE_ID_INDEX );
11521da177e4SLinus Torvalds /*
11531da177e4SLinus Torvalds ** Exit configuration mode
11541da177e4SLinus Torvalds */
11551da177e4SLinus Torvalds 	SMC37c669_config_mode( FALSE );
11561da177e4SLinus Torvalds /*
11571da177e4SLinus Torvalds ** Does the device id match?  If so, assume we have found an
11581da177e4SLinus Torvalds ** SMC37c669 controller at this address.
11591da177e4SLinus Torvalds */
11601da177e4SLinus Torvalds 	if ( id.by_field.device_id == SMC37c669_DEVICE_ID ) {
11611da177e4SLinus Torvalds /*
11621da177e4SLinus Torvalds ** Initialize the IRQ and DRQ translation tables.
11631da177e4SLinus Torvalds */
11641da177e4SLinus Torvalds     	    SMC37c669_irq_table = SMC37c669_irq_tables[ index ];
11651da177e4SLinus Torvalds 	    SMC37c669_drq_table = SMC37c669_default_drq_table;
11661da177e4SLinus Torvalds /*
11671da177e4SLinus Torvalds ** erfix
11681da177e4SLinus Torvalds **
11691da177e4SLinus Torvalds ** If the platform can't use the IRQ and DRQ defaults set up in this
11701da177e4SLinus Torvalds ** file, it should call a platform-specific external routine at this
11711da177e4SLinus Torvalds ** point to reset the IRQ and DRQ translation table pointers to point
11721da177e4SLinus Torvalds ** at the appropriate tables for the platform.  If the defaults are
11731da177e4SLinus Torvalds ** acceptable, then the external routine should do nothing.
11741da177e4SLinus Torvalds */
11751da177e4SLinus Torvalds 
11761da177e4SLinus Torvalds /*
11771da177e4SLinus Torvalds ** Put the chip back into configuration mode
11781da177e4SLinus Torvalds */
11791da177e4SLinus Torvalds 	    SMC37c669_config_mode( TRUE );
11801da177e4SLinus Torvalds /*
11811da177e4SLinus Torvalds ** Initialize local storage for configuration information
11821da177e4SLinus Torvalds */
11831da177e4SLinus Torvalds 	    SMC37c669_init_local_config( );
11841da177e4SLinus Torvalds /*
11851da177e4SLinus Torvalds ** Exit configuration mode
11861da177e4SLinus Torvalds */
11871da177e4SLinus Torvalds 	    SMC37c669_config_mode( FALSE );
11881da177e4SLinus Torvalds /*
11891da177e4SLinus Torvalds ** SMC37c669 controller found, break out of search loop
11901da177e4SLinus Torvalds */
11911da177e4SLinus Torvalds 	    break;
11921da177e4SLinus Torvalds 	}
11931da177e4SLinus Torvalds 	else {
11941da177e4SLinus Torvalds /*
11951da177e4SLinus Torvalds ** Otherwise, we did not find an SMC37c669 controller at this
11961da177e4SLinus Torvalds ** address so set the device pointer to NULL.
11971da177e4SLinus Torvalds */
11981da177e4SLinus Torvalds 	    SMC37c669 = NULL;
11991da177e4SLinus Torvalds 	}
12001da177e4SLinus Torvalds     }
12011da177e4SLinus Torvalds     return SMC37c669;
12021da177e4SLinus Torvalds }
12031da177e4SLinus Torvalds 
12041da177e4SLinus Torvalds 
12051da177e4SLinus Torvalds /*
12061da177e4SLinus Torvalds **++
12071da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
12081da177e4SLinus Torvalds **
12091da177e4SLinus Torvalds **      This function enables an SMC37c669 device function.
12101da177e4SLinus Torvalds **
12111da177e4SLinus Torvalds **  FORMAL PARAMETERS:
12121da177e4SLinus Torvalds **
12131da177e4SLinus Torvalds **      func:
12141da177e4SLinus Torvalds **          Which device function to enable
12151da177e4SLinus Torvalds **
12161da177e4SLinus Torvalds **  RETURN VALUE:
12171da177e4SLinus Torvalds **
12181da177e4SLinus Torvalds **      Returns TRUE is the device function was enabled, otherwise, FALSE
12191da177e4SLinus Torvalds **
12201da177e4SLinus Torvalds **  SIDE EFFECTS:
12211da177e4SLinus Torvalds **
12221da177e4SLinus Torvalds **      {@description or none@}
12231da177e4SLinus Torvalds **
12241da177e4SLinus Torvalds **  DESIGN:
12251da177e4SLinus Torvalds **
12261da177e4SLinus Torvalds **      Enabling a device function in the SMC37c669 controller involves
12271da177e4SLinus Torvalds **	setting all of its mappings (port, irq, drq ...).  A local
12281da177e4SLinus Torvalds **	"shadow" copy of the device configuration is kept so we can
12291da177e4SLinus Torvalds **	just set each mapping to what the local copy says.
12301da177e4SLinus Torvalds **
12311da177e4SLinus Torvalds **	This function ALWAYS updates the local shadow configuration of
12321da177e4SLinus Torvalds **	the device function being enabled, even if the device is always
12331da177e4SLinus Torvalds **	enabled.  To avoid replication of code, functions such as
12341da177e4SLinus Torvalds **	configure_device set up the local copy and then call this
12351da177e4SLinus Torvalds **	function to the update the real device.
12361da177e4SLinus Torvalds **
12371da177e4SLinus Torvalds **--
12381da177e4SLinus Torvalds */
12391da177e4SLinus Torvalds unsigned int __init SMC37c669_enable_device ( unsigned int func )
12401da177e4SLinus Torvalds {
12411da177e4SLinus Torvalds     unsigned int ret_val = FALSE;
12421da177e4SLinus Torvalds /*
12431da177e4SLinus Torvalds ** Put the device into configuration mode
12441da177e4SLinus Torvalds */
12451da177e4SLinus Torvalds     SMC37c669_config_mode( TRUE );
12461da177e4SLinus Torvalds     switch ( func ) {
12471da177e4SLinus Torvalds     	case SERIAL_0:
12481da177e4SLinus Torvalds 	    {
12491da177e4SLinus Torvalds 	    	SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
12501da177e4SLinus Torvalds 		SMC37c669_SERIAL_IRQ_REGISTER irq;
12511da177e4SLinus Torvalds /*
12521da177e4SLinus Torvalds ** Enable the serial 1 IRQ mapping
12531da177e4SLinus Torvalds */
12541da177e4SLinus Torvalds 	    	irq.as_uchar =
12551da177e4SLinus Torvalds 		    SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
12561da177e4SLinus Torvalds 
12571da177e4SLinus Torvalds 		irq.by_field.uart1_irq =
12581da177e4SLinus Torvalds 		    SMC37c669_RAW_DEVICE_IRQ(
12591da177e4SLinus Torvalds 			SMC37c669_xlate_irq( local_config[ func ].irq )
12601da177e4SLinus Torvalds 		    );
12611da177e4SLinus Torvalds 
12621da177e4SLinus Torvalds 		SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
12631da177e4SLinus Torvalds /*
12641da177e4SLinus Torvalds ** Enable the serial 1 port base address mapping
12651da177e4SLinus Torvalds */
12661da177e4SLinus Torvalds 		base_addr.as_uchar = 0;
12671da177e4SLinus Torvalds 		base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
12681da177e4SLinus Torvalds 
12691da177e4SLinus Torvalds 		SMC37c669_write_config(
12701da177e4SLinus Torvalds 		    SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
12711da177e4SLinus Torvalds 		    base_addr.as_uchar
12721da177e4SLinus Torvalds 		);
12731da177e4SLinus Torvalds 		ret_val = TRUE;
12741da177e4SLinus Torvalds 		break;
12751da177e4SLinus Torvalds 	    }
12761da177e4SLinus Torvalds 	case SERIAL_1:
12771da177e4SLinus Torvalds 	    {
12781da177e4SLinus Torvalds 	    	SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
12791da177e4SLinus Torvalds 		SMC37c669_SERIAL_IRQ_REGISTER irq;
12801da177e4SLinus Torvalds /*
12811da177e4SLinus Torvalds ** Enable the serial 2 IRQ mapping
12821da177e4SLinus Torvalds */
12831da177e4SLinus Torvalds 	    	irq.as_uchar =
12841da177e4SLinus Torvalds 		    SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
12851da177e4SLinus Torvalds 
12861da177e4SLinus Torvalds 		irq.by_field.uart2_irq =
12871da177e4SLinus Torvalds 		    SMC37c669_RAW_DEVICE_IRQ(
12881da177e4SLinus Torvalds 			SMC37c669_xlate_irq( local_config[ func ].irq )
12891da177e4SLinus Torvalds 		    );
12901da177e4SLinus Torvalds 
12911da177e4SLinus Torvalds 		SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
12921da177e4SLinus Torvalds /*
12931da177e4SLinus Torvalds ** Enable the serial 2 port base address mapping
12941da177e4SLinus Torvalds */
12951da177e4SLinus Torvalds 		base_addr.as_uchar = 0;
12961da177e4SLinus Torvalds 		base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
12971da177e4SLinus Torvalds 
12981da177e4SLinus Torvalds 		SMC37c669_write_config(
12991da177e4SLinus Torvalds 		    SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
13001da177e4SLinus Torvalds 		    base_addr.as_uchar
13011da177e4SLinus Torvalds 		);
13021da177e4SLinus Torvalds 		ret_val = TRUE;
13031da177e4SLinus Torvalds 		break;
13041da177e4SLinus Torvalds 	    }
13051da177e4SLinus Torvalds 	case PARALLEL_0:
13061da177e4SLinus Torvalds 	    {
13071da177e4SLinus Torvalds 	    	SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
13081da177e4SLinus Torvalds 		SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
13091da177e4SLinus Torvalds 		SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
13101da177e4SLinus Torvalds /*
13111da177e4SLinus Torvalds ** Enable the parallel port DMA channel mapping
13121da177e4SLinus Torvalds */
13131da177e4SLinus Torvalds 	    	drq.as_uchar =
13141da177e4SLinus Torvalds 		    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
13151da177e4SLinus Torvalds 
13161da177e4SLinus Torvalds 		drq.by_field.ppt_drq =
13171da177e4SLinus Torvalds 		    SMC37c669_RAW_DEVICE_DRQ(
13181da177e4SLinus Torvalds 			SMC37c669_xlate_drq( local_config[ func ].drq )
13191da177e4SLinus Torvalds 		    );
13201da177e4SLinus Torvalds 
13211da177e4SLinus Torvalds 		SMC37c669_write_config(
13221da177e4SLinus Torvalds 		    SMC37c669_PARALLEL_FDC_DRQ_INDEX,
13231da177e4SLinus Torvalds 		    drq.as_uchar
13241da177e4SLinus Torvalds 		);
13251da177e4SLinus Torvalds /*
13261da177e4SLinus Torvalds ** Enable the parallel port IRQ mapping
13271da177e4SLinus Torvalds */
13281da177e4SLinus Torvalds 		irq.as_uchar =
13291da177e4SLinus Torvalds 		    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
13301da177e4SLinus Torvalds 
13311da177e4SLinus Torvalds 		irq.by_field.ppt_irq =
13321da177e4SLinus Torvalds 		    SMC37c669_RAW_DEVICE_IRQ(
13331da177e4SLinus Torvalds 			SMC37c669_xlate_irq( local_config[ func ].irq )
13341da177e4SLinus Torvalds 		    );
13351da177e4SLinus Torvalds 
13361da177e4SLinus Torvalds 		SMC37c669_write_config(
13371da177e4SLinus Torvalds 		    SMC37c669_PARALLEL_FDC_IRQ_INDEX,
13381da177e4SLinus Torvalds 		    irq.as_uchar
13391da177e4SLinus Torvalds 		);
13401da177e4SLinus Torvalds /*
13411da177e4SLinus Torvalds ** Enable the parallel port base address mapping
13421da177e4SLinus Torvalds */
13431da177e4SLinus Torvalds 		base_addr.as_uchar = 0;
13441da177e4SLinus Torvalds 		base_addr.by_field.addr9_2 = local_config[ func ].port1 >> 2;
13451da177e4SLinus Torvalds 
13461da177e4SLinus Torvalds 		SMC37c669_write_config(
13471da177e4SLinus Torvalds 		    SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
13481da177e4SLinus Torvalds 		    base_addr.as_uchar
13491da177e4SLinus Torvalds 		);
13501da177e4SLinus Torvalds 		ret_val = TRUE;
13511da177e4SLinus Torvalds 		break;
13521da177e4SLinus Torvalds 	    }
13531da177e4SLinus Torvalds 	case FLOPPY_0:
13541da177e4SLinus Torvalds 	    {
13551da177e4SLinus Torvalds 	    	SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
13561da177e4SLinus Torvalds 		SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
13571da177e4SLinus Torvalds 		SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
13581da177e4SLinus Torvalds /*
13591da177e4SLinus Torvalds ** Enable the floppy controller DMA channel mapping
13601da177e4SLinus Torvalds */
13611da177e4SLinus Torvalds 	    	drq.as_uchar =
13621da177e4SLinus Torvalds 		    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
13631da177e4SLinus Torvalds 
13641da177e4SLinus Torvalds 		drq.by_field.fdc_drq =
13651da177e4SLinus Torvalds 		    SMC37c669_RAW_DEVICE_DRQ(
13661da177e4SLinus Torvalds 			SMC37c669_xlate_drq( local_config[ func ].drq )
13671da177e4SLinus Torvalds 		    );
13681da177e4SLinus Torvalds 
13691da177e4SLinus Torvalds 		SMC37c669_write_config(
13701da177e4SLinus Torvalds 		    SMC37c669_PARALLEL_FDC_DRQ_INDEX,
13711da177e4SLinus Torvalds 		    drq.as_uchar
13721da177e4SLinus Torvalds 		);
13731da177e4SLinus Torvalds /*
13741da177e4SLinus Torvalds ** Enable the floppy controller IRQ mapping
13751da177e4SLinus Torvalds */
13761da177e4SLinus Torvalds 		irq.as_uchar =
13771da177e4SLinus Torvalds 		    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
13781da177e4SLinus Torvalds 
13791da177e4SLinus Torvalds 		irq.by_field.fdc_irq =
13801da177e4SLinus Torvalds 		    SMC37c669_RAW_DEVICE_IRQ(
13811da177e4SLinus Torvalds 			SMC37c669_xlate_irq( local_config[ func ].irq )
13821da177e4SLinus Torvalds 		    );
13831da177e4SLinus Torvalds 
13841da177e4SLinus Torvalds 		SMC37c669_write_config(
13851da177e4SLinus Torvalds 		    SMC37c669_PARALLEL_FDC_IRQ_INDEX,
13861da177e4SLinus Torvalds 		    irq.as_uchar
13871da177e4SLinus Torvalds 		);
13881da177e4SLinus Torvalds /*
13891da177e4SLinus Torvalds ** Enable the floppy controller base address mapping
13901da177e4SLinus Torvalds */
13911da177e4SLinus Torvalds 		base_addr.as_uchar = 0;
13921da177e4SLinus Torvalds 		base_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
13931da177e4SLinus Torvalds 
13941da177e4SLinus Torvalds 		SMC37c669_write_config(
13951da177e4SLinus Torvalds 		    SMC37c669_FDC_BASE_ADDRESS_INDEX,
13961da177e4SLinus Torvalds 		    base_addr.as_uchar
13971da177e4SLinus Torvalds 		);
13981da177e4SLinus Torvalds 		ret_val = TRUE;
13991da177e4SLinus Torvalds 		break;
14001da177e4SLinus Torvalds 	    }
14011da177e4SLinus Torvalds 	case IDE_0:
14021da177e4SLinus Torvalds 	    {
14031da177e4SLinus Torvalds 	    	SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
14041da177e4SLinus Torvalds /*
14051da177e4SLinus Torvalds ** Enable the IDE alternate status base address mapping
14061da177e4SLinus Torvalds */
14071da177e4SLinus Torvalds 	    	ide_addr.as_uchar = 0;
14081da177e4SLinus Torvalds 		ide_addr.by_field.addr9_4 = local_config[ func ].port2 >> 4;
14091da177e4SLinus Torvalds 
14101da177e4SLinus Torvalds 		SMC37c669_write_config(
14111da177e4SLinus Torvalds 		    SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
14121da177e4SLinus Torvalds 		    ide_addr.as_uchar
14131da177e4SLinus Torvalds 		);
14141da177e4SLinus Torvalds /*
14151da177e4SLinus Torvalds ** Enable the IDE controller base address mapping
14161da177e4SLinus Torvalds */
14171da177e4SLinus Torvalds 		ide_addr.as_uchar = 0;
14181da177e4SLinus Torvalds 		ide_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
14191da177e4SLinus Torvalds 
14201da177e4SLinus Torvalds 		SMC37c669_write_config(
14211da177e4SLinus Torvalds 		    SMC37c669_IDE_BASE_ADDRESS_INDEX,
14221da177e4SLinus Torvalds 		    ide_addr.as_uchar
14231da177e4SLinus Torvalds 		);
14241da177e4SLinus Torvalds 		ret_val = TRUE;
14251da177e4SLinus Torvalds 		break;
14261da177e4SLinus Torvalds 	    }
14271da177e4SLinus Torvalds     }
14281da177e4SLinus Torvalds /*
14291da177e4SLinus Torvalds ** Exit configuration mode and return
14301da177e4SLinus Torvalds */
14311da177e4SLinus Torvalds     SMC37c669_config_mode( FALSE );
14321da177e4SLinus Torvalds 
14331da177e4SLinus Torvalds     return ret_val;
14341da177e4SLinus Torvalds }
14351da177e4SLinus Torvalds 
14361da177e4SLinus Torvalds 
14371da177e4SLinus Torvalds /*
14381da177e4SLinus Torvalds **++
14391da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
14401da177e4SLinus Torvalds **
14411da177e4SLinus Torvalds **      This function disables a device function within the
14421da177e4SLinus Torvalds **	SMC37c669 Super I/O controller.
14431da177e4SLinus Torvalds **
14441da177e4SLinus Torvalds **  FORMAL PARAMETERS:
14451da177e4SLinus Torvalds **
14461da177e4SLinus Torvalds **      func:
14471da177e4SLinus Torvalds **          Which function to disable
14481da177e4SLinus Torvalds **
14491da177e4SLinus Torvalds **  RETURN VALUE:
14501da177e4SLinus Torvalds **
14511da177e4SLinus Torvalds **      Return TRUE if the device function was disabled, otherwise, FALSE
14521da177e4SLinus Torvalds **
14531da177e4SLinus Torvalds **  SIDE EFFECTS:
14541da177e4SLinus Torvalds **
14551da177e4SLinus Torvalds **      {@description or none@}
14561da177e4SLinus Torvalds **
14571da177e4SLinus Torvalds **  DESIGN:
14581da177e4SLinus Torvalds **
14591da177e4SLinus Torvalds **      Disabling a function in the SMC37c669 device involves
14601da177e4SLinus Torvalds **	disabling all the function's mappings (port, irq, drq ...).
14611da177e4SLinus Torvalds **	A shadow copy of the device configuration is maintained
14621da177e4SLinus Torvalds **	in local storage so we won't worry aboving saving the
14631da177e4SLinus Torvalds **	current configuration information.
14641da177e4SLinus Torvalds **
14651da177e4SLinus Torvalds **--
14661da177e4SLinus Torvalds */
14671da177e4SLinus Torvalds unsigned int __init SMC37c669_disable_device ( unsigned int func )
14681da177e4SLinus Torvalds {
14691da177e4SLinus Torvalds     unsigned int ret_val = FALSE;
14701da177e4SLinus Torvalds 
14711da177e4SLinus Torvalds /*
14721da177e4SLinus Torvalds ** Put the device into configuration mode
14731da177e4SLinus Torvalds */
14741da177e4SLinus Torvalds     SMC37c669_config_mode( TRUE );
14751da177e4SLinus Torvalds     switch ( func ) {
14761da177e4SLinus Torvalds     	case SERIAL_0:
14771da177e4SLinus Torvalds 	    {
14781da177e4SLinus Torvalds 	    	SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
14791da177e4SLinus Torvalds 		SMC37c669_SERIAL_IRQ_REGISTER irq;
14801da177e4SLinus Torvalds /*
14811da177e4SLinus Torvalds ** Disable the serial 1 IRQ mapping
14821da177e4SLinus Torvalds */
14831da177e4SLinus Torvalds 	    	irq.as_uchar =
14841da177e4SLinus Torvalds 		    SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
14851da177e4SLinus Torvalds 
14861da177e4SLinus Torvalds 		irq.by_field.uart1_irq = 0;
14871da177e4SLinus Torvalds 
14881da177e4SLinus Torvalds 		SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
14891da177e4SLinus Torvalds /*
14901da177e4SLinus Torvalds ** Disable the serial 1 port base address mapping
14911da177e4SLinus Torvalds */
14921da177e4SLinus Torvalds 		base_addr.as_uchar = 0;
14931da177e4SLinus Torvalds 		SMC37c669_write_config(
14941da177e4SLinus Torvalds 		    SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
14951da177e4SLinus Torvalds 		    base_addr.as_uchar
14961da177e4SLinus Torvalds 		);
14971da177e4SLinus Torvalds 		ret_val = TRUE;
14981da177e4SLinus Torvalds 		break;
14991da177e4SLinus Torvalds 	    }
15001da177e4SLinus Torvalds 	case SERIAL_1:
15011da177e4SLinus Torvalds 	    {
15021da177e4SLinus Torvalds 	    	SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
15031da177e4SLinus Torvalds 		SMC37c669_SERIAL_IRQ_REGISTER irq;
15041da177e4SLinus Torvalds /*
15051da177e4SLinus Torvalds ** Disable the serial 2 IRQ mapping
15061da177e4SLinus Torvalds */
15071da177e4SLinus Torvalds 	    	irq.as_uchar =
15081da177e4SLinus Torvalds 		    SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
15091da177e4SLinus Torvalds 
15101da177e4SLinus Torvalds 		irq.by_field.uart2_irq = 0;
15111da177e4SLinus Torvalds 
15121da177e4SLinus Torvalds 		SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
15131da177e4SLinus Torvalds /*
15141da177e4SLinus Torvalds ** Disable the serial 2 port base address mapping
15151da177e4SLinus Torvalds */
15161da177e4SLinus Torvalds 		base_addr.as_uchar = 0;
15171da177e4SLinus Torvalds 
15181da177e4SLinus Torvalds 		SMC37c669_write_config(
15191da177e4SLinus Torvalds 		    SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
15201da177e4SLinus Torvalds 		    base_addr.as_uchar
15211da177e4SLinus Torvalds 		);
15221da177e4SLinus Torvalds 		ret_val = TRUE;
15231da177e4SLinus Torvalds 		break;
15241da177e4SLinus Torvalds 	    }
15251da177e4SLinus Torvalds 	case PARALLEL_0:
15261da177e4SLinus Torvalds 	    {
15271da177e4SLinus Torvalds 	    	SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
15281da177e4SLinus Torvalds 		SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
15291da177e4SLinus Torvalds 		SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
15301da177e4SLinus Torvalds /*
15311da177e4SLinus Torvalds ** Disable the parallel port DMA channel mapping
15321da177e4SLinus Torvalds */
15331da177e4SLinus Torvalds 	    	drq.as_uchar =
15341da177e4SLinus Torvalds 		    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
15351da177e4SLinus Torvalds 
15361da177e4SLinus Torvalds 		drq.by_field.ppt_drq = 0;
15371da177e4SLinus Torvalds 
15381da177e4SLinus Torvalds 		SMC37c669_write_config(
15391da177e4SLinus Torvalds 		    SMC37c669_PARALLEL_FDC_DRQ_INDEX,
15401da177e4SLinus Torvalds 		    drq.as_uchar
15411da177e4SLinus Torvalds 		);
15421da177e4SLinus Torvalds /*
15431da177e4SLinus Torvalds ** Disable the parallel port IRQ mapping
15441da177e4SLinus Torvalds */
15451da177e4SLinus Torvalds 		irq.as_uchar =
15461da177e4SLinus Torvalds 		    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
15471da177e4SLinus Torvalds 
15481da177e4SLinus Torvalds 		irq.by_field.ppt_irq = 0;
15491da177e4SLinus Torvalds 
15501da177e4SLinus Torvalds 		SMC37c669_write_config(
15511da177e4SLinus Torvalds 		    SMC37c669_PARALLEL_FDC_IRQ_INDEX,
15521da177e4SLinus Torvalds 		    irq.as_uchar
15531da177e4SLinus Torvalds 		);
15541da177e4SLinus Torvalds /*
15551da177e4SLinus Torvalds ** Disable the parallel port base address mapping
15561da177e4SLinus Torvalds */
15571da177e4SLinus Torvalds 		base_addr.as_uchar = 0;
15581da177e4SLinus Torvalds 
15591da177e4SLinus Torvalds 		SMC37c669_write_config(
15601da177e4SLinus Torvalds 		    SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
15611da177e4SLinus Torvalds 		    base_addr.as_uchar
15621da177e4SLinus Torvalds 		);
15631da177e4SLinus Torvalds 		ret_val = TRUE;
15641da177e4SLinus Torvalds 		break;
15651da177e4SLinus Torvalds 	    }
15661da177e4SLinus Torvalds 	case FLOPPY_0:
15671da177e4SLinus Torvalds 	    {
15681da177e4SLinus Torvalds 	    	SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
15691da177e4SLinus Torvalds 		SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
15701da177e4SLinus Torvalds 		SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
15711da177e4SLinus Torvalds /*
15721da177e4SLinus Torvalds ** Disable the floppy controller DMA channel mapping
15731da177e4SLinus Torvalds */
15741da177e4SLinus Torvalds 	    	drq.as_uchar =
15751da177e4SLinus Torvalds 		    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
15761da177e4SLinus Torvalds 
15771da177e4SLinus Torvalds 		drq.by_field.fdc_drq = 0;
15781da177e4SLinus Torvalds 
15791da177e4SLinus Torvalds 		SMC37c669_write_config(
15801da177e4SLinus Torvalds 		    SMC37c669_PARALLEL_FDC_DRQ_INDEX,
15811da177e4SLinus Torvalds 		    drq.as_uchar
15821da177e4SLinus Torvalds 		);
15831da177e4SLinus Torvalds /*
15841da177e4SLinus Torvalds ** Disable the floppy controller IRQ mapping
15851da177e4SLinus Torvalds */
15861da177e4SLinus Torvalds 		irq.as_uchar =
15871da177e4SLinus Torvalds 		    SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
15881da177e4SLinus Torvalds 
15891da177e4SLinus Torvalds 		irq.by_field.fdc_irq = 0;
15901da177e4SLinus Torvalds 
15911da177e4SLinus Torvalds 		SMC37c669_write_config(
15921da177e4SLinus Torvalds 		    SMC37c669_PARALLEL_FDC_IRQ_INDEX,
15931da177e4SLinus Torvalds 		    irq.as_uchar
15941da177e4SLinus Torvalds 		);
15951da177e4SLinus Torvalds /*
15961da177e4SLinus Torvalds ** Disable the floppy controller base address mapping
15971da177e4SLinus Torvalds */
15981da177e4SLinus Torvalds 		base_addr.as_uchar = 0;
15991da177e4SLinus Torvalds 
16001da177e4SLinus Torvalds 		SMC37c669_write_config(
16011da177e4SLinus Torvalds 		    SMC37c669_FDC_BASE_ADDRESS_INDEX,
16021da177e4SLinus Torvalds 		    base_addr.as_uchar
16031da177e4SLinus Torvalds 		);
16041da177e4SLinus Torvalds 		ret_val = TRUE;
16051da177e4SLinus Torvalds 		break;
16061da177e4SLinus Torvalds 	    }
16071da177e4SLinus Torvalds 	case IDE_0:
16081da177e4SLinus Torvalds 	    {
16091da177e4SLinus Torvalds 	    	SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
16101da177e4SLinus Torvalds /*
16111da177e4SLinus Torvalds ** Disable the IDE alternate status base address mapping
16121da177e4SLinus Torvalds */
16131da177e4SLinus Torvalds 	    	ide_addr.as_uchar = 0;
16141da177e4SLinus Torvalds 
16151da177e4SLinus Torvalds 		SMC37c669_write_config(
16161da177e4SLinus Torvalds 		    SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
16171da177e4SLinus Torvalds 		    ide_addr.as_uchar
16181da177e4SLinus Torvalds 		);
16191da177e4SLinus Torvalds /*
16201da177e4SLinus Torvalds ** Disable the IDE controller base address mapping
16211da177e4SLinus Torvalds */
16221da177e4SLinus Torvalds 		ide_addr.as_uchar = 0;
16231da177e4SLinus Torvalds 
16241da177e4SLinus Torvalds 		SMC37c669_write_config(
16251da177e4SLinus Torvalds 		    SMC37c669_IDE_BASE_ADDRESS_INDEX,
16261da177e4SLinus Torvalds 		    ide_addr.as_uchar
16271da177e4SLinus Torvalds 		);
16281da177e4SLinus Torvalds 		ret_val = TRUE;
16291da177e4SLinus Torvalds 		break;
16301da177e4SLinus Torvalds 	    }
16311da177e4SLinus Torvalds     }
16321da177e4SLinus Torvalds /*
16331da177e4SLinus Torvalds ** Exit configuration mode and return
16341da177e4SLinus Torvalds */
16351da177e4SLinus Torvalds     SMC37c669_config_mode( FALSE );
16361da177e4SLinus Torvalds 
16371da177e4SLinus Torvalds     return ret_val;
16381da177e4SLinus Torvalds }
16391da177e4SLinus Torvalds 
16401da177e4SLinus Torvalds 
16411da177e4SLinus Torvalds /*
16421da177e4SLinus Torvalds **++
16431da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
16441da177e4SLinus Torvalds **
16451da177e4SLinus Torvalds **      This function configures a device function within the
16461da177e4SLinus Torvalds **	SMC37c669 Super I/O controller.
16471da177e4SLinus Torvalds **
16481da177e4SLinus Torvalds **  FORMAL PARAMETERS:
16491da177e4SLinus Torvalds **
16501da177e4SLinus Torvalds **      func:
16511da177e4SLinus Torvalds **          Which device function
16521da177e4SLinus Torvalds **
16531da177e4SLinus Torvalds **      port:
16541da177e4SLinus Torvalds **          I/O port for the function to use
16551da177e4SLinus Torvalds **
16561da177e4SLinus Torvalds **      irq:
16571da177e4SLinus Torvalds **          IRQ for the device function to use
16581da177e4SLinus Torvalds **
16591da177e4SLinus Torvalds **      drq:
16601da177e4SLinus Torvalds **          DMA channel for the device function to use
16611da177e4SLinus Torvalds **
16621da177e4SLinus Torvalds **  RETURN VALUE:
16631da177e4SLinus Torvalds **
16641da177e4SLinus Torvalds **      Returns TRUE if the device function was configured,
16651da177e4SLinus Torvalds **	otherwise, FALSE.
16661da177e4SLinus Torvalds **
16671da177e4SLinus Torvalds **  SIDE EFFECTS:
16681da177e4SLinus Torvalds **
16691da177e4SLinus Torvalds **      {@description or none@}
16701da177e4SLinus Torvalds **
16711da177e4SLinus Torvalds **  DESIGN:
16721da177e4SLinus Torvalds **
16731da177e4SLinus Torvalds **	If this function returns TRUE, the local shadow copy of
16741da177e4SLinus Torvalds **	the configuration is also updated.  If the device function
16751da177e4SLinus Torvalds **	is currently disabled, only the local shadow copy is
16761da177e4SLinus Torvalds **	updated and the actual device function will be updated
16771da177e4SLinus Torvalds **	if/when it is enabled.
16781da177e4SLinus Torvalds **
16791da177e4SLinus Torvalds **--
16801da177e4SLinus Torvalds */
16811da177e4SLinus Torvalds unsigned int __init SMC37c669_configure_device (
16821da177e4SLinus Torvalds     unsigned int func,
16831da177e4SLinus Torvalds     int port,
16841da177e4SLinus Torvalds     int irq,
16851da177e4SLinus Torvalds     int drq )
16861da177e4SLinus Torvalds {
16871da177e4SLinus Torvalds     struct DEVICE_CONFIG *cp;
16881da177e4SLinus Torvalds 
16891da177e4SLinus Torvalds /*
16901da177e4SLinus Torvalds ** Check for a valid configuration
16911da177e4SLinus Torvalds */
16921da177e4SLinus Torvalds     if ( ( cp = SMC37c669_get_config ( func ) ) != NULL ) {
16931da177e4SLinus Torvalds /*
16941da177e4SLinus Torvalds ** Configuration is valid, update the local shadow copy
16951da177e4SLinus Torvalds */
16961da177e4SLinus Torvalds     	if ( ( drq & ~0xFF ) == 0 ) {
16971da177e4SLinus Torvalds 	    cp->drq = drq;
16981da177e4SLinus Torvalds 	}
16991da177e4SLinus Torvalds 	if ( ( irq & ~0xFF ) == 0 ) {
17001da177e4SLinus Torvalds 	    cp->irq = irq;
17011da177e4SLinus Torvalds 	}
17021da177e4SLinus Torvalds 	if ( ( port & ~0xFFFF ) == 0 ) {
17031da177e4SLinus Torvalds 	    cp->port1 = port;
17041da177e4SLinus Torvalds 	}
17051da177e4SLinus Torvalds /*
17061da177e4SLinus Torvalds ** If the device function is enabled, update the actual
17071da177e4SLinus Torvalds ** device configuration.
17081da177e4SLinus Torvalds */
17091da177e4SLinus Torvalds 	if ( SMC37c669_is_device_enabled( func ) ) {
17101da177e4SLinus Torvalds 	    SMC37c669_enable_device( func );
17111da177e4SLinus Torvalds 	}
17121da177e4SLinus Torvalds 	return TRUE;
17131da177e4SLinus Torvalds     }
17141da177e4SLinus Torvalds     return FALSE;
17151da177e4SLinus Torvalds }
17161da177e4SLinus Torvalds 
17171da177e4SLinus Torvalds 
17181da177e4SLinus Torvalds /*
17191da177e4SLinus Torvalds **++
17201da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
17211da177e4SLinus Torvalds **
17221da177e4SLinus Torvalds **      This function determines whether a device function
17231da177e4SLinus Torvalds **	within the SMC37c669 controller is enabled.
17241da177e4SLinus Torvalds **
17251da177e4SLinus Torvalds **  FORMAL PARAMETERS:
17261da177e4SLinus Torvalds **
17271da177e4SLinus Torvalds **      func:
17281da177e4SLinus Torvalds **          Which device function
17291da177e4SLinus Torvalds **
17301da177e4SLinus Torvalds **  RETURN VALUE:
17311da177e4SLinus Torvalds **
17321da177e4SLinus Torvalds **      Returns TRUE if the device function is enabled, otherwise, FALSE
17331da177e4SLinus Torvalds **
17341da177e4SLinus Torvalds **  SIDE EFFECTS:
17351da177e4SLinus Torvalds **
17361da177e4SLinus Torvalds **      {@description or none@}
17371da177e4SLinus Torvalds **
17381da177e4SLinus Torvalds **  DESIGN:
17391da177e4SLinus Torvalds **
17401da177e4SLinus Torvalds **      To check whether a device is enabled we will only look at
17411da177e4SLinus Torvalds **	the port base address mapping.  According to the SMC37c669
17421da177e4SLinus Torvalds **	specification, all of the port base address mappings are
17431da177e4SLinus Torvalds **	disabled if the addr<9:8> (bits <7:6> of the register) are
17441da177e4SLinus Torvalds **	zero.
17451da177e4SLinus Torvalds **
17461da177e4SLinus Torvalds **--
17471da177e4SLinus Torvalds */
17481da177e4SLinus Torvalds static unsigned int __init SMC37c669_is_device_enabled ( unsigned int func )
17491da177e4SLinus Torvalds {
17501da177e4SLinus Torvalds     unsigned char base_addr = 0;
17511da177e4SLinus Torvalds     unsigned int dev_ok = FALSE;
17521da177e4SLinus Torvalds     unsigned int ret_val = FALSE;
17531da177e4SLinus Torvalds /*
17541da177e4SLinus Torvalds ** Enter configuration mode
17551da177e4SLinus Torvalds */
17561da177e4SLinus Torvalds     SMC37c669_config_mode( TRUE );
17571da177e4SLinus Torvalds 
17581da177e4SLinus Torvalds     switch ( func ) {
17591da177e4SLinus Torvalds     	case SERIAL_0:
17601da177e4SLinus Torvalds 	    base_addr =
17611da177e4SLinus Torvalds 		SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
17621da177e4SLinus Torvalds 	    dev_ok = TRUE;
17631da177e4SLinus Torvalds 	    break;
17641da177e4SLinus Torvalds 	case SERIAL_1:
17651da177e4SLinus Torvalds 	    base_addr =
17661da177e4SLinus Torvalds 		SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
17671da177e4SLinus Torvalds 	    dev_ok = TRUE;
17681da177e4SLinus Torvalds 	    break;
17691da177e4SLinus Torvalds 	case PARALLEL_0:
17701da177e4SLinus Torvalds 	    base_addr =
17711da177e4SLinus Torvalds 		SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
17721da177e4SLinus Torvalds 	    dev_ok = TRUE;
17731da177e4SLinus Torvalds 	    break;
17741da177e4SLinus Torvalds 	case FLOPPY_0:
17751da177e4SLinus Torvalds 	    base_addr =
17761da177e4SLinus Torvalds 		SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
17771da177e4SLinus Torvalds 	    dev_ok = TRUE;
17781da177e4SLinus Torvalds 	    break;
17791da177e4SLinus Torvalds 	case IDE_0:
17801da177e4SLinus Torvalds 	    base_addr =
17811da177e4SLinus Torvalds 		SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
17821da177e4SLinus Torvalds 	    dev_ok = TRUE;
17831da177e4SLinus Torvalds 	    break;
17841da177e4SLinus Torvalds     }
17851da177e4SLinus Torvalds /*
17861da177e4SLinus Torvalds ** If we have a valid device, check base_addr<7:6> to see if the
17871da177e4SLinus Torvalds ** device is enabled (mapped).
17881da177e4SLinus Torvalds */
17891da177e4SLinus Torvalds     if ( ( dev_ok ) && ( ( base_addr & 0xC0 ) != 0 ) ) {
17901da177e4SLinus Torvalds /*
17911da177e4SLinus Torvalds ** The mapping is not disabled, so assume that the function is
17921da177e4SLinus Torvalds ** enabled.
17931da177e4SLinus Torvalds */
17941da177e4SLinus Torvalds     	ret_val = TRUE;
17951da177e4SLinus Torvalds     }
17961da177e4SLinus Torvalds /*
17971da177e4SLinus Torvalds ** Exit configuration mode
17981da177e4SLinus Torvalds */
17991da177e4SLinus Torvalds     SMC37c669_config_mode( FALSE );
18001da177e4SLinus Torvalds 
18011da177e4SLinus Torvalds     return ret_val;
18021da177e4SLinus Torvalds }
18031da177e4SLinus Torvalds 
18041da177e4SLinus Torvalds 
18051da177e4SLinus Torvalds #if 0
18061da177e4SLinus Torvalds /*
18071da177e4SLinus Torvalds **++
18081da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
18091da177e4SLinus Torvalds **
18101da177e4SLinus Torvalds **      This function retrieves the configuration information of a
18111da177e4SLinus Torvalds **	device function within the SMC37c699 Super I/O controller.
18121da177e4SLinus Torvalds **
18131da177e4SLinus Torvalds **  FORMAL PARAMETERS:
18141da177e4SLinus Torvalds **
18151da177e4SLinus Torvalds **      func:
18161da177e4SLinus Torvalds **          Which device function
18171da177e4SLinus Torvalds **
18181da177e4SLinus Torvalds **      port:
18191da177e4SLinus Torvalds **          I/O port returned
18201da177e4SLinus Torvalds **
18211da177e4SLinus Torvalds **      irq:
18221da177e4SLinus Torvalds **          IRQ returned
18231da177e4SLinus Torvalds **
18241da177e4SLinus Torvalds **      drq:
18251da177e4SLinus Torvalds **          DMA channel returned
18261da177e4SLinus Torvalds **
18271da177e4SLinus Torvalds **  RETURN VALUE:
18281da177e4SLinus Torvalds **
18291da177e4SLinus Torvalds **      Returns TRUE if the device configuration was successfully
18301da177e4SLinus Torvalds **	retrieved, otherwise, FALSE.
18311da177e4SLinus Torvalds **
18321da177e4SLinus Torvalds **  SIDE EFFECTS:
18331da177e4SLinus Torvalds **
18341da177e4SLinus Torvalds **      The data pointed to by the port, irq, and drq parameters
18351da177e4SLinus Torvalds **	my be modified even if the configuration is not successfully
18361da177e4SLinus Torvalds **	retrieved.
18371da177e4SLinus Torvalds **
18381da177e4SLinus Torvalds **  DESIGN:
18391da177e4SLinus Torvalds **
18401da177e4SLinus Torvalds **      The device configuration is fetched from the local shadow
18411da177e4SLinus Torvalds **	copy.  Any unused parameters will be set to -1.  Any
18421da177e4SLinus Torvalds **	parameter which is not desired can specify the NULL
18431da177e4SLinus Torvalds **	pointer.
18441da177e4SLinus Torvalds **
18451da177e4SLinus Torvalds **--
18461da177e4SLinus Torvalds */
18471da177e4SLinus Torvalds static unsigned int __init SMC37c669_get_device_config (
18481da177e4SLinus Torvalds     unsigned int func,
18491da177e4SLinus Torvalds     int *port,
18501da177e4SLinus Torvalds     int *irq,
18511da177e4SLinus Torvalds     int *drq )
18521da177e4SLinus Torvalds {
18531da177e4SLinus Torvalds     struct DEVICE_CONFIG *cp;
18541da177e4SLinus Torvalds     unsigned int ret_val = FALSE;
18551da177e4SLinus Torvalds /*
18561da177e4SLinus Torvalds ** Check for a valid device configuration
18571da177e4SLinus Torvalds */
18581da177e4SLinus Torvalds     if ( ( cp = SMC37c669_get_config( func ) ) != NULL ) {
18591da177e4SLinus Torvalds     	if ( drq != NULL ) {
18601da177e4SLinus Torvalds 	    *drq = cp->drq;
18611da177e4SLinus Torvalds 	    ret_val = TRUE;
18621da177e4SLinus Torvalds 	}
18631da177e4SLinus Torvalds 	if ( irq != NULL ) {
18641da177e4SLinus Torvalds 	    *irq = cp->irq;
18651da177e4SLinus Torvalds 	    ret_val = TRUE;
18661da177e4SLinus Torvalds 	}
18671da177e4SLinus Torvalds 	if ( port != NULL ) {
18681da177e4SLinus Torvalds 	    *port = cp->port1;
18691da177e4SLinus Torvalds 	    ret_val = TRUE;
18701da177e4SLinus Torvalds 	}
18711da177e4SLinus Torvalds     }
18721da177e4SLinus Torvalds     return ret_val;
18731da177e4SLinus Torvalds }
18741da177e4SLinus Torvalds #endif
18751da177e4SLinus Torvalds 
18761da177e4SLinus Torvalds 
18771da177e4SLinus Torvalds /*
18781da177e4SLinus Torvalds **++
18791da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
18801da177e4SLinus Torvalds **
18811da177e4SLinus Torvalds **      This function displays the current state of the SMC37c699
18821da177e4SLinus Torvalds **	Super I/O controller's device functions.
18831da177e4SLinus Torvalds **
18841da177e4SLinus Torvalds **  FORMAL PARAMETERS:
18851da177e4SLinus Torvalds **
18861da177e4SLinus Torvalds **      None
18871da177e4SLinus Torvalds **
18881da177e4SLinus Torvalds **  RETURN VALUE:
18891da177e4SLinus Torvalds **
18901da177e4SLinus Torvalds **      None
18911da177e4SLinus Torvalds **
18921da177e4SLinus Torvalds **  SIDE EFFECTS:
18931da177e4SLinus Torvalds **
18941da177e4SLinus Torvalds **      None
18951da177e4SLinus Torvalds **
18961da177e4SLinus Torvalds **--
18971da177e4SLinus Torvalds */
18981da177e4SLinus Torvalds void __init SMC37c669_display_device_info ( void )
18991da177e4SLinus Torvalds {
19001da177e4SLinus Torvalds     if ( SMC37c669_is_device_enabled( SERIAL_0 ) ) {
19011da177e4SLinus Torvalds     	printk( "  Serial 0:    Enabled [ Port 0x%x, IRQ %d ]\n",
19021da177e4SLinus Torvalds 		 local_config[ SERIAL_0 ].port1,
19031da177e4SLinus Torvalds 		 local_config[ SERIAL_0 ].irq
19041da177e4SLinus Torvalds 	);
19051da177e4SLinus Torvalds     }
19061da177e4SLinus Torvalds     else {
19071da177e4SLinus Torvalds     	printk( "  Serial 0:    Disabled\n" );
19081da177e4SLinus Torvalds     }
19091da177e4SLinus Torvalds 
19101da177e4SLinus Torvalds     if ( SMC37c669_is_device_enabled( SERIAL_1 ) ) {
19111da177e4SLinus Torvalds     	printk( "  Serial 1:    Enabled [ Port 0x%x, IRQ %d ]\n",
19121da177e4SLinus Torvalds 		 local_config[ SERIAL_1 ].port1,
19131da177e4SLinus Torvalds 		 local_config[ SERIAL_1 ].irq
19141da177e4SLinus Torvalds 	);
19151da177e4SLinus Torvalds     }
19161da177e4SLinus Torvalds     else {
19171da177e4SLinus Torvalds     	printk( "  Serial 1:    Disabled\n" );
19181da177e4SLinus Torvalds     }
19191da177e4SLinus Torvalds 
19201da177e4SLinus Torvalds     if ( SMC37c669_is_device_enabled( PARALLEL_0 ) ) {
19211da177e4SLinus Torvalds     	printk( "  Parallel:    Enabled [ Port 0x%x, IRQ %d/%d ]\n",
19221da177e4SLinus Torvalds 		 local_config[ PARALLEL_0 ].port1,
19231da177e4SLinus Torvalds 		 local_config[ PARALLEL_0 ].irq,
19241da177e4SLinus Torvalds 		 local_config[ PARALLEL_0 ].drq
19251da177e4SLinus Torvalds 	);
19261da177e4SLinus Torvalds     }
19271da177e4SLinus Torvalds     else {
19281da177e4SLinus Torvalds     	printk( "  Parallel:    Disabled\n" );
19291da177e4SLinus Torvalds     }
19301da177e4SLinus Torvalds 
19311da177e4SLinus Torvalds     if ( SMC37c669_is_device_enabled( FLOPPY_0 ) ) {
19321da177e4SLinus Torvalds     	printk( "  Floppy Ctrl: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
19331da177e4SLinus Torvalds 		 local_config[ FLOPPY_0 ].port1,
19341da177e4SLinus Torvalds 		 local_config[ FLOPPY_0 ].irq,
19351da177e4SLinus Torvalds 		 local_config[ FLOPPY_0 ].drq
19361da177e4SLinus Torvalds 	);
19371da177e4SLinus Torvalds     }
19381da177e4SLinus Torvalds     else {
19391da177e4SLinus Torvalds     	printk( "  Floppy Ctrl: Disabled\n" );
19401da177e4SLinus Torvalds     }
19411da177e4SLinus Torvalds 
19421da177e4SLinus Torvalds     if ( SMC37c669_is_device_enabled( IDE_0 ) ) {
19431da177e4SLinus Torvalds     	printk( "  IDE 0:       Enabled [ Port 0x%x, IRQ %d ]\n",
19441da177e4SLinus Torvalds 		 local_config[ IDE_0 ].port1,
19451da177e4SLinus Torvalds 		 local_config[ IDE_0 ].irq
19461da177e4SLinus Torvalds 	);
19471da177e4SLinus Torvalds     }
19481da177e4SLinus Torvalds     else {
19491da177e4SLinus Torvalds     	printk( "  IDE 0:       Disabled\n" );
19501da177e4SLinus Torvalds     }
19511da177e4SLinus Torvalds }
19521da177e4SLinus Torvalds 
19531da177e4SLinus Torvalds 
19541da177e4SLinus Torvalds /*
19551da177e4SLinus Torvalds **++
19561da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
19571da177e4SLinus Torvalds **
19581da177e4SLinus Torvalds **      This function puts the SMC37c669 Super I/O controller into,
19591da177e4SLinus Torvalds **	and takes it out of, configuration mode.
19601da177e4SLinus Torvalds **
19611da177e4SLinus Torvalds **  FORMAL PARAMETERS:
19621da177e4SLinus Torvalds **
19631da177e4SLinus Torvalds **      enable:
19641da177e4SLinus Torvalds **          TRUE to enter configuration mode, FALSE to exit.
19651da177e4SLinus Torvalds **
19661da177e4SLinus Torvalds **  RETURN VALUE:
19671da177e4SLinus Torvalds **
19681da177e4SLinus Torvalds **      None
19691da177e4SLinus Torvalds **
19701da177e4SLinus Torvalds **  SIDE EFFECTS:
19711da177e4SLinus Torvalds **
19721da177e4SLinus Torvalds **      The SMC37c669 controller may be left in configuration mode.
19731da177e4SLinus Torvalds **
19741da177e4SLinus Torvalds **--
19751da177e4SLinus Torvalds */
19761da177e4SLinus Torvalds static void __init SMC37c669_config_mode(
19771da177e4SLinus Torvalds     unsigned int enable )
19781da177e4SLinus Torvalds {
19791da177e4SLinus Torvalds     if ( enable ) {
19801da177e4SLinus Torvalds /*
19811da177e4SLinus Torvalds ** To enter configuration mode, two writes in succession to the index
19821da177e4SLinus Torvalds ** port are required.  If a write to another address or port occurs
19831da177e4SLinus Torvalds ** between these two writes, the chip does not enter configuration
19841da177e4SLinus Torvalds ** mode.  Therefore, a spinlock is placed around the two writes to
19851da177e4SLinus Torvalds ** guarantee that they complete uninterrupted.
19861da177e4SLinus Torvalds */
19871da177e4SLinus Torvalds 	spin_lock(&smc_lock);
19881da177e4SLinus Torvalds     	wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
19891da177e4SLinus Torvalds     	wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
19901da177e4SLinus Torvalds 	spin_unlock(&smc_lock);
19911da177e4SLinus Torvalds     }
19921da177e4SLinus Torvalds     else {
19931da177e4SLinus Torvalds     	wb( &SMC37c669->index_port, SMC37c669_CONFIG_OFF_KEY );
19941da177e4SLinus Torvalds     }
19951da177e4SLinus Torvalds }
19961da177e4SLinus Torvalds 
19971da177e4SLinus Torvalds /*
19981da177e4SLinus Torvalds **++
19991da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
20001da177e4SLinus Torvalds **
20011da177e4SLinus Torvalds **      This function reads an SMC37c669 Super I/O controller
20021da177e4SLinus Torvalds **	configuration register.  This function assumes that the
20031da177e4SLinus Torvalds **	device is already in configuration mode.
20041da177e4SLinus Torvalds **
20051da177e4SLinus Torvalds **  FORMAL PARAMETERS:
20061da177e4SLinus Torvalds **
20071da177e4SLinus Torvalds **      index:
20081da177e4SLinus Torvalds **          Index value of configuration register to read
20091da177e4SLinus Torvalds **
20101da177e4SLinus Torvalds **  RETURN VALUE:
20111da177e4SLinus Torvalds **
20121da177e4SLinus Torvalds **      Data read from configuration register
20131da177e4SLinus Torvalds **
20141da177e4SLinus Torvalds **  SIDE EFFECTS:
20151da177e4SLinus Torvalds **
20161da177e4SLinus Torvalds **      None
20171da177e4SLinus Torvalds **
20181da177e4SLinus Torvalds **--
20191da177e4SLinus Torvalds */
20201da177e4SLinus Torvalds static unsigned char __init SMC37c669_read_config(
20211da177e4SLinus Torvalds     unsigned char index )
20221da177e4SLinus Torvalds {
20231da177e4SLinus Torvalds     unsigned char data;
20241da177e4SLinus Torvalds 
20251da177e4SLinus Torvalds     wb( &SMC37c669->index_port, index );
20261da177e4SLinus Torvalds     data = rb( &SMC37c669->data_port );
20271da177e4SLinus Torvalds     return data;
20281da177e4SLinus Torvalds }
20291da177e4SLinus Torvalds 
20301da177e4SLinus Torvalds /*
20311da177e4SLinus Torvalds **++
20321da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
20331da177e4SLinus Torvalds **
20341da177e4SLinus Torvalds **      This function writes an SMC37c669 Super I/O controller
20351da177e4SLinus Torvalds **	configuration register.  This function assumes that the
20361da177e4SLinus Torvalds **	device is already in configuration mode.
20371da177e4SLinus Torvalds **
20381da177e4SLinus Torvalds **  FORMAL PARAMETERS:
20391da177e4SLinus Torvalds **
20401da177e4SLinus Torvalds **      index:
20411da177e4SLinus Torvalds **          Index of configuration register to write
20421da177e4SLinus Torvalds **
20431da177e4SLinus Torvalds **      data:
20441da177e4SLinus Torvalds **          Data to be written
20451da177e4SLinus Torvalds **
20461da177e4SLinus Torvalds **  RETURN VALUE:
20471da177e4SLinus Torvalds **
20481da177e4SLinus Torvalds **      None
20491da177e4SLinus Torvalds **
20501da177e4SLinus Torvalds **  SIDE EFFECTS:
20511da177e4SLinus Torvalds **
20521da177e4SLinus Torvalds **      None
20531da177e4SLinus Torvalds **
20541da177e4SLinus Torvalds **--
20551da177e4SLinus Torvalds */
20561da177e4SLinus Torvalds static void __init SMC37c669_write_config(
20571da177e4SLinus Torvalds     unsigned char index,
20581da177e4SLinus Torvalds     unsigned char data )
20591da177e4SLinus Torvalds {
20601da177e4SLinus Torvalds     wb( &SMC37c669->index_port, index );
20611da177e4SLinus Torvalds     wb( &SMC37c669->data_port, data );
20621da177e4SLinus Torvalds }
20631da177e4SLinus Torvalds 
20641da177e4SLinus Torvalds 
20651da177e4SLinus Torvalds /*
20661da177e4SLinus Torvalds **++
20671da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
20681da177e4SLinus Torvalds **
20691da177e4SLinus Torvalds **      This function initializes the local device
20701da177e4SLinus Torvalds **	configuration storage.  This function assumes
20711da177e4SLinus Torvalds **	that the device is already in configuration
20721da177e4SLinus Torvalds **	mode.
20731da177e4SLinus Torvalds **
20741da177e4SLinus Torvalds **  FORMAL PARAMETERS:
20751da177e4SLinus Torvalds **
20761da177e4SLinus Torvalds **      None
20771da177e4SLinus Torvalds **
20781da177e4SLinus Torvalds **  RETURN VALUE:
20791da177e4SLinus Torvalds **
20801da177e4SLinus Torvalds **      None
20811da177e4SLinus Torvalds **
20821da177e4SLinus Torvalds **  SIDE EFFECTS:
20831da177e4SLinus Torvalds **
20841da177e4SLinus Torvalds **      Local storage for device configuration information
20851da177e4SLinus Torvalds **	is initialized.
20861da177e4SLinus Torvalds **
20871da177e4SLinus Torvalds **--
20881da177e4SLinus Torvalds */
20891da177e4SLinus Torvalds static void __init SMC37c669_init_local_config ( void )
20901da177e4SLinus Torvalds {
20911da177e4SLinus Torvalds     SMC37c669_SERIAL_BASE_ADDRESS_REGISTER uart_base;
20921da177e4SLinus Torvalds     SMC37c669_SERIAL_IRQ_REGISTER uart_irqs;
20931da177e4SLinus Torvalds     SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER ppt_base;
20941da177e4SLinus Torvalds     SMC37c669_PARALLEL_FDC_IRQ_REGISTER ppt_fdc_irqs;
20951da177e4SLinus Torvalds     SMC37c669_PARALLEL_FDC_DRQ_REGISTER ppt_fdc_drqs;
20961da177e4SLinus Torvalds     SMC37c669_FDC_BASE_ADDRESS_REGISTER fdc_base;
20971da177e4SLinus Torvalds     SMC37c669_IDE_ADDRESS_REGISTER ide_base;
20981da177e4SLinus Torvalds     SMC37c669_IDE_ADDRESS_REGISTER ide_alt;
20991da177e4SLinus Torvalds 
21001da177e4SLinus Torvalds /*
21011da177e4SLinus Torvalds ** Get serial port 1 base address
21021da177e4SLinus Torvalds */
21031da177e4SLinus Torvalds     uart_base.as_uchar =
21041da177e4SLinus Torvalds 	SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
21051da177e4SLinus Torvalds /*
21061da177e4SLinus Torvalds ** Get IRQs for serial ports 1 & 2
21071da177e4SLinus Torvalds */
21081da177e4SLinus Torvalds     uart_irqs.as_uchar =
21091da177e4SLinus Torvalds 	SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
21101da177e4SLinus Torvalds /*
21111da177e4SLinus Torvalds ** Store local configuration information for serial port 1
21121da177e4SLinus Torvalds */
21131da177e4SLinus Torvalds     local_config[SERIAL_0].port1 = uart_base.by_field.addr9_3 << 3;
21141da177e4SLinus Torvalds     local_config[SERIAL_0].irq =
21151da177e4SLinus Torvalds 	SMC37c669_xlate_irq(
21161da177e4SLinus Torvalds 	    SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart1_irq )
21171da177e4SLinus Torvalds 	);
21181da177e4SLinus Torvalds /*
21191da177e4SLinus Torvalds ** Get serial port 2 base address
21201da177e4SLinus Torvalds */
21211da177e4SLinus Torvalds     uart_base.as_uchar =
21221da177e4SLinus Torvalds 	SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
21231da177e4SLinus Torvalds /*
21241da177e4SLinus Torvalds ** Store local configuration information for serial port 2
21251da177e4SLinus Torvalds */
21261da177e4SLinus Torvalds     local_config[SERIAL_1].port1 = uart_base.by_field.addr9_3 << 3;
21271da177e4SLinus Torvalds     local_config[SERIAL_1].irq =
21281da177e4SLinus Torvalds 	SMC37c669_xlate_irq(
21291da177e4SLinus Torvalds 	    SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart2_irq )
21301da177e4SLinus Torvalds 	);
21311da177e4SLinus Torvalds /*
21321da177e4SLinus Torvalds ** Get parallel port base address
21331da177e4SLinus Torvalds */
21341da177e4SLinus Torvalds     ppt_base.as_uchar =
21351da177e4SLinus Torvalds 	SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
21361da177e4SLinus Torvalds /*
21371da177e4SLinus Torvalds ** Get IRQs for parallel port and floppy controller
21381da177e4SLinus Torvalds */
21391da177e4SLinus Torvalds     ppt_fdc_irqs.as_uchar =
21401da177e4SLinus Torvalds 	SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
21411da177e4SLinus Torvalds /*
21421da177e4SLinus Torvalds ** Get DRQs for parallel port and floppy controller
21431da177e4SLinus Torvalds */
21441da177e4SLinus Torvalds     ppt_fdc_drqs.as_uchar =
21451da177e4SLinus Torvalds 	SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
21461da177e4SLinus Torvalds /*
21471da177e4SLinus Torvalds ** Store local configuration information for parallel port
21481da177e4SLinus Torvalds */
21491da177e4SLinus Torvalds     local_config[PARALLEL_0].port1 = ppt_base.by_field.addr9_2 << 2;
21501da177e4SLinus Torvalds     local_config[PARALLEL_0].irq =
21511da177e4SLinus Torvalds 	SMC37c669_xlate_irq(
21521da177e4SLinus Torvalds 	    SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.ppt_irq )
21531da177e4SLinus Torvalds 	);
21541da177e4SLinus Torvalds     local_config[PARALLEL_0].drq =
21551da177e4SLinus Torvalds 	SMC37c669_xlate_drq(
21561da177e4SLinus Torvalds 	    SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.ppt_drq )
21571da177e4SLinus Torvalds 	);
21581da177e4SLinus Torvalds /*
21591da177e4SLinus Torvalds ** Get floppy controller base address
21601da177e4SLinus Torvalds */
21611da177e4SLinus Torvalds     fdc_base.as_uchar =
21621da177e4SLinus Torvalds 	SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
21631da177e4SLinus Torvalds /*
21641da177e4SLinus Torvalds ** Store local configuration information for floppy controller
21651da177e4SLinus Torvalds */
21661da177e4SLinus Torvalds     local_config[FLOPPY_0].port1 = fdc_base.by_field.addr9_4 << 4;
21671da177e4SLinus Torvalds     local_config[FLOPPY_0].irq =
21681da177e4SLinus Torvalds 	SMC37c669_xlate_irq(
21691da177e4SLinus Torvalds 	    SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.fdc_irq )
21701da177e4SLinus Torvalds 	);
21711da177e4SLinus Torvalds     local_config[FLOPPY_0].drq =
21721da177e4SLinus Torvalds 	SMC37c669_xlate_drq(
21731da177e4SLinus Torvalds 	    SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.fdc_drq )
21741da177e4SLinus Torvalds 	);
21751da177e4SLinus Torvalds /*
21761da177e4SLinus Torvalds ** Get IDE controller base address
21771da177e4SLinus Torvalds */
21781da177e4SLinus Torvalds     ide_base.as_uchar =
21791da177e4SLinus Torvalds 	SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
21801da177e4SLinus Torvalds /*
21811da177e4SLinus Torvalds ** Get IDE alternate status base address
21821da177e4SLinus Torvalds */
21831da177e4SLinus Torvalds     ide_alt.as_uchar =
21841da177e4SLinus Torvalds 	SMC37c669_read_config( SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX );
21851da177e4SLinus Torvalds /*
21861da177e4SLinus Torvalds ** Store local configuration information for IDE controller
21871da177e4SLinus Torvalds */
21881da177e4SLinus Torvalds     local_config[IDE_0].port1 = ide_base.by_field.addr9_4 << 4;
21891da177e4SLinus Torvalds     local_config[IDE_0].port2 = ide_alt.by_field.addr9_4 << 4;
21901da177e4SLinus Torvalds     local_config[IDE_0].irq = 14;
21911da177e4SLinus Torvalds }
21921da177e4SLinus Torvalds 
21931da177e4SLinus Torvalds 
21941da177e4SLinus Torvalds /*
21951da177e4SLinus Torvalds **++
21961da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
21971da177e4SLinus Torvalds **
21981da177e4SLinus Torvalds **      This function returns a pointer to the local shadow
21991da177e4SLinus Torvalds **	configuration of the requested device function.
22001da177e4SLinus Torvalds **
22011da177e4SLinus Torvalds **  FORMAL PARAMETERS:
22021da177e4SLinus Torvalds **
22031da177e4SLinus Torvalds **      func:
22041da177e4SLinus Torvalds **          Which device function
22051da177e4SLinus Torvalds **
22061da177e4SLinus Torvalds **  RETURN VALUE:
22071da177e4SLinus Torvalds **
22081da177e4SLinus Torvalds **      Returns a pointer to the DEVICE_CONFIG structure for the
22091da177e4SLinus Torvalds **	requested function, otherwise, NULL.
22101da177e4SLinus Torvalds **
22111da177e4SLinus Torvalds **  SIDE EFFECTS:
22121da177e4SLinus Torvalds **
22131da177e4SLinus Torvalds **      {@description or none@}
22141da177e4SLinus Torvalds **
22151da177e4SLinus Torvalds **--
22161da177e4SLinus Torvalds */
22171da177e4SLinus Torvalds static struct DEVICE_CONFIG * __init SMC37c669_get_config( unsigned int func )
22181da177e4SLinus Torvalds {
22191da177e4SLinus Torvalds     struct DEVICE_CONFIG *cp = NULL;
22201da177e4SLinus Torvalds 
22211da177e4SLinus Torvalds     switch ( func ) {
22221da177e4SLinus Torvalds     	case SERIAL_0:
22231da177e4SLinus Torvalds 	    cp = &local_config[ SERIAL_0 ];
22241da177e4SLinus Torvalds 	    break;
22251da177e4SLinus Torvalds 	case SERIAL_1:
22261da177e4SLinus Torvalds 	    cp = &local_config[ SERIAL_1 ];
22271da177e4SLinus Torvalds 	    break;
22281da177e4SLinus Torvalds 	case PARALLEL_0:
22291da177e4SLinus Torvalds 	    cp = &local_config[ PARALLEL_0 ];
22301da177e4SLinus Torvalds 	    break;
22311da177e4SLinus Torvalds 	case FLOPPY_0:
22321da177e4SLinus Torvalds 	    cp = &local_config[ FLOPPY_0 ];
22331da177e4SLinus Torvalds 	    break;
22341da177e4SLinus Torvalds 	case IDE_0:
22351da177e4SLinus Torvalds 	    cp = &local_config[ IDE_0 ];
22361da177e4SLinus Torvalds 	    break;
22371da177e4SLinus Torvalds     }
22381da177e4SLinus Torvalds     return cp;
22391da177e4SLinus Torvalds }
22401da177e4SLinus Torvalds 
22411da177e4SLinus Torvalds /*
22421da177e4SLinus Torvalds **++
22431da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
22441da177e4SLinus Torvalds **
22451da177e4SLinus Torvalds **      This function translates IRQs back and forth between ISA
22461da177e4SLinus Torvalds **	IRQs and SMC37c669 device IRQs.
22471da177e4SLinus Torvalds **
22481da177e4SLinus Torvalds **  FORMAL PARAMETERS:
22491da177e4SLinus Torvalds **
22501da177e4SLinus Torvalds **      irq:
22511da177e4SLinus Torvalds **          The IRQ to translate
22521da177e4SLinus Torvalds **
22531da177e4SLinus Torvalds **  RETURN VALUE:
22541da177e4SLinus Torvalds **
22551da177e4SLinus Torvalds **      Returns the translated IRQ, otherwise, returns -1.
22561da177e4SLinus Torvalds **
22571da177e4SLinus Torvalds **  SIDE EFFECTS:
22581da177e4SLinus Torvalds **
22591da177e4SLinus Torvalds **      {@description or none@}
22601da177e4SLinus Torvalds **
22611da177e4SLinus Torvalds **--
22621da177e4SLinus Torvalds */
22631da177e4SLinus Torvalds static int __init SMC37c669_xlate_irq ( int irq )
22641da177e4SLinus Torvalds {
22651da177e4SLinus Torvalds     int i, translated_irq = -1;
22661da177e4SLinus Torvalds 
22671da177e4SLinus Torvalds     if ( SMC37c669_IS_DEVICE_IRQ( irq ) ) {
22681da177e4SLinus Torvalds /*
22691da177e4SLinus Torvalds ** We are translating a device IRQ to an ISA IRQ
22701da177e4SLinus Torvalds */
22711da177e4SLinus Torvalds     	for ( i = 0; ( SMC37c669_irq_table[i].device_irq != -1 ) || ( SMC37c669_irq_table[i].isa_irq != -1 ); i++ ) {
22721da177e4SLinus Torvalds 	    if ( irq == SMC37c669_irq_table[i].device_irq ) {
22731da177e4SLinus Torvalds 	    	translated_irq = SMC37c669_irq_table[i].isa_irq;
22741da177e4SLinus Torvalds 		break;
22751da177e4SLinus Torvalds 	    }
22761da177e4SLinus Torvalds 	}
22771da177e4SLinus Torvalds     }
22781da177e4SLinus Torvalds     else {
22791da177e4SLinus Torvalds /*
22801da177e4SLinus Torvalds ** We are translating an ISA IRQ to a device IRQ
22811da177e4SLinus Torvalds */
22821da177e4SLinus Torvalds     	for ( i = 0; ( SMC37c669_irq_table[i].isa_irq != -1 ) || ( SMC37c669_irq_table[i].device_irq != -1 ); i++ ) {
22831da177e4SLinus Torvalds 	    if ( irq == SMC37c669_irq_table[i].isa_irq ) {
22841da177e4SLinus Torvalds 	    	translated_irq = SMC37c669_irq_table[i].device_irq;
22851da177e4SLinus Torvalds 		break;
22861da177e4SLinus Torvalds 	    }
22871da177e4SLinus Torvalds 	}
22881da177e4SLinus Torvalds     }
22891da177e4SLinus Torvalds     return translated_irq;
22901da177e4SLinus Torvalds }
22911da177e4SLinus Torvalds 
22921da177e4SLinus Torvalds 
22931da177e4SLinus Torvalds /*
22941da177e4SLinus Torvalds **++
22951da177e4SLinus Torvalds **  FUNCTIONAL DESCRIPTION:
22961da177e4SLinus Torvalds **
22971da177e4SLinus Torvalds **      This function translates DMA channels back and forth between
22981da177e4SLinus Torvalds **	ISA DMA channels and SMC37c669 device DMA channels.
22991da177e4SLinus Torvalds **
23001da177e4SLinus Torvalds **  FORMAL PARAMETERS:
23011da177e4SLinus Torvalds **
23021da177e4SLinus Torvalds **      drq:
23031da177e4SLinus Torvalds **          The DMA channel to translate
23041da177e4SLinus Torvalds **
23051da177e4SLinus Torvalds **  RETURN VALUE:
23061da177e4SLinus Torvalds **
23071da177e4SLinus Torvalds **      Returns the translated DMA channel, otherwise, returns -1
23081da177e4SLinus Torvalds **
23091da177e4SLinus Torvalds **  SIDE EFFECTS:
23101da177e4SLinus Torvalds **
23111da177e4SLinus Torvalds **      {@description or none@}
23121da177e4SLinus Torvalds **
23131da177e4SLinus Torvalds **--
23141da177e4SLinus Torvalds */
23151da177e4SLinus Torvalds static int __init SMC37c669_xlate_drq ( int drq )
23161da177e4SLinus Torvalds {
23171da177e4SLinus Torvalds     int i, translated_drq = -1;
23181da177e4SLinus Torvalds 
23191da177e4SLinus Torvalds     if ( SMC37c669_IS_DEVICE_DRQ( drq ) ) {
23201da177e4SLinus Torvalds /*
23211da177e4SLinus Torvalds ** We are translating a device DMA channel to an ISA DMA channel
23221da177e4SLinus Torvalds */
23231da177e4SLinus Torvalds     	for ( i = 0; ( SMC37c669_drq_table[i].device_drq != -1 ) || ( SMC37c669_drq_table[i].isa_drq != -1 ); i++ ) {
23241da177e4SLinus Torvalds 	    if ( drq == SMC37c669_drq_table[i].device_drq ) {
23251da177e4SLinus Torvalds 	    	translated_drq = SMC37c669_drq_table[i].isa_drq;
23261da177e4SLinus Torvalds 		break;
23271da177e4SLinus Torvalds 	    }
23281da177e4SLinus Torvalds 	}
23291da177e4SLinus Torvalds     }
23301da177e4SLinus Torvalds     else {
23311da177e4SLinus Torvalds /*
23321da177e4SLinus Torvalds ** We are translating an ISA DMA channel to a device DMA channel
23331da177e4SLinus Torvalds */
23341da177e4SLinus Torvalds     	for ( i = 0; ( SMC37c669_drq_table[i].isa_drq != -1 ) || ( SMC37c669_drq_table[i].device_drq != -1 ); i++ ) {
23351da177e4SLinus Torvalds 	    if ( drq == SMC37c669_drq_table[i].isa_drq ) {
23361da177e4SLinus Torvalds 	    	translated_drq = SMC37c669_drq_table[i].device_drq;
23371da177e4SLinus Torvalds 		break;
23381da177e4SLinus Torvalds 	    }
23391da177e4SLinus Torvalds 	}
23401da177e4SLinus Torvalds     }
23411da177e4SLinus Torvalds     return translated_drq;
23421da177e4SLinus Torvalds }
23431da177e4SLinus Torvalds 
23441da177e4SLinus Torvalds #if 0
23451da177e4SLinus Torvalds int __init smcc669_init ( void )
23461da177e4SLinus Torvalds {
23471da177e4SLinus Torvalds     struct INODE *ip;
23481da177e4SLinus Torvalds 
23491da177e4SLinus Torvalds     allocinode( smc_ddb.name, 1, &ip );
23501da177e4SLinus Torvalds     ip->dva = &smc_ddb;
23511da177e4SLinus Torvalds     ip->attr = ATTR$M_WRITE | ATTR$M_READ;
23521da177e4SLinus Torvalds     ip->len[0] = 0x30;
23531da177e4SLinus Torvalds     ip->misc = 0;
23541da177e4SLinus Torvalds     INODE_UNLOCK( ip );
23551da177e4SLinus Torvalds 
23561da177e4SLinus Torvalds     return msg_success;
23571da177e4SLinus Torvalds }
23581da177e4SLinus Torvalds 
23591da177e4SLinus Torvalds int __init smcc669_open( struct FILE *fp, char *info, char *next, char *mode )
23601da177e4SLinus Torvalds {
23611da177e4SLinus Torvalds     struct INODE *ip;
23621da177e4SLinus Torvalds /*
23631da177e4SLinus Torvalds ** Allow multiple readers but only one writer.  ip->misc keeps track
23641da177e4SLinus Torvalds ** of the number of writers
23651da177e4SLinus Torvalds */
23661da177e4SLinus Torvalds     ip = fp->ip;
23671da177e4SLinus Torvalds     INODE_LOCK( ip );
23681da177e4SLinus Torvalds     if ( fp->mode & ATTR$M_WRITE ) {
23691da177e4SLinus Torvalds 	if ( ip->misc ) {
23701da177e4SLinus Torvalds 	    INODE_UNLOCK( ip );
23711da177e4SLinus Torvalds 	    return msg_failure;	    /* too many writers */
23721da177e4SLinus Torvalds 	}
23731da177e4SLinus Torvalds 	ip->misc++;
23741da177e4SLinus Torvalds     }
23751da177e4SLinus Torvalds /*
23761da177e4SLinus Torvalds ** Treat the information field as a byte offset
23771da177e4SLinus Torvalds */
23781da177e4SLinus Torvalds     *fp->offset = xtoi( info );
23791da177e4SLinus Torvalds     INODE_UNLOCK( ip );
23801da177e4SLinus Torvalds 
23811da177e4SLinus Torvalds     return msg_success;
23821da177e4SLinus Torvalds }
23831da177e4SLinus Torvalds 
23841da177e4SLinus Torvalds int __init smcc669_close( struct FILE *fp )
23851da177e4SLinus Torvalds {
23861da177e4SLinus Torvalds     struct INODE *ip;
23871da177e4SLinus Torvalds 
23881da177e4SLinus Torvalds     ip = fp->ip;
23891da177e4SLinus Torvalds     if ( fp->mode & ATTR$M_WRITE ) {
23901da177e4SLinus Torvalds 	INODE_LOCK( ip );
23911da177e4SLinus Torvalds 	ip->misc--;
23921da177e4SLinus Torvalds 	INODE_UNLOCK( ip );
23931da177e4SLinus Torvalds     }
23941da177e4SLinus Torvalds     return msg_success;
23951da177e4SLinus Torvalds }
23961da177e4SLinus Torvalds 
23971da177e4SLinus Torvalds int __init smcc669_read( struct FILE *fp, int size, int number, unsigned char *buf )
23981da177e4SLinus Torvalds {
23991da177e4SLinus Torvalds     int i;
24001da177e4SLinus Torvalds     int length;
24011da177e4SLinus Torvalds     int nbytes;
24021da177e4SLinus Torvalds     struct INODE *ip;
24031da177e4SLinus Torvalds 
24041da177e4SLinus Torvalds /*
24051da177e4SLinus Torvalds ** Always access a byte at a time
24061da177e4SLinus Torvalds */
24071da177e4SLinus Torvalds     ip = fp->ip;
24081da177e4SLinus Torvalds     length = size * number;
24091da177e4SLinus Torvalds     nbytes = 0;
24101da177e4SLinus Torvalds 
24111da177e4SLinus Torvalds     SMC37c669_config_mode( TRUE );
24121da177e4SLinus Torvalds     for ( i = 0; i < length; i++ ) {
24131da177e4SLinus Torvalds 	if ( !inrange( *fp->offset, 0, ip->len[0] ) )
24141da177e4SLinus Torvalds 	    break;
24151da177e4SLinus Torvalds 	*buf++ = SMC37c669_read_config( *fp->offset );
24161da177e4SLinus Torvalds 	*fp->offset += 1;
24171da177e4SLinus Torvalds 	nbytes++;
24181da177e4SLinus Torvalds     }
24191da177e4SLinus Torvalds     SMC37c669_config_mode( FALSE );
24201da177e4SLinus Torvalds     return nbytes;
24211da177e4SLinus Torvalds }
24221da177e4SLinus Torvalds 
24231da177e4SLinus Torvalds int __init smcc669_write( struct FILE *fp, int size, int number, unsigned char *buf )
24241da177e4SLinus Torvalds {
24251da177e4SLinus Torvalds     int i;
24261da177e4SLinus Torvalds     int length;
24271da177e4SLinus Torvalds     int nbytes;
24281da177e4SLinus Torvalds     struct INODE *ip;
24291da177e4SLinus Torvalds /*
24301da177e4SLinus Torvalds ** Always access a byte at a time
24311da177e4SLinus Torvalds */
24321da177e4SLinus Torvalds     ip = fp->ip;
24331da177e4SLinus Torvalds     length = size * number;
24341da177e4SLinus Torvalds     nbytes = 0;
24351da177e4SLinus Torvalds 
24361da177e4SLinus Torvalds     SMC37c669_config_mode( TRUE );
24371da177e4SLinus Torvalds     for ( i = 0; i < length; i++ ) {
24381da177e4SLinus Torvalds 	if ( !inrange( *fp->offset, 0, ip->len[0] ) )
24391da177e4SLinus Torvalds 	    break;
24401da177e4SLinus Torvalds 	SMC37c669_write_config( *fp->offset, *buf );
24411da177e4SLinus Torvalds 	*fp->offset += 1;
24421da177e4SLinus Torvalds 	buf++;
24431da177e4SLinus Torvalds 	nbytes++;
24441da177e4SLinus Torvalds     }
24451da177e4SLinus Torvalds     SMC37c669_config_mode( FALSE );
24461da177e4SLinus Torvalds     return nbytes;
24471da177e4SLinus Torvalds }
24481da177e4SLinus Torvalds #endif
24491da177e4SLinus Torvalds 
24501da177e4SLinus Torvalds void __init
24511da177e4SLinus Torvalds SMC37c669_dump_registers(void)
24521da177e4SLinus Torvalds {
24531da177e4SLinus Torvalds   int i;
24541da177e4SLinus Torvalds   for (i = 0; i <= 0x29; i++)
24551da177e4SLinus Torvalds     printk("-- CR%02x : %02x\n", i, SMC37c669_read_config(i));
24561da177e4SLinus Torvalds }
24571da177e4SLinus Torvalds /*+
24581da177e4SLinus Torvalds  * ============================================================================
24591da177e4SLinus Torvalds  * = SMC_init - SMC37c669 Super I/O controller initialization                 =
24601da177e4SLinus Torvalds  * ============================================================================
24611da177e4SLinus Torvalds  *
24621da177e4SLinus Torvalds  * OVERVIEW:
24631da177e4SLinus Torvalds  *
24641da177e4SLinus Torvalds  *      This routine configures and enables device functions on the
24651da177e4SLinus Torvalds  *      SMC37c669 Super I/O controller.
24661da177e4SLinus Torvalds  *
24671da177e4SLinus Torvalds  * FORM OF CALL:
24681da177e4SLinus Torvalds  *
24691da177e4SLinus Torvalds  *      SMC_init( );
24701da177e4SLinus Torvalds  *
24711da177e4SLinus Torvalds  * RETURNS:
24721da177e4SLinus Torvalds  *
24731da177e4SLinus Torvalds  *      Nothing
24741da177e4SLinus Torvalds  *
24751da177e4SLinus Torvalds  * ARGUMENTS:
24761da177e4SLinus Torvalds  *
24771da177e4SLinus Torvalds  *      None
24781da177e4SLinus Torvalds  *
24791da177e4SLinus Torvalds  * SIDE EFFECTS:
24801da177e4SLinus Torvalds  *
24811da177e4SLinus Torvalds  *      None
24821da177e4SLinus Torvalds  *
24831da177e4SLinus Torvalds  */
24841da177e4SLinus Torvalds void __init SMC669_Init ( int index )
24851da177e4SLinus Torvalds {
24861da177e4SLinus Torvalds     SMC37c669_CONFIG_REGS *SMC_base;
24871da177e4SLinus Torvalds     unsigned long flags;
24881da177e4SLinus Torvalds 
24891da177e4SLinus Torvalds     local_irq_save(flags);
24901da177e4SLinus Torvalds     if ( ( SMC_base = SMC37c669_detect( index ) ) != NULL ) {
24911da177e4SLinus Torvalds #if SMC_DEBUG
24921da177e4SLinus Torvalds 	SMC37c669_config_mode( TRUE );
24931da177e4SLinus Torvalds 	SMC37c669_dump_registers( );
24941da177e4SLinus Torvalds 	SMC37c669_config_mode( FALSE );
24951da177e4SLinus Torvalds         SMC37c669_display_device_info( );
24961da177e4SLinus Torvalds #endif
24971da177e4SLinus Torvalds         SMC37c669_disable_device( SERIAL_0 );
24981da177e4SLinus Torvalds         SMC37c669_configure_device(
24991da177e4SLinus Torvalds             SERIAL_0,
25001da177e4SLinus Torvalds             COM1_BASE,
25011da177e4SLinus Torvalds             COM1_IRQ,
25021da177e4SLinus Torvalds             -1
25031da177e4SLinus Torvalds         );
25041da177e4SLinus Torvalds         SMC37c669_enable_device( SERIAL_0 );
25051da177e4SLinus Torvalds 
25061da177e4SLinus Torvalds         SMC37c669_disable_device( SERIAL_1 );
25071da177e4SLinus Torvalds         SMC37c669_configure_device(
25081da177e4SLinus Torvalds             SERIAL_1,
25091da177e4SLinus Torvalds             COM2_BASE,
25101da177e4SLinus Torvalds             COM2_IRQ,
25111da177e4SLinus Torvalds             -1
25121da177e4SLinus Torvalds         );
25131da177e4SLinus Torvalds         SMC37c669_enable_device( SERIAL_1 );
25141da177e4SLinus Torvalds 
25151da177e4SLinus Torvalds         SMC37c669_disable_device( PARALLEL_0 );
25161da177e4SLinus Torvalds         SMC37c669_configure_device(
25171da177e4SLinus Torvalds             PARALLEL_0,
25181da177e4SLinus Torvalds             PARP_BASE,
25191da177e4SLinus Torvalds             PARP_IRQ,
25201da177e4SLinus Torvalds             PARP_DRQ
25211da177e4SLinus Torvalds         );
25221da177e4SLinus Torvalds         SMC37c669_enable_device( PARALLEL_0 );
25231da177e4SLinus Torvalds 
25241da177e4SLinus Torvalds         SMC37c669_disable_device( FLOPPY_0 );
25251da177e4SLinus Torvalds         SMC37c669_configure_device(
25261da177e4SLinus Torvalds             FLOPPY_0,
25271da177e4SLinus Torvalds             FDC_BASE,
25281da177e4SLinus Torvalds             FDC_IRQ,
25291da177e4SLinus Torvalds             FDC_DRQ
25301da177e4SLinus Torvalds         );
25311da177e4SLinus Torvalds         SMC37c669_enable_device( FLOPPY_0 );
25321da177e4SLinus Torvalds 
25331da177e4SLinus Torvalds 	/* Wake up sometimes forgotten floppy, especially on DP264. */
25341da177e4SLinus Torvalds 	outb(0xc, 0x3f2);
25351da177e4SLinus Torvalds 
25361da177e4SLinus Torvalds         SMC37c669_disable_device( IDE_0 );
25371da177e4SLinus Torvalds 
25381da177e4SLinus Torvalds #if SMC_DEBUG
25391da177e4SLinus Torvalds 	SMC37c669_config_mode( TRUE );
25401da177e4SLinus Torvalds 	SMC37c669_dump_registers( );
25411da177e4SLinus Torvalds 	SMC37c669_config_mode( FALSE );
25421da177e4SLinus Torvalds         SMC37c669_display_device_info( );
25431da177e4SLinus Torvalds #endif
25441da177e4SLinus Torvalds 	local_irq_restore(flags);
25455f0e3da6SRandy Dunlap         printk( "SMC37c669 Super I/O Controller found @ 0x%p\n",
25465f0e3da6SRandy Dunlap 		SMC_base );
25471da177e4SLinus Torvalds     }
25481da177e4SLinus Torvalds     else {
25491da177e4SLinus Torvalds 	local_irq_restore(flags);
25501da177e4SLinus Torvalds #if SMC_DEBUG
25511da177e4SLinus Torvalds         printk( "No SMC37c669 Super I/O Controller found\n" );
25521da177e4SLinus Torvalds #endif
25531da177e4SLinus Torvalds     }
25541da177e4SLinus Torvalds }
2555