PageRenderTime 28ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/alpha/kernel/smc37c669.c

https://github.com/neuros/linux-davinci-2.6
C | 2554 lines | 1242 code | 160 blank | 1152 comment | 82 complexity | 1f1809c650da58c190993d9499592bb6 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0, CC-BY-SA-3.0

Large files files are truncated, but you can click here to view the full file

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

Large files files are truncated, but you can click here to view the full file