This source file includes following definitions.
- OPTI_cd_addr
- OPTI_cd_irq
- OPTI_cd_drq
- OPTI_snd_addr
- OPTI_snd_irq
- OPTI_snd_drq
- opti_outb
- opti_inb
- opti_present
- opti_cd_setup
- opti_snd_setup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/kernel.h>
39 #include <sys/conf.h>
40 #include <sys/device.h>
41
42 #include <machine/pio.h>
43
44 #include <dev/isa/isavar.h>
45
46 #include <dev/isa/opti.h>
47
48 #ifdef OPTI_DEBUG
49 int opti_debuglevel = OPTI_DEBUG;
50 # define XDEBUG(level, data) ((opti_debuglevel >= level)? printf data:0)
51 #else
52 # define XDEBUG(level, data)
53 #endif
54
55 int opti_type = OPTI_C929;
56
57 #define OPTI_cd_valid_ift(i) ((i)==OPTI_SONY||(i)==OPTI_PANASONIC||\
58 (i)==OPTI_MITSUMI||(i)==OPTI_IDE)
59
60 static __inline int OPTI_cd_addr(int);
61 static __inline int OPTI_cd_irq(int);
62 static __inline int OPTI_cd_drq(int);
63 static __inline int OPTI_snd_addr(int);
64 static __inline int OPTI_snd_irq(int);
65 static __inline int OPTI_snd_drq(int);
66 static __inline void opti_outb(u_short, u_char);
67 static __inline u_char opti_inb(u_short);
68 static int opti_present(void);
69
70 static __inline int
71 OPTI_cd_addr(a)
72 int a;
73 {
74 switch(a) {
75 case 0x320:
76 return 0xc0;
77 case 0x330:
78 return 0x40;
79 case 0x340:
80 return 0x00;
81 case 0x360:
82 return 0x80;
83 default:
84 return -1;
85 }
86 }
87
88 static __inline int
89 OPTI_cd_irq(i)
90 int i;
91 {
92 switch(i) {
93 case 5:
94 return 0x04;
95 case 7:
96 return 0x08;
97 case 3:
98 return 0x0c;
99 case 9:
100 return 0x10;
101 case 10:
102 return 0x14;
103 case 11:
104 return 0x18;
105 case -1:
106 return 0x00;
107 default:
108 return -1;
109 }
110 }
111
112 static __inline int
113 OPTI_cd_drq(d)
114 int d;
115 {
116 switch(d) {
117 case 3:
118 case 5:
119 return 0;
120 case 6:
121 return 1;
122 case 7:
123 return 2;
124 default:
125 return 3;
126 }
127 }
128
129 #define OPTI_snd_valid_ift(i) ((i)==OPTI_WSS||(i)==OPTI_SB)
130
131 static __inline int
132 OPTI_snd_addr(a)
133 int a;
134 {
135 switch(a) {
136 case 0x220:
137 return 0x0;
138 case 0x240:
139 return 0x3;
140 case 0x530:
141 return 0x8;
142 case 0xE80:
143 return 0x9;
144 case 0xF40:
145 return 0xa;
146 case 0x604:
147 return 0xb;
148 default:
149 return -1;
150 }
151 }
152
153 static __inline int
154 OPTI_snd_irq(i)
155 int i;
156 {
157 switch(i) {
158 case 5:
159 return 0x04;
160 case 7:
161 return 0x08;
162 case 3:
163 return 0x0c;
164 case 9:
165 return 0x10;
166 case 10:
167 return 0x14;
168 case 11:
169 return 0x18;
170 case -1:
171 return 0x00;
172 default:
173 return -1;
174 }
175 }
176
177 static __inline int
178 OPTI_snd_drq(d)
179 int d;
180 {
181 switch(d) {
182 case 3:
183 case 5:
184 return 0;
185 case 6:
186 return 1;
187 case 7:
188 return 2;
189 default:
190 return 3;
191 }
192 }
193
194 static __inline void
195 opti_outb(port, byte)
196 u_short port;
197 u_char byte;
198 {
199 outb( OPTI_PASSWD, opti_type );
200 outb( port, byte );
201 }
202
203 static __inline u_char
204 opti_inb(port)
205 u_short port;
206 {
207 outb( OPTI_PASSWD, opti_type );
208 return inb( port );
209 }
210
211 static int
212 opti_present()
213 {
214 register u_char a, b;
215 int s = splhigh();
216
217 a = opti_inb( OPTI_PASSWD );
218 opti_outb( OPTI_PASSWD, 0x00 );
219 b = opti_inb( OPTI_PASSWD );
220 opti_outb( OPTI_PASSWD, a );
221
222 if (b != 2) {
223 opti_type = OPTI_C928;
224
225 a = opti_inb( OPTI_PASSWD );
226 opti_outb( OPTI_PASSWD, 0x00 );
227 b = opti_inb( OPTI_PASSWD );
228 opti_outb( OPTI_PASSWD, a );
229 }
230
231 splx(s);
232
233 return b == 2;
234 }
235
236 int
237 opti_cd_setup(ift, addr, irq, drq)
238 int ift, addr, irq, drq;
239 {
240 int ret = 0;
241
242 XDEBUG( 2, ("opti: do CD setup type=%u, addr=0x%x, irq=%d, drq=%d\n",
243 ift, addr, irq, drq));
244
245 if( !opti_present() )
246 XDEBUG( 2, ("opti: not present.\n"));
247 else if( !OPTI_cd_valid_ift(ift) )
248 XDEBUG( 2, ("opti: invalid CD-ROM interface type.\n"));
249 else if( OPTI_cd_addr(addr) == -1)
250 XDEBUG( 2, ("opti: illegal CD-ROM interface address.\n"));
251 else if( OPTI_cd_irq(irq) == -1)
252 XDEBUG( 2, ("opti: wrong CD-ROM irq number.\n"));
253 else if( OPTI_cd_drq(drq) == -1)
254 XDEBUG( 2, ("opti: bad CD_ROM drq number.\n"));
255 else {
256
257 int s = splhigh();
258 register u_char a, b;
259
260
261 a = opti_inb( OPTI_IFTP );
262 b = (opti_inb( OPTI_DATA ) & 0x20) | 3 ;
263 opti_outb( OPTI_DATA, b );
264 opti_outb( OPTI_IFTP, (a & OPTI_SND_MASK) | 2 * ift );
265 opti_outb( OPTI_ENBL, 0x80 );
266
267
268 if( ift != OPTI_IDE )
269 {
270
271 a = opti_inb( OPTI_DATA );
272 opti_outb( OPTI_DATA, (a & 0x3f) |
273 (0x40 * OPTI_cd_addr(addr)) );
274
275
276 if( irq != IRQUNK )
277 {
278 a = opti_inb( OPTI_DATA );
279 opti_outb( OPTI_DATA,
280 (inb( OPTI_DATA ) & 0xe3) |
281 OPTI_cd_irq(irq) );
282 }
283
284
285 if( drq != DRQUNK )
286 {
287 a = opti_inb( OPTI_DATA );
288 opti_outb( OPTI_DATA,
289 (inb( OPTI_DATA ) & 0xfc) |
290 OPTI_cd_drq(drq) );
291 }
292 }
293 splx(s);
294 DELAY(1000);
295 ret = 1;
296 }
297
298 return ret;
299 }
300
301 int
302 opti_snd_setup(ift, addr, irq, drq)
303 int ift, addr, irq, drq;
304 {
305 XDEBUG( 2, ("opti: do SND setup type=%u,addr=%x,irq=%d,drq=%d\n",
306 ift, addr, irq, drq));
307
308 if( !opti_present() )
309 XDEBUG( 2, ("opti: not present.\n"));
310 else if( !OPTI_snd_valid_ift(ift) )
311 XDEBUG( 2, ("opti: invalid SND interface type.\n"));
312 else if( OPTI_snd_addr(addr) == -1)
313 XDEBUG( 2, ("opti: illegal SND interface address.\n"));
314 else if( OPTI_snd_irq(irq) == -1)
315 XDEBUG( 2, ("opti: wrong SND irq number.\n"));
316 else if( OPTI_snd_drq(drq) == -1)
317 XDEBUG( 2, ("opti: bad SND drq number.\n"));
318 else {
319
320 int s = splhigh();
321 register u_char a;
322
323 if (ift == OPTI_WSS) {
324 a = opti_inb(OPTI_IFTP);
325 opti_outb(OPTI_IFTP, ((a & ~OPTI_SND_MASK)
326 | (OPTI_snd_addr(addr)*16)) + 1);
327 opti_outb(OPTI_ENBL, 0x1a);
328 }
329
330 splx(s);
331 DELAY(1000);
332 return 1;
333 }
334
335 return 0;
336 }