1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542 |
- /*
- * SMC 37C669 initialization code
- */
- #include <linux/kernel.h>
- #include <linux/mm.h>
- #include <linux/init.h>
- #include <linux/delay.h>
- #include <linux/spinlock.h>
- #include <asm/hwrpb.h>
- #include <asm/io.h>
- #include <asm/segment.h>
- #if 0
- # define DBG_DEVS(args) printk args
- #else
- # define DBG_DEVS(args)
- #endif
- #define KB 1024
- #define MB (1024*KB)
- #define GB (1024*MB)
- #define SMC_DEBUG 0
- /* File: smcc669_def.h
- *
- * Copyright (C) 1997 by
- * Digital Equipment Corporation, Maynard, Massachusetts.
- * All rights reserved.
- *
- * This software is furnished under a license and may be used and copied
- * only in accordance of the terms of such license and with the
- * inclusion of the above copyright notice. This software or any other
- * copies thereof may not be provided or otherwise made available to any
- * other person. No title to and ownership of the software is hereby
- * transferred.
- *
- * The information in this software is subject to change without notice
- * and should not be construed as a commitment by Digital Equipment
- * Corporation.
- *
- * Digital assumes no responsibility for the use or reliability of its
- * software on equipment which is not supplied by Digital.
- *
- *
- * Abstract:
- *
- * This file contains header definitions for the SMC37c669
- * Super I/O controller.
- *
- * Author:
- *
- * Eric Rasmussen
- *
- * Modification History:
- *
- * er 28-Jan-1997 Initial Entry
- */
- #ifndef __SMC37c669_H
- #define __SMC37c669_H
- /*
- ** Macros for handling device IRQs
- **
- ** The mask acts as a flag used in mapping actual ISA IRQs (0 - 15)
- ** to device IRQs (A - H).
- */
- #define SMC37c669_DEVICE_IRQ_MASK 0x80000000
- #define SMC37c669_DEVICE_IRQ( __i ) \
- ((SMC37c669_DEVICE_IRQ_MASK) | (__i))
- #define SMC37c669_IS_DEVICE_IRQ(__i) \
- (((__i) & (SMC37c669_DEVICE_IRQ_MASK)) == (SMC37c669_DEVICE_IRQ_MASK))
- #define SMC37c669_RAW_DEVICE_IRQ(__i) \
- ((__i) & ~(SMC37c669_DEVICE_IRQ_MASK))
- /*
- ** Macros for handling device DRQs
- **
- ** The mask acts as a flag used in mapping actual ISA DMA
- ** channels to device DMA channels (A - C).
- */
- #define SMC37c669_DEVICE_DRQ_MASK 0x80000000
- #define SMC37c669_DEVICE_DRQ(__d) \
- ((SMC37c669_DEVICE_DRQ_MASK) | (__d))
- #define SMC37c669_IS_DEVICE_DRQ(__d) \
- (((__d) & (SMC37c669_DEVICE_DRQ_MASK)) == (SMC37c669_DEVICE_DRQ_MASK))
- #define SMC37c669_RAW_DEVICE_DRQ(__d) \
- ((__d) & ~(SMC37c669_DEVICE_DRQ_MASK))
- #define SMC37c669_DEVICE_ID 0x3
- /*
- ** SMC37c669 Device Function Definitions
- */
- #define SERIAL_0 0
- #define SERIAL_1 1
- #define PARALLEL_0 2
- #define FLOPPY_0 3
- #define IDE_0 4
- #define NUM_FUNCS 5
- /*
- ** Default Device Function Mappings
- */
- #define COM1_BASE 0x3F8
- #define COM1_IRQ 4
- #define COM2_BASE 0x2F8
- #define COM2_IRQ 3
- #define PARP_BASE 0x3BC
- #define PARP_IRQ 7
- #define PARP_DRQ 3
- #define FDC_BASE 0x3F0
- #define FDC_IRQ 6
- #define FDC_DRQ 2
- /*
- ** Configuration On/Off Key Definitions
- */
- #define SMC37c669_CONFIG_ON_KEY 0x55
- #define SMC37c669_CONFIG_OFF_KEY 0xAA
- /*
- ** SMC 37c669 Device IRQs
- */
- #define SMC37c669_DEVICE_IRQ_A ( SMC37c669_DEVICE_IRQ( 0x01 ) )
- #define SMC37c669_DEVICE_IRQ_B ( SMC37c669_DEVICE_IRQ( 0x02 ) )
- #define SMC37c669_DEVICE_IRQ_C ( SMC37c669_DEVICE_IRQ( 0x03 ) )
- #define SMC37c669_DEVICE_IRQ_D ( SMC37c669_DEVICE_IRQ( 0x04 ) )
- #define SMC37c669_DEVICE_IRQ_E ( SMC37c669_DEVICE_IRQ( 0x05 ) )
- #define SMC37c669_DEVICE_IRQ_F ( SMC37c669_DEVICE_IRQ( 0x06 ) )
- /* SMC37c669_DEVICE_IRQ_G *** RESERVED ***/
- #define SMC37c669_DEVICE_IRQ_H ( SMC37c669_DEVICE_IRQ( 0x08 ) )
- /*
- ** SMC 37c669 Device DMA Channel Definitions
- */
- #define SMC37c669_DEVICE_DRQ_A ( SMC37c669_DEVICE_DRQ( 0x01 ) )
- #define SMC37c669_DEVICE_DRQ_B ( SMC37c669_DEVICE_DRQ( 0x02 ) )
- #define SMC37c669_DEVICE_DRQ_C ( SMC37c669_DEVICE_DRQ( 0x03 ) )
- /*
- ** Configuration Register Index Definitions
- */
- #define SMC37c669_CR00_INDEX 0x00
- #define SMC37c669_CR01_INDEX 0x01
- #define SMC37c669_CR02_INDEX 0x02
- #define SMC37c669_CR03_INDEX 0x03
- #define SMC37c669_CR04_INDEX 0x04
- #define SMC37c669_CR05_INDEX 0x05
- #define SMC37c669_CR06_INDEX 0x06
- #define SMC37c669_CR07_INDEX 0x07
- #define SMC37c669_CR08_INDEX 0x08
- #define SMC37c669_CR09_INDEX 0x09
- #define SMC37c669_CR0A_INDEX 0x0A
- #define SMC37c669_CR0B_INDEX 0x0B
- #define SMC37c669_CR0C_INDEX 0x0C
- #define SMC37c669_CR0D_INDEX 0x0D
- #define SMC37c669_CR0E_INDEX 0x0E
- #define SMC37c669_CR0F_INDEX 0x0F
- #define SMC37c669_CR10_INDEX 0x10
- #define SMC37c669_CR11_INDEX 0x11
- #define SMC37c669_CR12_INDEX 0x12
- #define SMC37c669_CR13_INDEX 0x13
- #define SMC37c669_CR14_INDEX 0x14
- #define SMC37c669_CR15_INDEX 0x15
- #define SMC37c669_CR16_INDEX 0x16
- #define SMC37c669_CR17_INDEX 0x17
- #define SMC37c669_CR18_INDEX 0x18
- #define SMC37c669_CR19_INDEX 0x19
- #define SMC37c669_CR1A_INDEX 0x1A
- #define SMC37c669_CR1B_INDEX 0x1B
- #define SMC37c669_CR1C_INDEX 0x1C
- #define SMC37c669_CR1D_INDEX 0x1D
- #define SMC37c669_CR1E_INDEX 0x1E
- #define SMC37c669_CR1F_INDEX 0x1F
- #define SMC37c669_CR20_INDEX 0x20
- #define SMC37c669_CR21_INDEX 0x21
- #define SMC37c669_CR22_INDEX 0x22
- #define SMC37c669_CR23_INDEX 0x23
- #define SMC37c669_CR24_INDEX 0x24
- #define SMC37c669_CR25_INDEX 0x25
- #define SMC37c669_CR26_INDEX 0x26
- #define SMC37c669_CR27_INDEX 0x27
- #define SMC37c669_CR28_INDEX 0x28
- #define SMC37c669_CR29_INDEX 0x29
- /*
- ** Configuration Register Alias Definitions
- */
- #define SMC37c669_DEVICE_ID_INDEX SMC37c669_CR0D_INDEX
- #define SMC37c669_DEVICE_REVISION_INDEX SMC37c669_CR0E_INDEX
- #define SMC37c669_FDC_BASE_ADDRESS_INDEX SMC37c669_CR20_INDEX
- #define SMC37c669_IDE_BASE_ADDRESS_INDEX SMC37c669_CR21_INDEX
- #define SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX SMC37c669_CR22_INDEX
- #define SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX SMC37c669_CR23_INDEX
- #define SMC37c669_SERIAL0_BASE_ADDRESS_INDEX SMC37c669_CR24_INDEX
- #define SMC37c669_SERIAL1_BASE_ADDRESS_INDEX SMC37c669_CR25_INDEX
- #define SMC37c669_PARALLEL_FDC_DRQ_INDEX SMC37c669_CR26_INDEX
- #define SMC37c669_PARALLEL_FDC_IRQ_INDEX SMC37c669_CR27_INDEX
- #define SMC37c669_SERIAL_IRQ_INDEX SMC37c669_CR28_INDEX
- /*
- ** Configuration Register Definitions
- **
- ** The INDEX (write only) and DATA (read/write) ports are effective
- ** only when the chip is in the Configuration State.
- */
- typedef struct _SMC37c669_CONFIG_REGS {
- unsigned char index_port;
- unsigned char data_port;
- } SMC37c669_CONFIG_REGS;
- /*
- ** CR00 - default value 0x28
- **
- ** IDE_EN (CR00<1:0>):
- ** 0x - 30ua pull-ups on nIDEEN, nHDCS0, NHDCS1
- ** 11 - IRQ_H available as IRQ output,
- ** IRRX2, IRTX2 available as alternate IR pins
- ** 10 - nIDEEN, nHDCS0, nHDCS1 used to control IDE
- **
- ** VALID (CR00<7>):
- ** A high level on this software controlled bit can
- ** be used to indicate that a valid configuration
- ** cycle has occurred. The control software must
- ** take care to set this bit at the appropriate times.
- ** Set to zero after power up. This bit has no
- ** effect on any other hardware in the chip.
- **
- */
- typedef union _SMC37c669_CR00 {
- unsigned char as_uchar;
- struct {
- unsigned ide_en : 2; /* See note above */
- unsigned reserved1 : 1; /* RAZ */
- unsigned fdc_pwr : 1; /* 1 = supply power to FDC */
- unsigned reserved2 : 3; /* Read as 010b */
- unsigned valid : 1; /* See note above */
- } by_field;
- } SMC37c669_CR00;
- /*
- ** CR01 - default value 0x9C
- */
- typedef union _SMC37c669_CR01 {
- unsigned char as_uchar;
- struct {
- unsigned reserved1 : 2; /* RAZ */
- unsigned ppt_pwr : 1; /* 1 = supply power to PPT */
- unsigned ppt_mode : 1; /* 1 = Printer mode, 0 = EPP */
- unsigned reserved2 : 1; /* Read as 1 */
- unsigned reserved3 : 2; /* RAZ */
- unsigned lock_crx: 1; /* Lock CR00 - CR18 */
- } by_field;
- } SMC37c669_CR01;
- /*
- ** CR02 - default value 0x88
- */
- typedef union _SMC37c669_CR02 {
- unsigned char as_uchar;
- struct {
- unsigned reserved1 : 3; /* RAZ */
- unsigned uart1_pwr : 1; /* 1 = supply power to UART1 */
- unsigned reserved2 : 3; /* RAZ */
- unsigned uart2_pwr : 1; /* 1 = supply power to UART2 */
- } by_field;
- } SMC37c669_CR02;
- /*
- ** CR03 - default value 0x78
- **
- ** CR03<7> CR03<2> Pin 94
- ** ------- ------- ------
- ** 0 X DRV2 (input)
- ** 1 0 ADRX
- ** 1 1 IRQ_B
- **
- ** CR03<6> CR03<5> Op Mode
- ** ------- ------- -------
- ** 0 0 Model 30
- ** 0 1 PS/2
- ** 1 0 Reserved
- ** 1 1 AT Mode
- */
- typedef union _SMC37c669_CR03 {
- unsigned char as_uchar;
- struct {
- unsigned pwrgd_gamecs : 1; /* 1 = PWRGD, 0 = GAMECS */
- unsigned fdc_mode2 : 1; /* 1 = Enhanced Mode 2 */
- unsigned pin94_0 : 1; /* See note above */
- unsigned reserved1 : 1; /* RAZ */
- unsigned drvden : 1; /* 1 = high, 0 - output */
- unsigned op_mode : 2; /* See note above */
- unsigned pin94_1 : 1; /* See note above */
- } by_field;
- } SMC37c669_CR03;
- /*
- ** CR04 - default value 0x00
- **
- ** PP_EXT_MODE:
- ** If CR01<PP_MODE> = 0 and PP_EXT_MODE =
- ** 00 - Standard and Bidirectional
- ** 01 - EPP mode and SPP
- ** 10 - ECP mode
- ** In this mode, 2 drives can be supported
- ** directly, 3 or 4 drives must use external
- ** 4 drive support. SPP can be selected
- ** through the ECR register of ECP as mode 000.
- ** 11 - ECP mode and EPP mode
- ** In this mode, 2 drives can be supported
- ** directly, 3 or 4 drives must use external
- ** 4 drive support. SPP can be selected
- ** through the ECR register of ECP as mode 000.
- ** In this mode, EPP can be selected through
- ** the ECR register of ECP as mode 100.
- **
- ** PP_FDC:
- ** 00 - Normal
- ** 01 - PPFD1
- ** 10 - PPFD2
- ** 11 - Reserved
- **
- ** MIDI1:
- ** Serial Clock Select:
- ** A low level on this bit disables MIDI support,
- ** clock = divide by 13. A high level on this
- ** bit enables MIDI support, clock = divide by 12.
- **
- ** MIDI operates at 31.25 Kbps which can be derived
- ** from 125 KHz (24 MHz / 12 = 2 MHz, 2 MHz / 16 = 125 KHz)
- **
- ** ALT_IO:
- ** 0 - Use pins IRRX, IRTX
- ** 1 - Use pins IRRX2, IRTX2
- **
- ** If this bit is set, the IR receive and transmit
- ** functions will not be available on pins 25 and 26
- ** unless CR00<IDE_EN> = 11.
- */
- typedef union _SMC37c669_CR04 {
- unsigned char as_uchar;
- struct {
- unsigned ppt_ext_mode : 2; /* See note above */
- unsigned ppt_fdc : 2; /* See note above */
- unsigned midi1 : 1; /* See note above */
- unsigned midi2 : 1; /* See note above */
- unsigned epp_type : 1; /* 0 = EPP 1.9, 1 = EPP 1.7 */
- unsigned alt_io : 1; /* See note above */
- } by_field;
- } SMC37c669_CR04;
- /*
- ** CR05 - default value 0x00
- **
- ** DEN_SEL:
- ** 00 - Densel output normal
- ** 01 - Reserved
- ** 10 - Densel output 1
- ** 11 - Densel output 0
- **
- */
- typedef union _SMC37c669_CR05 {
- unsigned char as_uchar;
- struct {
- unsigned reserved1 : 2; /* RAZ */
- unsigned fdc_dma_mode : 1; /* 0 = burst, 1 = non-burst */
- unsigned den_sel : 2; /* See note above */
- unsigned swap_drv : 1; /* Swap the FDC motor selects */
- unsigned extx4 : 1; /* 0 = 2 drive, 1 = external 4 drive decode */
- unsigned reserved2 : 1; /* RAZ */
- } by_field;
- } SMC37c669_CR05;
- /*
- ** CR06 - default value 0xFF
- */
- typedef union _SMC37c669_CR06 {
- unsigned char as_uchar;
- struct {
- unsigned floppy_a : 2; /* Type of floppy drive A */
- unsigned floppy_b : 2; /* Type of floppy drive B */
- unsigned floppy_c : 2; /* Type of floppy drive C */
- unsigned floppy_d : 2; /* Type of floppy drive D */
- } by_field;
- } SMC37c669_CR06;
- /*
- ** CR07 - default value 0x00
- **
- ** Auto Power Management CR07<7:4>:
- ** 0 - Auto Powerdown disabled (default)
- ** 1 - Auto Powerdown enabled
- **
- ** This bit is reset to the default state by POR or
- ** a hardware reset.
- **
- */
- typedef union _SMC37c669_CR07 {
- unsigned char as_uchar;
- struct {
- unsigned floppy_boot : 2; /* 0 = A:, 1 = B: */
- unsigned reserved1 : 2; /* RAZ */
- unsigned ppt_en : 1; /* See note above */
- unsigned uart1_en : 1; /* See note above */
- unsigned uart2_en : 1; /* See note above */
- unsigned fdc_en : 1; /* See note above */
- } by_field;
- } SMC37c669_CR07;
- /*
- ** CR08 - default value 0x00
- */
- typedef union _SMC37c669_CR08 {
- unsigned char as_uchar;
- struct {
- unsigned zero : 4; /* 0 */
- unsigned addrx7_4 : 4; /* ADR<7:3> for ADRx decode */
- } by_field;
- } SMC37c669_CR08;
- /*
- ** CR09 - default value 0x00
- **
- ** ADRx_CONFIG:
- ** 00 - ADRx disabled
- ** 01 - 1 byte decode A<3:0> = 0000b
- ** 10 - 8 byte block decode A<3:0> = 0XXXb
- ** 11 - 16 byte block decode A<3:0> = XXXXb
- **
- */
- typedef union _SMC37c669_CR09 {
- unsigned char as_uchar;
- struct {
- unsigned adra8 : 3; /* ADR<10:8> for ADRx decode */
- unsigned reserved1 : 3;
- unsigned adrx_config : 2; /* See note above */
- } by_field;
- } SMC37c669_CR09;
- /*
- ** CR0A - default value 0x00
- */
- typedef union _SMC37c669_CR0A {
- unsigned char as_uchar;
- struct {
- unsigned ecp_fifo_threshold : 4;
- unsigned reserved1 : 4;
- } by_field;
- } SMC37c669_CR0A;
- /*
- ** CR0B - default value 0x00
- */
- typedef union _SMC37c669_CR0B {
- unsigned char as_uchar;
- struct {
- unsigned fdd0_drtx : 2; /* FDD0 Data Rate Table */
- unsigned fdd1_drtx : 2; /* FDD1 Data Rate Table */
- unsigned fdd2_drtx : 2; /* FDD2 Data Rate Table */
- unsigned fdd3_drtx : 2; /* FDD3 Data Rate Table */
- } by_field;
- } SMC37c669_CR0B;
- /*
- ** CR0C - default value 0x00
- **
- ** UART2_MODE:
- ** 000 - Standard (default)
- ** 001 - IrDA (HPSIR)
- ** 010 - Amplitude Shift Keyed IR @500 KHz
- ** 011 - Reserved
- ** 1xx - Reserved
- **
- */
- typedef union _SMC37c669_CR0C {
- unsigned char as_uchar;
- struct {
- unsigned uart2_rcv_polarity : 1; /* 1 = invert RX */
- unsigned uart2_xmit_polarity : 1; /* 1 = invert TX */
- unsigned uart2_duplex : 1; /* 1 = full, 0 = half */
- unsigned uart2_mode : 3; /* See note above */
- unsigned uart1_speed : 1; /* 1 = high speed enabled */
- unsigned uart2_speed : 1; /* 1 = high speed enabled */
- } by_field;
- } SMC37c669_CR0C;
- /*
- ** CR0D - default value 0x03
- **
- ** Device ID Register - read only
- */
- typedef union _SMC37c669_CR0D {
- unsigned char as_uchar;
- struct {
- unsigned device_id : 8; /* Returns 0x3 in this field */
- } by_field;
- } SMC37c669_CR0D;
- /*
- ** CR0E - default value 0x02
- **
- ** Device Revision Register - read only
- */
- typedef union _SMC37c669_CR0E {
- unsigned char as_uchar;
- struct {
- unsigned device_rev : 8; /* Returns 0x2 in this field */
- } by_field;
- } SMC37c669_CR0E;
- /*
- ** CR0F - default value 0x00
- */
- typedef union _SMC37c669_CR0F {
- unsigned char as_uchar;
- struct {
- unsigned test0 : 1; /* Reserved - set to 0 */
- unsigned test1 : 1; /* Reserved - set to 0 */
- unsigned test2 : 1; /* Reserved - set to 0 */
- unsigned test3 : 1; /* Reserved - set t0 0 */
- unsigned test4 : 1; /* Reserved - set to 0 */
- unsigned test5 : 1; /* Reserved - set t0 0 */
- unsigned test6 : 1; /* Reserved - set t0 0 */
- unsigned test7 : 1; /* Reserved - set to 0 */
- } by_field;
- } SMC37c669_CR0F;
- /*
- ** CR10 - default value 0x00
- */
- typedef union _SMC37c669_CR10 {
- unsigned char as_uchar;
- struct {
- unsigned reserved1 : 3; /* RAZ */
- unsigned pll_gain : 1; /* 1 = 3V, 2 = 5V operation */
- unsigned pll_stop : 1; /* 1 = stop PLLs */
- unsigned ace_stop : 1; /* 1 = stop UART clocks */
- unsigned pll_clock_ctrl : 1; /* 0 = 14.318 MHz, 1 = 24 MHz */
- unsigned ir_test : 1; /* Enable IR test mode */
- } by_field;
- } SMC37c669_CR10;
- /*
- ** CR11 - default value 0x00
- */
- typedef union _SMC37c669_CR11 {
- unsigned char as_uchar;
- struct {
- unsigned ir_loopback : 1; /* Internal IR loop back */
- unsigned test_10ms : 1; /* Test 10ms autopowerdown FDC timeout */
- unsigned reserved1 : 6; /* RAZ */
- } by_field;
- } SMC37c669_CR11;
- /*
- ** CR12 - CR1D are reserved registers
- */
- /*
- ** CR1E - default value 0x80
- **
- ** GAMECS:
- ** 00 - GAMECS disabled
- ** 01 - 1 byte decode ADR<3:0> = 0001b
- ** 10 - 8 byte block decode ADR<3:0> = 0XXXb
- ** 11 - 16 byte block decode ADR<3:0> = XXXXb
- **
- */
- typedef union _SMC37c66_CR1E {
- unsigned char as_uchar;
- struct {
- unsigned gamecs_config: 2; /* See note above */
- unsigned gamecs_addr9_4 : 6; /* GAMECS Addr<9:4> */
- } by_field;
- } SMC37c669_CR1E;
- /*
- ** CR1F - default value 0x00
- **
- ** DT0 DT1 DRVDEN0 DRVDEN1 Drive Type
- ** --- --- ------- ------- ----------
- ** 0 0 DENSEL DRATE0 4/2/1 MB 3.5"
- ** 2/1 MB 5.25"
- ** 2/1.6/1 MB 3.5" (3-mode)
- ** 0 1 DRATE1 DRATE0
- ** 1 0 nDENSEL DRATE0 PS/2
- ** 1 1 DRATE0 DRATE1
- **
- ** Note: DENSEL, DRATE1, and DRATE0 map onto two output
- ** pins - DRVDEN0 and DRVDEN1.
- **
- */
- typedef union _SMC37c669_CR1F {
- unsigned char as_uchar;
- struct {
- unsigned fdd0_drive_type : 2; /* FDD0 drive type */
- unsigned fdd1_drive_type : 2; /* FDD1 drive type */
- unsigned fdd2_drive_type : 2; /* FDD2 drive type */
- unsigned fdd3_drive_type : 2; /* FDD3 drive type */
- } by_field;
- } SMC37c669_CR1F;
- /*
- ** CR20 - default value 0x3C
- **
- ** FDC Base Address Register
- ** - To disable this decode set Addr<9:8> = 0
- ** - A<10> = 0, A<3:0> = 0XXXb to access.
- **
- */
- typedef union _SMC37c669_CR20 {
- unsigned char as_uchar;
- struct {
- unsigned zero : 2; /* 0 */
- unsigned addr9_4 : 6; /* FDC Addr<9:4> */
- } by_field;
- } SMC37c669_CR20;
- /*
- ** CR21 - default value 0x3C
- **
- ** IDE Base Address Register
- ** - To disable this decode set Addr<9:8> = 0
- ** - A<10> = 0, A<3:0> = 0XXXb to access.
- **
- */
- typedef union _SMC37c669_CR21 {
- unsigned char as_uchar;
- struct {
- unsigned zero : 2; /* 0 */
- unsigned addr9_4 : 6; /* IDE Addr<9:4> */
- } by_field;
- } SMC37c669_CR21;
- /*
- ** CR22 - default value 0x3D
- **
- ** IDE Alternate Status Base Address Register
- ** - To disable this decode set Addr<9:8> = 0
- ** - A<10> = 0, A<3:0> = 0110b to access.
- **
- */
- typedef union _SMC37c669_CR22 {
- unsigned char as_uchar;
- struct {
- unsigned zero : 2; /* 0 */
- unsigned addr9_4 : 6; /* IDE Alt Status Addr<9:4> */
- } by_field;
- } SMC37c669_CR22;
- /*
- ** CR23 - default value 0x00
- **
- ** Parallel Port Base Address Register
- ** - To disable this decode set Addr<9:8> = 0
- ** - A<10> = 0 to access.
- ** - If EPP is enabled, A<2:0> = XXXb to access.
- ** If EPP is NOT enabled, A<1:0> = XXb to access
- **
- */
- typedef union _SMC37c669_CR23 {
- unsigned char as_uchar;
- struct {
- unsigned addr9_2 : 8; /* Parallel Port Addr<9:2> */
- } by_field;
- } SMC37c669_CR23;
- /*
- ** CR24 - default value 0x00
- **
- ** UART1 Base Address Register
- ** - To disable this decode set Addr<9:8> = 0
- ** - A<10> = 0, A<2:0> = XXXb to access.
- **
- */
- typedef union _SMC37c669_CR24 {
- unsigned char as_uchar;
- struct {
- unsigned zero : 1; /* 0 */
- unsigned addr9_3 : 7; /* UART1 Addr<9:3> */
- } by_field;
- } SMC37c669_CR24;
- /*
- ** CR25 - default value 0x00
- **
- ** UART2 Base Address Register
- ** - To disable this decode set Addr<9:8> = 0
- ** - A<10> = 0, A<2:0> = XXXb to access.
- **
- */
- typedef union _SMC37c669_CR25 {
- unsigned char as_uchar;
- struct {
- unsigned zero : 1; /* 0 */
- unsigned addr9_3 : 7; /* UART2 Addr<9:3> */
- } by_field;
- } SMC37c669_CR25;
- /*
- ** CR26 - default value 0x00
- **
- ** Parallel Port / FDC DMA Select Register
- **
- ** D3 - D0 DMA
- ** D7 - D4 Selected
- ** ------- --------
- ** 0000 None
- ** 0001 DMA_A
- ** 0010 DMA_B
- ** 0011 DMA_C
- **
- */
- typedef union _SMC37c669_CR26 {
- unsigned char as_uchar;
- struct {
- unsigned ppt_drq : 4; /* See note above */
- unsigned fdc_drq : 4; /* See note above */
- } by_field;
- } SMC37c669_CR26;
- /*
- ** CR27 - default value 0x00
- **
- ** Parallel Port / FDC IRQ Select Register
- **
- ** D3 - D0 IRQ
- ** D7 - D4 Selected
- ** ------- --------
- ** 0000 None
- ** 0001 IRQ_A
- ** 0010 IRQ_B
- ** 0011 IRQ_C
- ** 0100 IRQ_D
- ** 0101 IRQ_E
- ** 0110 IRQ_F
- ** 0111 Reserved
- ** 1000 IRQ_H
- **
- ** Any unselected IRQ REQ is in tristate
- **
- */
- typedef union _SMC37c669_CR27 {
- unsigned char as_uchar;
- struct {
- unsigned ppt_irq : 4; /* See note above */
- unsigned fdc_irq : 4; /* See note above */
- } by_field;
- } SMC37c669_CR27;
- /*
- ** CR28 - default value 0x00
- **
- ** UART IRQ Select Register
- **
- ** D3 - D0 IRQ
- ** D7 - D4 Selected
- ** ------- --------
- ** 0000 None
- ** 0001 IRQ_A
- ** 0010 IRQ_B
- ** 0011 IRQ_C
- ** 0100 IRQ_D
- ** 0101 IRQ_E
- ** 0110 IRQ_F
- ** 0111 Reserved
- ** 1000 IRQ_H
- ** 1111 share with UART1 (only for UART2)
- **
- ** Any unselected IRQ REQ is in tristate
- **
- ** To share an IRQ between UART1 and UART2, set
- ** UART1 to use the desired IRQ and set UART2 to
- ** 0xF to enable sharing mechanism.
- **
- */
- typedef union _SMC37c669_CR28 {
- unsigned char as_uchar;
- struct {
- unsigned uart2_irq : 4; /* See note above */
- unsigned uart1_irq : 4; /* See note above */
- } by_field;
- } SMC37c669_CR28;
- /*
- ** CR29 - default value 0x00
- **
- ** IRQIN IRQ Select Register
- **
- ** D3 - D0 IRQ
- ** D7 - D4 Selected
- ** ------- --------
- ** 0000 None
- ** 0001 IRQ_A
- ** 0010 IRQ_B
- ** 0011 IRQ_C
- ** 0100 IRQ_D
- ** 0101 IRQ_E
- ** 0110 IRQ_F
- ** 0111 Reserved
- ** 1000 IRQ_H
- **
- ** Any unselected IRQ REQ is in tristate
- **
- */
- typedef union _SMC37c669_CR29 {
- unsigned char as_uchar;
- struct {
- unsigned irqin_irq : 4; /* See note above */
- unsigned reserved1 : 4; /* RAZ */
- } by_field;
- } SMC37c669_CR29;
- /*
- ** Aliases of Configuration Register formats (should match
- ** the set of index aliases).
- **
- ** Note that CR24 and CR25 have the same format and are the
- ** base address registers for UART1 and UART2. Because of
- ** this we only define 1 alias here - for CR24 - as the serial
- ** base address register.
- **
- ** Note that CR21 and CR22 have the same format and are the
- ** base address and alternate status address registers for
- ** the IDE controller. Because of this we only define 1 alias
- ** here - for CR21 - as the IDE address register.
- **
- */
- typedef SMC37c669_CR0D SMC37c669_DEVICE_ID_REGISTER;
- typedef SMC37c669_CR0E SMC37c669_DEVICE_REVISION_REGISTER;
- typedef SMC37c669_CR20 SMC37c669_FDC_BASE_ADDRESS_REGISTER;
- typedef SMC37c669_CR21 SMC37c669_IDE_ADDRESS_REGISTER;
- typedef SMC37c669_CR23 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER;
- typedef SMC37c669_CR24 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER;
- typedef SMC37c669_CR26 SMC37c669_PARALLEL_FDC_DRQ_REGISTER;
- typedef SMC37c669_CR27 SMC37c669_PARALLEL_FDC_IRQ_REGISTER;
- typedef SMC37c669_CR28 SMC37c669_SERIAL_IRQ_REGISTER;
- /*
- ** ISA/Device IRQ Translation Table Entry Definition
- */
- typedef struct _SMC37c669_IRQ_TRANSLATION_ENTRY {
- int device_irq;
- int isa_irq;
- } SMC37c669_IRQ_TRANSLATION_ENTRY;
- /*
- ** ISA/Device DMA Translation Table Entry Definition
- */
- typedef struct _SMC37c669_DRQ_TRANSLATION_ENTRY {
- int device_drq;
- int isa_drq;
- } SMC37c669_DRQ_TRANSLATION_ENTRY;
- /*
- ** External Interface Function Prototype Declarations
- */
- SMC37c669_CONFIG_REGS *SMC37c669_detect(
- int
- );
- unsigned int SMC37c669_enable_device(
- unsigned int func
- );
- unsigned int SMC37c669_disable_device(
- unsigned int func
- );
- unsigned int SMC37c669_configure_device(
- unsigned int func,
- int port,
- int irq,
- int drq
- );
- void SMC37c669_display_device_info(
- void
- );
- #endif /* __SMC37c669_H */
- /* file: smcc669.c
- *
- * Copyright (C) 1997 by
- * Digital Equipment Corporation, Maynard, Massachusetts.
- * All rights reserved.
- *
- * This software is furnished under a license and may be used and copied
- * only in accordance of the terms of such license and with the
- * inclusion of the above copyright notice. This software or any other
- * copies thereof may not be provided or otherwise made available to any
- * other person. No title to and ownership of the software is hereby
- * transferred.
- *
- * The information in this software is subject to change without notice
- * and should not be construed as a commitment by digital equipment
- * corporation.
- *
- * Digital assumes no responsibility for the use or reliability of its
- * software on equipment which is not supplied by digital.
- */
- /*
- *++
- * FACILITY:
- *
- * Alpha SRM Console Firmware
- *
- * MODULE DESCRIPTION:
- *
- * SMC37c669 Super I/O controller configuration routines.
- *
- * AUTHORS:
- *
- * Eric Rasmussen
- *
- * CREATION DATE:
- *
- * 28-Jan-1997
- *
- * MODIFICATION HISTORY:
- *
- * er 01-May-1997 Fixed pointer conversion errors in
- * SMC37c669_get_device_config().
- * er 28-Jan-1997 Initial version.
- *
- *--
- */
- #ifndef TRUE
- #define TRUE 1
- #endif
- #ifndef FALSE
- #define FALSE 0
- #endif
- #define wb( _x_, _y_ ) outb( _y_, (unsigned int)((unsigned long)_x_) )
- #define rb( _x_ ) inb( (unsigned int)((unsigned long)_x_) )
- /*
- ** Local storage for device configuration information.
- **
- ** Since the SMC37c669 does not provide an explicit
- ** mechanism for enabling/disabling individual device
- ** functions, other than unmapping the device, local
- ** storage for device configuration information is
- ** allocated here for use in implementing our own
- ** function enable/disable scheme.
- */
- static struct DEVICE_CONFIG {
- unsigned int port1;
- unsigned int port2;
- int irq;
- int drq;
- } local_config [NUM_FUNCS];
- /*
- ** List of all possible addresses for the Super I/O chip
- */
- static unsigned long SMC37c669_Addresses[] __initdata =
- {
- 0x3F0UL, /* Primary address */
- 0x370UL, /* Secondary address */
- 0UL /* End of list */
- };
- /*
- ** Global Pointer to the Super I/O device
- */
- static SMC37c669_CONFIG_REGS *SMC37c669 __initdata = NULL;
- /*
- ** IRQ Translation Table
- **
- ** The IRQ translation table is a list of SMC37c669 device
- ** and standard ISA IRQs.
- **
- */
- static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_table __initdata;
- /*
- ** The following definition is for the default IRQ
- ** translation table.
- */
- static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_default_irq_table[]
- __initdata =
- {
- { SMC37c669_DEVICE_IRQ_A, -1 },
- { SMC37c669_DEVICE_IRQ_B, -1 },
- { SMC37c669_DEVICE_IRQ_C, 7 },
- { SMC37c669_DEVICE_IRQ_D, 6 },
- { SMC37c669_DEVICE_IRQ_E, 4 },
- { SMC37c669_DEVICE_IRQ_F, 3 },
- { SMC37c669_DEVICE_IRQ_H, -1 },
- { -1, -1 } /* End of table */
- };
- /*
- ** The following definition is for the MONET (XP1000) IRQ
- ** translation table.
- */
- static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_monet_irq_table[]
- __initdata =
- {
- { SMC37c669_DEVICE_IRQ_A, -1 },
- { SMC37c669_DEVICE_IRQ_B, -1 },
- { SMC37c669_DEVICE_IRQ_C, 6 },
- { SMC37c669_DEVICE_IRQ_D, 7 },
- { SMC37c669_DEVICE_IRQ_E, 4 },
- { SMC37c669_DEVICE_IRQ_F, 3 },
- { SMC37c669_DEVICE_IRQ_H, -1 },
- { -1, -1 } /* End of table */
- };
- static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_tables[] __initdata =
- {
- SMC37c669_default_irq_table,
- SMC37c669_monet_irq_table
- };
- /*
- ** DRQ Translation Table
- **
- ** The DRQ translation table is a list of SMC37c669 device and
- ** ISA DMA channels.
- **
- */
- static SMC37c669_DRQ_TRANSLATION_ENTRY *SMC37c669_drq_table __initdata;
- /*
- ** The following definition is the default DRQ
- ** translation table.
- */
- static SMC37c669_DRQ_TRANSLATION_ENTRY SMC37c669_default_drq_table[]
- __initdata =
- {
- { SMC37c669_DEVICE_DRQ_A, 2 },
- { SMC37c669_DEVICE_DRQ_B, 3 },
- { SMC37c669_DEVICE_DRQ_C, -1 },
- { -1, -1 } /* End of table */
- };
- /*
- ** Local Function Prototype Declarations
- */
- static unsigned int SMC37c669_is_device_enabled(
- unsigned int func
- );
- #if 0
- static unsigned int SMC37c669_get_device_config(
- unsigned int func,
- int *port,
- int *irq,
- int *drq
- );
- #endif
- static void SMC37c669_config_mode(
- unsigned int enable
- );
- static unsigned char SMC37c669_read_config(
- unsigned char index
- );
- static void SMC37c669_write_config(
- unsigned char index,
- unsigned char data
- );
- static void SMC37c669_init_local_config( void );
- static struct DEVICE_CONFIG *SMC37c669_get_config(
- unsigned int func
- );
- static int SMC37c669_xlate_irq(
- int irq
- );
- static int SMC37c669_xlate_drq(
- int drq
- );
- static __cacheline_aligned DEFINE_SPINLOCK(smc_lock);
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function detects the presence of an SMC37c669 Super I/O
- ** controller.
- **
- ** FORMAL PARAMETERS:
- **
- ** None
- **
- ** RETURN VALUE:
- **
- ** Returns a pointer to the device if found, otherwise,
- ** the NULL pointer is returned.
- **
- ** SIDE EFFECTS:
- **
- ** None
- **
- **--
- */
- SMC37c669_CONFIG_REGS * __init SMC37c669_detect( int index )
- {
- int i;
- SMC37c669_DEVICE_ID_REGISTER id;
- for ( i = 0; SMC37c669_Addresses[i] != 0; i++ ) {
- /*
- ** Initialize the device pointer even though we don't yet know if
- ** the controller is at this address. The support functions access
- ** the controller through this device pointer so we need to set it
- ** even when we are looking ...
- */
- SMC37c669 = ( SMC37c669_CONFIG_REGS * )SMC37c669_Addresses[i];
- /*
- ** Enter configuration mode
- */
- SMC37c669_config_mode( TRUE );
- /*
- ** Read the device id
- */
- id.as_uchar = SMC37c669_read_config( SMC37c669_DEVICE_ID_INDEX );
- /*
- ** Exit configuration mode
- */
- SMC37c669_config_mode( FALSE );
- /*
- ** Does the device id match? If so, assume we have found an
- ** SMC37c669 controller at this address.
- */
- if ( id.by_field.device_id == SMC37c669_DEVICE_ID ) {
- /*
- ** Initialize the IRQ and DRQ translation tables.
- */
- SMC37c669_irq_table = SMC37c669_irq_tables[ index ];
- SMC37c669_drq_table = SMC37c669_default_drq_table;
- /*
- ** erfix
- **
- ** If the platform can't use the IRQ and DRQ defaults set up in this
- ** file, it should call a platform-specific external routine at this
- ** point to reset the IRQ and DRQ translation table pointers to point
- ** at the appropriate tables for the platform. If the defaults are
- ** acceptable, then the external routine should do nothing.
- */
- /*
- ** Put the chip back into configuration mode
- */
- SMC37c669_config_mode( TRUE );
- /*
- ** Initialize local storage for configuration information
- */
- SMC37c669_init_local_config( );
- /*
- ** Exit configuration mode
- */
- SMC37c669_config_mode( FALSE );
- /*
- ** SMC37c669 controller found, break out of search loop
- */
- break;
- }
- else {
- /*
- ** Otherwise, we did not find an SMC37c669 controller at this
- ** address so set the device pointer to NULL.
- */
- SMC37c669 = NULL;
- }
- }
- return SMC37c669;
- }
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function enables an SMC37c669 device function.
- **
- ** FORMAL PARAMETERS:
- **
- ** func:
- ** Which device function to enable
- **
- ** RETURN VALUE:
- **
- ** Returns TRUE is the device function was enabled, otherwise, FALSE
- **
- ** SIDE EFFECTS:
- **
- ** {@description or none@}
- **
- ** DESIGN:
- **
- ** Enabling a device function in the SMC37c669 controller involves
- ** setting all of its mappings (port, irq, drq ...). A local
- ** "shadow" copy of the device configuration is kept so we can
- ** just set each mapping to what the local copy says.
- **
- ** This function ALWAYS updates the local shadow configuration of
- ** the device function being enabled, even if the device is always
- ** enabled. To avoid replication of code, functions such as
- ** configure_device set up the local copy and then call this
- ** function to the update the real device.
- **
- **--
- */
- unsigned int __init SMC37c669_enable_device ( unsigned int func )
- {
- unsigned int ret_val = FALSE;
- /*
- ** Put the device into configuration mode
- */
- SMC37c669_config_mode( TRUE );
- switch ( func ) {
- case SERIAL_0:
- {
- SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
- SMC37c669_SERIAL_IRQ_REGISTER irq;
- /*
- ** Enable the serial 1 IRQ mapping
- */
- irq.as_uchar =
- SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
- irq.by_field.uart1_irq =
- SMC37c669_RAW_DEVICE_IRQ(
- SMC37c669_xlate_irq( local_config[ func ].irq )
- );
- SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
- /*
- ** Enable the serial 1 port base address mapping
- */
- base_addr.as_uchar = 0;
- base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
- SMC37c669_write_config(
- SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
- base_addr.as_uchar
- );
- ret_val = TRUE;
- break;
- }
- case SERIAL_1:
- {
- SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
- SMC37c669_SERIAL_IRQ_REGISTER irq;
- /*
- ** Enable the serial 2 IRQ mapping
- */
- irq.as_uchar =
- SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
- irq.by_field.uart2_irq =
- SMC37c669_RAW_DEVICE_IRQ(
- SMC37c669_xlate_irq( local_config[ func ].irq )
- );
- SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
- /*
- ** Enable the serial 2 port base address mapping
- */
- base_addr.as_uchar = 0;
- base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
- SMC37c669_write_config(
- SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
- base_addr.as_uchar
- );
- ret_val = TRUE;
- break;
- }
- case PARALLEL_0:
- {
- SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
- SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
- SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
- /*
- ** Enable the parallel port DMA channel mapping
- */
- drq.as_uchar =
- SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
- drq.by_field.ppt_drq =
- SMC37c669_RAW_DEVICE_DRQ(
- SMC37c669_xlate_drq( local_config[ func ].drq )
- );
- SMC37c669_write_config(
- SMC37c669_PARALLEL_FDC_DRQ_INDEX,
- drq.as_uchar
- );
- /*
- ** Enable the parallel port IRQ mapping
- */
- irq.as_uchar =
- SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
- irq.by_field.ppt_irq =
- SMC37c669_RAW_DEVICE_IRQ(
- SMC37c669_xlate_irq( local_config[ func ].irq )
- );
- SMC37c669_write_config(
- SMC37c669_PARALLEL_FDC_IRQ_INDEX,
- irq.as_uchar
- );
- /*
- ** Enable the parallel port base address mapping
- */
- base_addr.as_uchar = 0;
- base_addr.by_field.addr9_2 = local_config[ func ].port1 >> 2;
- SMC37c669_write_config(
- SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
- base_addr.as_uchar
- );
- ret_val = TRUE;
- break;
- }
- case FLOPPY_0:
- {
- SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
- SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
- SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
- /*
- ** Enable the floppy controller DMA channel mapping
- */
- drq.as_uchar =
- SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
-
- drq.by_field.fdc_drq =
- SMC37c669_RAW_DEVICE_DRQ(
- SMC37c669_xlate_drq( local_config[ func ].drq )
- );
-
- SMC37c669_write_config(
- SMC37c669_PARALLEL_FDC_DRQ_INDEX,
- drq.as_uchar
- );
- /*
- ** Enable the floppy controller IRQ mapping
- */
- irq.as_uchar =
- SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
-
- irq.by_field.fdc_irq =
- SMC37c669_RAW_DEVICE_IRQ(
- SMC37c669_xlate_irq( local_config[ func ].irq )
- );
-
- SMC37c669_write_config(
- SMC37c669_PARALLEL_FDC_IRQ_INDEX,
- irq.as_uchar
- );
- /*
- ** Enable the floppy controller base address mapping
- */
- base_addr.as_uchar = 0;
- base_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
-
- SMC37c669_write_config(
- SMC37c669_FDC_BASE_ADDRESS_INDEX,
- base_addr.as_uchar
- );
- ret_val = TRUE;
- break;
- }
- case IDE_0:
- {
- SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
- /*
- ** Enable the IDE alternate status base address mapping
- */
- ide_addr.as_uchar = 0;
- ide_addr.by_field.addr9_4 = local_config[ func ].port2 >> 4;
-
- SMC37c669_write_config(
- SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
- ide_addr.as_uchar
- );
- /*
- ** Enable the IDE controller base address mapping
- */
- ide_addr.as_uchar = 0;
- ide_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
-
- SMC37c669_write_config(
- SMC37c669_IDE_BASE_ADDRESS_INDEX,
- ide_addr.as_uchar
- );
- ret_val = TRUE;
- break;
- }
- }
- /*
- ** Exit configuration mode and return
- */
- SMC37c669_config_mode( FALSE );
- return ret_val;
- }
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function disables a device function within the
- ** SMC37c669 Super I/O controller.
- **
- ** FORMAL PARAMETERS:
- **
- ** func:
- ** Which function to disable
- **
- ** RETURN VALUE:
- **
- ** Return TRUE if the device function was disabled, otherwise, FALSE
- **
- ** SIDE EFFECTS:
- **
- ** {@description or none@}
- **
- ** DESIGN:
- **
- ** Disabling a function in the SMC37c669 device involves
- ** disabling all the function's mappings (port, irq, drq ...).
- ** A shadow copy of the device configuration is maintained
- ** in local storage so we won't worry aboving saving the
- ** current configuration information.
- **
- **--
- */
- unsigned int __init SMC37c669_disable_device ( unsigned int func )
- {
- unsigned int ret_val = FALSE;
- /*
- ** Put the device into configuration mode
- */
- SMC37c669_config_mode( TRUE );
- switch ( func ) {
- case SERIAL_0:
- {
- SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
- SMC37c669_SERIAL_IRQ_REGISTER irq;
- /*
- ** Disable the serial 1 IRQ mapping
- */
- irq.as_uchar =
- SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
- irq.by_field.uart1_irq = 0;
- SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
- /*
- ** Disable the serial 1 port base address mapping
- */
- base_addr.as_uchar = 0;
- SMC37c669_write_config(
- SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
- base_addr.as_uchar
- );
- ret_val = TRUE;
- break;
- }
- case SERIAL_1:
- {
- SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
- SMC37c669_SERIAL_IRQ_REGISTER irq;
- /*
- ** Disable the serial 2 IRQ mapping
- */
- irq.as_uchar =
- SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
- irq.by_field.uart2_irq = 0;
- SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
- /*
- ** Disable the serial 2 port base address mapping
- */
- base_addr.as_uchar = 0;
- SMC37c669_write_config(
- SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
- base_addr.as_uchar
- );
- ret_val = TRUE;
- break;
- }
- case PARALLEL_0:
- {
- SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
- SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
- SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
- /*
- ** Disable the parallel port DMA channel mapping
- */
- drq.as_uchar =
- SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
- drq.by_field.ppt_drq = 0;
- SMC37c669_write_config(
- SMC37c669_PARALLEL_FDC_DRQ_INDEX,
- drq.as_uchar
- );
- /*
- ** Disable the parallel port IRQ mapping
- */
- irq.as_uchar =
- SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
- irq.by_field.ppt_irq = 0;
- SMC37c669_write_config(
- SMC37c669_PARALLEL_FDC_IRQ_INDEX,
- irq.as_uchar
- );
- /*
- ** Disable the parallel port base address mapping
- */
- base_addr.as_uchar = 0;
- SMC37c669_write_config(
- SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
- base_addr.as_uchar
- );
- ret_val = TRUE;
- break;
- }
- case FLOPPY_0:
- {
- SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
- SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
- SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
- /*
- ** Disable the floppy controller DMA channel mapping
- */
- drq.as_uchar =
- SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
-
- drq.by_field.fdc_drq = 0;
-
- SMC37c669_write_config(
- SMC37c669_PARALLEL_FDC_DRQ_INDEX,
- drq.as_uchar
- );
- /*
- ** Disable the floppy controller IRQ mapping
- */
- irq.as_uchar =
- SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
-
- irq.by_field.fdc_irq = 0;
-
- SMC37c669_write_config(
- SMC37c669_PARALLEL_FDC_IRQ_INDEX,
- irq.as_uchar
- );
- /*
- ** Disable the floppy controller base address mapping
- */
- base_addr.as_uchar = 0;
-
- SMC37c669_write_config(
- SMC37c669_FDC_BASE_ADDRESS_INDEX,
- base_addr.as_uchar
- );
- ret_val = TRUE;
- break;
- }
- case IDE_0:
- {
- SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
- /*
- ** Disable the IDE alternate status base address mapping
- */
- ide_addr.as_uchar = 0;
-
- SMC37c669_write_config(
- SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
- ide_addr.as_uchar
- );
- /*
- ** Disable the IDE controller base address mapping
- */
- ide_addr.as_uchar = 0;
-
- SMC37c669_write_config(
- SMC37c669_IDE_BASE_ADDRESS_INDEX,
- ide_addr.as_uchar
- );
- ret_val = TRUE;
- break;
- }
- }
- /*
- ** Exit configuration mode and return
- */
- SMC37c669_config_mode( FALSE );
- return ret_val;
- }
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function configures a device function within the
- ** SMC37c669 Super I/O controller.
- **
- ** FORMAL PARAMETERS:
- **
- ** func:
- ** Which device function
- **
- ** port:
- ** I/O port for the function to use
- **
- ** irq:
- ** IRQ for the device function to use
- **
- ** drq:
- ** DMA channel for the device function to use
- **
- ** RETURN VALUE:
- **
- ** Returns TRUE if the device function was configured,
- ** otherwise, FALSE.
- **
- ** SIDE EFFECTS:
- **
- ** {@description or none@}
- **
- ** DESIGN:
- **
- ** If this function returns TRUE, the local shadow copy of
- ** the configuration is also updated. If the device function
- ** is currently disabled, only the local shadow copy is
- ** updated and the actual device function will be updated
- ** if/when it is enabled.
- **
- **--
- */
- unsigned int __init SMC37c669_configure_device (
- unsigned int func,
- int port,
- int irq,
- int drq )
- {
- struct DEVICE_CONFIG *cp;
- /*
- ** Check for a valid configuration
- */
- if ( ( cp = SMC37c669_get_config ( func ) ) != NULL ) {
- /*
- ** Configuration is valid, update the local shadow copy
- */
- if ( ( drq & ~0xFF ) == 0 ) {
- cp->drq = drq;
- }
- if ( ( irq & ~0xFF ) == 0 ) {
- cp->irq = irq;
- }
- if ( ( port & ~0xFFFF ) == 0 ) {
- cp->port1 = port;
- }
- /*
- ** If the device function is enabled, update the actual
- ** device configuration.
- */
- if ( SMC37c669_is_device_enabled( func ) ) {
- SMC37c669_enable_device( func );
- }
- return TRUE;
- }
- return FALSE;
- }
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function determines whether a device function
- ** within the SMC37c669 controller is enabled.
- **
- ** FORMAL PARAMETERS:
- **
- ** func:
- ** Which device function
- **
- ** RETURN VALUE:
- **
- ** Returns TRUE if the device function is enabled, otherwise, FALSE
- **
- ** SIDE EFFECTS:
- **
- ** {@description or none@}
- **
- ** DESIGN:
- **
- ** To check whether a device is enabled we will only look at
- ** the port base address mapping. According to the SMC37c669
- ** specification, all of the port base address mappings are
- ** disabled if the addr<9:8> (bits <7:6> of the register) are
- ** zero.
- **
- **--
- */
- static unsigned int __init SMC37c669_is_device_enabled ( unsigned int func )
- {
- unsigned char base_addr = 0;
- unsigned int dev_ok = FALSE;
- unsigned int ret_val = FALSE;
- /*
- ** Enter configuration mode
- */
- SMC37c669_config_mode( TRUE );
-
- switch ( func ) {
- case SERIAL_0:
- base_addr =
- SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
- dev_ok = TRUE;
- break;
- case SERIAL_1:
- base_addr =
- SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
- dev_ok = TRUE;
- break;
- case PARALLEL_0:
- base_addr =
- SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
- dev_ok = TRUE;
- break;
- case FLOPPY_0:
- base_addr =
- SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
- dev_ok = TRUE;
- break;
- case IDE_0:
- base_addr =
- SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
- dev_ok = TRUE;
- break;
- }
- /*
- ** If we have a valid device, check base_addr<7:6> to see if the
- ** device is enabled (mapped).
- */
- if ( ( dev_ok ) && ( ( base_addr & 0xC0 ) != 0 ) ) {
- /*
- ** The mapping is not disabled, so assume that the function is
- ** enabled.
- */
- ret_val = TRUE;
- }
- /*
- ** Exit configuration mode
- */
- SMC37c669_config_mode( FALSE );
- return ret_val;
- }
- #if 0
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function retrieves the configuration information of a
- ** device function within the SMC37c699 Super I/O controller.
- **
- ** FORMAL PARAMETERS:
- **
- ** func:
- ** Which device function
- **
- ** port:
- ** I/O port returned
- **
- ** irq:
- ** IRQ returned
- **
- ** drq:
- ** DMA channel returned
- **
- ** RETURN VALUE:
- **
- ** Returns TRUE if the device configuration was successfully
- ** retrieved, otherwise, FALSE.
- **
- ** SIDE EFFECTS:
- **
- ** The data pointed to by the port, irq, and drq parameters
- ** my be modified even if the configuration is not successfully
- ** retrieved.
- **
- ** DESIGN:
- **
- ** The device configuration is fetched from the local shadow
- ** copy. Any unused parameters will be set to -1. Any
- ** parameter which is not desired can specify the NULL
- ** pointer.
- **
- **--
- */
- static unsigned int __init SMC37c669_get_device_config (
- unsigned int func,
- int *port,
- int *irq,
- int *drq )
- {
- struct DEVICE_CONFIG *cp;
- unsigned int ret_val = FALSE;
- /*
- ** Check for a valid device configuration
- */
- if ( ( cp = SMC37c669_get_config( func ) ) != NULL ) {
- if ( drq != NULL ) {
- *drq = cp->drq;
- ret_val = TRUE;
- }
- if ( irq != NULL ) {
- *irq = cp->irq;
- ret_val = TRUE;
- }
- if ( port != NULL ) {
- *port = cp->port1;
- ret_val = TRUE;
- }
- }
- return ret_val;
- }
- #endif
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function displays the current state of the SMC37c699
- ** Super I/O controller's device functions.
- **
- ** FORMAL PARAMETERS:
- **
- ** None
- **
- ** RETURN VALUE:
- **
- ** None
- **
- ** SIDE EFFECTS:
- **
- ** None
- **
- **--
- */
- void __init SMC37c669_display_device_info ( void )
- {
- if ( SMC37c669_is_device_enabled( SERIAL_0 ) ) {
- printk( " Serial 0: Enabled [ Port 0x%x, IRQ %d ]\n",
- local_config[ SERIAL_0 ].port1,
- local_config[ SERIAL_0 ].irq
- );
- }
- else {
- printk( " Serial 0: Disabled\n" );
- }
- if ( SMC37c669_is_device_enabled( SERIAL_1 ) ) {
- printk( " Serial 1: Enabled [ Port 0x%x, IRQ %d ]\n",
- local_config[ SERIAL_1 ].port1,
- local_config[ SERIAL_1 ].irq
- );
- }
- else {
- printk( " Serial 1: Disabled\n" );
- }
- if ( SMC37c669_is_device_enabled( PARALLEL_0 ) ) {
- printk( " Parallel: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
- local_config[ PARALLEL_0 ].port1,
- local_config[ PARALLEL_0 ].irq,
- local_config[ PARALLEL_0 ].drq
- );
- }
- else {
- printk( " Parallel: Disabled\n" );
- }
- if ( SMC37c669_is_device_enabled( FLOPPY_0 ) ) {
- printk( " Floppy Ctrl: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
- local_config[ FLOPPY_0 ].port1,
- local_config[ FLOPPY_0 ].irq,
- local_config[ FLOPPY_0 ].drq
- );
- }
- else {
- printk( " Floppy Ctrl: Disabled\n" );
- }
- if ( SMC37c669_is_device_enabled( IDE_0 ) ) {
- printk( " IDE 0: Enabled [ Port 0x%x, IRQ %d ]\n",
- local_config[ IDE_0 ].port1,
- local_config[ IDE_0 ].irq
- );
- }
- else {
- printk( " IDE 0: Disabled\n" );
- }
- }
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function puts the SMC37c669 Super I/O controller into,
- ** and takes it out of, configuration mode.
- **
- ** FORMAL PARAMETERS:
- **
- ** enable:
- ** TRUE to enter configuration mode, FALSE to exit.
- **
- ** RETURN VALUE:
- **
- ** None
- **
- ** SIDE EFFECTS:
- **
- ** The SMC37c669 controller may be left in configuration mode.
- **
- **--
- */
- static void __init SMC37c669_config_mode(
- unsigned int enable )
- {
- if ( enable ) {
- /*
- ** To enter configuration mode, two writes in succession to the index
- ** port are required. If a write to another address or port occurs
- ** between these two writes, the chip does not enter configuration
- ** mode. Therefore, a spinlock is placed around the two writes to
- ** guarantee that they complete uninterrupted.
- */
- spin_lock(&smc_lock);
- wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
- wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
- spin_unlock(&smc_lock);
- }
- else {
- wb( &SMC37c669->index_port, SMC37c669_CONFIG_OFF_KEY );
- }
- }
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function reads an SMC37c669 Super I/O controller
- ** configuration register. This function assumes that the
- ** device is already in configuration mode.
- **
- ** FORMAL PARAMETERS:
- **
- ** index:
- ** Index value of configuration register to read
- **
- ** RETURN VALUE:
- **
- ** Data read from configuration register
- **
- ** SIDE EFFECTS:
- **
- ** None
- **
- **--
- */
- static unsigned char __init SMC37c669_read_config(
- unsigned char index )
- {
- unsigned char data;
- wb( &SMC37c669->index_port, index );
- data = rb( &SMC37c669->data_port );
- return data;
- }
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function writes an SMC37c669 Super I/O controller
- ** configuration register. This function assumes that the
- ** device is already in configuration mode.
- **
- ** FORMAL PARAMETERS:
- **
- ** index:
- ** Index of configuration register to write
- **
- ** data:
- ** Data to be written
- **
- ** RETURN VALUE:
- **
- ** None
- **
- ** SIDE EFFECTS:
- **
- ** None
- **
- **--
- */
- static void __init SMC37c669_write_config(
- unsigned char index,
- unsigned char data )
- {
- wb( &SMC37c669->index_port, index );
- wb( &SMC37c669->data_port, data );
- }
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function initializes the local device
- ** configuration storage. This function assumes
- ** that the device is already in configuration
- ** mode.
- **
- ** FORMAL PARAMETERS:
- **
- ** None
- **
- ** RETURN VALUE:
- **
- ** None
- **
- ** SIDE EFFECTS:
- **
- ** Local storage for device configuration information
- ** is initialized.
- **
- **--
- */
- static void __init SMC37c669_init_local_config ( void )
- {
- SMC37c669_SERIAL_BASE_ADDRESS_REGISTER uart_base;
- SMC37c669_SERIAL_IRQ_REGISTER uart_irqs;
- SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER ppt_base;
- SMC37c669_PARALLEL_FDC_IRQ_REGISTER ppt_fdc_irqs;
- SMC37c669_PARALLEL_FDC_DRQ_REGISTER ppt_fdc_drqs;
- SMC37c669_FDC_BASE_ADDRESS_REGISTER fdc_base;
- SMC37c669_IDE_ADDRESS_REGISTER ide_base;
- SMC37c669_IDE_ADDRESS_REGISTER ide_alt;
- /*
- ** Get serial port 1 base address
- */
- uart_base.as_uchar =
- SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
- /*
- ** Get IRQs for serial ports 1 & 2
- */
- uart_irqs.as_uchar =
- SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
- /*
- ** Store local configuration information for serial port 1
- */
- local_config[SERIAL_0].port1 = uart_base.by_field.addr9_3 << 3;
- local_config[SERIAL_0].irq =
- SMC37c669_xlate_irq(
- SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart1_irq )
- );
- /*
- ** Get serial port 2 base address
- */
- uart_base.as_uchar =
- SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
- /*
- ** Store local configuration information for serial port 2
- */
- local_config[SERIAL_1].port1 = uart_base.by_field.addr9_3 << 3;
- local_config[SERIAL_1].irq =
- SMC37c669_xlate_irq(
- SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart2_irq )
- );
- /*
- ** Get parallel port base address
- */
- ppt_base.as_uchar =
- SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
- /*
- ** Get IRQs for parallel port and floppy controller
- */
- ppt_fdc_irqs.as_uchar =
- SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
- /*
- ** Get DRQs for parallel port and floppy controller
- */
- ppt_fdc_drqs.as_uchar =
- SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
- /*
- ** Store local configuration information for parallel port
- */
- local_config[PARALLEL_0].port1 = ppt_base.by_field.addr9_2 << 2;
- local_config[PARALLEL_0].irq =
- SMC37c669_xlate_irq(
- SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.ppt_irq )
- );
- local_config[PARALLEL_0].drq =
- SMC37c669_xlate_drq(
- SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.ppt_drq )
- );
- /*
- ** Get floppy controller base address
- */
- fdc_base.as_uchar =
- SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
- /*
- ** Store local configuration information for floppy controller
- */
- local_config[FLOPPY_0].port1 = fdc_base.by_field.addr9_4 << 4;
- local_config[FLOPPY_0].irq =
- SMC37c669_xlate_irq(
- SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.fdc_irq )
- );
- local_config[FLOPPY_0].drq =
- SMC37c669_xlate_drq(
- SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.fdc_drq )
- );
- /*
- ** Get IDE controller base address
- */
- ide_base.as_uchar =
- SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
- /*
- ** Get IDE alternate status base address
- */
- ide_alt.as_uchar =
- SMC37c669_read_config( SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX );
- /*
- ** Store local configuration information for IDE controller
- */
- local_config[IDE_0].port1 = ide_base.by_field.addr9_4 << 4;
- local_config[IDE_0].port2 = ide_alt.by_field.addr9_4 << 4;
- local_config[IDE_0].irq = 14;
- }
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function returns a pointer to the local shadow
- ** configuration of the requested device function.
- **
- ** FORMAL PARAMETERS:
- **
- ** func:
- ** Which device function
- **
- ** RETURN VALUE:
- **
- ** Returns a pointer to the DEVICE_CONFIG structure for the
- ** requested function, otherwise, NULL.
- **
- ** SIDE EFFECTS:
- **
- ** {@description or none@}
- **
- **--
- */
- static struct DEVICE_CONFIG * __init SMC37c669_get_config( unsigned int func )
- {
- struct DEVICE_CONFIG *cp = NULL;
- switch ( func ) {
- case SERIAL_0:
- cp = &local_config[ SERIAL_0 ];
- break;
- case SERIAL_1:
- cp = &local_config[ SERIAL_1 ];
- break;
- case PARALLEL_0:
- cp = &local_config[ PARALLEL_0 ];
- break;
- case FLOPPY_0:
- cp = &local_config[ FLOPPY_0 ];
- break;
- case IDE_0:
- cp = &local_config[ IDE_0 ];
- break;
- }
- return cp;
- }
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function translates IRQs back and forth between ISA
- ** IRQs and SMC37c669 device IRQs.
- **
- ** FORMAL PARAMETERS:
- **
- ** irq:
- ** The IRQ to translate
- **
- ** RETURN VALUE:
- **
- ** Returns the translated IRQ, otherwise, returns -1.
- **
- ** SIDE EFFECTS:
- **
- ** {@description or none@}
- **
- **--
- */
- static int __init SMC37c669_xlate_irq ( int irq )
- {
- int i, translated_irq = -1;
- if ( SMC37c669_IS_DEVICE_IRQ( irq ) ) {
- /*
- ** We are translating a device IRQ to an ISA IRQ
- */
- for ( i = 0; ( SMC37c669_irq_table[i].device_irq != -1 ) || ( SMC37c669_irq_table[i].isa_irq != -1 ); i++ ) {
- if ( irq == SMC37c669_irq_table[i].device_irq ) {
- translated_irq = SMC37c669_irq_table[i].isa_irq;
- break;
- }
- }
- }
- else {
- /*
- ** We are translating an ISA IRQ to a device IRQ
- */
- for ( i = 0; ( SMC37c669_irq_table[i].isa_irq != -1 ) || ( SMC37c669_irq_table[i].device_irq != -1 ); i++ ) {
- if ( irq == SMC37c669_irq_table[i].isa_irq ) {
- translated_irq = SMC37c669_irq_table[i].device_irq;
- break;
- }
- }
- }
- return translated_irq;
- }
- /*
- **++
- ** FUNCTIONAL DESCRIPTION:
- **
- ** This function translates DMA channels back and forth between
- ** ISA DMA channels and SMC37c669 device DMA channels.
- **
- ** FORMAL PARAMETERS:
- **
- ** drq:
- ** The DMA channel to translate
- **
- ** RETURN VALUE:
- **
- ** Returns the translated DMA channel, otherwise, returns -1
- **
- ** SIDE EFFECTS:
- **
- ** {@description or none@}
- **
- **--
- */
- static int __init SMC37c669_xlate_drq ( int drq )
- {
- int i, translated_drq = -1;
- if ( SMC37c669_IS_DEVICE_DRQ( drq ) ) {
- /*
- ** We are translating a device DMA channel to an ISA DMA channel
- */
- for ( i = 0; ( SMC37c669_drq_table[i].device_drq != -1 ) || ( SMC37c669_drq_table[i].isa_drq != -1 ); i++ ) {
- if ( drq == SMC37c669_drq_table[i].device_drq ) {
- translated_drq = SMC37c669_drq_table[i].isa_drq;
- break;
- }
- }
- }
- else {
- /*
- ** We are translating an ISA DMA channel to a device DMA channel
- */
- for ( i = 0; ( SMC37c669_drq_table[i].isa_drq != -1 ) || ( SMC37c669_drq_table[i].device_drq != -1 ); i++ ) {
- if ( drq == SMC37c669_drq_table[i].isa_drq ) {
- translated_drq = SMC37c669_drq_table[i].device_drq;
- break;
- }
- }
- }
- return translated_drq;
- }
- #if 0
- int __init smcc669_init ( void )
- {
- struct INODE *ip;
- allocinode( smc_ddb.name, 1, &ip );
- ip->dva = &smc_ddb;
- ip->attr = ATTR$M_WRITE | ATTR$M_READ;
- ip->len[0] = 0x30;
- ip->misc = 0;
- INODE_UNLOCK( ip );
- return msg_success;
- }
- int __init smcc669_open( struct FILE *fp, char *info, char *next, char *mode )
- {
- struct INODE *ip;
- /*
- ** Allow multiple readers but only one writer. ip->misc keeps track
- ** of the number of writers
- */
- ip = fp->ip;
- INODE_LOCK( ip );
- if ( fp->mode & ATTR$M_WRITE ) {
- if ( ip->misc ) {
- INODE_UNLOCK( ip );
- return msg_failure; /* too many writers */
- }
- ip->misc++;
- }
- /*
- ** Treat the information field as a byte offset
- */
- *fp->offset = xtoi( info );
- INODE_UNLOCK( ip );
- return msg_success;
- }
- int __init smcc669_close( struct FILE *fp )
- {
- struct INODE *ip;
- ip = fp->ip;
- if ( fp->mode & ATTR$M_WRITE ) {
- INODE_LOCK( ip );
- ip->misc--;
- INODE_UNLOCK( ip );
- }
- return msg_success;
- }
- int __init smcc669_read( struct FILE *fp, int size, int number, unsigned char *buf )
- {
- int i;
- int length;
- int nbytes;
- struct INODE *ip;
- /*
- ** Always access a byte at a time
- */
- ip = fp->ip;
- length = size * number;
- nbytes = 0;
- SMC37c669_config_mode( TRUE );
- for ( i = 0; i < length; i++ ) {
- if ( !inrange( *fp->offset, 0, ip->len[0] ) )
- break;
- *buf++ = SMC37c669_read_config( *fp->offset );
- *fp->offset += 1;
- nbytes++;
- }
- SMC37c669_config_mode( FALSE );
- return nbytes;
- }
- int __init smcc669_write( struct FILE *fp, int size, int number, unsigned char *buf )
- {
- int i;
- int length;
- int nbytes;
- struct INODE *ip;
- /*
- ** Always access a byte at a time
- */
- ip = fp->ip;
- length = size * number;
- nbytes = 0;
- SMC37c669_config_mode( TRUE );
- for ( i = 0; i < length; i++ ) {
- if ( !inrange( *fp->offset, 0, ip->len[0] ) )
- break;
- SMC37c669_write_config( *fp->offset, *buf );
- *fp->offset += 1;
- buf++;
- nbytes++;
- }
- SMC37c669_config_mode( FALSE );
- return nbytes;
- }
- #endif
- void __init
- SMC37c669_dump_registers(void)
- {
- int i;
- for (i = 0; i <= 0x29; i++)
- printk("-- CR%02x : %02x\n", i, SMC37c669_read_config(i));
- }
- /*+
- * ============================================================================
- * = SMC_init - SMC37c669 Super I/O controller initialization =
- * ============================================================================
- *
- * OVERVIEW:
- *
- * This routine configures and enables device functions on the
- * SMC37c669 Super I/O controller.
- *
- * FORM OF CALL:
- *
- * SMC_init( );
- *
- * RETURNS:
- *
- * Nothing
- *
- * ARGUMENTS:
- *
- * None
- *
- * SIDE EFFECTS:
- *
- * None
- *
- */
- void __init SMC669_Init ( int index )
- {
- SMC37c669_CONFIG_REGS *SMC_base;
- unsigned long flags;
- local_irq_save(flags);
- if ( ( SMC_base = SMC37c669_detect( index ) ) != NULL ) {
- #if SMC_DEBUG
- SMC37c669_config_mode( TRUE );
- SMC37c669_dump_registers( );
- SMC37c669_config_mode( FALSE );
- SMC37c669_display_device_info( );
- #endif
- SMC37c669_disable_device( SERIAL_0 );
- SMC37c669_configure_device(
- SERIAL_0,
- COM1_BASE,
- COM1_IRQ,
- -1
- );
- SMC37c669_enable_device( SERIAL_0 );
- SMC37c669_disable_device( SERIAL_1 );
- SMC37c669_configure_device(
- SERIAL_1,
- COM2_BASE,
- COM2_IRQ,
- -1
- );
- SMC37c669_enable_device( SERIAL_1 );
- SMC37c669_disable_device( PARALLEL_0 );
- SMC37c669_configure_device(
- PARALLEL_0,
- PARP_BASE,
- PARP_IRQ,
- PARP_DRQ
- );
- SMC37c669_enable_device( PARALLEL_0 );
- SMC37c669_disable_device( FLOPPY_0 );
- SMC37c669_configure_device(
- FLOPPY_0,
- FDC_BASE,
- FDC_IRQ,
- FDC_DRQ
- );
- SMC37c669_enable_device( FLOPPY_0 );
-
- /* Wake up sometimes forgotten floppy, especially on DP264. */
- outb(0xc, 0x3f2);
- SMC37c669_disable_device( IDE_0 );
- #if SMC_DEBUG
- SMC37c669_config_mode( TRUE );
- SMC37c669_dump_registers( );
- SMC37c669_config_mode( FALSE );
- SMC37c669_display_device_info( );
- #endif
- local_irq_restore(flags);
- printk( "SMC37c669 Super I/O Controller found @ 0x%p\n",
- SMC_base );
- }
- else {
- local_irq_restore(flags);
- #if SMC_DEBUG
- printk( "No SMC37c669 Super I/O Controller found\n" );
- #endif
- }
- }
|