smc37c669.c 60 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554
  1. /*
  2. * SMC 37C669 initialization code
  3. */
  4. #include <linux/kernel.h>
  5. #include <linux/mm.h>
  6. #include <linux/init.h>
  7. #include <linux/delay.h>
  8. #include <linux/spinlock.h>
  9. #include <asm/hwrpb.h>
  10. #include <asm/io.h>
  11. #include <asm/segment.h>
  12. #if 0
  13. # define DBG_DEVS(args) printk args
  14. #else
  15. # define DBG_DEVS(args)
  16. #endif
  17. #define KB 1024
  18. #define MB (1024*KB)
  19. #define GB (1024*MB)
  20. #define SMC_DEBUG 0
  21. /* File: smcc669_def.h
  22. *
  23. * Copyright (C) 1997 by
  24. * Digital Equipment Corporation, Maynard, Massachusetts.
  25. * All rights reserved.
  26. *
  27. * This software is furnished under a license and may be used and copied
  28. * only in accordance of the terms of such license and with the
  29. * inclusion of the above copyright notice. This software or any other
  30. * copies thereof may not be provided or otherwise made available to any
  31. * other person. No title to and ownership of the software is hereby
  32. * transferred.
  33. *
  34. * The information in this software is subject to change without notice
  35. * and should not be construed as a commitment by Digital Equipment
  36. * Corporation.
  37. *
  38. * Digital assumes no responsibility for the use or reliability of its
  39. * software on equipment which is not supplied by Digital.
  40. *
  41. *
  42. * Abstract:
  43. *
  44. * This file contains header definitions for the SMC37c669
  45. * Super I/O controller.
  46. *
  47. * Author:
  48. *
  49. * Eric Rasmussen
  50. *
  51. * Modification History:
  52. *
  53. * er 28-Jan-1997 Initial Entry
  54. */
  55. #ifndef __SMC37c669_H
  56. #define __SMC37c669_H
  57. /*
  58. ** Macros for handling device IRQs
  59. **
  60. ** The mask acts as a flag used in mapping actual ISA IRQs (0 - 15)
  61. ** to device IRQs (A - H).
  62. */
  63. #define SMC37c669_DEVICE_IRQ_MASK 0x80000000
  64. #define SMC37c669_DEVICE_IRQ( __i ) \
  65. ((SMC37c669_DEVICE_IRQ_MASK) | (__i))
  66. #define SMC37c669_IS_DEVICE_IRQ(__i) \
  67. (((__i) & (SMC37c669_DEVICE_IRQ_MASK)) == (SMC37c669_DEVICE_IRQ_MASK))
  68. #define SMC37c669_RAW_DEVICE_IRQ(__i) \
  69. ((__i) & ~(SMC37c669_DEVICE_IRQ_MASK))
  70. /*
  71. ** Macros for handling device DRQs
  72. **
  73. ** The mask acts as a flag used in mapping actual ISA DMA
  74. ** channels to device DMA channels (A - C).
  75. */
  76. #define SMC37c669_DEVICE_DRQ_MASK 0x80000000
  77. #define SMC37c669_DEVICE_DRQ(__d) \
  78. ((SMC37c669_DEVICE_DRQ_MASK) | (__d))
  79. #define SMC37c669_IS_DEVICE_DRQ(__d) \
  80. (((__d) & (SMC37c669_DEVICE_DRQ_MASK)) == (SMC37c669_DEVICE_DRQ_MASK))
  81. #define SMC37c669_RAW_DEVICE_DRQ(__d) \
  82. ((__d) & ~(SMC37c669_DEVICE_DRQ_MASK))
  83. #define SMC37c669_DEVICE_ID 0x3
  84. /*
  85. ** SMC37c669 Device Function Definitions
  86. */
  87. #define SERIAL_0 0
  88. #define SERIAL_1 1
  89. #define PARALLEL_0 2
  90. #define FLOPPY_0 3
  91. #define IDE_0 4
  92. #define NUM_FUNCS 5
  93. /*
  94. ** Default Device Function Mappings
  95. */
  96. #define COM1_BASE 0x3F8
  97. #define COM1_IRQ 4
  98. #define COM2_BASE 0x2F8
  99. #define COM2_IRQ 3
  100. #define PARP_BASE 0x3BC
  101. #define PARP_IRQ 7
  102. #define PARP_DRQ 3
  103. #define FDC_BASE 0x3F0
  104. #define FDC_IRQ 6
  105. #define FDC_DRQ 2
  106. /*
  107. ** Configuration On/Off Key Definitions
  108. */
  109. #define SMC37c669_CONFIG_ON_KEY 0x55
  110. #define SMC37c669_CONFIG_OFF_KEY 0xAA
  111. /*
  112. ** SMC 37c669 Device IRQs
  113. */
  114. #define SMC37c669_DEVICE_IRQ_A ( SMC37c669_DEVICE_IRQ( 0x01 ) )
  115. #define SMC37c669_DEVICE_IRQ_B ( SMC37c669_DEVICE_IRQ( 0x02 ) )
  116. #define SMC37c669_DEVICE_IRQ_C ( SMC37c669_DEVICE_IRQ( 0x03 ) )
  117. #define SMC37c669_DEVICE_IRQ_D ( SMC37c669_DEVICE_IRQ( 0x04 ) )
  118. #define SMC37c669_DEVICE_IRQ_E ( SMC37c669_DEVICE_IRQ( 0x05 ) )
  119. #define SMC37c669_DEVICE_IRQ_F ( SMC37c669_DEVICE_IRQ( 0x06 ) )
  120. /* SMC37c669_DEVICE_IRQ_G *** RESERVED ***/
  121. #define SMC37c669_DEVICE_IRQ_H ( SMC37c669_DEVICE_IRQ( 0x08 ) )
  122. /*
  123. ** SMC 37c669 Device DMA Channel Definitions
  124. */
  125. #define SMC37c669_DEVICE_DRQ_A ( SMC37c669_DEVICE_DRQ( 0x01 ) )
  126. #define SMC37c669_DEVICE_DRQ_B ( SMC37c669_DEVICE_DRQ( 0x02 ) )
  127. #define SMC37c669_DEVICE_DRQ_C ( SMC37c669_DEVICE_DRQ( 0x03 ) )
  128. /*
  129. ** Configuration Register Index Definitions
  130. */
  131. #define SMC37c669_CR00_INDEX 0x00
  132. #define SMC37c669_CR01_INDEX 0x01
  133. #define SMC37c669_CR02_INDEX 0x02
  134. #define SMC37c669_CR03_INDEX 0x03
  135. #define SMC37c669_CR04_INDEX 0x04
  136. #define SMC37c669_CR05_INDEX 0x05
  137. #define SMC37c669_CR06_INDEX 0x06
  138. #define SMC37c669_CR07_INDEX 0x07
  139. #define SMC37c669_CR08_INDEX 0x08
  140. #define SMC37c669_CR09_INDEX 0x09
  141. #define SMC37c669_CR0A_INDEX 0x0A
  142. #define SMC37c669_CR0B_INDEX 0x0B
  143. #define SMC37c669_CR0C_INDEX 0x0C
  144. #define SMC37c669_CR0D_INDEX 0x0D
  145. #define SMC37c669_CR0E_INDEX 0x0E
  146. #define SMC37c669_CR0F_INDEX 0x0F
  147. #define SMC37c669_CR10_INDEX 0x10
  148. #define SMC37c669_CR11_INDEX 0x11
  149. #define SMC37c669_CR12_INDEX 0x12
  150. #define SMC37c669_CR13_INDEX 0x13
  151. #define SMC37c669_CR14_INDEX 0x14
  152. #define SMC37c669_CR15_INDEX 0x15
  153. #define SMC37c669_CR16_INDEX 0x16
  154. #define SMC37c669_CR17_INDEX 0x17
  155. #define SMC37c669_CR18_INDEX 0x18
  156. #define SMC37c669_CR19_INDEX 0x19
  157. #define SMC37c669_CR1A_INDEX 0x1A
  158. #define SMC37c669_CR1B_INDEX 0x1B
  159. #define SMC37c669_CR1C_INDEX 0x1C
  160. #define SMC37c669_CR1D_INDEX 0x1D
  161. #define SMC37c669_CR1E_INDEX 0x1E
  162. #define SMC37c669_CR1F_INDEX 0x1F
  163. #define SMC37c669_CR20_INDEX 0x20
  164. #define SMC37c669_CR21_INDEX 0x21
  165. #define SMC37c669_CR22_INDEX 0x22
  166. #define SMC37c669_CR23_INDEX 0x23
  167. #define SMC37c669_CR24_INDEX 0x24
  168. #define SMC37c669_CR25_INDEX 0x25
  169. #define SMC37c669_CR26_INDEX 0x26
  170. #define SMC37c669_CR27_INDEX 0x27
  171. #define SMC37c669_CR28_INDEX 0x28
  172. #define SMC37c669_CR29_INDEX 0x29
  173. /*
  174. ** Configuration Register Alias Definitions
  175. */
  176. #define SMC37c669_DEVICE_ID_INDEX SMC37c669_CR0D_INDEX
  177. #define SMC37c669_DEVICE_REVISION_INDEX SMC37c669_CR0E_INDEX
  178. #define SMC37c669_FDC_BASE_ADDRESS_INDEX SMC37c669_CR20_INDEX
  179. #define SMC37c669_IDE_BASE_ADDRESS_INDEX SMC37c669_CR21_INDEX
  180. #define SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX SMC37c669_CR22_INDEX
  181. #define SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX SMC37c669_CR23_INDEX
  182. #define SMC37c669_SERIAL0_BASE_ADDRESS_INDEX SMC37c669_CR24_INDEX
  183. #define SMC37c669_SERIAL1_BASE_ADDRESS_INDEX SMC37c669_CR25_INDEX
  184. #define SMC37c669_PARALLEL_FDC_DRQ_INDEX SMC37c669_CR26_INDEX
  185. #define SMC37c669_PARALLEL_FDC_IRQ_INDEX SMC37c669_CR27_INDEX
  186. #define SMC37c669_SERIAL_IRQ_INDEX SMC37c669_CR28_INDEX
  187. /*
  188. ** Configuration Register Definitions
  189. **
  190. ** The INDEX (write only) and DATA (read/write) ports are effective
  191. ** only when the chip is in the Configuration State.
  192. */
  193. typedef struct _SMC37c669_CONFIG_REGS {
  194. unsigned char index_port;
  195. unsigned char data_port;
  196. } SMC37c669_CONFIG_REGS;
  197. /*
  198. ** CR00 - default value 0x28
  199. **
  200. ** IDE_EN (CR00<1:0>):
  201. ** 0x - 30ua pull-ups on nIDEEN, nHDCS0, NHDCS1
  202. ** 11 - IRQ_H available as IRQ output,
  203. ** IRRX2, IRTX2 available as alternate IR pins
  204. ** 10 - nIDEEN, nHDCS0, nHDCS1 used to control IDE
  205. **
  206. ** VALID (CR00<7>):
  207. ** A high level on this software controlled bit can
  208. ** be used to indicate that a valid configuration
  209. ** cycle has occurred. The control software must
  210. ** take care to set this bit at the appropriate times.
  211. ** Set to zero after power up. This bit has no
  212. ** effect on any other hardware in the chip.
  213. **
  214. */
  215. typedef union _SMC37c669_CR00 {
  216. unsigned char as_uchar;
  217. struct {
  218. unsigned ide_en : 2; /* See note above */
  219. unsigned reserved1 : 1; /* RAZ */
  220. unsigned fdc_pwr : 1; /* 1 = supply power to FDC */
  221. unsigned reserved2 : 3; /* Read as 010b */
  222. unsigned valid : 1; /* See note above */
  223. } by_field;
  224. } SMC37c669_CR00;
  225. /*
  226. ** CR01 - default value 0x9C
  227. */
  228. typedef union _SMC37c669_CR01 {
  229. unsigned char as_uchar;
  230. struct {
  231. unsigned reserved1 : 2; /* RAZ */
  232. unsigned ppt_pwr : 1; /* 1 = supply power to PPT */
  233. unsigned ppt_mode : 1; /* 1 = Printer mode, 0 = EPP */
  234. unsigned reserved2 : 1; /* Read as 1 */
  235. unsigned reserved3 : 2; /* RAZ */
  236. unsigned lock_crx: 1; /* Lock CR00 - CR18 */
  237. } by_field;
  238. } SMC37c669_CR01;
  239. /*
  240. ** CR02 - default value 0x88
  241. */
  242. typedef union _SMC37c669_CR02 {
  243. unsigned char as_uchar;
  244. struct {
  245. unsigned reserved1 : 3; /* RAZ */
  246. unsigned uart1_pwr : 1; /* 1 = supply power to UART1 */
  247. unsigned reserved2 : 3; /* RAZ */
  248. unsigned uart2_pwr : 1; /* 1 = supply power to UART2 */
  249. } by_field;
  250. } SMC37c669_CR02;
  251. /*
  252. ** CR03 - default value 0x78
  253. **
  254. ** CR03<7> CR03<2> Pin 94
  255. ** ------- ------- ------
  256. ** 0 X DRV2 (input)
  257. ** 1 0 ADRX
  258. ** 1 1 IRQ_B
  259. **
  260. ** CR03<6> CR03<5> Op Mode
  261. ** ------- ------- -------
  262. ** 0 0 Model 30
  263. ** 0 1 PS/2
  264. ** 1 0 Reserved
  265. ** 1 1 AT Mode
  266. */
  267. typedef union _SMC37c669_CR03 {
  268. unsigned char as_uchar;
  269. struct {
  270. unsigned pwrgd_gamecs : 1; /* 1 = PWRGD, 0 = GAMECS */
  271. unsigned fdc_mode2 : 1; /* 1 = Enhanced Mode 2 */
  272. unsigned pin94_0 : 1; /* See note above */
  273. unsigned reserved1 : 1; /* RAZ */
  274. unsigned drvden : 1; /* 1 = high, 0 - output */
  275. unsigned op_mode : 2; /* See note above */
  276. unsigned pin94_1 : 1; /* See note above */
  277. } by_field;
  278. } SMC37c669_CR03;
  279. /*
  280. ** CR04 - default value 0x00
  281. **
  282. ** PP_EXT_MODE:
  283. ** If CR01<PP_MODE> = 0 and PP_EXT_MODE =
  284. ** 00 - Standard and Bidirectional
  285. ** 01 - EPP mode and SPP
  286. ** 10 - ECP mode
  287. ** In this mode, 2 drives can be supported
  288. ** directly, 3 or 4 drives must use external
  289. ** 4 drive support. SPP can be selected
  290. ** through the ECR register of ECP as mode 000.
  291. ** 11 - ECP mode and EPP mode
  292. ** In this mode, 2 drives can be supported
  293. ** directly, 3 or 4 drives must use external
  294. ** 4 drive support. SPP can be selected
  295. ** through the ECR register of ECP as mode 000.
  296. ** In this mode, EPP can be selected through
  297. ** the ECR register of ECP as mode 100.
  298. **
  299. ** PP_FDC:
  300. ** 00 - Normal
  301. ** 01 - PPFD1
  302. ** 10 - PPFD2
  303. ** 11 - Reserved
  304. **
  305. ** MIDI1:
  306. ** Serial Clock Select:
  307. ** A low level on this bit disables MIDI support,
  308. ** clock = divide by 13. A high level on this
  309. ** bit enables MIDI support, clock = divide by 12.
  310. **
  311. ** MIDI operates at 31.25 Kbps which can be derived
  312. ** from 125 KHz (24 MHz / 12 = 2 MHz, 2 MHz / 16 = 125 KHz)
  313. **
  314. ** ALT_IO:
  315. ** 0 - Use pins IRRX, IRTX
  316. ** 1 - Use pins IRRX2, IRTX2
  317. **
  318. ** If this bit is set, the IR receive and transmit
  319. ** functions will not be available on pins 25 and 26
  320. ** unless CR00<IDE_EN> = 11.
  321. */
  322. typedef union _SMC37c669_CR04 {
  323. unsigned char as_uchar;
  324. struct {
  325. unsigned ppt_ext_mode : 2; /* See note above */
  326. unsigned ppt_fdc : 2; /* See note above */
  327. unsigned midi1 : 1; /* See note above */
  328. unsigned midi2 : 1; /* See note above */
  329. unsigned epp_type : 1; /* 0 = EPP 1.9, 1 = EPP 1.7 */
  330. unsigned alt_io : 1; /* See note above */
  331. } by_field;
  332. } SMC37c669_CR04;
  333. /*
  334. ** CR05 - default value 0x00
  335. **
  336. ** DEN_SEL:
  337. ** 00 - Densel output normal
  338. ** 01 - Reserved
  339. ** 10 - Densel output 1
  340. ** 11 - Densel output 0
  341. **
  342. */
  343. typedef union _SMC37c669_CR05 {
  344. unsigned char as_uchar;
  345. struct {
  346. unsigned reserved1 : 2; /* RAZ */
  347. unsigned fdc_dma_mode : 1; /* 0 = burst, 1 = non-burst */
  348. unsigned den_sel : 2; /* See note above */
  349. unsigned swap_drv : 1; /* Swap the FDC motor selects */
  350. unsigned extx4 : 1; /* 0 = 2 drive, 1 = external 4 drive decode */
  351. unsigned reserved2 : 1; /* RAZ */
  352. } by_field;
  353. } SMC37c669_CR05;
  354. /*
  355. ** CR06 - default value 0xFF
  356. */
  357. typedef union _SMC37c669_CR06 {
  358. unsigned char as_uchar;
  359. struct {
  360. unsigned floppy_a : 2; /* Type of floppy drive A */
  361. unsigned floppy_b : 2; /* Type of floppy drive B */
  362. unsigned floppy_c : 2; /* Type of floppy drive C */
  363. unsigned floppy_d : 2; /* Type of floppy drive D */
  364. } by_field;
  365. } SMC37c669_CR06;
  366. /*
  367. ** CR07 - default value 0x00
  368. **
  369. ** Auto Power Management CR07<7:4>:
  370. ** 0 - Auto Powerdown disabled (default)
  371. ** 1 - Auto Powerdown enabled
  372. **
  373. ** This bit is reset to the default state by POR or
  374. ** a hardware reset.
  375. **
  376. */
  377. typedef union _SMC37c669_CR07 {
  378. unsigned char as_uchar;
  379. struct {
  380. unsigned floppy_boot : 2; /* 0 = A:, 1 = B: */
  381. unsigned reserved1 : 2; /* RAZ */
  382. unsigned ppt_en : 1; /* See note above */
  383. unsigned uart1_en : 1; /* See note above */
  384. unsigned uart2_en : 1; /* See note above */
  385. unsigned fdc_en : 1; /* See note above */
  386. } by_field;
  387. } SMC37c669_CR07;
  388. /*
  389. ** CR08 - default value 0x00
  390. */
  391. typedef union _SMC37c669_CR08 {
  392. unsigned char as_uchar;
  393. struct {
  394. unsigned zero : 4; /* 0 */
  395. unsigned addrx7_4 : 4; /* ADR<7:3> for ADRx decode */
  396. } by_field;
  397. } SMC37c669_CR08;
  398. /*
  399. ** CR09 - default value 0x00
  400. **
  401. ** ADRx_CONFIG:
  402. ** 00 - ADRx disabled
  403. ** 01 - 1 byte decode A<3:0> = 0000b
  404. ** 10 - 8 byte block decode A<3:0> = 0XXXb
  405. ** 11 - 16 byte block decode A<3:0> = XXXXb
  406. **
  407. */
  408. typedef union _SMC37c669_CR09 {
  409. unsigned char as_uchar;
  410. struct {
  411. unsigned adra8 : 3; /* ADR<10:8> for ADRx decode */
  412. unsigned reserved1 : 3;
  413. unsigned adrx_config : 2; /* See note above */
  414. } by_field;
  415. } SMC37c669_CR09;
  416. /*
  417. ** CR0A - default value 0x00
  418. */
  419. typedef union _SMC37c669_CR0A {
  420. unsigned char as_uchar;
  421. struct {
  422. unsigned ecp_fifo_threshold : 4;
  423. unsigned reserved1 : 4;
  424. } by_field;
  425. } SMC37c669_CR0A;
  426. /*
  427. ** CR0B - default value 0x00
  428. */
  429. typedef union _SMC37c669_CR0B {
  430. unsigned char as_uchar;
  431. struct {
  432. unsigned fdd0_drtx : 2; /* FDD0 Data Rate Table */
  433. unsigned fdd1_drtx : 2; /* FDD1 Data Rate Table */
  434. unsigned fdd2_drtx : 2; /* FDD2 Data Rate Table */
  435. unsigned fdd3_drtx : 2; /* FDD3 Data Rate Table */
  436. } by_field;
  437. } SMC37c669_CR0B;
  438. /*
  439. ** CR0C - default value 0x00
  440. **
  441. ** UART2_MODE:
  442. ** 000 - Standard (default)
  443. ** 001 - IrDA (HPSIR)
  444. ** 010 - Amplitude Shift Keyed IR @500 KHz
  445. ** 011 - Reserved
  446. ** 1xx - Reserved
  447. **
  448. */
  449. typedef union _SMC37c669_CR0C {
  450. unsigned char as_uchar;
  451. struct {
  452. unsigned uart2_rcv_polarity : 1; /* 1 = invert RX */
  453. unsigned uart2_xmit_polarity : 1; /* 1 = invert TX */
  454. unsigned uart2_duplex : 1; /* 1 = full, 0 = half */
  455. unsigned uart2_mode : 3; /* See note above */
  456. unsigned uart1_speed : 1; /* 1 = high speed enabled */
  457. unsigned uart2_speed : 1; /* 1 = high speed enabled */
  458. } by_field;
  459. } SMC37c669_CR0C;
  460. /*
  461. ** CR0D - default value 0x03
  462. **
  463. ** Device ID Register - read only
  464. */
  465. typedef union _SMC37c669_CR0D {
  466. unsigned char as_uchar;
  467. struct {
  468. unsigned device_id : 8; /* Returns 0x3 in this field */
  469. } by_field;
  470. } SMC37c669_CR0D;
  471. /*
  472. ** CR0E - default value 0x02
  473. **
  474. ** Device Revision Register - read only
  475. */
  476. typedef union _SMC37c669_CR0E {
  477. unsigned char as_uchar;
  478. struct {
  479. unsigned device_rev : 8; /* Returns 0x2 in this field */
  480. } by_field;
  481. } SMC37c669_CR0E;
  482. /*
  483. ** CR0F - default value 0x00
  484. */
  485. typedef union _SMC37c669_CR0F {
  486. unsigned char as_uchar;
  487. struct {
  488. unsigned test0 : 1; /* Reserved - set to 0 */
  489. unsigned test1 : 1; /* Reserved - set to 0 */
  490. unsigned test2 : 1; /* Reserved - set to 0 */
  491. unsigned test3 : 1; /* Reserved - set t0 0 */
  492. unsigned test4 : 1; /* Reserved - set to 0 */
  493. unsigned test5 : 1; /* Reserved - set t0 0 */
  494. unsigned test6 : 1; /* Reserved - set t0 0 */
  495. unsigned test7 : 1; /* Reserved - set to 0 */
  496. } by_field;
  497. } SMC37c669_CR0F;
  498. /*
  499. ** CR10 - default value 0x00
  500. */
  501. typedef union _SMC37c669_CR10 {
  502. unsigned char as_uchar;
  503. struct {
  504. unsigned reserved1 : 3; /* RAZ */
  505. unsigned pll_gain : 1; /* 1 = 3V, 2 = 5V operation */
  506. unsigned pll_stop : 1; /* 1 = stop PLLs */
  507. unsigned ace_stop : 1; /* 1 = stop UART clocks */
  508. unsigned pll_clock_ctrl : 1; /* 0 = 14.318 MHz, 1 = 24 MHz */
  509. unsigned ir_test : 1; /* Enable IR test mode */
  510. } by_field;
  511. } SMC37c669_CR10;
  512. /*
  513. ** CR11 - default value 0x00
  514. */
  515. typedef union _SMC37c669_CR11 {
  516. unsigned char as_uchar;
  517. struct {
  518. unsigned ir_loopback : 1; /* Internal IR loop back */
  519. unsigned test_10ms : 1; /* Test 10ms autopowerdown FDC timeout */
  520. unsigned reserved1 : 6; /* RAZ */
  521. } by_field;
  522. } SMC37c669_CR11;
  523. /*
  524. ** CR12 - CR1D are reserved registers
  525. */
  526. /*
  527. ** CR1E - default value 0x80
  528. **
  529. ** GAMECS:
  530. ** 00 - GAMECS disabled
  531. ** 01 - 1 byte decode ADR<3:0> = 0001b
  532. ** 10 - 8 byte block decode ADR<3:0> = 0XXXb
  533. ** 11 - 16 byte block decode ADR<3:0> = XXXXb
  534. **
  535. */
  536. typedef union _SMC37c66_CR1E {
  537. unsigned char as_uchar;
  538. struct {
  539. unsigned gamecs_config: 2; /* See note above */
  540. unsigned gamecs_addr9_4 : 6; /* GAMECS Addr<9:4> */
  541. } by_field;
  542. } SMC37c669_CR1E;
  543. /*
  544. ** CR1F - default value 0x00
  545. **
  546. ** DT0 DT1 DRVDEN0 DRVDEN1 Drive Type
  547. ** --- --- ------- ------- ----------
  548. ** 0 0 DENSEL DRATE0 4/2/1 MB 3.5"
  549. ** 2/1 MB 5.25"
  550. ** 2/1.6/1 MB 3.5" (3-mode)
  551. ** 0 1 DRATE1 DRATE0
  552. ** 1 0 nDENSEL DRATE0 PS/2
  553. ** 1 1 DRATE0 DRATE1
  554. **
  555. ** Note: DENSEL, DRATE1, and DRATE0 map onto two output
  556. ** pins - DRVDEN0 and DRVDEN1.
  557. **
  558. */
  559. typedef union _SMC37c669_CR1F {
  560. unsigned char as_uchar;
  561. struct {
  562. unsigned fdd0_drive_type : 2; /* FDD0 drive type */
  563. unsigned fdd1_drive_type : 2; /* FDD1 drive type */
  564. unsigned fdd2_drive_type : 2; /* FDD2 drive type */
  565. unsigned fdd3_drive_type : 2; /* FDD3 drive type */
  566. } by_field;
  567. } SMC37c669_CR1F;
  568. /*
  569. ** CR20 - default value 0x3C
  570. **
  571. ** FDC Base Address Register
  572. ** - To disable this decode set Addr<9:8> = 0
  573. ** - A<10> = 0, A<3:0> = 0XXXb to access.
  574. **
  575. */
  576. typedef union _SMC37c669_CR20 {
  577. unsigned char as_uchar;
  578. struct {
  579. unsigned zero : 2; /* 0 */
  580. unsigned addr9_4 : 6; /* FDC Addr<9:4> */
  581. } by_field;
  582. } SMC37c669_CR20;
  583. /*
  584. ** CR21 - default value 0x3C
  585. **
  586. ** IDE Base Address Register
  587. ** - To disable this decode set Addr<9:8> = 0
  588. ** - A<10> = 0, A<3:0> = 0XXXb to access.
  589. **
  590. */
  591. typedef union _SMC37c669_CR21 {
  592. unsigned char as_uchar;
  593. struct {
  594. unsigned zero : 2; /* 0 */
  595. unsigned addr9_4 : 6; /* IDE Addr<9:4> */
  596. } by_field;
  597. } SMC37c669_CR21;
  598. /*
  599. ** CR22 - default value 0x3D
  600. **
  601. ** IDE Alternate Status Base Address Register
  602. ** - To disable this decode set Addr<9:8> = 0
  603. ** - A<10> = 0, A<3:0> = 0110b to access.
  604. **
  605. */
  606. typedef union _SMC37c669_CR22 {
  607. unsigned char as_uchar;
  608. struct {
  609. unsigned zero : 2; /* 0 */
  610. unsigned addr9_4 : 6; /* IDE Alt Status Addr<9:4> */
  611. } by_field;
  612. } SMC37c669_CR22;
  613. /*
  614. ** CR23 - default value 0x00
  615. **
  616. ** Parallel Port Base Address Register
  617. ** - To disable this decode set Addr<9:8> = 0
  618. ** - A<10> = 0 to access.
  619. ** - If EPP is enabled, A<2:0> = XXXb to access.
  620. ** If EPP is NOT enabled, A<1:0> = XXb to access
  621. **
  622. */
  623. typedef union _SMC37c669_CR23 {
  624. unsigned char as_uchar;
  625. struct {
  626. unsigned addr9_2 : 8; /* Parallel Port Addr<9:2> */
  627. } by_field;
  628. } SMC37c669_CR23;
  629. /*
  630. ** CR24 - default value 0x00
  631. **
  632. ** UART1 Base Address Register
  633. ** - To disable this decode set Addr<9:8> = 0
  634. ** - A<10> = 0, A<2:0> = XXXb to access.
  635. **
  636. */
  637. typedef union _SMC37c669_CR24 {
  638. unsigned char as_uchar;
  639. struct {
  640. unsigned zero : 1; /* 0 */
  641. unsigned addr9_3 : 7; /* UART1 Addr<9:3> */
  642. } by_field;
  643. } SMC37c669_CR24;
  644. /*
  645. ** CR25 - default value 0x00
  646. **
  647. ** UART2 Base Address Register
  648. ** - To disable this decode set Addr<9:8> = 0
  649. ** - A<10> = 0, A<2:0> = XXXb to access.
  650. **
  651. */
  652. typedef union _SMC37c669_CR25 {
  653. unsigned char as_uchar;
  654. struct {
  655. unsigned zero : 1; /* 0 */
  656. unsigned addr9_3 : 7; /* UART2 Addr<9:3> */
  657. } by_field;
  658. } SMC37c669_CR25;
  659. /*
  660. ** CR26 - default value 0x00
  661. **
  662. ** Parallel Port / FDC DMA Select Register
  663. **
  664. ** D3 - D0 DMA
  665. ** D7 - D4 Selected
  666. ** ------- --------
  667. ** 0000 None
  668. ** 0001 DMA_A
  669. ** 0010 DMA_B
  670. ** 0011 DMA_C
  671. **
  672. */
  673. typedef union _SMC37c669_CR26 {
  674. unsigned char as_uchar;
  675. struct {
  676. unsigned ppt_drq : 4; /* See note above */
  677. unsigned fdc_drq : 4; /* See note above */
  678. } by_field;
  679. } SMC37c669_CR26;
  680. /*
  681. ** CR27 - default value 0x00
  682. **
  683. ** Parallel Port / FDC IRQ Select Register
  684. **
  685. ** D3 - D0 IRQ
  686. ** D7 - D4 Selected
  687. ** ------- --------
  688. ** 0000 None
  689. ** 0001 IRQ_A
  690. ** 0010 IRQ_B
  691. ** 0011 IRQ_C
  692. ** 0100 IRQ_D
  693. ** 0101 IRQ_E
  694. ** 0110 IRQ_F
  695. ** 0111 Reserved
  696. ** 1000 IRQ_H
  697. **
  698. ** Any unselected IRQ REQ is in tristate
  699. **
  700. */
  701. typedef union _SMC37c669_CR27 {
  702. unsigned char as_uchar;
  703. struct {
  704. unsigned ppt_irq : 4; /* See note above */
  705. unsigned fdc_irq : 4; /* See note above */
  706. } by_field;
  707. } SMC37c669_CR27;
  708. /*
  709. ** CR28 - default value 0x00
  710. **
  711. ** UART IRQ Select Register
  712. **
  713. ** D3 - D0 IRQ
  714. ** D7 - D4 Selected
  715. ** ------- --------
  716. ** 0000 None
  717. ** 0001 IRQ_A
  718. ** 0010 IRQ_B
  719. ** 0011 IRQ_C
  720. ** 0100 IRQ_D
  721. ** 0101 IRQ_E
  722. ** 0110 IRQ_F
  723. ** 0111 Reserved
  724. ** 1000 IRQ_H
  725. ** 1111 share with UART1 (only for UART2)
  726. **
  727. ** Any unselected IRQ REQ is in tristate
  728. **
  729. ** To share an IRQ between UART1 and UART2, set
  730. ** UART1 to use the desired IRQ and set UART2 to
  731. ** 0xF to enable sharing mechanism.
  732. **
  733. */
  734. typedef union _SMC37c669_CR28 {
  735. unsigned char as_uchar;
  736. struct {
  737. unsigned uart2_irq : 4; /* See note above */
  738. unsigned uart1_irq : 4; /* See note above */
  739. } by_field;
  740. } SMC37c669_CR28;
  741. /*
  742. ** CR29 - default value 0x00
  743. **
  744. ** IRQIN IRQ Select Register
  745. **
  746. ** D3 - D0 IRQ
  747. ** D7 - D4 Selected
  748. ** ------- --------
  749. ** 0000 None
  750. ** 0001 IRQ_A
  751. ** 0010 IRQ_B
  752. ** 0011 IRQ_C
  753. ** 0100 IRQ_D
  754. ** 0101 IRQ_E
  755. ** 0110 IRQ_F
  756. ** 0111 Reserved
  757. ** 1000 IRQ_H
  758. **
  759. ** Any unselected IRQ REQ is in tristate
  760. **
  761. */
  762. typedef union _SMC37c669_CR29 {
  763. unsigned char as_uchar;
  764. struct {
  765. unsigned irqin_irq : 4; /* See note above */
  766. unsigned reserved1 : 4; /* RAZ */
  767. } by_field;
  768. } SMC37c669_CR29;
  769. /*
  770. ** Aliases of Configuration Register formats (should match
  771. ** the set of index aliases).
  772. **
  773. ** Note that CR24 and CR25 have the same format and are the
  774. ** base address registers for UART1 and UART2. Because of
  775. ** this we only define 1 alias here - for CR24 - as the serial
  776. ** base address register.
  777. **
  778. ** Note that CR21 and CR22 have the same format and are the
  779. ** base address and alternate status address registers for
  780. ** the IDE controller. Because of this we only define 1 alias
  781. ** here - for CR21 - as the IDE address register.
  782. **
  783. */
  784. typedef SMC37c669_CR0D SMC37c669_DEVICE_ID_REGISTER;
  785. typedef SMC37c669_CR0E SMC37c669_DEVICE_REVISION_REGISTER;
  786. typedef SMC37c669_CR20 SMC37c669_FDC_BASE_ADDRESS_REGISTER;
  787. typedef SMC37c669_CR21 SMC37c669_IDE_ADDRESS_REGISTER;
  788. typedef SMC37c669_CR23 SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER;
  789. typedef SMC37c669_CR24 SMC37c669_SERIAL_BASE_ADDRESS_REGISTER;
  790. typedef SMC37c669_CR26 SMC37c669_PARALLEL_FDC_DRQ_REGISTER;
  791. typedef SMC37c669_CR27 SMC37c669_PARALLEL_FDC_IRQ_REGISTER;
  792. typedef SMC37c669_CR28 SMC37c669_SERIAL_IRQ_REGISTER;
  793. /*
  794. ** ISA/Device IRQ Translation Table Entry Definition
  795. */
  796. typedef struct _SMC37c669_IRQ_TRANSLATION_ENTRY {
  797. int device_irq;
  798. int isa_irq;
  799. } SMC37c669_IRQ_TRANSLATION_ENTRY;
  800. /*
  801. ** ISA/Device DMA Translation Table Entry Definition
  802. */
  803. typedef struct _SMC37c669_DRQ_TRANSLATION_ENTRY {
  804. int device_drq;
  805. int isa_drq;
  806. } SMC37c669_DRQ_TRANSLATION_ENTRY;
  807. /*
  808. ** External Interface Function Prototype Declarations
  809. */
  810. SMC37c669_CONFIG_REGS *SMC37c669_detect(
  811. int
  812. );
  813. unsigned int SMC37c669_enable_device(
  814. unsigned int func
  815. );
  816. unsigned int SMC37c669_disable_device(
  817. unsigned int func
  818. );
  819. unsigned int SMC37c669_configure_device(
  820. unsigned int func,
  821. int port,
  822. int irq,
  823. int drq
  824. );
  825. void SMC37c669_display_device_info(
  826. void
  827. );
  828. #endif /* __SMC37c669_H */
  829. /* file: smcc669.c
  830. *
  831. * Copyright (C) 1997 by
  832. * Digital Equipment Corporation, Maynard, Massachusetts.
  833. * All rights reserved.
  834. *
  835. * This software is furnished under a license and may be used and copied
  836. * only in accordance of the terms of such license and with the
  837. * inclusion of the above copyright notice. This software or any other
  838. * copies thereof may not be provided or otherwise made available to any
  839. * other person. No title to and ownership of the software is hereby
  840. * transferred.
  841. *
  842. * The information in this software is subject to change without notice
  843. * and should not be construed as a commitment by digital equipment
  844. * corporation.
  845. *
  846. * Digital assumes no responsibility for the use or reliability of its
  847. * software on equipment which is not supplied by digital.
  848. */
  849. /*
  850. *++
  851. * FACILITY:
  852. *
  853. * Alpha SRM Console Firmware
  854. *
  855. * MODULE DESCRIPTION:
  856. *
  857. * SMC37c669 Super I/O controller configuration routines.
  858. *
  859. * AUTHORS:
  860. *
  861. * Eric Rasmussen
  862. *
  863. * CREATION DATE:
  864. *
  865. * 28-Jan-1997
  866. *
  867. * MODIFICATION HISTORY:
  868. *
  869. * er 01-May-1997 Fixed pointer conversion errors in
  870. * SMC37c669_get_device_config().
  871. * er 28-Jan-1997 Initial version.
  872. *
  873. *--
  874. */
  875. #if 0
  876. /* $INCLUDE_OPTIONS$ */
  877. #include "cp$inc:platform_io.h"
  878. /* $INCLUDE_OPTIONS_END$ */
  879. #include "cp$src:common.h"
  880. #include "cp$inc:prototypes.h"
  881. #include "cp$src:kernel_def.h"
  882. #include "cp$src:msg_def.h"
  883. #include "cp$src:smcc669_def.h"
  884. /* Platform-specific includes */
  885. #include "cp$src:platform.h"
  886. #endif
  887. #ifndef TRUE
  888. #define TRUE 1
  889. #endif
  890. #ifndef FALSE
  891. #define FALSE 0
  892. #endif
  893. #define wb( _x_, _y_ ) outb( _y_, (unsigned int)((unsigned long)_x_) )
  894. #define rb( _x_ ) inb( (unsigned int)((unsigned long)_x_) )
  895. /*
  896. ** Local storage for device configuration information.
  897. **
  898. ** Since the SMC37c669 does not provide an explicit
  899. ** mechanism for enabling/disabling individual device
  900. ** functions, other than unmapping the device, local
  901. ** storage for device configuration information is
  902. ** allocated here for use in implementing our own
  903. ** function enable/disable scheme.
  904. */
  905. static struct DEVICE_CONFIG {
  906. unsigned int port1;
  907. unsigned int port2;
  908. int irq;
  909. int drq;
  910. } local_config [NUM_FUNCS];
  911. /*
  912. ** List of all possible addresses for the Super I/O chip
  913. */
  914. static unsigned long SMC37c669_Addresses[] __initdata =
  915. {
  916. 0x3F0UL, /* Primary address */
  917. 0x370UL, /* Secondary address */
  918. 0UL /* End of list */
  919. };
  920. /*
  921. ** Global Pointer to the Super I/O device
  922. */
  923. static SMC37c669_CONFIG_REGS *SMC37c669 __initdata = NULL;
  924. /*
  925. ** IRQ Translation Table
  926. **
  927. ** The IRQ translation table is a list of SMC37c669 device
  928. ** and standard ISA IRQs.
  929. **
  930. */
  931. static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_table __initdata;
  932. /*
  933. ** The following definition is for the default IRQ
  934. ** translation table.
  935. */
  936. static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_default_irq_table[]
  937. __initdata =
  938. {
  939. { SMC37c669_DEVICE_IRQ_A, -1 },
  940. { SMC37c669_DEVICE_IRQ_B, -1 },
  941. { SMC37c669_DEVICE_IRQ_C, 7 },
  942. { SMC37c669_DEVICE_IRQ_D, 6 },
  943. { SMC37c669_DEVICE_IRQ_E, 4 },
  944. { SMC37c669_DEVICE_IRQ_F, 3 },
  945. { SMC37c669_DEVICE_IRQ_H, -1 },
  946. { -1, -1 } /* End of table */
  947. };
  948. /*
  949. ** The following definition is for the MONET (XP1000) IRQ
  950. ** translation table.
  951. */
  952. static SMC37c669_IRQ_TRANSLATION_ENTRY SMC37c669_monet_irq_table[]
  953. __initdata =
  954. {
  955. { SMC37c669_DEVICE_IRQ_A, -1 },
  956. { SMC37c669_DEVICE_IRQ_B, -1 },
  957. { SMC37c669_DEVICE_IRQ_C, 6 },
  958. { SMC37c669_DEVICE_IRQ_D, 7 },
  959. { SMC37c669_DEVICE_IRQ_E, 4 },
  960. { SMC37c669_DEVICE_IRQ_F, 3 },
  961. { SMC37c669_DEVICE_IRQ_H, -1 },
  962. { -1, -1 } /* End of table */
  963. };
  964. static SMC37c669_IRQ_TRANSLATION_ENTRY *SMC37c669_irq_tables[] __initdata =
  965. {
  966. SMC37c669_default_irq_table,
  967. SMC37c669_monet_irq_table
  968. };
  969. /*
  970. ** DRQ Translation Table
  971. **
  972. ** The DRQ translation table is a list of SMC37c669 device and
  973. ** ISA DMA channels.
  974. **
  975. */
  976. static SMC37c669_DRQ_TRANSLATION_ENTRY *SMC37c669_drq_table __initdata;
  977. /*
  978. ** The following definition is the default DRQ
  979. ** translation table.
  980. */
  981. static SMC37c669_DRQ_TRANSLATION_ENTRY SMC37c669_default_drq_table[]
  982. __initdata =
  983. {
  984. { SMC37c669_DEVICE_DRQ_A, 2 },
  985. { SMC37c669_DEVICE_DRQ_B, 3 },
  986. { SMC37c669_DEVICE_DRQ_C, -1 },
  987. { -1, -1 } /* End of table */
  988. };
  989. /*
  990. ** Local Function Prototype Declarations
  991. */
  992. static unsigned int SMC37c669_is_device_enabled(
  993. unsigned int func
  994. );
  995. #if 0
  996. static unsigned int SMC37c669_get_device_config(
  997. unsigned int func,
  998. int *port,
  999. int *irq,
  1000. int *drq
  1001. );
  1002. #endif
  1003. static void SMC37c669_config_mode(
  1004. unsigned int enable
  1005. );
  1006. static unsigned char SMC37c669_read_config(
  1007. unsigned char index
  1008. );
  1009. static void SMC37c669_write_config(
  1010. unsigned char index,
  1011. unsigned char data
  1012. );
  1013. static void SMC37c669_init_local_config( void );
  1014. static struct DEVICE_CONFIG *SMC37c669_get_config(
  1015. unsigned int func
  1016. );
  1017. static int SMC37c669_xlate_irq(
  1018. int irq
  1019. );
  1020. static int SMC37c669_xlate_drq(
  1021. int drq
  1022. );
  1023. static __cacheline_aligned DEFINE_SPINLOCK(smc_lock);
  1024. /*
  1025. **++
  1026. ** FUNCTIONAL DESCRIPTION:
  1027. **
  1028. ** This function detects the presence of an SMC37c669 Super I/O
  1029. ** controller.
  1030. **
  1031. ** FORMAL PARAMETERS:
  1032. **
  1033. ** None
  1034. **
  1035. ** RETURN VALUE:
  1036. **
  1037. ** Returns a pointer to the device if found, otherwise,
  1038. ** the NULL pointer is returned.
  1039. **
  1040. ** SIDE EFFECTS:
  1041. **
  1042. ** None
  1043. **
  1044. **--
  1045. */
  1046. SMC37c669_CONFIG_REGS * __init SMC37c669_detect( int index )
  1047. {
  1048. int i;
  1049. SMC37c669_DEVICE_ID_REGISTER id;
  1050. for ( i = 0; SMC37c669_Addresses[i] != 0; i++ ) {
  1051. /*
  1052. ** Initialize the device pointer even though we don't yet know if
  1053. ** the controller is at this address. The support functions access
  1054. ** the controller through this device pointer so we need to set it
  1055. ** even when we are looking ...
  1056. */
  1057. SMC37c669 = ( SMC37c669_CONFIG_REGS * )SMC37c669_Addresses[i];
  1058. /*
  1059. ** Enter configuration mode
  1060. */
  1061. SMC37c669_config_mode( TRUE );
  1062. /*
  1063. ** Read the device id
  1064. */
  1065. id.as_uchar = SMC37c669_read_config( SMC37c669_DEVICE_ID_INDEX );
  1066. /*
  1067. ** Exit configuration mode
  1068. */
  1069. SMC37c669_config_mode( FALSE );
  1070. /*
  1071. ** Does the device id match? If so, assume we have found an
  1072. ** SMC37c669 controller at this address.
  1073. */
  1074. if ( id.by_field.device_id == SMC37c669_DEVICE_ID ) {
  1075. /*
  1076. ** Initialize the IRQ and DRQ translation tables.
  1077. */
  1078. SMC37c669_irq_table = SMC37c669_irq_tables[ index ];
  1079. SMC37c669_drq_table = SMC37c669_default_drq_table;
  1080. /*
  1081. ** erfix
  1082. **
  1083. ** If the platform can't use the IRQ and DRQ defaults set up in this
  1084. ** file, it should call a platform-specific external routine at this
  1085. ** point to reset the IRQ and DRQ translation table pointers to point
  1086. ** at the appropriate tables for the platform. If the defaults are
  1087. ** acceptable, then the external routine should do nothing.
  1088. */
  1089. /*
  1090. ** Put the chip back into configuration mode
  1091. */
  1092. SMC37c669_config_mode( TRUE );
  1093. /*
  1094. ** Initialize local storage for configuration information
  1095. */
  1096. SMC37c669_init_local_config( );
  1097. /*
  1098. ** Exit configuration mode
  1099. */
  1100. SMC37c669_config_mode( FALSE );
  1101. /*
  1102. ** SMC37c669 controller found, break out of search loop
  1103. */
  1104. break;
  1105. }
  1106. else {
  1107. /*
  1108. ** Otherwise, we did not find an SMC37c669 controller at this
  1109. ** address so set the device pointer to NULL.
  1110. */
  1111. SMC37c669 = NULL;
  1112. }
  1113. }
  1114. return SMC37c669;
  1115. }
  1116. /*
  1117. **++
  1118. ** FUNCTIONAL DESCRIPTION:
  1119. **
  1120. ** This function enables an SMC37c669 device function.
  1121. **
  1122. ** FORMAL PARAMETERS:
  1123. **
  1124. ** func:
  1125. ** Which device function to enable
  1126. **
  1127. ** RETURN VALUE:
  1128. **
  1129. ** Returns TRUE is the device function was enabled, otherwise, FALSE
  1130. **
  1131. ** SIDE EFFECTS:
  1132. **
  1133. ** {@description or none@}
  1134. **
  1135. ** DESIGN:
  1136. **
  1137. ** Enabling a device function in the SMC37c669 controller involves
  1138. ** setting all of its mappings (port, irq, drq ...). A local
  1139. ** "shadow" copy of the device configuration is kept so we can
  1140. ** just set each mapping to what the local copy says.
  1141. **
  1142. ** This function ALWAYS updates the local shadow configuration of
  1143. ** the device function being enabled, even if the device is always
  1144. ** enabled. To avoid replication of code, functions such as
  1145. ** configure_device set up the local copy and then call this
  1146. ** function to the update the real device.
  1147. **
  1148. **--
  1149. */
  1150. unsigned int __init SMC37c669_enable_device ( unsigned int func )
  1151. {
  1152. unsigned int ret_val = FALSE;
  1153. /*
  1154. ** Put the device into configuration mode
  1155. */
  1156. SMC37c669_config_mode( TRUE );
  1157. switch ( func ) {
  1158. case SERIAL_0:
  1159. {
  1160. SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
  1161. SMC37c669_SERIAL_IRQ_REGISTER irq;
  1162. /*
  1163. ** Enable the serial 1 IRQ mapping
  1164. */
  1165. irq.as_uchar =
  1166. SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
  1167. irq.by_field.uart1_irq =
  1168. SMC37c669_RAW_DEVICE_IRQ(
  1169. SMC37c669_xlate_irq( local_config[ func ].irq )
  1170. );
  1171. SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
  1172. /*
  1173. ** Enable the serial 1 port base address mapping
  1174. */
  1175. base_addr.as_uchar = 0;
  1176. base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
  1177. SMC37c669_write_config(
  1178. SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
  1179. base_addr.as_uchar
  1180. );
  1181. ret_val = TRUE;
  1182. break;
  1183. }
  1184. case SERIAL_1:
  1185. {
  1186. SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
  1187. SMC37c669_SERIAL_IRQ_REGISTER irq;
  1188. /*
  1189. ** Enable the serial 2 IRQ mapping
  1190. */
  1191. irq.as_uchar =
  1192. SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
  1193. irq.by_field.uart2_irq =
  1194. SMC37c669_RAW_DEVICE_IRQ(
  1195. SMC37c669_xlate_irq( local_config[ func ].irq )
  1196. );
  1197. SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
  1198. /*
  1199. ** Enable the serial 2 port base address mapping
  1200. */
  1201. base_addr.as_uchar = 0;
  1202. base_addr.by_field.addr9_3 = local_config[ func ].port1 >> 3;
  1203. SMC37c669_write_config(
  1204. SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
  1205. base_addr.as_uchar
  1206. );
  1207. ret_val = TRUE;
  1208. break;
  1209. }
  1210. case PARALLEL_0:
  1211. {
  1212. SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
  1213. SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
  1214. SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
  1215. /*
  1216. ** Enable the parallel port DMA channel mapping
  1217. */
  1218. drq.as_uchar =
  1219. SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
  1220. drq.by_field.ppt_drq =
  1221. SMC37c669_RAW_DEVICE_DRQ(
  1222. SMC37c669_xlate_drq( local_config[ func ].drq )
  1223. );
  1224. SMC37c669_write_config(
  1225. SMC37c669_PARALLEL_FDC_DRQ_INDEX,
  1226. drq.as_uchar
  1227. );
  1228. /*
  1229. ** Enable the parallel port IRQ mapping
  1230. */
  1231. irq.as_uchar =
  1232. SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
  1233. irq.by_field.ppt_irq =
  1234. SMC37c669_RAW_DEVICE_IRQ(
  1235. SMC37c669_xlate_irq( local_config[ func ].irq )
  1236. );
  1237. SMC37c669_write_config(
  1238. SMC37c669_PARALLEL_FDC_IRQ_INDEX,
  1239. irq.as_uchar
  1240. );
  1241. /*
  1242. ** Enable the parallel port base address mapping
  1243. */
  1244. base_addr.as_uchar = 0;
  1245. base_addr.by_field.addr9_2 = local_config[ func ].port1 >> 2;
  1246. SMC37c669_write_config(
  1247. SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
  1248. base_addr.as_uchar
  1249. );
  1250. ret_val = TRUE;
  1251. break;
  1252. }
  1253. case FLOPPY_0:
  1254. {
  1255. SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
  1256. SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
  1257. SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
  1258. /*
  1259. ** Enable the floppy controller DMA channel mapping
  1260. */
  1261. drq.as_uchar =
  1262. SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
  1263. drq.by_field.fdc_drq =
  1264. SMC37c669_RAW_DEVICE_DRQ(
  1265. SMC37c669_xlate_drq( local_config[ func ].drq )
  1266. );
  1267. SMC37c669_write_config(
  1268. SMC37c669_PARALLEL_FDC_DRQ_INDEX,
  1269. drq.as_uchar
  1270. );
  1271. /*
  1272. ** Enable the floppy controller IRQ mapping
  1273. */
  1274. irq.as_uchar =
  1275. SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
  1276. irq.by_field.fdc_irq =
  1277. SMC37c669_RAW_DEVICE_IRQ(
  1278. SMC37c669_xlate_irq( local_config[ func ].irq )
  1279. );
  1280. SMC37c669_write_config(
  1281. SMC37c669_PARALLEL_FDC_IRQ_INDEX,
  1282. irq.as_uchar
  1283. );
  1284. /*
  1285. ** Enable the floppy controller base address mapping
  1286. */
  1287. base_addr.as_uchar = 0;
  1288. base_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
  1289. SMC37c669_write_config(
  1290. SMC37c669_FDC_BASE_ADDRESS_INDEX,
  1291. base_addr.as_uchar
  1292. );
  1293. ret_val = TRUE;
  1294. break;
  1295. }
  1296. case IDE_0:
  1297. {
  1298. SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
  1299. /*
  1300. ** Enable the IDE alternate status base address mapping
  1301. */
  1302. ide_addr.as_uchar = 0;
  1303. ide_addr.by_field.addr9_4 = local_config[ func ].port2 >> 4;
  1304. SMC37c669_write_config(
  1305. SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
  1306. ide_addr.as_uchar
  1307. );
  1308. /*
  1309. ** Enable the IDE controller base address mapping
  1310. */
  1311. ide_addr.as_uchar = 0;
  1312. ide_addr.by_field.addr9_4 = local_config[ func ].port1 >> 4;
  1313. SMC37c669_write_config(
  1314. SMC37c669_IDE_BASE_ADDRESS_INDEX,
  1315. ide_addr.as_uchar
  1316. );
  1317. ret_val = TRUE;
  1318. break;
  1319. }
  1320. }
  1321. /*
  1322. ** Exit configuration mode and return
  1323. */
  1324. SMC37c669_config_mode( FALSE );
  1325. return ret_val;
  1326. }
  1327. /*
  1328. **++
  1329. ** FUNCTIONAL DESCRIPTION:
  1330. **
  1331. ** This function disables a device function within the
  1332. ** SMC37c669 Super I/O controller.
  1333. **
  1334. ** FORMAL PARAMETERS:
  1335. **
  1336. ** func:
  1337. ** Which function to disable
  1338. **
  1339. ** RETURN VALUE:
  1340. **
  1341. ** Return TRUE if the device function was disabled, otherwise, FALSE
  1342. **
  1343. ** SIDE EFFECTS:
  1344. **
  1345. ** {@description or none@}
  1346. **
  1347. ** DESIGN:
  1348. **
  1349. ** Disabling a function in the SMC37c669 device involves
  1350. ** disabling all the function's mappings (port, irq, drq ...).
  1351. ** A shadow copy of the device configuration is maintained
  1352. ** in local storage so we won't worry aboving saving the
  1353. ** current configuration information.
  1354. **
  1355. **--
  1356. */
  1357. unsigned int __init SMC37c669_disable_device ( unsigned int func )
  1358. {
  1359. unsigned int ret_val = FALSE;
  1360. /*
  1361. ** Put the device into configuration mode
  1362. */
  1363. SMC37c669_config_mode( TRUE );
  1364. switch ( func ) {
  1365. case SERIAL_0:
  1366. {
  1367. SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
  1368. SMC37c669_SERIAL_IRQ_REGISTER irq;
  1369. /*
  1370. ** Disable the serial 1 IRQ mapping
  1371. */
  1372. irq.as_uchar =
  1373. SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
  1374. irq.by_field.uart1_irq = 0;
  1375. SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
  1376. /*
  1377. ** Disable the serial 1 port base address mapping
  1378. */
  1379. base_addr.as_uchar = 0;
  1380. SMC37c669_write_config(
  1381. SMC37c669_SERIAL0_BASE_ADDRESS_INDEX,
  1382. base_addr.as_uchar
  1383. );
  1384. ret_val = TRUE;
  1385. break;
  1386. }
  1387. case SERIAL_1:
  1388. {
  1389. SMC37c669_SERIAL_BASE_ADDRESS_REGISTER base_addr;
  1390. SMC37c669_SERIAL_IRQ_REGISTER irq;
  1391. /*
  1392. ** Disable the serial 2 IRQ mapping
  1393. */
  1394. irq.as_uchar =
  1395. SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
  1396. irq.by_field.uart2_irq = 0;
  1397. SMC37c669_write_config( SMC37c669_SERIAL_IRQ_INDEX, irq.as_uchar );
  1398. /*
  1399. ** Disable the serial 2 port base address mapping
  1400. */
  1401. base_addr.as_uchar = 0;
  1402. SMC37c669_write_config(
  1403. SMC37c669_SERIAL1_BASE_ADDRESS_INDEX,
  1404. base_addr.as_uchar
  1405. );
  1406. ret_val = TRUE;
  1407. break;
  1408. }
  1409. case PARALLEL_0:
  1410. {
  1411. SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER base_addr;
  1412. SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
  1413. SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
  1414. /*
  1415. ** Disable the parallel port DMA channel mapping
  1416. */
  1417. drq.as_uchar =
  1418. SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
  1419. drq.by_field.ppt_drq = 0;
  1420. SMC37c669_write_config(
  1421. SMC37c669_PARALLEL_FDC_DRQ_INDEX,
  1422. drq.as_uchar
  1423. );
  1424. /*
  1425. ** Disable the parallel port IRQ mapping
  1426. */
  1427. irq.as_uchar =
  1428. SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
  1429. irq.by_field.ppt_irq = 0;
  1430. SMC37c669_write_config(
  1431. SMC37c669_PARALLEL_FDC_IRQ_INDEX,
  1432. irq.as_uchar
  1433. );
  1434. /*
  1435. ** Disable the parallel port base address mapping
  1436. */
  1437. base_addr.as_uchar = 0;
  1438. SMC37c669_write_config(
  1439. SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX,
  1440. base_addr.as_uchar
  1441. );
  1442. ret_val = TRUE;
  1443. break;
  1444. }
  1445. case FLOPPY_0:
  1446. {
  1447. SMC37c669_FDC_BASE_ADDRESS_REGISTER base_addr;
  1448. SMC37c669_PARALLEL_FDC_IRQ_REGISTER irq;
  1449. SMC37c669_PARALLEL_FDC_DRQ_REGISTER drq;
  1450. /*
  1451. ** Disable the floppy controller DMA channel mapping
  1452. */
  1453. drq.as_uchar =
  1454. SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
  1455. drq.by_field.fdc_drq = 0;
  1456. SMC37c669_write_config(
  1457. SMC37c669_PARALLEL_FDC_DRQ_INDEX,
  1458. drq.as_uchar
  1459. );
  1460. /*
  1461. ** Disable the floppy controller IRQ mapping
  1462. */
  1463. irq.as_uchar =
  1464. SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
  1465. irq.by_field.fdc_irq = 0;
  1466. SMC37c669_write_config(
  1467. SMC37c669_PARALLEL_FDC_IRQ_INDEX,
  1468. irq.as_uchar
  1469. );
  1470. /*
  1471. ** Disable the floppy controller base address mapping
  1472. */
  1473. base_addr.as_uchar = 0;
  1474. SMC37c669_write_config(
  1475. SMC37c669_FDC_BASE_ADDRESS_INDEX,
  1476. base_addr.as_uchar
  1477. );
  1478. ret_val = TRUE;
  1479. break;
  1480. }
  1481. case IDE_0:
  1482. {
  1483. SMC37c669_IDE_ADDRESS_REGISTER ide_addr;
  1484. /*
  1485. ** Disable the IDE alternate status base address mapping
  1486. */
  1487. ide_addr.as_uchar = 0;
  1488. SMC37c669_write_config(
  1489. SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX,
  1490. ide_addr.as_uchar
  1491. );
  1492. /*
  1493. ** Disable the IDE controller base address mapping
  1494. */
  1495. ide_addr.as_uchar = 0;
  1496. SMC37c669_write_config(
  1497. SMC37c669_IDE_BASE_ADDRESS_INDEX,
  1498. ide_addr.as_uchar
  1499. );
  1500. ret_val = TRUE;
  1501. break;
  1502. }
  1503. }
  1504. /*
  1505. ** Exit configuration mode and return
  1506. */
  1507. SMC37c669_config_mode( FALSE );
  1508. return ret_val;
  1509. }
  1510. /*
  1511. **++
  1512. ** FUNCTIONAL DESCRIPTION:
  1513. **
  1514. ** This function configures a device function within the
  1515. ** SMC37c669 Super I/O controller.
  1516. **
  1517. ** FORMAL PARAMETERS:
  1518. **
  1519. ** func:
  1520. ** Which device function
  1521. **
  1522. ** port:
  1523. ** I/O port for the function to use
  1524. **
  1525. ** irq:
  1526. ** IRQ for the device function to use
  1527. **
  1528. ** drq:
  1529. ** DMA channel for the device function to use
  1530. **
  1531. ** RETURN VALUE:
  1532. **
  1533. ** Returns TRUE if the device function was configured,
  1534. ** otherwise, FALSE.
  1535. **
  1536. ** SIDE EFFECTS:
  1537. **
  1538. ** {@description or none@}
  1539. **
  1540. ** DESIGN:
  1541. **
  1542. ** If this function returns TRUE, the local shadow copy of
  1543. ** the configuration is also updated. If the device function
  1544. ** is currently disabled, only the local shadow copy is
  1545. ** updated and the actual device function will be updated
  1546. ** if/when it is enabled.
  1547. **
  1548. **--
  1549. */
  1550. unsigned int __init SMC37c669_configure_device (
  1551. unsigned int func,
  1552. int port,
  1553. int irq,
  1554. int drq )
  1555. {
  1556. struct DEVICE_CONFIG *cp;
  1557. /*
  1558. ** Check for a valid configuration
  1559. */
  1560. if ( ( cp = SMC37c669_get_config ( func ) ) != NULL ) {
  1561. /*
  1562. ** Configuration is valid, update the local shadow copy
  1563. */
  1564. if ( ( drq & ~0xFF ) == 0 ) {
  1565. cp->drq = drq;
  1566. }
  1567. if ( ( irq & ~0xFF ) == 0 ) {
  1568. cp->irq = irq;
  1569. }
  1570. if ( ( port & ~0xFFFF ) == 0 ) {
  1571. cp->port1 = port;
  1572. }
  1573. /*
  1574. ** If the device function is enabled, update the actual
  1575. ** device configuration.
  1576. */
  1577. if ( SMC37c669_is_device_enabled( func ) ) {
  1578. SMC37c669_enable_device( func );
  1579. }
  1580. return TRUE;
  1581. }
  1582. return FALSE;
  1583. }
  1584. /*
  1585. **++
  1586. ** FUNCTIONAL DESCRIPTION:
  1587. **
  1588. ** This function determines whether a device function
  1589. ** within the SMC37c669 controller is enabled.
  1590. **
  1591. ** FORMAL PARAMETERS:
  1592. **
  1593. ** func:
  1594. ** Which device function
  1595. **
  1596. ** RETURN VALUE:
  1597. **
  1598. ** Returns TRUE if the device function is enabled, otherwise, FALSE
  1599. **
  1600. ** SIDE EFFECTS:
  1601. **
  1602. ** {@description or none@}
  1603. **
  1604. ** DESIGN:
  1605. **
  1606. ** To check whether a device is enabled we will only look at
  1607. ** the port base address mapping. According to the SMC37c669
  1608. ** specification, all of the port base address mappings are
  1609. ** disabled if the addr<9:8> (bits <7:6> of the register) are
  1610. ** zero.
  1611. **
  1612. **--
  1613. */
  1614. static unsigned int __init SMC37c669_is_device_enabled ( unsigned int func )
  1615. {
  1616. unsigned char base_addr = 0;
  1617. unsigned int dev_ok = FALSE;
  1618. unsigned int ret_val = FALSE;
  1619. /*
  1620. ** Enter configuration mode
  1621. */
  1622. SMC37c669_config_mode( TRUE );
  1623. switch ( func ) {
  1624. case SERIAL_0:
  1625. base_addr =
  1626. SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
  1627. dev_ok = TRUE;
  1628. break;
  1629. case SERIAL_1:
  1630. base_addr =
  1631. SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
  1632. dev_ok = TRUE;
  1633. break;
  1634. case PARALLEL_0:
  1635. base_addr =
  1636. SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
  1637. dev_ok = TRUE;
  1638. break;
  1639. case FLOPPY_0:
  1640. base_addr =
  1641. SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
  1642. dev_ok = TRUE;
  1643. break;
  1644. case IDE_0:
  1645. base_addr =
  1646. SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
  1647. dev_ok = TRUE;
  1648. break;
  1649. }
  1650. /*
  1651. ** If we have a valid device, check base_addr<7:6> to see if the
  1652. ** device is enabled (mapped).
  1653. */
  1654. if ( ( dev_ok ) && ( ( base_addr & 0xC0 ) != 0 ) ) {
  1655. /*
  1656. ** The mapping is not disabled, so assume that the function is
  1657. ** enabled.
  1658. */
  1659. ret_val = TRUE;
  1660. }
  1661. /*
  1662. ** Exit configuration mode
  1663. */
  1664. SMC37c669_config_mode( FALSE );
  1665. return ret_val;
  1666. }
  1667. #if 0
  1668. /*
  1669. **++
  1670. ** FUNCTIONAL DESCRIPTION:
  1671. **
  1672. ** This function retrieves the configuration information of a
  1673. ** device function within the SMC37c699 Super I/O controller.
  1674. **
  1675. ** FORMAL PARAMETERS:
  1676. **
  1677. ** func:
  1678. ** Which device function
  1679. **
  1680. ** port:
  1681. ** I/O port returned
  1682. **
  1683. ** irq:
  1684. ** IRQ returned
  1685. **
  1686. ** drq:
  1687. ** DMA channel returned
  1688. **
  1689. ** RETURN VALUE:
  1690. **
  1691. ** Returns TRUE if the device configuration was successfully
  1692. ** retrieved, otherwise, FALSE.
  1693. **
  1694. ** SIDE EFFECTS:
  1695. **
  1696. ** The data pointed to by the port, irq, and drq parameters
  1697. ** my be modified even if the configuration is not successfully
  1698. ** retrieved.
  1699. **
  1700. ** DESIGN:
  1701. **
  1702. ** The device configuration is fetched from the local shadow
  1703. ** copy. Any unused parameters will be set to -1. Any
  1704. ** parameter which is not desired can specify the NULL
  1705. ** pointer.
  1706. **
  1707. **--
  1708. */
  1709. static unsigned int __init SMC37c669_get_device_config (
  1710. unsigned int func,
  1711. int *port,
  1712. int *irq,
  1713. int *drq )
  1714. {
  1715. struct DEVICE_CONFIG *cp;
  1716. unsigned int ret_val = FALSE;
  1717. /*
  1718. ** Check for a valid device configuration
  1719. */
  1720. if ( ( cp = SMC37c669_get_config( func ) ) != NULL ) {
  1721. if ( drq != NULL ) {
  1722. *drq = cp->drq;
  1723. ret_val = TRUE;
  1724. }
  1725. if ( irq != NULL ) {
  1726. *irq = cp->irq;
  1727. ret_val = TRUE;
  1728. }
  1729. if ( port != NULL ) {
  1730. *port = cp->port1;
  1731. ret_val = TRUE;
  1732. }
  1733. }
  1734. return ret_val;
  1735. }
  1736. #endif
  1737. /*
  1738. **++
  1739. ** FUNCTIONAL DESCRIPTION:
  1740. **
  1741. ** This function displays the current state of the SMC37c699
  1742. ** Super I/O controller's device functions.
  1743. **
  1744. ** FORMAL PARAMETERS:
  1745. **
  1746. ** None
  1747. **
  1748. ** RETURN VALUE:
  1749. **
  1750. ** None
  1751. **
  1752. ** SIDE EFFECTS:
  1753. **
  1754. ** None
  1755. **
  1756. **--
  1757. */
  1758. void __init SMC37c669_display_device_info ( void )
  1759. {
  1760. if ( SMC37c669_is_device_enabled( SERIAL_0 ) ) {
  1761. printk( " Serial 0: Enabled [ Port 0x%x, IRQ %d ]\n",
  1762. local_config[ SERIAL_0 ].port1,
  1763. local_config[ SERIAL_0 ].irq
  1764. );
  1765. }
  1766. else {
  1767. printk( " Serial 0: Disabled\n" );
  1768. }
  1769. if ( SMC37c669_is_device_enabled( SERIAL_1 ) ) {
  1770. printk( " Serial 1: Enabled [ Port 0x%x, IRQ %d ]\n",
  1771. local_config[ SERIAL_1 ].port1,
  1772. local_config[ SERIAL_1 ].irq
  1773. );
  1774. }
  1775. else {
  1776. printk( " Serial 1: Disabled\n" );
  1777. }
  1778. if ( SMC37c669_is_device_enabled( PARALLEL_0 ) ) {
  1779. printk( " Parallel: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
  1780. local_config[ PARALLEL_0 ].port1,
  1781. local_config[ PARALLEL_0 ].irq,
  1782. local_config[ PARALLEL_0 ].drq
  1783. );
  1784. }
  1785. else {
  1786. printk( " Parallel: Disabled\n" );
  1787. }
  1788. if ( SMC37c669_is_device_enabled( FLOPPY_0 ) ) {
  1789. printk( " Floppy Ctrl: Enabled [ Port 0x%x, IRQ %d/%d ]\n",
  1790. local_config[ FLOPPY_0 ].port1,
  1791. local_config[ FLOPPY_0 ].irq,
  1792. local_config[ FLOPPY_0 ].drq
  1793. );
  1794. }
  1795. else {
  1796. printk( " Floppy Ctrl: Disabled\n" );
  1797. }
  1798. if ( SMC37c669_is_device_enabled( IDE_0 ) ) {
  1799. printk( " IDE 0: Enabled [ Port 0x%x, IRQ %d ]\n",
  1800. local_config[ IDE_0 ].port1,
  1801. local_config[ IDE_0 ].irq
  1802. );
  1803. }
  1804. else {
  1805. printk( " IDE 0: Disabled\n" );
  1806. }
  1807. }
  1808. /*
  1809. **++
  1810. ** FUNCTIONAL DESCRIPTION:
  1811. **
  1812. ** This function puts the SMC37c669 Super I/O controller into,
  1813. ** and takes it out of, configuration mode.
  1814. **
  1815. ** FORMAL PARAMETERS:
  1816. **
  1817. ** enable:
  1818. ** TRUE to enter configuration mode, FALSE to exit.
  1819. **
  1820. ** RETURN VALUE:
  1821. **
  1822. ** None
  1823. **
  1824. ** SIDE EFFECTS:
  1825. **
  1826. ** The SMC37c669 controller may be left in configuration mode.
  1827. **
  1828. **--
  1829. */
  1830. static void __init SMC37c669_config_mode(
  1831. unsigned int enable )
  1832. {
  1833. if ( enable ) {
  1834. /*
  1835. ** To enter configuration mode, two writes in succession to the index
  1836. ** port are required. If a write to another address or port occurs
  1837. ** between these two writes, the chip does not enter configuration
  1838. ** mode. Therefore, a spinlock is placed around the two writes to
  1839. ** guarantee that they complete uninterrupted.
  1840. */
  1841. spin_lock(&smc_lock);
  1842. wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
  1843. wb( &SMC37c669->index_port, SMC37c669_CONFIG_ON_KEY );
  1844. spin_unlock(&smc_lock);
  1845. }
  1846. else {
  1847. wb( &SMC37c669->index_port, SMC37c669_CONFIG_OFF_KEY );
  1848. }
  1849. }
  1850. /*
  1851. **++
  1852. ** FUNCTIONAL DESCRIPTION:
  1853. **
  1854. ** This function reads an SMC37c669 Super I/O controller
  1855. ** configuration register. This function assumes that the
  1856. ** device is already in configuration mode.
  1857. **
  1858. ** FORMAL PARAMETERS:
  1859. **
  1860. ** index:
  1861. ** Index value of configuration register to read
  1862. **
  1863. ** RETURN VALUE:
  1864. **
  1865. ** Data read from configuration register
  1866. **
  1867. ** SIDE EFFECTS:
  1868. **
  1869. ** None
  1870. **
  1871. **--
  1872. */
  1873. static unsigned char __init SMC37c669_read_config(
  1874. unsigned char index )
  1875. {
  1876. unsigned char data;
  1877. wb( &SMC37c669->index_port, index );
  1878. data = rb( &SMC37c669->data_port );
  1879. return data;
  1880. }
  1881. /*
  1882. **++
  1883. ** FUNCTIONAL DESCRIPTION:
  1884. **
  1885. ** This function writes an SMC37c669 Super I/O controller
  1886. ** configuration register. This function assumes that the
  1887. ** device is already in configuration mode.
  1888. **
  1889. ** FORMAL PARAMETERS:
  1890. **
  1891. ** index:
  1892. ** Index of configuration register to write
  1893. **
  1894. ** data:
  1895. ** Data to be written
  1896. **
  1897. ** RETURN VALUE:
  1898. **
  1899. ** None
  1900. **
  1901. ** SIDE EFFECTS:
  1902. **
  1903. ** None
  1904. **
  1905. **--
  1906. */
  1907. static void __init SMC37c669_write_config(
  1908. unsigned char index,
  1909. unsigned char data )
  1910. {
  1911. wb( &SMC37c669->index_port, index );
  1912. wb( &SMC37c669->data_port, data );
  1913. }
  1914. /*
  1915. **++
  1916. ** FUNCTIONAL DESCRIPTION:
  1917. **
  1918. ** This function initializes the local device
  1919. ** configuration storage. This function assumes
  1920. ** that the device is already in configuration
  1921. ** mode.
  1922. **
  1923. ** FORMAL PARAMETERS:
  1924. **
  1925. ** None
  1926. **
  1927. ** RETURN VALUE:
  1928. **
  1929. ** None
  1930. **
  1931. ** SIDE EFFECTS:
  1932. **
  1933. ** Local storage for device configuration information
  1934. ** is initialized.
  1935. **
  1936. **--
  1937. */
  1938. static void __init SMC37c669_init_local_config ( void )
  1939. {
  1940. SMC37c669_SERIAL_BASE_ADDRESS_REGISTER uart_base;
  1941. SMC37c669_SERIAL_IRQ_REGISTER uart_irqs;
  1942. SMC37c669_PARALLEL_BASE_ADDRESS_REGISTER ppt_base;
  1943. SMC37c669_PARALLEL_FDC_IRQ_REGISTER ppt_fdc_irqs;
  1944. SMC37c669_PARALLEL_FDC_DRQ_REGISTER ppt_fdc_drqs;
  1945. SMC37c669_FDC_BASE_ADDRESS_REGISTER fdc_base;
  1946. SMC37c669_IDE_ADDRESS_REGISTER ide_base;
  1947. SMC37c669_IDE_ADDRESS_REGISTER ide_alt;
  1948. /*
  1949. ** Get serial port 1 base address
  1950. */
  1951. uart_base.as_uchar =
  1952. SMC37c669_read_config( SMC37c669_SERIAL0_BASE_ADDRESS_INDEX );
  1953. /*
  1954. ** Get IRQs for serial ports 1 & 2
  1955. */
  1956. uart_irqs.as_uchar =
  1957. SMC37c669_read_config( SMC37c669_SERIAL_IRQ_INDEX );
  1958. /*
  1959. ** Store local configuration information for serial port 1
  1960. */
  1961. local_config[SERIAL_0].port1 = uart_base.by_field.addr9_3 << 3;
  1962. local_config[SERIAL_0].irq =
  1963. SMC37c669_xlate_irq(
  1964. SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart1_irq )
  1965. );
  1966. /*
  1967. ** Get serial port 2 base address
  1968. */
  1969. uart_base.as_uchar =
  1970. SMC37c669_read_config( SMC37c669_SERIAL1_BASE_ADDRESS_INDEX );
  1971. /*
  1972. ** Store local configuration information for serial port 2
  1973. */
  1974. local_config[SERIAL_1].port1 = uart_base.by_field.addr9_3 << 3;
  1975. local_config[SERIAL_1].irq =
  1976. SMC37c669_xlate_irq(
  1977. SMC37c669_DEVICE_IRQ( uart_irqs.by_field.uart2_irq )
  1978. );
  1979. /*
  1980. ** Get parallel port base address
  1981. */
  1982. ppt_base.as_uchar =
  1983. SMC37c669_read_config( SMC37c669_PARALLEL0_BASE_ADDRESS_INDEX );
  1984. /*
  1985. ** Get IRQs for parallel port and floppy controller
  1986. */
  1987. ppt_fdc_irqs.as_uchar =
  1988. SMC37c669_read_config( SMC37c669_PARALLEL_FDC_IRQ_INDEX );
  1989. /*
  1990. ** Get DRQs for parallel port and floppy controller
  1991. */
  1992. ppt_fdc_drqs.as_uchar =
  1993. SMC37c669_read_config( SMC37c669_PARALLEL_FDC_DRQ_INDEX );
  1994. /*
  1995. ** Store local configuration information for parallel port
  1996. */
  1997. local_config[PARALLEL_0].port1 = ppt_base.by_field.addr9_2 << 2;
  1998. local_config[PARALLEL_0].irq =
  1999. SMC37c669_xlate_irq(
  2000. SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.ppt_irq )
  2001. );
  2002. local_config[PARALLEL_0].drq =
  2003. SMC37c669_xlate_drq(
  2004. SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.ppt_drq )
  2005. );
  2006. /*
  2007. ** Get floppy controller base address
  2008. */
  2009. fdc_base.as_uchar =
  2010. SMC37c669_read_config( SMC37c669_FDC_BASE_ADDRESS_INDEX );
  2011. /*
  2012. ** Store local configuration information for floppy controller
  2013. */
  2014. local_config[FLOPPY_0].port1 = fdc_base.by_field.addr9_4 << 4;
  2015. local_config[FLOPPY_0].irq =
  2016. SMC37c669_xlate_irq(
  2017. SMC37c669_DEVICE_IRQ( ppt_fdc_irqs.by_field.fdc_irq )
  2018. );
  2019. local_config[FLOPPY_0].drq =
  2020. SMC37c669_xlate_drq(
  2021. SMC37c669_DEVICE_DRQ( ppt_fdc_drqs.by_field.fdc_drq )
  2022. );
  2023. /*
  2024. ** Get IDE controller base address
  2025. */
  2026. ide_base.as_uchar =
  2027. SMC37c669_read_config( SMC37c669_IDE_BASE_ADDRESS_INDEX );
  2028. /*
  2029. ** Get IDE alternate status base address
  2030. */
  2031. ide_alt.as_uchar =
  2032. SMC37c669_read_config( SMC37c669_IDE_ALTERNATE_ADDRESS_INDEX );
  2033. /*
  2034. ** Store local configuration information for IDE controller
  2035. */
  2036. local_config[IDE_0].port1 = ide_base.by_field.addr9_4 << 4;
  2037. local_config[IDE_0].port2 = ide_alt.by_field.addr9_4 << 4;
  2038. local_config[IDE_0].irq = 14;
  2039. }
  2040. /*
  2041. **++
  2042. ** FUNCTIONAL DESCRIPTION:
  2043. **
  2044. ** This function returns a pointer to the local shadow
  2045. ** configuration of the requested device function.
  2046. **
  2047. ** FORMAL PARAMETERS:
  2048. **
  2049. ** func:
  2050. ** Which device function
  2051. **
  2052. ** RETURN VALUE:
  2053. **
  2054. ** Returns a pointer to the DEVICE_CONFIG structure for the
  2055. ** requested function, otherwise, NULL.
  2056. **
  2057. ** SIDE EFFECTS:
  2058. **
  2059. ** {@description or none@}
  2060. **
  2061. **--
  2062. */
  2063. static struct DEVICE_CONFIG * __init SMC37c669_get_config( unsigned int func )
  2064. {
  2065. struct DEVICE_CONFIG *cp = NULL;
  2066. switch ( func ) {
  2067. case SERIAL_0:
  2068. cp = &local_config[ SERIAL_0 ];
  2069. break;
  2070. case SERIAL_1:
  2071. cp = &local_config[ SERIAL_1 ];
  2072. break;
  2073. case PARALLEL_0:
  2074. cp = &local_config[ PARALLEL_0 ];
  2075. break;
  2076. case FLOPPY_0:
  2077. cp = &local_config[ FLOPPY_0 ];
  2078. break;
  2079. case IDE_0:
  2080. cp = &local_config[ IDE_0 ];
  2081. break;
  2082. }
  2083. return cp;
  2084. }
  2085. /*
  2086. **++
  2087. ** FUNCTIONAL DESCRIPTION:
  2088. **
  2089. ** This function translates IRQs back and forth between ISA
  2090. ** IRQs and SMC37c669 device IRQs.
  2091. **
  2092. ** FORMAL PARAMETERS:
  2093. **
  2094. ** irq:
  2095. ** The IRQ to translate
  2096. **
  2097. ** RETURN VALUE:
  2098. **
  2099. ** Returns the translated IRQ, otherwise, returns -1.
  2100. **
  2101. ** SIDE EFFECTS:
  2102. **
  2103. ** {@description or none@}
  2104. **
  2105. **--
  2106. */
  2107. static int __init SMC37c669_xlate_irq ( int irq )
  2108. {
  2109. int i, translated_irq = -1;
  2110. if ( SMC37c669_IS_DEVICE_IRQ( irq ) ) {
  2111. /*
  2112. ** We are translating a device IRQ to an ISA IRQ
  2113. */
  2114. for ( i = 0; ( SMC37c669_irq_table[i].device_irq != -1 ) || ( SMC37c669_irq_table[i].isa_irq != -1 ); i++ ) {
  2115. if ( irq == SMC37c669_irq_table[i].device_irq ) {
  2116. translated_irq = SMC37c669_irq_table[i].isa_irq;
  2117. break;
  2118. }
  2119. }
  2120. }
  2121. else {
  2122. /*
  2123. ** We are translating an ISA IRQ to a device IRQ
  2124. */
  2125. for ( i = 0; ( SMC37c669_irq_table[i].isa_irq != -1 ) || ( SMC37c669_irq_table[i].device_irq != -1 ); i++ ) {
  2126. if ( irq == SMC37c669_irq_table[i].isa_irq ) {
  2127. translated_irq = SMC37c669_irq_table[i].device_irq;
  2128. break;
  2129. }
  2130. }
  2131. }
  2132. return translated_irq;
  2133. }
  2134. /*
  2135. **++
  2136. ** FUNCTIONAL DESCRIPTION:
  2137. **
  2138. ** This function translates DMA channels back and forth between
  2139. ** ISA DMA channels and SMC37c669 device DMA channels.
  2140. **
  2141. ** FORMAL PARAMETERS:
  2142. **
  2143. ** drq:
  2144. ** The DMA channel to translate
  2145. **
  2146. ** RETURN VALUE:
  2147. **
  2148. ** Returns the translated DMA channel, otherwise, returns -1
  2149. **
  2150. ** SIDE EFFECTS:
  2151. **
  2152. ** {@description or none@}
  2153. **
  2154. **--
  2155. */
  2156. static int __init SMC37c669_xlate_drq ( int drq )
  2157. {
  2158. int i, translated_drq = -1;
  2159. if ( SMC37c669_IS_DEVICE_DRQ( drq ) ) {
  2160. /*
  2161. ** We are translating a device DMA channel to an ISA DMA channel
  2162. */
  2163. for ( i = 0; ( SMC37c669_drq_table[i].device_drq != -1 ) || ( SMC37c669_drq_table[i].isa_drq != -1 ); i++ ) {
  2164. if ( drq == SMC37c669_drq_table[i].device_drq ) {
  2165. translated_drq = SMC37c669_drq_table[i].isa_drq;
  2166. break;
  2167. }
  2168. }
  2169. }
  2170. else {
  2171. /*
  2172. ** We are translating an ISA DMA channel to a device DMA channel
  2173. */
  2174. for ( i = 0; ( SMC37c669_drq_table[i].isa_drq != -1 ) || ( SMC37c669_drq_table[i].device_drq != -1 ); i++ ) {
  2175. if ( drq == SMC37c669_drq_table[i].isa_drq ) {
  2176. translated_drq = SMC37c669_drq_table[i].device_drq;
  2177. break;
  2178. }
  2179. }
  2180. }
  2181. return translated_drq;
  2182. }
  2183. #if 0
  2184. int __init smcc669_init ( void )
  2185. {
  2186. struct INODE *ip;
  2187. allocinode( smc_ddb.name, 1, &ip );
  2188. ip->dva = &smc_ddb;
  2189. ip->attr = ATTR$M_WRITE | ATTR$M_READ;
  2190. ip->len[0] = 0x30;
  2191. ip->misc = 0;
  2192. INODE_UNLOCK( ip );
  2193. return msg_success;
  2194. }
  2195. int __init smcc669_open( struct FILE *fp, char *info, char *next, char *mode )
  2196. {
  2197. struct INODE *ip;
  2198. /*
  2199. ** Allow multiple readers but only one writer. ip->misc keeps track
  2200. ** of the number of writers
  2201. */
  2202. ip = fp->ip;
  2203. INODE_LOCK( ip );
  2204. if ( fp->mode & ATTR$M_WRITE ) {
  2205. if ( ip->misc ) {
  2206. INODE_UNLOCK( ip );
  2207. return msg_failure; /* too many writers */
  2208. }
  2209. ip->misc++;
  2210. }
  2211. /*
  2212. ** Treat the information field as a byte offset
  2213. */
  2214. *fp->offset = xtoi( info );
  2215. INODE_UNLOCK( ip );
  2216. return msg_success;
  2217. }
  2218. int __init smcc669_close( struct FILE *fp )
  2219. {
  2220. struct INODE *ip;
  2221. ip = fp->ip;
  2222. if ( fp->mode & ATTR$M_WRITE ) {
  2223. INODE_LOCK( ip );
  2224. ip->misc--;
  2225. INODE_UNLOCK( ip );
  2226. }
  2227. return msg_success;
  2228. }
  2229. int __init smcc669_read( struct FILE *fp, int size, int number, unsigned char *buf )
  2230. {
  2231. int i;
  2232. int length;
  2233. int nbytes;
  2234. struct INODE *ip;
  2235. /*
  2236. ** Always access a byte at a time
  2237. */
  2238. ip = fp->ip;
  2239. length = size * number;
  2240. nbytes = 0;
  2241. SMC37c669_config_mode( TRUE );
  2242. for ( i = 0; i < length; i++ ) {
  2243. if ( !inrange( *fp->offset, 0, ip->len[0] ) )
  2244. break;
  2245. *buf++ = SMC37c669_read_config( *fp->offset );
  2246. *fp->offset += 1;
  2247. nbytes++;
  2248. }
  2249. SMC37c669_config_mode( FALSE );
  2250. return nbytes;
  2251. }
  2252. int __init smcc669_write( struct FILE *fp, int size, int number, unsigned char *buf )
  2253. {
  2254. int i;
  2255. int length;
  2256. int nbytes;
  2257. struct INODE *ip;
  2258. /*
  2259. ** Always access a byte at a time
  2260. */
  2261. ip = fp->ip;
  2262. length = size * number;
  2263. nbytes = 0;
  2264. SMC37c669_config_mode( TRUE );
  2265. for ( i = 0; i < length; i++ ) {
  2266. if ( !inrange( *fp->offset, 0, ip->len[0] ) )
  2267. break;
  2268. SMC37c669_write_config( *fp->offset, *buf );
  2269. *fp->offset += 1;
  2270. buf++;
  2271. nbytes++;
  2272. }
  2273. SMC37c669_config_mode( FALSE );
  2274. return nbytes;
  2275. }
  2276. #endif
  2277. void __init
  2278. SMC37c669_dump_registers(void)
  2279. {
  2280. int i;
  2281. for (i = 0; i <= 0x29; i++)
  2282. printk("-- CR%02x : %02x\n", i, SMC37c669_read_config(i));
  2283. }
  2284. /*+
  2285. * ============================================================================
  2286. * = SMC_init - SMC37c669 Super I/O controller initialization =
  2287. * ============================================================================
  2288. *
  2289. * OVERVIEW:
  2290. *
  2291. * This routine configures and enables device functions on the
  2292. * SMC37c669 Super I/O controller.
  2293. *
  2294. * FORM OF CALL:
  2295. *
  2296. * SMC_init( );
  2297. *
  2298. * RETURNS:
  2299. *
  2300. * Nothing
  2301. *
  2302. * ARGUMENTS:
  2303. *
  2304. * None
  2305. *
  2306. * SIDE EFFECTS:
  2307. *
  2308. * None
  2309. *
  2310. */
  2311. void __init SMC669_Init ( int index )
  2312. {
  2313. SMC37c669_CONFIG_REGS *SMC_base;
  2314. unsigned long flags;
  2315. local_irq_save(flags);
  2316. if ( ( SMC_base = SMC37c669_detect( index ) ) != NULL ) {
  2317. #if SMC_DEBUG
  2318. SMC37c669_config_mode( TRUE );
  2319. SMC37c669_dump_registers( );
  2320. SMC37c669_config_mode( FALSE );
  2321. SMC37c669_display_device_info( );
  2322. #endif
  2323. SMC37c669_disable_device( SERIAL_0 );
  2324. SMC37c669_configure_device(
  2325. SERIAL_0,
  2326. COM1_BASE,
  2327. COM1_IRQ,
  2328. -1
  2329. );
  2330. SMC37c669_enable_device( SERIAL_0 );
  2331. SMC37c669_disable_device( SERIAL_1 );
  2332. SMC37c669_configure_device(
  2333. SERIAL_1,
  2334. COM2_BASE,
  2335. COM2_IRQ,
  2336. -1
  2337. );
  2338. SMC37c669_enable_device( SERIAL_1 );
  2339. SMC37c669_disable_device( PARALLEL_0 );
  2340. SMC37c669_configure_device(
  2341. PARALLEL_0,
  2342. PARP_BASE,
  2343. PARP_IRQ,
  2344. PARP_DRQ
  2345. );
  2346. SMC37c669_enable_device( PARALLEL_0 );
  2347. SMC37c669_disable_device( FLOPPY_0 );
  2348. SMC37c669_configure_device(
  2349. FLOPPY_0,
  2350. FDC_BASE,
  2351. FDC_IRQ,
  2352. FDC_DRQ
  2353. );
  2354. SMC37c669_enable_device( FLOPPY_0 );
  2355. /* Wake up sometimes forgotten floppy, especially on DP264. */
  2356. outb(0xc, 0x3f2);
  2357. SMC37c669_disable_device( IDE_0 );
  2358. #if SMC_DEBUG
  2359. SMC37c669_config_mode( TRUE );
  2360. SMC37c669_dump_registers( );
  2361. SMC37c669_config_mode( FALSE );
  2362. SMC37c669_display_device_info( );
  2363. #endif
  2364. local_irq_restore(flags);
  2365. printk( "SMC37c669 Super I/O Controller found @ 0x%p\n",
  2366. SMC_base );
  2367. }
  2368. else {
  2369. local_irq_restore(flags);
  2370. #if SMC_DEBUG
  2371. printk( "No SMC37c669 Super I/O Controller found\n" );
  2372. #endif
  2373. }
  2374. }