Annotation of sys/dev/isa/opti.c, Revision 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