Annotation of sys/dev/isa/opti.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: opti.c,v 1.8 2004/06/13 21:49:24 niklas Exp $ */
2:
3: /*
4: * Copyright (c) 1996 Michael Shalayeff
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26: * SUCH DAMAGE.
27: *
28: */
29:
30: /*
31: * Code to setup 82C929 chipset
32: */
33:
34: /* #define OPTI_DEBUG 9 */
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) /* ((opti_debuglevel >= level)? printf data:0) */
53: #endif
54:
55: int opti_type = OPTI_C929; /* XXX only one card can be installed */
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: /* so the setup */
257: int s = splhigh();
258: register u_char a, b;
259:
260: /* set interface type */
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: /* we don't need any additional setup for IDE CD-ROM */
268: if( ift != OPTI_IDE )
269: {
270: /* set address */
271: a = opti_inb( OPTI_DATA );
272: opti_outb( OPTI_DATA, (a & 0x3f) |
273: (0x40 * OPTI_cd_addr(addr)) );
274:
275: /* set irq */
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: /* set drq */
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: /* so the setup */
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: }
CVSweb