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); 25451da177e4SLinus Torvalds printk( "SMC37c669 Super I/O Controller found @ 0x%lx\n", 25461da177e4SLinus Torvalds (unsigned long) 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