root/dev/isa/opti.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. OPTI_cd_addr
  2. OPTI_cd_irq
  3. OPTI_cd_drq
  4. OPTI_snd_addr
  5. OPTI_snd_irq
  6. OPTI_snd_drq
  7. opti_outb
  8. opti_inb
  9. opti_present
  10. opti_cd_setup
  11. opti_snd_setup

    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 }

/* [<][>][^][v][top][bottom][index][help] */