4 #include <linux/kernel.h>
13 #include <asm/segment.h>
16 # define DBG_DEVS(args) printk args
18 # define DBG_DEVS(args)
71 #define SMC37c669_DEVICE_IRQ_MASK 0x80000000
72 #define SMC37c669_DEVICE_IRQ( __i ) \
73 ((SMC37c669_DEVICE_IRQ_MASK) | (__i))
74 #define SMC37c669_IS_DEVICE_IRQ(__i) \
75 (((__i) & (SMC37c669_DEVICE_IRQ_MASK)) == (SMC37c669_DEVICE_IRQ_MASK))
76 #define SMC37c669_RAW_DEVICE_IRQ(__i) \
77 ((__i) & ~(SMC37c669_DEVICE_IRQ_MASK))
85 #define SMC37c669_DEVICE_DRQ_MASK 0x80000000
86 #define SMC37c669_DEVICE_DRQ(__d) \
87 ((SMC37c669_DEVICE_DRQ_MASK) | (__d))
88 #define SMC37c669_IS_DEVICE_DRQ(__d) \
89 (((__d) & (SMC37c669_DEVICE_DRQ_MASK)) == (SMC37c669_DEVICE_DRQ_MASK))
90 #define SMC37c669_RAW_DEVICE_DRQ(__d) \
91 ((__d) & ~(SMC37c669_DEVICE_DRQ_MASK))
93 #define SMC37c669_DEVICE_ID 0x3
108 #define COM1_BASE 0x3F8
110 #define COM2_BASE 0x2F8
112 #define PARP_BASE 0x3BC
115 #define FDC_BASE 0x3F0
122 #define SMC37c669_CONFIG_ON_KEY 0x55
123 #define SMC37c669_CONFIG_OFF_KEY 0xAA
128 #define SMC37c669_DEVICE_IRQ_A ( SMC37c669_DEVICE_IRQ( 0x01 ) )
129 #define SMC37c669_DEVICE_IRQ_B ( SMC37c669_DEVICE_IRQ( 0x02 ) )
130 #define SMC37c669_DEVICE_IRQ_C ( SMC37c669_DEVICE_IRQ( 0x03 ) )
131 #define SMC37c669_DEVICE_IRQ_D ( SMC37c669_DEVICE_IRQ( 0x04 ) )
132 #define SMC37c669_DEVICE_IRQ_E ( SMC37c669_DEVICE_IRQ( 0x05 ) )
133 #define SMC37c669_DEVICE_IRQ_F ( SMC37c669_DEVICE_IRQ( 0x06 ) )
135 #define SMC37c669_DEVICE_IRQ_H ( SMC37c669_DEVICE_IRQ( 0x08 ) )
140 #define SMC37c669_DEVICE_DRQ_A ( SMC37c669_DEVICE_DRQ( 0x01 ) )
141 #define SMC37c669_DEVICE_DRQ_B ( SMC37c669_DEVICE_DRQ( 0x02 ) )
142 #define SMC37c669_DEVICE_DRQ_C ( SMC37c669_DEVICE_DRQ( 0x03 ) )
147 #define SMC37c669_CR00_INDEX 0x00
148 #define SMC37c669_CR01_INDEX 0x01
149 #define SMC37c669_CR02_INDEX 0x02
150 #define SMC37c669_CR03_INDEX 0x03
151 #define SMC37c669_CR04_INDEX 0x04
152 #define SMC37c669_CR05_INDEX 0x05
153 #define SMC37c669_CR06_INDEX 0x06
154 #define SMC37c669_CR07_INDEX 0x07
155 #define SMC37c669_CR08_INDEX 0x08
156 #define SMC37c669_CR09_INDEX 0x09
157 #define SMC37c669_CR0A_INDEX 0x0A
158 #define SMC37c669_CR0B_INDEX 0x0B
159 #define SMC37c669_CR0C_INDEX 0x0C
160 #define SMC37c669_CR0D_INDEX 0x0D
161 #define SMC37c669_CR0E_INDEX 0x0E
162 #define SMC37c669_CR0F_INDEX 0x0F
163 #define SMC37c669_CR10_INDEX 0x10
164 #define SMC37c669_CR11_INDEX 0x11
165 #define SMC37c669_CR12_INDEX 0x12
166 #define SMC37c669_CR13_INDEX 0x13
167 #define SMC37c669_CR14_INDEX 0x14
168 #define SMC37c669_CR15_INDEX 0x15
169 #define SMC37c669_CR16_INDEX 0x16
170 #define SMC37c669_CR17_INDEX 0x17
171 #define SMC37c669_CR18_INDEX 0x18
172 #define SMC37c669_CR19_INDEX 0x19
173 #define SMC37c669_CR1A_INDEX 0x1A
174 #define SMC37c669_CR1B_INDEX 0x1B
175 #define SMC37c669_CR1C_INDEX 0x1C
176 #define SMC37c669_CR1D_INDEX 0x1D
177 #define SMC37c669_CR1E_INDEX 0x1E
178 #define SMC37c669_CR1F_INDEX 0x1F
179 #define SMC37c669_CR20_INDEX 0x20
180 #define SMC37c669_CR21_INDEX 0x21
181 #define SMC37c669_CR22_INDEX 0x22
182 #define SMC37c669_CR23_INDEX 0x23
183 #define SMC37c669_CR24_INDEX 0x24
184 #define SMC37c669_CR25_INDEX 0x25
185 #define SMC37c669_CR26_INDEX 0x26
186 #define SMC37c669_CR27_INDEX 0x27
187 #define SMC37c669_CR28_INDEX 0x28
188 #define SMC37c669_CR29_INDEX 0x29
193 #define SMC37c669_DEVICE_ID_INDEX SMC37c669_CR0D_INDEX
194 #define SMC37c669_DEVICE_REVISION_INDEX SMC37c669_CR0E_INDEX
195 #define SMC37c669_FDC_BASE_ADDRESS_INDEX SMC37c669_CR20_INDEX
196 #define SMC37c669_IDE_BASE_ADDRESS_INDEX SMC37c669_CR21_INDEX
197 #define SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX SMC37c669_CR22_INDEX
198 #define SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX SMC37c669_CR23_INDEX
199 #define SMC37c669_SERIAL0_BASE_ADDRESS_INDEX SMC37c669_CR24_INDEX
200 #define SMC37c669_SERIAL1_BASE_ADDRESS_INDEX SMC37c669_CR25_INDEX
201 #define SMC37c669_PARALLEL_FDC_DRQ_INDEX SMC37c669_CR26_INDEX
202 #define SMC37c669_PARALLEL_FDC_IRQ_INDEX SMC37c669_CR27_INDEX
203 #define SMC37c669_SERIAL_IRQ_INDEX SMC37c669_CR28_INDEX
944 #define wb( _x_, _y_ ) outb( _y_, (unsigned int)((unsigned long)_x_) )
945 #define rb( _x_ ) inb( (unsigned int)((unsigned long)_x_) )
957 static struct DEVICE_CONFIG {
967 static unsigned long SMC37c669_Addresses[]
__initdata =
1024 SMC37c669_default_irq_table,
1025 SMC37c669_monet_irq_table
1054 static unsigned int SMC37c669_is_device_enabled(
1059 static unsigned int SMC37c669_get_device_config(
1067 static void SMC37c669_config_mode(
1071 static unsigned char SMC37c669_read_config(
1075 static void SMC37c669_write_config(
1076 unsigned char index,
1080 static void SMC37c669_init_local_config(
void );
1082 static struct DEVICE_CONFIG *SMC37c669_get_config(
1086 static int SMC37c669_xlate_irq(
1090 static int SMC37c669_xlate_drq(
1123 for ( i = 0; SMC37c669_Addresses[
i] != 0; i++ ) {
1134 SMC37c669_config_mode(
TRUE );
1142 SMC37c669_config_mode(
FALSE );
1151 SMC37c669_irq_table = SMC37c669_irq_tables[
index ];
1152 SMC37c669_drq_table = SMC37c669_default_drq_table;
1166 SMC37c669_config_mode(
TRUE );
1170 SMC37c669_init_local_config( );
1174 SMC37c669_config_mode(
FALSE );
1228 unsigned int ret_val =
FALSE;
1232 SMC37c669_config_mode(
TRUE );
1246 SMC37c669_xlate_irq( local_config[ func ].irq )
1254 base_addr.
by_field.addr9_3 = local_config[
func ].port1 >> 3;
1256 SMC37c669_write_config(
1275 SMC37c669_xlate_irq( local_config[ func ].irq )
1283 base_addr.
by_field.addr9_3 = local_config[
func ].port1 >> 3;
1285 SMC37c669_write_config(
1305 SMC37c669_xlate_drq( local_config[ func ].drq )
1308 SMC37c669_write_config(
1320 SMC37c669_xlate_irq( local_config[ func ].irq )
1323 SMC37c669_write_config(
1331 base_addr.
by_field.addr9_2 = local_config[
func ].port1 >> 2;
1333 SMC37c669_write_config(
1353 SMC37c669_xlate_drq( local_config[ func ].drq )
1356 SMC37c669_write_config(
1368 SMC37c669_xlate_irq( local_config[ func ].irq )
1371 SMC37c669_write_config(
1379 base_addr.
by_field.addr9_4 = local_config[
func ].port1 >> 4;
1381 SMC37c669_write_config(
1395 ide_addr.
by_field.addr9_4 = local_config[
func ].port2 >> 4;
1397 SMC37c669_write_config(
1405 ide_addr.
by_field.addr9_4 = local_config[
func ].port1 >> 4;
1407 SMC37c669_write_config(
1418 SMC37c669_config_mode(
FALSE );
1456 unsigned int ret_val =
FALSE;
1461 SMC37c669_config_mode(
TRUE );
1480 SMC37c669_write_config(
1505 SMC37c669_write_config(
1525 SMC37c669_write_config(
1537 SMC37c669_write_config(
1546 SMC37c669_write_config(
1566 SMC37c669_write_config(
1578 SMC37c669_write_config(
1587 SMC37c669_write_config(
1602 SMC37c669_write_config(
1611 SMC37c669_write_config(
1622 SMC37c669_config_mode(
FALSE );
1674 struct DEVICE_CONFIG *
cp;
1679 if ( ( cp = SMC37c669_get_config ( func ) ) !=
NULL ) {
1683 if ( ( drq & ~0xFF ) == 0 ) {
1686 if ( ( irq & ~0xFF ) == 0 ) {
1689 if ( ( port & ~0xFFFF ) == 0 ) {
1696 if ( SMC37c669_is_device_enabled( func ) ) {
1735 static unsigned int __init SMC37c669_is_device_enabled (
unsigned int func )
1737 unsigned char base_addr = 0;
1738 unsigned int dev_ok =
FALSE;
1739 unsigned int ret_val =
FALSE;
1743 SMC37c669_config_mode(
TRUE );
1776 if ( ( dev_ok ) && ( ( base_addr & 0xC0 ) != 0 ) ) {
1786 SMC37c669_config_mode(
FALSE );
1834 static unsigned int __init SMC37c669_get_device_config (
1840 struct DEVICE_CONFIG *
cp;
1841 unsigned int ret_val =
FALSE;
1845 if ( ( cp = SMC37c669_get_config( func ) ) !=
NULL ) {
1846 if ( drq !=
NULL ) {
1850 if ( irq !=
NULL ) {
1854 if ( port !=
NULL ) {
1887 if ( SMC37c669_is_device_enabled(
SERIAL_0 ) ) {
1888 printk(
" Serial 0: Enabled [ Port 0x%x, IRQ %d ]\n",
1894 printk(
" Serial 0: Disabled\n" );
1897 if ( SMC37c669_is_device_enabled(
SERIAL_1 ) ) {
1898 printk(
" Serial 1: Enabled [ Port 0x%x, IRQ %d ]\n",
1904 printk(
" Serial 1: Disabled\n" );
1907 if ( SMC37c669_is_device_enabled(
PARALLEL_0 ) ) {
1908 printk(
" Parallel: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
1915 printk(
" Parallel: Disabled\n" );
1918 if ( SMC37c669_is_device_enabled(
FLOPPY_0 ) ) {
1919 printk(
" Floppy Ctrl: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
1926 printk(
" Floppy Ctrl: Disabled\n" );
1929 if ( SMC37c669_is_device_enabled(
IDE_0 ) ) {
1930 printk(
" IDE 0: Enabled [ Port 0x%x, IRQ %d ]\n",
1931 local_config[
IDE_0 ].port1,
1932 local_config[
IDE_0 ].irq
1936 printk(
" IDE 0: Disabled\n" );
1963 static void __init SMC37c669_config_mode(
1974 spin_lock(&smc_lock);
1977 spin_unlock(&smc_lock);
2007 static unsigned char __init SMC37c669_read_config(
2008 unsigned char index )
2012 wb( &SMC37c669->index_port, index );
2013 data =
rb( &SMC37c669->data_port );
2043 static void __init SMC37c669_write_config(
2044 unsigned char index,
2045 unsigned char data )
2047 wb( &SMC37c669->index_port, index );
2048 wb( &SMC37c669->data_port, data );
2076 static void __init SMC37c669_init_local_config (
void )
2102 SMC37c669_xlate_irq(
2115 SMC37c669_xlate_irq(
2138 SMC37c669_xlate_irq(
2142 SMC37c669_xlate_drq(
2155 SMC37c669_xlate_irq(
2159 SMC37c669_xlate_drq(
2177 local_config[
IDE_0].irq = 14;
2204 static struct DEVICE_CONFIG *
__init SMC37c669_get_config(
unsigned int func )
2206 struct DEVICE_CONFIG *cp =
NULL;
2222 cp = &local_config[
IDE_0 ];
2250 static int __init SMC37c669_xlate_irq (
int irq )
2252 int i, translated_irq = -1;
2258 for ( i = 0; ( SMC37c669_irq_table[
i].device_irq != -1 ) || ( SMC37c669_irq_table[i].isa_irq != -1 ); i++ ) {
2259 if ( irq == SMC37c669_irq_table[i].device_irq ) {
2260 translated_irq = SMC37c669_irq_table[
i].isa_irq;
2269 for ( i = 0; ( SMC37c669_irq_table[
i].isa_irq != -1 ) || ( SMC37c669_irq_table[i].device_irq != -1 ); i++ ) {
2270 if ( irq == SMC37c669_irq_table[i].isa_irq ) {
2271 translated_irq = SMC37c669_irq_table[
i].device_irq;
2276 return translated_irq;
2302 static int __init SMC37c669_xlate_drq (
int drq )
2304 int i, translated_drq = -1;
2310 for ( i = 0; ( SMC37c669_drq_table[
i].device_drq != -1 ) || ( SMC37c669_drq_table[i].isa_drq != -1 ); i++ ) {
2311 if ( drq == SMC37c669_drq_table[i].device_drq ) {
2312 translated_drq = SMC37c669_drq_table[
i].isa_drq;
2321 for ( i = 0; ( SMC37c669_drq_table[
i].isa_drq != -1 ) || ( SMC37c669_drq_table[i].device_drq != -1 ); i++ ) {
2322 if ( drq == SMC37c669_drq_table[i].isa_drq ) {
2323 translated_drq = SMC37c669_drq_table[
i].device_drq;
2328 return translated_drq;
2332 int __init smcc669_init (
void )
2336 allocinode( smc_ddb.name, 1, &ip );
2338 ip->attr =
ATTR$M_WRITE |
ATTR$M_READ;
2355 if ( fp->mode &
ATTR$M_WRITE ) {
2365 *fp->offset = xtoi( info );
2371 int __init smcc669_close(
struct FILE *fp )
2376 if ( fp->mode &
ATTR$M_WRITE ) {
2384 int __init smcc669_read(
struct FILE *fp,
int size,
int number,
unsigned char *
buf )
2395 length = size * number;
2398 SMC37c669_config_mode(
TRUE );
2399 for ( i = 0; i <
length; i++ ) {
2400 if ( !inrange( *fp->offset, 0, ip->len[0] ) )
2402 *buf++ = SMC37c669_read_config( *fp->offset );
2406 SMC37c669_config_mode(
FALSE );
2410 int __init smcc669_write(
struct FILE *fp,
int size,
int number,
unsigned char *buf )
2420 length = size * number;
2423 SMC37c669_config_mode(
TRUE );
2424 for ( i = 0; i <
length; i++ ) {
2425 if ( !inrange( *fp->offset, 0, ip->len[0] ) )
2427 SMC37c669_write_config( *fp->offset, *buf );
2432 SMC37c669_config_mode(
FALSE );
2441 for (i = 0; i <= 0x29; i++)
2442 printk(
"-- CR%02x : %02x\n", i, SMC37c669_read_config(i));
2474 unsigned long flags;
2479 SMC37c669_config_mode(
TRUE );
2481 SMC37c669_config_mode(
FALSE );
2526 SMC37c669_config_mode(
TRUE );
2528 SMC37c669_config_mode(
FALSE );
2532 printk(
"SMC37c669 Super I/O Controller found @ 0x%p\n",
2538 printk(
"No SMC37c669 Super I/O Controller found\n" );