smc37c669.c 60 KB

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