[BACK]Return to opti.c CVS log [TXT][DIR] Up to [local] / sys / dev / isa

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