The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/sound/isa/mss.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2001 George Reid <greid@ukug.uk.freebsd.org>
    5  * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
    6  * Copyright (c) 1997,1998 Luigi Rizzo
    7  * Copyright (c) 1994,1995 Hannu Savolainen
    8  * All rights reserved.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  */
   31 
   32 #ifdef HAVE_KERNEL_OPTION_HEADERS
   33 #include "opt_snd.h"
   34 #endif
   35 
   36 #include <dev/sound/pcm/sound.h>
   37 
   38 SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/isa/mss.c 328524 2018-01-29 00:22:30Z imp $");
   39 
   40 /* board-specific include files */
   41 #include <dev/sound/isa/mss.h>
   42 #include <dev/sound/isa/sb.h>
   43 #include <dev/sound/chip.h>
   44 
   45 #include <isa/isavar.h>
   46 
   47 #include "mixer_if.h"
   48 
   49 #define MSS_DEFAULT_BUFSZ (4096)
   50 #define MSS_INDEXED_REGS 0x20
   51 #define OPL_INDEXED_REGS 0x19
   52 
   53 struct mss_info;
   54 
   55 struct mss_chinfo {
   56         struct mss_info *parent;
   57         struct pcm_channel *channel;
   58         struct snd_dbuf *buffer;
   59         int dir;
   60         u_int32_t fmt, blksz;
   61 };
   62 
   63 struct mss_info {
   64     struct resource *io_base;   /* primary I/O address for the board */
   65     int              io_rid;
   66     struct resource *conf_base; /* and the opti931 also has a config space */
   67     int              conf_rid;
   68     struct resource *irq;
   69     int              irq_rid;
   70     struct resource *drq1; /* play */
   71     int              drq1_rid;
   72     struct resource *drq2; /* rec */
   73     int              drq2_rid;
   74     void            *ih;
   75     bus_dma_tag_t    parent_dmat;
   76     struct mtx      *lock;
   77 
   78     char mss_indexed_regs[MSS_INDEXED_REGS];
   79     char opl_indexed_regs[OPL_INDEXED_REGS];
   80     int bd_id;      /* used to hold board-id info, eg. sb version,
   81                      * mss codec type, etc. etc.
   82                      */
   83     int opti_offset;            /* offset from config_base for opti931 */
   84     u_long  bd_flags;       /* board-specific flags */
   85     int optibase;               /* base address for OPTi9xx config */
   86     struct resource *indir;     /* Indirect register index address */
   87     int indir_rid;
   88     int password;               /* password for opti9xx cards */
   89     int passwdreg;              /* password register */
   90     unsigned int bufsize;
   91     struct mss_chinfo pch, rch;
   92 };
   93 
   94 static int              mss_probe(device_t dev);
   95 static int              mss_attach(device_t dev);
   96 
   97 static driver_intr_t    mss_intr;
   98 
   99 /* prototypes for local functions */
  100 static int              mss_detect(device_t dev, struct mss_info *mss);
  101 static int              opti_detect(device_t dev, struct mss_info *mss);
  102 static char             *ymf_test(device_t dev, struct mss_info *mss);
  103 static void             ad_unmute(struct mss_info *mss);
  104 
  105 /* mixer set funcs */
  106 static int              mss_mixer_set(struct mss_info *mss, int dev, int left, int right);
  107 static int              mss_set_recsrc(struct mss_info *mss, int mask);
  108 
  109 /* io funcs */
  110 static int              ad_wait_init(struct mss_info *mss, int x);
  111 static int              ad_read(struct mss_info *mss, int reg);
  112 static void             ad_write(struct mss_info *mss, int reg, u_char data);
  113 static void             ad_write_cnt(struct mss_info *mss, int reg, u_short data);
  114 static void             ad_enter_MCE(struct mss_info *mss);
  115 static void             ad_leave_MCE(struct mss_info *mss);
  116 
  117 /* OPTi-specific functions */
  118 static void             opti_write(struct mss_info *mss, u_char reg,
  119                                    u_char data);
  120 static u_char           opti_read(struct mss_info *mss, u_char reg);
  121 static int              opti_init(device_t dev, struct mss_info *mss);
  122 
  123 /* io primitives */
  124 static void             conf_wr(struct mss_info *mss, u_char reg, u_char data);
  125 static u_char           conf_rd(struct mss_info *mss, u_char reg);
  126 
  127 static int              pnpmss_probe(device_t dev);
  128 static int              pnpmss_attach(device_t dev);
  129 
  130 static driver_intr_t    opti931_intr;
  131 
  132 static u_int32_t mss_fmt[] = {
  133         SND_FORMAT(AFMT_U8, 1, 0),
  134         SND_FORMAT(AFMT_U8, 2, 0),
  135         SND_FORMAT(AFMT_S16_LE, 1, 0),
  136         SND_FORMAT(AFMT_S16_LE, 2, 0),
  137         SND_FORMAT(AFMT_MU_LAW, 1, 0),
  138         SND_FORMAT(AFMT_MU_LAW, 2, 0),
  139         SND_FORMAT(AFMT_A_LAW, 1, 0),
  140         SND_FORMAT(AFMT_A_LAW, 2, 0),
  141         0
  142 };
  143 static struct pcmchan_caps mss_caps = {4000, 48000, mss_fmt, 0};
  144 
  145 static u_int32_t guspnp_fmt[] = {
  146         SND_FORMAT(AFMT_U8, 1, 0),
  147         SND_FORMAT(AFMT_U8, 2, 0),
  148         SND_FORMAT(AFMT_S16_LE, 1, 0),
  149         SND_FORMAT(AFMT_S16_LE, 2, 0),
  150         SND_FORMAT(AFMT_A_LAW, 1, 0),
  151         SND_FORMAT(AFMT_A_LAW, 2, 0),
  152         0
  153 };
  154 static struct pcmchan_caps guspnp_caps = {4000, 48000, guspnp_fmt, 0};
  155 
  156 static u_int32_t opti931_fmt[] = {
  157         SND_FORMAT(AFMT_U8, 1, 0),
  158         SND_FORMAT(AFMT_U8, 2, 0),
  159         SND_FORMAT(AFMT_S16_LE, 1, 0),
  160         SND_FORMAT(AFMT_S16_LE, 2, 0),
  161         0
  162 };
  163 static struct pcmchan_caps opti931_caps = {4000, 48000, opti931_fmt, 0};
  164 
  165 #define MD_AD1848       0x91
  166 #define MD_AD1845       0x92
  167 #define MD_CS42XX       0xA1
  168 #define MD_CS423X       0xA2
  169 #define MD_OPTI930      0xB0
  170 #define MD_OPTI931      0xB1
  171 #define MD_OPTI925      0xB2
  172 #define MD_OPTI924      0xB3
  173 #define MD_GUSPNP       0xB8
  174 #define MD_GUSMAX       0xB9
  175 #define MD_YM0020       0xC1
  176 #define MD_VIVO         0xD1
  177 
  178 #define DV_F_TRUE_MSS   0x00010000      /* mss _with_ base regs */
  179 
  180 #define FULL_DUPLEX(x) ((x)->bd_flags & BD_F_DUPLEX)
  181 
  182 static void
  183 mss_lock(struct mss_info *mss)
  184 {
  185         snd_mtxlock(mss->lock);
  186 }
  187 
  188 static void
  189 mss_unlock(struct mss_info *mss)
  190 {
  191         snd_mtxunlock(mss->lock);
  192 }
  193 
  194 static int
  195 port_rd(struct resource *port, int off)
  196 {
  197         if (port)
  198                 return bus_space_read_1(rman_get_bustag(port),
  199                                         rman_get_bushandle(port),
  200                                         off);
  201         else
  202                 return -1;
  203 }
  204 
  205 static void
  206 port_wr(struct resource *port, int off, u_int8_t data)
  207 {
  208         if (port)
  209                 bus_space_write_1(rman_get_bustag(port),
  210                                   rman_get_bushandle(port),
  211                                   off, data);
  212 }
  213 
  214 static int
  215 io_rd(struct mss_info *mss, int reg)
  216 {
  217         if (mss->bd_flags & BD_F_MSS_OFFSET) reg -= 4;
  218         return port_rd(mss->io_base, reg);
  219 }
  220 
  221 static void
  222 io_wr(struct mss_info *mss, int reg, u_int8_t data)
  223 {
  224         if (mss->bd_flags & BD_F_MSS_OFFSET) reg -= 4;
  225         port_wr(mss->io_base, reg, data);
  226 }
  227 
  228 static void
  229 conf_wr(struct mss_info *mss, u_char reg, u_char value)
  230 {
  231         port_wr(mss->conf_base, 0, reg);
  232         port_wr(mss->conf_base, 1, value);
  233 }
  234 
  235 static u_char
  236 conf_rd(struct mss_info *mss, u_char reg)
  237 {
  238         port_wr(mss->conf_base, 0, reg);
  239         return port_rd(mss->conf_base, 1);
  240 }
  241 
  242 static void
  243 opti_wr(struct mss_info *mss, u_char reg, u_char value)
  244 {
  245         port_wr(mss->conf_base, mss->opti_offset + 0, reg);
  246         port_wr(mss->conf_base, mss->opti_offset + 1, value);
  247 }
  248 
  249 static u_char
  250 opti_rd(struct mss_info *mss, u_char reg)
  251 {
  252         port_wr(mss->conf_base, mss->opti_offset + 0, reg);
  253         return port_rd(mss->conf_base, mss->opti_offset + 1);
  254 }
  255 
  256 static void
  257 gus_wr(struct mss_info *mss, u_char reg, u_char value)
  258 {
  259         port_wr(mss->conf_base, 3, reg);
  260         port_wr(mss->conf_base, 5, value);
  261 }
  262 
  263 static u_char
  264 gus_rd(struct mss_info *mss, u_char reg)
  265 {
  266         port_wr(mss->conf_base, 3, reg);
  267         return port_rd(mss->conf_base, 5);
  268 }
  269 
  270 static void
  271 mss_release_resources(struct mss_info *mss, device_t dev)
  272 {
  273         if (mss->irq) {
  274                 if (mss->ih)
  275                         bus_teardown_intr(dev, mss->irq, mss->ih);
  276                 bus_release_resource(dev, SYS_RES_IRQ, mss->irq_rid,
  277                                      mss->irq);
  278                 mss->irq = NULL;
  279         }
  280         if (mss->drq2) {
  281                 if (mss->drq2 != mss->drq1) {
  282                         isa_dma_release(rman_get_start(mss->drq2));
  283                         bus_release_resource(dev, SYS_RES_DRQ, mss->drq2_rid,
  284                                         mss->drq2);
  285                 }
  286                 mss->drq2 = NULL;
  287         }
  288         if (mss->drq1) {
  289                 isa_dma_release(rman_get_start(mss->drq1));
  290                 bus_release_resource(dev, SYS_RES_DRQ, mss->drq1_rid,
  291                                      mss->drq1);
  292                 mss->drq1 = NULL;
  293         }
  294         if (mss->io_base) {
  295                 bus_release_resource(dev, SYS_RES_IOPORT, mss->io_rid,
  296                                      mss->io_base);
  297                 mss->io_base = NULL;
  298         }
  299         if (mss->conf_base) {
  300                 bus_release_resource(dev, SYS_RES_IOPORT, mss->conf_rid,
  301                                      mss->conf_base);
  302                 mss->conf_base = NULL;
  303         }
  304         if (mss->indir) {
  305                 bus_release_resource(dev, SYS_RES_IOPORT, mss->indir_rid,
  306                                      mss->indir);
  307                 mss->indir = NULL;
  308         }
  309         if (mss->parent_dmat) {
  310                 bus_dma_tag_destroy(mss->parent_dmat);
  311                 mss->parent_dmat = 0;
  312         }
  313         if (mss->lock) snd_mtxfree(mss->lock);
  314 
  315         free(mss, M_DEVBUF);
  316 }
  317 
  318 static int
  319 mss_alloc_resources(struct mss_info *mss, device_t dev)
  320 {
  321         int pdma, rdma, ok = 1;
  322         if (!mss->io_base)
  323                 mss->io_base = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
  324                                                       &mss->io_rid, RF_ACTIVE);
  325         if (!mss->irq)
  326                 mss->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
  327                                                   &mss->irq_rid, RF_ACTIVE);
  328         if (!mss->drq1)
  329                 mss->drq1 = bus_alloc_resource_any(dev, SYS_RES_DRQ,
  330                                                    &mss->drq1_rid,
  331                                                    RF_ACTIVE);
  332         if (mss->conf_rid >= 0 && !mss->conf_base)
  333                 mss->conf_base = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
  334                                                         &mss->conf_rid,
  335                                                         RF_ACTIVE);
  336         if (mss->drq2_rid >= 0 && !mss->drq2)
  337                 mss->drq2 = bus_alloc_resource_any(dev, SYS_RES_DRQ,
  338                                                    &mss->drq2_rid,
  339                                                    RF_ACTIVE);
  340 
  341         if (!mss->io_base || !mss->drq1 || !mss->irq) ok = 0;
  342         if (mss->conf_rid >= 0 && !mss->conf_base) ok = 0;
  343         if (mss->drq2_rid >= 0 && !mss->drq2) ok = 0;
  344 
  345         if (ok) {
  346                 pdma = rman_get_start(mss->drq1);
  347                 isa_dma_acquire(pdma);
  348                 isa_dmainit(pdma, mss->bufsize);
  349                 mss->bd_flags &= ~BD_F_DUPLEX;
  350                 if (mss->drq2) {
  351                         rdma = rman_get_start(mss->drq2);
  352                         isa_dma_acquire(rdma);
  353                         isa_dmainit(rdma, mss->bufsize);
  354                         mss->bd_flags |= BD_F_DUPLEX;
  355                 } else mss->drq2 = mss->drq1;
  356         }
  357         return ok;
  358 }
  359 
  360 /*
  361  * The various mixers use a variety of bitmasks etc. The Voxware
  362  * driver had a very nice technique to describe a mixer and interface
  363  * to it. A table defines, for each channel, which register, bits,
  364  * offset, polarity to use. This procedure creates the new value
  365  * using the table and the old value.
  366  */
  367 
  368 static void
  369 change_bits(mixer_tab *t, u_char *regval, int dev, int chn, int newval)
  370 {
  371         u_char mask;
  372         int shift;
  373 
  374         DEB(printf("ch_bits dev %d ch %d val %d old 0x%02x "
  375                 "r %d p %d bit %d off %d\n",
  376                 dev, chn, newval, *regval,
  377                 (*t)[dev][chn].regno, (*t)[dev][chn].polarity,
  378                 (*t)[dev][chn].nbits, (*t)[dev][chn].bitoffs ) );
  379 
  380         if ( (*t)[dev][chn].polarity == 1)      /* reverse */
  381                 newval = 100 - newval ;
  382 
  383         mask = (1 << (*t)[dev][chn].nbits) - 1;
  384         newval = (int) ((newval * mask) + 50) / 100; /* Scale it */
  385         shift = (*t)[dev][chn].bitoffs /*- (*t)[dev][LEFT_CHN].nbits + 1*/;
  386 
  387         *regval &= ~(mask << shift);        /* Filter out the previous value */
  388         *regval |= (newval & mask) << shift;        /* Set the new value */
  389 }
  390 
  391 /* -------------------------------------------------------------------- */
  392 /* only one source can be set... */
  393 static int
  394 mss_set_recsrc(struct mss_info *mss, int mask)
  395 {
  396         u_char   recdev;
  397 
  398         switch (mask) {
  399         case SOUND_MASK_LINE:
  400         case SOUND_MASK_LINE3:
  401                 recdev = 0;
  402                 break;
  403 
  404         case SOUND_MASK_CD:
  405         case SOUND_MASK_LINE1:
  406                 recdev = 0x40;
  407                 break;
  408 
  409         case SOUND_MASK_IMIX:
  410                 recdev = 0xc0;
  411                 break;
  412 
  413         case SOUND_MASK_MIC:
  414         default:
  415                 mask = SOUND_MASK_MIC;
  416                 recdev = 0x80;
  417         }
  418         ad_write(mss, 0, (ad_read(mss, 0) & 0x3f) | recdev);
  419         ad_write(mss, 1, (ad_read(mss, 1) & 0x3f) | recdev);
  420         return mask;
  421 }
  422 
  423 /* there are differences in the mixer depending on the actual sound card. */
  424 static int
  425 mss_mixer_set(struct mss_info *mss, int dev, int left, int right)
  426 {
  427         int        regoffs;
  428         mixer_tab *mix_d;
  429         u_char     old, val;
  430 
  431         switch (mss->bd_id) {
  432                 case MD_OPTI931:
  433                         mix_d = &opti931_devices;
  434                         break;
  435                 case MD_OPTI930:
  436                         mix_d = &opti930_devices;
  437                         break;
  438                 default:
  439                         mix_d = &mix_devices;
  440         }
  441 
  442         if ((*mix_d)[dev][LEFT_CHN].nbits == 0) {
  443                 DEB(printf("nbits = 0 for dev %d\n", dev));
  444                 return -1;
  445         }
  446 
  447         if ((*mix_d)[dev][RIGHT_CHN].nbits == 0) right = left; /* mono */
  448 
  449         /* Set the left channel */
  450 
  451         regoffs = (*mix_d)[dev][LEFT_CHN].regno;
  452         old = val = ad_read(mss, regoffs);
  453         /* if volume is 0, mute chan. Otherwise, unmute. */
  454         if (regoffs != 0) val = (left == 0)? old | 0x80 : old & 0x7f;
  455         change_bits(mix_d, &val, dev, LEFT_CHN, left);
  456         ad_write(mss, regoffs, val);
  457 
  458         DEB(printf("LEFT: dev %d reg %d old 0x%02x new 0x%02x\n",
  459                 dev, regoffs, old, val));
  460 
  461         if ((*mix_d)[dev][RIGHT_CHN].nbits != 0) { /* have stereo */
  462                 /* Set the right channel */
  463                 regoffs = (*mix_d)[dev][RIGHT_CHN].regno;
  464                 old = val = ad_read(mss, regoffs);
  465                 if (regoffs != 1) val = (right == 0)? old | 0x80 : old & 0x7f;
  466                 change_bits(mix_d, &val, dev, RIGHT_CHN, right);
  467                 ad_write(mss, regoffs, val);
  468 
  469                 DEB(printf("RIGHT: dev %d reg %d old 0x%02x new 0x%02x\n",
  470                 dev, regoffs, old, val));
  471         }
  472         return 0; /* success */
  473 }
  474 
  475 /* -------------------------------------------------------------------- */
  476 
  477 static int
  478 mssmix_init(struct snd_mixer *m)
  479 {
  480         struct mss_info *mss = mix_getdevinfo(m);
  481 
  482         mix_setdevs(m, MODE2_MIXER_DEVICES);
  483         mix_setrecdevs(m, MSS_REC_DEVICES);
  484         switch(mss->bd_id) {
  485         case MD_OPTI930:
  486                 mix_setdevs(m, OPTI930_MIXER_DEVICES);
  487                 break;
  488 
  489         case MD_OPTI931:
  490                 mix_setdevs(m, OPTI931_MIXER_DEVICES);
  491                 mss_lock(mss);
  492                 ad_write(mss, 20, 0x88);
  493                 ad_write(mss, 21, 0x88);
  494                 mss_unlock(mss);
  495                 break;
  496 
  497         case MD_AD1848:
  498                 mix_setdevs(m, MODE1_MIXER_DEVICES);
  499                 break;
  500 
  501         case MD_GUSPNP:
  502         case MD_GUSMAX:
  503                 /* this is only necessary in mode 3 ... */
  504                 mss_lock(mss);
  505                 ad_write(mss, 22, 0x88);
  506                 ad_write(mss, 23, 0x88);
  507                 mss_unlock(mss);
  508                 break;
  509         }
  510         return 0;
  511 }
  512 
  513 static int
  514 mssmix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
  515 {
  516         struct mss_info *mss = mix_getdevinfo(m);
  517 
  518         mss_lock(mss);
  519         mss_mixer_set(mss, dev, left, right);
  520         mss_unlock(mss);
  521 
  522         return left | (right << 8);
  523 }
  524 
  525 static u_int32_t
  526 mssmix_setrecsrc(struct snd_mixer *m, u_int32_t src)
  527 {
  528         struct mss_info *mss = mix_getdevinfo(m);
  529 
  530         mss_lock(mss);
  531         src = mss_set_recsrc(mss, src);
  532         mss_unlock(mss);
  533         return src;
  534 }
  535 
  536 static kobj_method_t mssmix_mixer_methods[] = {
  537         KOBJMETHOD(mixer_init,          mssmix_init),
  538         KOBJMETHOD(mixer_set,           mssmix_set),
  539         KOBJMETHOD(mixer_setrecsrc,     mssmix_setrecsrc),
  540         KOBJMETHOD_END
  541 };
  542 MIXER_DECLARE(mssmix_mixer);
  543 
  544 /* -------------------------------------------------------------------- */
  545 
  546 static int
  547 ymmix_init(struct snd_mixer *m)
  548 {
  549         struct mss_info *mss = mix_getdevinfo(m);
  550 
  551         mssmix_init(m);
  552         mix_setdevs(m, mix_getdevs(m) | SOUND_MASK_VOLUME | SOUND_MASK_MIC
  553                                       | SOUND_MASK_BASS | SOUND_MASK_TREBLE);
  554         /* Set master volume */
  555         mss_lock(mss);
  556         conf_wr(mss, OPL3SAx_VOLUMEL, 7);
  557         conf_wr(mss, OPL3SAx_VOLUMER, 7);
  558         mss_unlock(mss);
  559 
  560         return 0;
  561 }
  562 
  563 static int
  564 ymmix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
  565 {
  566         struct mss_info *mss = mix_getdevinfo(m);
  567         int t, l, r;
  568 
  569         mss_lock(mss);
  570         switch (dev) {
  571         case SOUND_MIXER_VOLUME:
  572                 if (left) t = 15 - (left * 15) / 100;
  573                 else t = 0x80; /* mute */
  574                 conf_wr(mss, OPL3SAx_VOLUMEL, t);
  575                 if (right) t = 15 - (right * 15) / 100;
  576                 else t = 0x80; /* mute */
  577                 conf_wr(mss, OPL3SAx_VOLUMER, t);
  578                 break;
  579 
  580         case SOUND_MIXER_MIC:
  581                 t = left;
  582                 if (left) t = 31 - (left * 31) / 100;
  583                 else t = 0x80; /* mute */
  584                 conf_wr(mss, OPL3SAx_MIC, t);
  585                 break;
  586 
  587         case SOUND_MIXER_BASS:
  588                 l = (left * 7) / 100;
  589                 r = (right * 7) / 100;
  590                 t = (r << 4) | l;
  591                 conf_wr(mss, OPL3SAx_BASS, t);
  592                 break;
  593 
  594         case SOUND_MIXER_TREBLE:
  595                 l = (left * 7) / 100;
  596                 r = (right * 7) / 100;
  597                 t = (r << 4) | l;
  598                 conf_wr(mss, OPL3SAx_TREBLE, t);
  599                 break;
  600 
  601         default:
  602                 mss_mixer_set(mss, dev, left, right);
  603         }
  604         mss_unlock(mss);
  605 
  606         return left | (right << 8);
  607 }
  608 
  609 static u_int32_t
  610 ymmix_setrecsrc(struct snd_mixer *m, u_int32_t src)
  611 {
  612         struct mss_info *mss = mix_getdevinfo(m);
  613         mss_lock(mss);
  614         src = mss_set_recsrc(mss, src);
  615         mss_unlock(mss);
  616         return src;
  617 }
  618 
  619 static kobj_method_t ymmix_mixer_methods[] = {
  620         KOBJMETHOD(mixer_init,          ymmix_init),
  621         KOBJMETHOD(mixer_set,           ymmix_set),
  622         KOBJMETHOD(mixer_setrecsrc,     ymmix_setrecsrc),
  623         KOBJMETHOD_END
  624 };
  625 MIXER_DECLARE(ymmix_mixer);
  626 
  627 /* -------------------------------------------------------------------- */
  628 /*
  629  * XXX This might be better off in the gusc driver.
  630  */
  631 static void
  632 gusmax_setup(struct mss_info *mss, device_t dev, struct resource *alt)
  633 {
  634         static const unsigned char irq_bits[16] = {
  635                 0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7
  636         };
  637         static const unsigned char dma_bits[8] = {
  638                 0, 1, 0, 2, 0, 3, 4, 5
  639         };
  640         device_t parent = device_get_parent(dev);
  641         unsigned char irqctl, dmactl;
  642         int s;
  643 
  644         s = splhigh();
  645 
  646         port_wr(alt, 0x0f, 0x05);
  647         port_wr(alt, 0x00, 0x0c);
  648         port_wr(alt, 0x0b, 0x00);
  649 
  650         port_wr(alt, 0x0f, 0x00);
  651 
  652         irqctl = irq_bits[isa_get_irq(parent)];
  653         /* Share the IRQ with the MIDI driver.  */
  654         irqctl |= 0x40;
  655         dmactl = dma_bits[isa_get_drq(parent)];
  656         if (device_get_flags(parent) & DV_F_DUAL_DMA)
  657                 dmactl |= dma_bits[device_get_flags(parent) & DV_F_DRQ_MASK]
  658                     << 3;
  659 
  660         /*
  661          * Set the DMA and IRQ control latches.
  662          */
  663         port_wr(alt, 0x00, 0x0c);
  664         port_wr(alt, 0x0b, dmactl | 0x80);
  665         port_wr(alt, 0x00, 0x4c);
  666         port_wr(alt, 0x0b, irqctl);
  667 
  668         port_wr(alt, 0x00, 0x0c);
  669         port_wr(alt, 0x0b, dmactl);
  670         port_wr(alt, 0x00, 0x4c);
  671         port_wr(alt, 0x0b, irqctl);
  672 
  673         port_wr(mss->conf_base, 2, 0);
  674         port_wr(alt, 0x00, 0x0c);
  675         port_wr(mss->conf_base, 2, 0);
  676 
  677         splx(s);
  678 }
  679 
  680 static int
  681 mss_init(struct mss_info *mss, device_t dev)
  682 {
  683         u_char r6, r9;
  684         struct resource *alt;
  685         int rid, tmp;
  686 
  687         mss->bd_flags |= BD_F_MCE_BIT;
  688         switch(mss->bd_id) {
  689         case MD_OPTI931:
  690                 /*
  691                  * The MED3931 v.1.0 allocates 3 bytes for the config
  692                  * space, whereas v.2.0 allocates 4 bytes. What I know
  693                  * for sure is that the upper two ports must be used,
  694                  * and they should end on a boundary of 4 bytes. So I
  695                  * need the following trick.
  696                  */
  697                 mss->opti_offset =
  698                         (rman_get_start(mss->conf_base) & ~3) + 2
  699                         - rman_get_start(mss->conf_base);
  700                 BVDDB(printf("mss_init: opti_offset=%d\n", mss->opti_offset));
  701                 opti_wr(mss, 4, 0xd6); /* fifo empty, OPL3, audio enable, SB3.2 */
  702                 ad_write(mss, 10, 2); /* enable interrupts */
  703                 opti_wr(mss, 6, 2);  /* MCIR6: mss enable, sb disable */
  704                 opti_wr(mss, 5, 0x28);  /* MCIR5: codec in exp. mode,fifo */
  705                 break;
  706 
  707         case MD_GUSPNP:
  708         case MD_GUSMAX:
  709                 gus_wr(mss, 0x4c /* _URSTI */, 0);/* Pull reset */
  710                 DELAY(1000 * 30);
  711                 /* release reset  and enable DAC */
  712                 gus_wr(mss, 0x4c /* _URSTI */, 3);
  713                 DELAY(1000 * 30);
  714                 /* end of reset */
  715 
  716                 rid = 0;
  717                 alt = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
  718                                              RF_ACTIVE);
  719                 if (alt == NULL) {
  720                         printf("XXX couldn't init GUS PnP/MAX\n");
  721                         break;
  722                 }
  723                 port_wr(alt, 0, 0xC); /* enable int and dma */
  724                 if (mss->bd_id == MD_GUSMAX)
  725                         gusmax_setup(mss, dev, alt);
  726                 bus_release_resource(dev, SYS_RES_IOPORT, rid, alt);
  727 
  728                 /*
  729                  * unmute left & right line. Need to go in mode3, unmute,
  730                  * and back to mode 2
  731                  */
  732                 tmp = ad_read(mss, 0x0c);
  733                 ad_write(mss, 0x0c, 0x6c); /* special value to enter mode 3 */
  734                 ad_write(mss, 0x19, 0); /* unmute left */
  735                 ad_write(mss, 0x1b, 0); /* unmute right */
  736                 ad_write(mss, 0x0c, tmp); /* restore old mode */
  737 
  738                 /* send codec interrupts on irq1 and only use that one */
  739                 gus_wr(mss, 0x5a, 0x4f);
  740 
  741                 /* enable access to hidden regs */
  742                 tmp = gus_rd(mss, 0x5b /* IVERI */);
  743                 gus_wr(mss, 0x5b, tmp | 1);
  744                 BVDDB(printf("GUS: silicon rev %c\n", 'A' + ((tmp & 0xf) >> 4)));
  745                 break;
  746 
  747         case MD_YM0020:
  748                 conf_wr(mss, OPL3SAx_DMACONF, 0xa9); /* dma-b rec, dma-a play */
  749                 r6 = conf_rd(mss, OPL3SAx_DMACONF);
  750                 r9 = conf_rd(mss, OPL3SAx_MISC); /* version */
  751                 BVDDB(printf("Yamaha: ver 0x%x DMA config 0x%x\n", r6, r9);)
  752                 /* yamaha - set volume to max */
  753                 conf_wr(mss, OPL3SAx_VOLUMEL, 0);
  754                 conf_wr(mss, OPL3SAx_VOLUMER, 0);
  755                 conf_wr(mss, OPL3SAx_DMACONF, FULL_DUPLEX(mss)? 0xa9 : 0x8b);
  756                 break;
  757         }
  758         if (FULL_DUPLEX(mss) && mss->bd_id != MD_OPTI931)
  759                 ad_write(mss, 12, ad_read(mss, 12) | 0x40); /* mode 2 */
  760         ad_enter_MCE(mss);
  761         ad_write(mss, 9, FULL_DUPLEX(mss)? 0 : 4);
  762         ad_leave_MCE(mss);
  763         ad_write(mss, 10, 2); /* int enable */
  764         io_wr(mss, MSS_STATUS, 0); /* Clear interrupt status */
  765         /* the following seem required on the CS4232 */
  766         ad_unmute(mss);
  767         return 0;
  768 }
  769 
  770 
  771 /*
  772  * main irq handler for the CS423x. The OPTi931 code is
  773  * a separate one.
  774  * The correct way to operate for a device with multiple internal
  775  * interrupt sources is to loop on the status register and ack
  776  * interrupts until all interrupts are served and none are reported. At
  777  * this point the IRQ line to the ISA IRQ controller should go low
  778  * and be raised at the next interrupt.
  779  *
  780  * Since the ISA IRQ controller is sent EOI _before_ passing control
  781  * to the isr, it might happen that we serve an interrupt early, in
  782  * which case the status register at the next interrupt should just
  783  * say that there are no more interrupts...
  784  */
  785 
  786 static void
  787 mss_intr(void *arg)
  788 {
  789         struct mss_info *mss = arg;
  790         u_char c = 0, served = 0;
  791         int i;
  792 
  793         DEB(printf("mss_intr\n"));
  794         mss_lock(mss);
  795         ad_read(mss, 11); /* fake read of status bits */
  796 
  797         /* loop until there are interrupts, but no more than 10 times. */
  798         for (i = 10; i > 0 && io_rd(mss, MSS_STATUS) & 1; i--) {
  799                 /* get exact reason for full-duplex boards */
  800                 c = FULL_DUPLEX(mss)? ad_read(mss, 24) : 0x30;
  801                 c &= ~served;
  802                 if (sndbuf_runsz(mss->pch.buffer) && (c & 0x10)) {
  803                         served |= 0x10;
  804                         mss_unlock(mss);
  805                         chn_intr(mss->pch.channel);
  806                         mss_lock(mss);
  807                 }
  808                 if (sndbuf_runsz(mss->rch.buffer) && (c & 0x20)) {
  809                         served |= 0x20;
  810                         mss_unlock(mss);
  811                         chn_intr(mss->rch.channel);
  812                         mss_lock(mss);
  813                 }
  814                 /* now ack the interrupt */
  815                 if (FULL_DUPLEX(mss)) ad_write(mss, 24, ~c); /* ack selectively */
  816                 else io_wr(mss, MSS_STATUS, 0); /* Clear interrupt status */
  817         }
  818         if (i == 10) {
  819                 BVDDB(printf("mss_intr: irq, but not from mss\n"));
  820         } else if (served == 0) {
  821                 BVDDB(printf("mss_intr: unexpected irq with reason %x\n", c));
  822                 /*
  823                 * this should not happen... I have no idea what to do now.
  824                 * maybe should do a sanity check and restart dmas ?
  825                 */
  826                 io_wr(mss, MSS_STATUS, 0);      /* Clear interrupt status */
  827         }
  828         mss_unlock(mss);
  829 }
  830 
  831 /*
  832  * AD_WAIT_INIT waits if we are initializing the board and
  833  * we cannot modify its settings
  834  */
  835 static int
  836 ad_wait_init(struct mss_info *mss, int x)
  837 {
  838         int arg = x, n = 0; /* to shut up the compiler... */
  839         for (; x > 0; x--)
  840                 if ((n = io_rd(mss, MSS_INDEX)) & MSS_IDXBUSY) DELAY(10);
  841                 else return n;
  842         printf("AD_WAIT_INIT FAILED %d 0x%02x\n", arg, n);
  843         return n;
  844 }
  845 
  846 static int
  847 ad_read(struct mss_info *mss, int reg)
  848 {
  849         int             x;
  850 
  851         ad_wait_init(mss, 201000);
  852         x = io_rd(mss, MSS_INDEX) & ~MSS_IDXMASK;
  853         io_wr(mss, MSS_INDEX, (u_char)(reg & MSS_IDXMASK) | x);
  854         x = io_rd(mss, MSS_IDATA);
  855         /* printf("ad_read %d, %x\n", reg, x); */
  856         return x;
  857 }
  858 
  859 static void
  860 ad_write(struct mss_info *mss, int reg, u_char data)
  861 {
  862         int x;
  863 
  864         /* printf("ad_write %d, %x\n", reg, data); */
  865         ad_wait_init(mss, 1002000);
  866         x = io_rd(mss, MSS_INDEX) & ~MSS_IDXMASK;
  867         io_wr(mss, MSS_INDEX, (u_char)(reg & MSS_IDXMASK) | x);
  868         io_wr(mss, MSS_IDATA, data);
  869 }
  870 
  871 static void
  872 ad_write_cnt(struct mss_info *mss, int reg, u_short cnt)
  873 {
  874         ad_write(mss, reg+1, cnt & 0xff);
  875         ad_write(mss, reg, cnt >> 8); /* upper base must be last */
  876 }
  877 
  878 static void
  879 wait_for_calibration(struct mss_info *mss)
  880 {
  881         int t;
  882 
  883         /*
  884          * Wait until the auto calibration process has finished.
  885          *
  886          * 1) Wait until the chip becomes ready (reads don't return 0x80).
  887          * 2) Wait until the ACI bit of I11 gets on
  888          * 3) Wait until the ACI bit of I11 gets off
  889          */
  890 
  891         t = ad_wait_init(mss, 1000000);
  892         if (t & MSS_IDXBUSY) printf("mss: Auto calibration timed out(1).\n");
  893 
  894         /*
  895          * The calibration mode for chips that support it is set so that
  896          * we never see ACI go on.
  897          */
  898         if (mss->bd_id == MD_GUSMAX || mss->bd_id == MD_GUSPNP) {
  899                 for (t = 100; t > 0 && (ad_read(mss, 11) & 0x20) == 0; t--);
  900         } else {
  901                 /*
  902                  * XXX This should only be enabled for cards that *really*
  903                  * need it.  Are there any?
  904                  */
  905                 for (t = 100; t > 0 && (ad_read(mss, 11) & 0x20) == 0; t--) DELAY(100);
  906         }
  907         for (t = 100; t > 0 && ad_read(mss, 11) & 0x20; t--) DELAY(100);
  908 }
  909 
  910 static void
  911 ad_unmute(struct mss_info *mss)
  912 {
  913         ad_write(mss, 6, ad_read(mss, 6) & ~I6_MUTE);
  914         ad_write(mss, 7, ad_read(mss, 7) & ~I6_MUTE);
  915 }
  916 
  917 static void
  918 ad_enter_MCE(struct mss_info *mss)
  919 {
  920         int prev;
  921 
  922         mss->bd_flags |= BD_F_MCE_BIT;
  923         ad_wait_init(mss, 203000);
  924         prev = io_rd(mss, MSS_INDEX);
  925         prev &= ~MSS_TRD;
  926         io_wr(mss, MSS_INDEX, prev | MSS_MCE);
  927 }
  928 
  929 static void
  930 ad_leave_MCE(struct mss_info *mss)
  931 {
  932         u_char   prev;
  933 
  934         if ((mss->bd_flags & BD_F_MCE_BIT) == 0) {
  935                 DEB(printf("--- hey, leave_MCE: MCE bit was not set!\n"));
  936                 return;
  937         }
  938 
  939         ad_wait_init(mss, 1000000);
  940 
  941         mss->bd_flags &= ~BD_F_MCE_BIT;
  942 
  943         prev = io_rd(mss, MSS_INDEX);
  944         prev &= ~MSS_TRD;
  945         io_wr(mss, MSS_INDEX, prev & ~MSS_MCE); /* Clear the MCE bit */
  946         wait_for_calibration(mss);
  947 }
  948 
  949 static int
  950 mss_speed(struct mss_chinfo *ch, int speed)
  951 {
  952         struct mss_info *mss = ch->parent;
  953         /*
  954         * In the CS4231, the low 4 bits of I8 are used to hold the
  955         * sample rate.  Only a fixed number of values is allowed. This
  956         * table lists them. The speed-setting routines scans the table
  957         * looking for the closest match. This is the only supported method.
  958         *
  959         * In the CS4236, there is an alternate metod (which we do not
  960         * support yet) which provides almost arbitrary frequency setting.
  961         * In the AD1845, it looks like the sample rate can be
  962         * almost arbitrary, and written directly to a register.
  963         * In the OPTi931, there is a SB command which provides for
  964         * almost arbitrary frequency setting.
  965         *
  966         */
  967         ad_enter_MCE(mss);
  968         if (mss->bd_id == MD_AD1845) { /* Use alternate speed select regs */
  969                 ad_write(mss, 22, (speed >> 8) & 0xff); /* Speed MSB */
  970                 ad_write(mss, 23, speed & 0xff);        /* Speed LSB */
  971                 /* XXX must also do something in I27 for the ad1845 */
  972         } else {
  973                 int i, sel = 0; /* assume entry 0 does not contain -1 */
  974                 static int speeds[] =
  975                 {8000, 5512, 16000, 11025, 27429, 18900, 32000, 22050,
  976                 -1, 37800, -1, 44100, 48000, 33075, 9600, 6615};
  977 
  978                 for (i = 1; i < 16; i++)
  979                         if (speeds[i] > 0 &&
  980                             abs(speed-speeds[i]) < abs(speed-speeds[sel])) sel = i;
  981                 speed = speeds[sel];
  982                 ad_write(mss, 8, (ad_read(mss, 8) & 0xf0) | sel);
  983                 ad_wait_init(mss, 10000);
  984         }
  985         ad_leave_MCE(mss);
  986 
  987         return speed;
  988 }
  989 
  990 /*
  991  * mss_format checks that the format is supported (or defaults to AFMT_U8)
  992  * and returns the bit setting for the 1848 register corresponding to
  993  * the desired format.
  994  *
  995  * fixed lr970724
  996  */
  997 
  998 static int
  999 mss_format(struct mss_chinfo *ch, u_int32_t format)
 1000 {
 1001         struct mss_info *mss = ch->parent;
 1002         int i, arg = AFMT_ENCODING(format);
 1003 
 1004         /*
 1005         * The data format uses 3 bits (just 2 on the 1848). For each
 1006         * bit setting, the following array returns the corresponding format.
 1007         * The code scans the array looking for a suitable format. In
 1008         * case it is not found, default to AFMT_U8 (not such a good
 1009         * choice, but let's do it for compatibility...).
 1010         */
 1011 
 1012         static int fmts[] =
 1013                 {AFMT_U8, AFMT_MU_LAW, AFMT_S16_LE, AFMT_A_LAW,
 1014                 -1, AFMT_IMA_ADPCM, AFMT_U16_BE, -1};
 1015 
 1016         ch->fmt = format;
 1017         for (i = 0; i < 8; i++) if (arg == fmts[i]) break;
 1018         arg = i << 1;
 1019         if (AFMT_CHANNEL(format) > 1) arg |= 1;
 1020         arg <<= 4;
 1021         ad_enter_MCE(mss);
 1022         ad_write(mss, 8, (ad_read(mss, 8) & 0x0f) | arg);
 1023         ad_wait_init(mss, 10000);
 1024         if (ad_read(mss, 12) & 0x40) {  /* mode2? */
 1025                 ad_write(mss, 28, arg); /* capture mode */
 1026                 ad_wait_init(mss, 10000);
 1027         }
 1028         ad_leave_MCE(mss);
 1029         return format;
 1030 }
 1031 
 1032 static int
 1033 mss_trigger(struct mss_chinfo *ch, int go)
 1034 {
 1035         struct mss_info *mss = ch->parent;
 1036         u_char m;
 1037         int retry, wr, cnt, ss;
 1038 
 1039         ss = 1;
 1040         ss <<= (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0;
 1041         ss <<= (ch->fmt & AFMT_16BIT)? 1 : 0;
 1042 
 1043         wr = (ch->dir == PCMDIR_PLAY)? 1 : 0;
 1044         m = ad_read(mss, 9);
 1045         switch (go) {
 1046         case PCMTRIG_START:
 1047                 cnt = (ch->blksz / ss) - 1;
 1048 
 1049                 DEB(if (m & 4) printf("OUCH! reg 9 0x%02x\n", m););
 1050                 m |= wr? I9_PEN : I9_CEN; /* enable DMA */
 1051                 ad_write_cnt(mss, (wr || !FULL_DUPLEX(mss))? 14 : 30, cnt);
 1052                 break;
 1053 
 1054         case PCMTRIG_STOP:
 1055         case PCMTRIG_ABORT: /* XXX check this... */
 1056                 m &= ~(wr? I9_PEN : I9_CEN); /* Stop DMA */
 1057 #if 0
 1058                 /*
 1059                 * try to disable DMA by clearing count registers. Not sure it
 1060                 * is needed, and it might cause false interrupts when the
 1061                 * DMA is re-enabled later.
 1062                 */
 1063                 ad_write_cnt(mss, (wr || !FULL_DUPLEX(mss))? 14 : 30, 0);
 1064 #endif
 1065         }
 1066         /* on the OPTi931 the enable bit seems hard to set... */
 1067         for (retry = 10; retry > 0; retry--) {
 1068                 ad_write(mss, 9, m);
 1069                 if (ad_read(mss, 9) == m) break;
 1070         }
 1071         if (retry == 0) BVDDB(printf("stop dma, failed to set bit 0x%02x 0x%02x\n", \
 1072                                m, ad_read(mss, 9)));
 1073         return 0;
 1074 }
 1075 
 1076 
 1077 /*
 1078  * the opti931 seems to miss interrupts when working in full
 1079  * duplex, so we try some heuristics to catch them.
 1080  */
 1081 static void
 1082 opti931_intr(void *arg)
 1083 {
 1084         struct mss_info *mss = (struct mss_info *)arg;
 1085         u_char masked = 0, i11, mc11, c = 0;
 1086         u_char reason; /* b0 = playback, b1 = capture, b2 = timer */
 1087         int loops = 10;
 1088 
 1089 #if 0
 1090         reason = io_rd(mss, MSS_STATUS);
 1091         if (!(reason & 1)) {/* no int, maybe a shared line ? */
 1092                 DEB(printf("intr: flag 0, mcir11 0x%02x\n", ad_read(mss, 11)));
 1093                 return;
 1094         }
 1095 #endif
 1096         mss_lock(mss);
 1097         i11 = ad_read(mss, 11); /* XXX what's for ? */
 1098         again:
 1099 
 1100         c = mc11 = FULL_DUPLEX(mss)? opti_rd(mss, 11) : 0xc;
 1101         mc11 &= 0x0c;
 1102         if (c & 0x10) {
 1103                 DEB(printf("Warning: CD interrupt\n");)
 1104                 mc11 |= 0x10;
 1105         }
 1106         if (c & 0x20) {
 1107                 DEB(printf("Warning: MPU interrupt\n");)
 1108                 mc11 |= 0x20;
 1109         }
 1110         if (mc11 & masked) BVDDB(printf("irq reset failed, mc11 0x%02x, 0x%02x\n",\
 1111                                   mc11, masked));
 1112         masked |= mc11;
 1113         /*
 1114         * the nice OPTi931 sets the IRQ line before setting the bits in
 1115         * mc11. So, on some occasions I have to retry (max 10 times).
 1116         */
 1117         if (mc11 == 0) { /* perhaps can return ... */
 1118                 reason = io_rd(mss, MSS_STATUS);
 1119                 if (reason & 1) {
 1120                         DEB(printf("one more try...\n");)
 1121                         if (--loops) goto again;
 1122                         else BVDDB(printf("intr, but mc11 not set\n");)
 1123                 }
 1124                 if (loops == 0) BVDDB(printf("intr, nothing in mcir11 0x%02x\n", mc11));
 1125                 mss_unlock(mss);
 1126                 return;
 1127         }
 1128 
 1129         if (sndbuf_runsz(mss->rch.buffer) && (mc11 & 8)) {
 1130                 mss_unlock(mss);
 1131                 chn_intr(mss->rch.channel);
 1132                 mss_lock(mss);
 1133         }
 1134         if (sndbuf_runsz(mss->pch.buffer) && (mc11 & 4)) {
 1135                 mss_unlock(mss);
 1136                 chn_intr(mss->pch.channel);
 1137                 mss_lock(mss);
 1138         }
 1139         opti_wr(mss, 11, ~mc11); /* ack */
 1140         if (--loops) goto again;
 1141         mss_unlock(mss);
 1142         DEB(printf("xxx too many loops\n");)
 1143 }
 1144 
 1145 /* -------------------------------------------------------------------- */
 1146 /* channel interface */
 1147 static void *
 1148 msschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
 1149 {
 1150         struct mss_info *mss = devinfo;
 1151         struct mss_chinfo *ch = (dir == PCMDIR_PLAY)? &mss->pch : &mss->rch;
 1152 
 1153         ch->parent = mss;
 1154         ch->channel = c;
 1155         ch->buffer = b;
 1156         ch->dir = dir;
 1157         if (sndbuf_alloc(ch->buffer, mss->parent_dmat, 0, mss->bufsize) != 0)
 1158                 return NULL;
 1159         sndbuf_dmasetup(ch->buffer, (dir == PCMDIR_PLAY)? mss->drq1 : mss->drq2);
 1160         return ch;
 1161 }
 1162 
 1163 static int
 1164 msschan_setformat(kobj_t obj, void *data, u_int32_t format)
 1165 {
 1166         struct mss_chinfo *ch = data;
 1167         struct mss_info *mss = ch->parent;
 1168 
 1169         mss_lock(mss);
 1170         mss_format(ch, format);
 1171         mss_unlock(mss);
 1172         return 0;
 1173 }
 1174 
 1175 static u_int32_t
 1176 msschan_setspeed(kobj_t obj, void *data, u_int32_t speed)
 1177 {
 1178         struct mss_chinfo *ch = data;
 1179         struct mss_info *mss = ch->parent;
 1180         u_int32_t r;
 1181 
 1182         mss_lock(mss);
 1183         r = mss_speed(ch, speed);
 1184         mss_unlock(mss);
 1185 
 1186         return r;
 1187 }
 1188 
 1189 static u_int32_t
 1190 msschan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
 1191 {
 1192         struct mss_chinfo *ch = data;
 1193 
 1194         ch->blksz = blocksize;
 1195         sndbuf_resize(ch->buffer, 2, ch->blksz);
 1196 
 1197         return ch->blksz;
 1198 }
 1199 
 1200 static int
 1201 msschan_trigger(kobj_t obj, void *data, int go)
 1202 {
 1203         struct mss_chinfo *ch = data;
 1204         struct mss_info *mss = ch->parent;
 1205 
 1206         if (!PCMTRIG_COMMON(go))
 1207                 return 0;
 1208 
 1209         sndbuf_dma(ch->buffer, go);
 1210         mss_lock(mss);
 1211         mss_trigger(ch, go);
 1212         mss_unlock(mss);
 1213         return 0;
 1214 }
 1215 
 1216 static u_int32_t
 1217 msschan_getptr(kobj_t obj, void *data)
 1218 {
 1219         struct mss_chinfo *ch = data;
 1220         return sndbuf_dmaptr(ch->buffer);
 1221 }
 1222 
 1223 static struct pcmchan_caps *
 1224 msschan_getcaps(kobj_t obj, void *data)
 1225 {
 1226         struct mss_chinfo *ch = data;
 1227 
 1228         switch(ch->parent->bd_id) {
 1229         case MD_OPTI931:
 1230                 return &opti931_caps;
 1231                 break;
 1232 
 1233         case MD_GUSPNP:
 1234         case MD_GUSMAX:
 1235                 return &guspnp_caps;
 1236                 break;
 1237 
 1238         default:
 1239                 return &mss_caps;
 1240                 break;
 1241         }
 1242 }
 1243 
 1244 static kobj_method_t msschan_methods[] = {
 1245         KOBJMETHOD(channel_init,                msschan_init),
 1246         KOBJMETHOD(channel_setformat,           msschan_setformat),
 1247         KOBJMETHOD(channel_setspeed,            msschan_setspeed),
 1248         KOBJMETHOD(channel_setblocksize,        msschan_setblocksize),
 1249         KOBJMETHOD(channel_trigger,             msschan_trigger),
 1250         KOBJMETHOD(channel_getptr,              msschan_getptr),
 1251         KOBJMETHOD(channel_getcaps,             msschan_getcaps),
 1252         KOBJMETHOD_END
 1253 };
 1254 CHANNEL_DECLARE(msschan);
 1255 
 1256 /* -------------------------------------------------------------------- */
 1257 
 1258 /*
 1259  * mss_probe() is the probe routine. Note, it is not necessary to
 1260  * go through this for PnP devices, since they are already
 1261  * indentified precisely using their PnP id.
 1262  *
 1263  * The base address supplied in the device refers to the old MSS
 1264  * specs where the four 4 registers in io space contain configuration
 1265  * information. Some boards (as an example, early MSS boards)
 1266  * has such a block of registers, whereas others (generally CS42xx)
 1267  * do not.  In order to distinguish between the two and do not have
 1268  * to supply two separate probe routines, the flags entry in isa_device
 1269  * has a bit to mark this.
 1270  *
 1271  */
 1272 
 1273 static int
 1274 mss_probe(device_t dev)
 1275 {
 1276         u_char tmp, tmpx;
 1277         int flags, irq, drq, result = ENXIO, setres = 0;
 1278         struct mss_info *mss;
 1279 
 1280         if (isa_get_logicalid(dev)) return ENXIO; /* not yet */
 1281 
 1282         mss = (struct mss_info *)malloc(sizeof *mss, M_DEVBUF, M_NOWAIT | M_ZERO);
 1283         if (!mss) return ENXIO;
 1284 
 1285         mss->io_rid = 0;
 1286         mss->conf_rid = -1;
 1287         mss->irq_rid = 0;
 1288         mss->drq1_rid = 0;
 1289         mss->drq2_rid = -1;
 1290         mss->io_base = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT,
 1291                                                 &mss->io_rid, 8, RF_ACTIVE);
 1292         if (!mss->io_base) {
 1293                 BVDDB(printf("mss_probe: no address given, try 0x%x\n", 0x530));
 1294                 mss->io_rid = 0;
 1295                 /* XXX verify this */
 1296                 setres = 1;
 1297                 bus_set_resource(dev, SYS_RES_IOPORT, mss->io_rid,
 1298                                 0x530, 8);
 1299                 mss->io_base = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT,
 1300                                                         &mss->io_rid,
 1301                                                         8, RF_ACTIVE);
 1302         }
 1303         if (!mss->io_base) goto no;
 1304 
 1305         /* got irq/dma regs? */
 1306         flags = device_get_flags(dev);
 1307         irq = isa_get_irq(dev);
 1308         drq = isa_get_drq(dev);
 1309 
 1310         if (!(device_get_flags(dev) & DV_F_TRUE_MSS)) goto mss_probe_end;
 1311 
 1312         /*
 1313         * Check if the IO port returns valid signature. The original MS
 1314         * Sound system returns 0x04 while some cards
 1315         * (AudioTriX Pro for example) return 0x00 or 0x0f.
 1316         */
 1317 
 1318         device_set_desc(dev, "MSS");
 1319         tmpx = tmp = io_rd(mss, 3);
 1320         if (tmp == 0xff) {      /* Bus float */
 1321                 BVDDB(printf("I/O addr inactive (%x), try pseudo_mss\n", tmp));
 1322                 device_set_flags(dev, flags & ~DV_F_TRUE_MSS);
 1323                 goto mss_probe_end;
 1324         }
 1325         tmp &= 0x3f;
 1326         if (!(tmp == 0x04 || tmp == 0x0f || tmp == 0x00 || tmp == 0x05)) {
 1327                 BVDDB(printf("No MSS signature detected on port 0x%jx (0x%x)\n",
 1328                         rman_get_start(mss->io_base), tmpx));
 1329                 goto no;
 1330         }
 1331         if (irq > 11) {
 1332                 printf("MSS: Bad IRQ %d\n", irq);
 1333                 goto no;
 1334         }
 1335         if (!(drq == 0 || drq == 1 || drq == 3)) {
 1336                 printf("MSS: Bad DMA %d\n", drq);
 1337                 goto no;
 1338         }
 1339         if (tmpx & 0x80) {
 1340                 /* 8-bit board: only drq1/3 and irq7/9 */
 1341                 if (drq == 0) {
 1342                         printf("MSS: Can't use DMA0 with a 8 bit card/slot\n");
 1343                         goto no;
 1344                 }
 1345                 if (!(irq == 7 || irq == 9)) {
 1346                         printf("MSS: Can't use IRQ%d with a 8 bit card/slot\n",
 1347                                irq);
 1348                         goto no;
 1349                 }
 1350         }
 1351         mss_probe_end:
 1352         result = mss_detect(dev, mss);
 1353         no:
 1354         mss_release_resources(mss, dev);
 1355 #if 0
 1356         if (setres) ISA_DELETE_RESOURCE(device_get_parent(dev), dev,
 1357                                         SYS_RES_IOPORT, mss->io_rid); /* XXX ? */
 1358 #endif
 1359         return result;
 1360 }
 1361 
 1362 static int
 1363 mss_detect(device_t dev, struct mss_info *mss)
 1364 {
 1365         int          i;
 1366         u_char       tmp = 0, tmp1, tmp2;
 1367         char        *name, *yamaha;
 1368 
 1369         if (mss->bd_id != 0) {
 1370                 device_printf(dev, "presel bd_id 0x%04x -- %s\n", mss->bd_id,
 1371                         device_get_desc(dev));
 1372                 return 0;
 1373         }
 1374 
 1375         name = "AD1848";
 1376         mss->bd_id = MD_AD1848; /* AD1848 or CS4248 */
 1377 
 1378         if (opti_detect(dev, mss)) {
 1379                 switch (mss->bd_id) {
 1380                         case MD_OPTI924:
 1381                                 name = "OPTi924";
 1382                                 break;
 1383                         case MD_OPTI930:
 1384                                 name = "OPTi930";
 1385                                 break;
 1386                 }
 1387                 printf("Found OPTi device %s\n", name);
 1388                 if (opti_init(dev, mss) == 0) goto gotit;
 1389         }
 1390 
 1391         /*
 1392         * Check that the I/O address is in use.
 1393         *
 1394         * bit 7 of the base I/O port is known to be 0 after the chip has
 1395         * performed its power on initialization. Just assume this has
 1396         * happened before the OS is starting.
 1397         *
 1398         * If the I/O address is unused, it typically returns 0xff.
 1399         */
 1400 
 1401         for (i = 0; i < 10; i++)
 1402                 if ((tmp = io_rd(mss, MSS_INDEX)) & MSS_IDXBUSY) DELAY(10000);
 1403                 else break;
 1404 
 1405         if (i >= 10) {  /* Not an AD1848 */
 1406                 BVDDB(printf("mss_detect, busy still set (0x%02x)\n", tmp));
 1407                 goto no;
 1408         }
 1409         /*
 1410         * Test if it's possible to change contents of the indirect
 1411         * registers. Registers 0 and 1 are ADC volume registers. The bit
 1412         * 0x10 is read only so try to avoid using it.
 1413         */
 1414 
 1415         ad_write(mss, 0, 0xaa);
 1416         ad_write(mss, 1, 0x45);/* 0x55 with bit 0x10 clear */
 1417         tmp1 = ad_read(mss, 0);
 1418         tmp2 = ad_read(mss, 1);
 1419         if (tmp1 != 0xaa || tmp2 != 0x45) {
 1420                 BVDDB(printf("mss_detect error - IREG (%x/%x)\n", tmp1, tmp2));
 1421                 goto no;
 1422         }
 1423 
 1424         ad_write(mss, 0, 0x45);
 1425         ad_write(mss, 1, 0xaa);
 1426         tmp1 = ad_read(mss, 0);
 1427         tmp2 = ad_read(mss, 1);
 1428         if (tmp1 != 0x45 || tmp2 != 0xaa) {
 1429                 BVDDB(printf("mss_detect error - IREG2 (%x/%x)\n", tmp1, tmp2));
 1430                 goto no;
 1431         }
 1432 
 1433         /*
 1434         * The indirect register I12 has some read only bits. Lets try to
 1435         * change them.
 1436         */
 1437 
 1438         tmp = ad_read(mss, 12);
 1439         ad_write(mss, 12, (~tmp) & 0x0f);
 1440         tmp1 = ad_read(mss, 12);
 1441 
 1442         if ((tmp & 0x0f) != (tmp1 & 0x0f)) {
 1443                 BVDDB(printf("mss_detect - I12 (0x%02x was 0x%02x)\n", tmp1, tmp));
 1444                 goto no;
 1445         }
 1446 
 1447         /*
 1448         * NOTE! Last 4 bits of the reg I12 tell the chip revision.
 1449         *       0x01=RevB
 1450         *  0x0A=RevC. also CS4231/CS4231A and OPTi931
 1451         */
 1452 
 1453         BVDDB(printf("mss_detect - chip revision 0x%02x\n", tmp & 0x0f);)
 1454 
 1455         /*
 1456         * The original AD1848/CS4248 has just 16 indirect registers. This
 1457         * means that I0 and I16 should return the same value (etc.). Ensure
 1458         * that the Mode2 enable bit of I12 is 0. Otherwise this test fails
 1459         * with new parts.
 1460         */
 1461 
 1462         ad_write(mss, 12, 0);   /* Mode2=disabled */
 1463 #if 0
 1464         for (i = 0; i < 16; i++) {
 1465                 if ((tmp1 = ad_read(mss, i)) != (tmp2 = ad_read(mss, i + 16))) {
 1466                 BVDDB(printf("mss_detect warning - I%d: 0x%02x/0x%02x\n",
 1467                         i, tmp1, tmp2));
 1468                 /*
 1469                 * note - this seems to fail on the 4232 on I11. So we just break
 1470                 * rather than fail.  (which makes this test pointless - cg)
 1471                 */
 1472                 break; /* return 0; */
 1473                 }
 1474         }
 1475 #endif
 1476         /*
 1477         * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit
 1478         * (0x40). The bit 0x80 is always 1 in CS4248 and CS4231.
 1479         *
 1480         * On the OPTi931, however, I12 is readonly and only contains the
 1481         * chip revision ID (as in the CS4231A). The upper bits return 0.
 1482         */
 1483 
 1484         ad_write(mss, 12, 0x40);        /* Set mode2, clear 0x80 */
 1485 
 1486         tmp1 = ad_read(mss, 12);
 1487         if (tmp1 & 0x80) name = "CS4248"; /* Our best knowledge just now */
 1488         if ((tmp1 & 0xf0) == 0x00) {
 1489                 BVDDB(printf("this should be an OPTi931\n");)
 1490         } else if ((tmp1 & 0xc0) != 0xC0) goto gotit;
 1491         /*
 1492         * The 4231 has bit7=1 always, and bit6 we just set to 1.
 1493         * We want to check that this is really a CS4231
 1494         * Verify that setting I0 doesn't change I16.
 1495         */
 1496         ad_write(mss, 16, 0);   /* Set I16 to known value */
 1497         ad_write(mss, 0, 0x45);
 1498         if ((tmp1 = ad_read(mss, 16)) == 0x45) goto gotit;
 1499 
 1500         ad_write(mss, 0, 0xaa);
 1501         if ((tmp1 = ad_read(mss, 16)) == 0xaa) {        /* Rotten bits? */
 1502                 BVDDB(printf("mss_detect error - step H(%x)\n", tmp1));
 1503                 goto no;
 1504         }
 1505         /* Verify that some bits of I25 are read only. */
 1506         tmp1 = ad_read(mss, 25);        /* Original bits */
 1507         ad_write(mss, 25, ~tmp1);       /* Invert all bits */
 1508         if ((ad_read(mss, 25) & 0xe7) == (tmp1 & 0xe7)) {
 1509                 int id;
 1510 
 1511                 /* It's at least CS4231 */
 1512                 name = "CS4231";
 1513                 mss->bd_id = MD_CS42XX;
 1514 
 1515                 /*
 1516                 * It could be an AD1845 or CS4231A as well.
 1517                 * CS4231 and AD1845 report the same revision info in I25
 1518                 * while the CS4231A reports different.
 1519                 */
 1520 
 1521                 id = ad_read(mss, 25) & 0xe7;
 1522                 /*
 1523                 * b7-b5 = version number;
 1524                 *       100 : all CS4231
 1525                 *       101 : CS4231A
 1526                 *
 1527                 * b2-b0 = chip id;
 1528                 */
 1529                 switch (id) {
 1530 
 1531                 case 0xa0:
 1532                         name = "CS4231A";
 1533                         mss->bd_id = MD_CS42XX;
 1534                 break;
 1535 
 1536                 case 0xa2:
 1537                         name = "CS4232";
 1538                         mss->bd_id = MD_CS42XX;
 1539                 break;
 1540 
 1541                 case 0xb2:
 1542                 /* strange: the 4231 data sheet says b4-b3 are XX
 1543                 * so this should be the same as 0xa2
 1544                 */
 1545                         name = "CS4232A";
 1546                         mss->bd_id = MD_CS42XX;
 1547                 break;
 1548 
 1549                 case 0x80:
 1550                         /*
 1551                         * It must be a CS4231 or AD1845. The register I23
 1552                         * of CS4231 is undefined and it appears to be read
 1553                         * only. AD1845 uses I23 for setting sample rate.
 1554                         * Assume the chip is AD1845 if I23 is changeable.
 1555                         */
 1556 
 1557                         tmp = ad_read(mss, 23);
 1558 
 1559                         ad_write(mss, 23, ~tmp);
 1560                         if (ad_read(mss, 23) != tmp) {  /* AD1845 ? */
 1561                                 name = "AD1845";
 1562                                 mss->bd_id = MD_AD1845;
 1563                         }
 1564                         ad_write(mss, 23, tmp); /* Restore */
 1565 
 1566                         yamaha = ymf_test(dev, mss);
 1567                         if (yamaha) {
 1568                                 mss->bd_id = MD_YM0020;
 1569                                 name = yamaha;
 1570                         }
 1571                         break;
 1572 
 1573                 case 0x83:      /* CS4236 */
 1574                 case 0x03:      /* CS4236 on Intel PR440FX motherboard XXX */
 1575                         name = "CS4236";
 1576                         mss->bd_id = MD_CS42XX;
 1577                         break;
 1578 
 1579                 default:        /* Assume CS4231 */
 1580                         BVDDB(printf("unknown id 0x%02x, assuming CS4231\n", id);)
 1581                         mss->bd_id = MD_CS42XX;
 1582                 }
 1583         }
 1584         ad_write(mss, 25, tmp1);        /* Restore bits */
 1585 gotit:
 1586         BVDDB(printf("mss_detect() - Detected %s\n", name));
 1587         device_set_desc(dev, name);
 1588         device_set_flags(dev,
 1589                          ((device_get_flags(dev) & ~DV_F_DEV_MASK) |
 1590                           ((mss->bd_id << DV_F_DEV_SHIFT) & DV_F_DEV_MASK)));
 1591         return 0;
 1592 no:
 1593         return ENXIO;
 1594 }
 1595 
 1596 static int
 1597 opti_detect(device_t dev, struct mss_info *mss)
 1598 {
 1599         int c;
 1600         static const struct opticard {
 1601                 int boardid;
 1602                 int passwdreg;
 1603                 int password;
 1604                 int base;
 1605                 int indir_reg;
 1606         } cards[] = {
 1607                 { MD_OPTI930, 0, 0xe4, 0xf8f, 0xe0e },  /* 930 */
 1608                 { MD_OPTI924, 3, 0xe5, 0xf8c, 0,    },  /* 924 */
 1609                 { 0 },
 1610         };
 1611         mss->conf_rid = 3;
 1612         mss->indir_rid = 4;
 1613         for (c = 0; cards[c].base; c++) {
 1614                 mss->optibase = cards[c].base;
 1615                 mss->password = cards[c].password;
 1616                 mss->passwdreg = cards[c].passwdreg;
 1617                 mss->bd_id = cards[c].boardid;
 1618 
 1619                 if (cards[c].indir_reg)
 1620                         mss->indir = bus_alloc_resource(dev, SYS_RES_IOPORT,
 1621                                 &mss->indir_rid, cards[c].indir_reg,
 1622                                 cards[c].indir_reg+1, 1, RF_ACTIVE);
 1623 
 1624                 mss->conf_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
 1625                         &mss->conf_rid, mss->optibase, mss->optibase+9,
 1626                         9, RF_ACTIVE);
 1627 
 1628                 if (opti_read(mss, 1) != 0xff) {
 1629                         return 1;
 1630                 } else {
 1631                         if (mss->indir)
 1632                                 bus_release_resource(dev, SYS_RES_IOPORT, mss->indir_rid, mss->indir);
 1633                         mss->indir = NULL;
 1634                         if (mss->conf_base)
 1635                                 bus_release_resource(dev, SYS_RES_IOPORT, mss->conf_rid, mss->conf_base);
 1636                         mss->conf_base = NULL;
 1637                 }
 1638         }
 1639         return 0;
 1640 }
 1641 
 1642 static char *
 1643 ymf_test(device_t dev, struct mss_info *mss)
 1644 {
 1645         static int ports[] = {0x370, 0x310, 0x538};
 1646         int p, i, j, version;
 1647         static char *chipset[] = {
 1648                 NULL,                   /* 0 */
 1649                 "OPL3-SA2 (YMF711)",    /* 1 */
 1650                 "OPL3-SA3 (YMF715)",    /* 2 */
 1651                 "OPL3-SA3 (YMF715)",    /* 3 */
 1652                 "OPL3-SAx (YMF719)",    /* 4 */
 1653                 "OPL3-SAx (YMF719)",    /* 5 */
 1654                 "OPL3-SAx (YMF719)",    /* 6 */
 1655                 "OPL3-SAx (YMF719)",    /* 7 */
 1656         };
 1657 
 1658         for (p = 0; p < 3; p++) {
 1659                 mss->conf_rid = 1;
 1660                 mss->conf_base = bus_alloc_resource(dev,
 1661                                                 SYS_RES_IOPORT,
 1662                                                 &mss->conf_rid,
 1663                                                 ports[p], ports[p] + 1, 2,
 1664                                                 RF_ACTIVE);
 1665                 if (!mss->conf_base) return 0;
 1666 
 1667                 /* Test the index port of the config registers */
 1668                 i = port_rd(mss->conf_base, 0);
 1669                 port_wr(mss->conf_base, 0, OPL3SAx_DMACONF);
 1670                 j = (port_rd(mss->conf_base, 0) == OPL3SAx_DMACONF)? 1 : 0;
 1671                 port_wr(mss->conf_base, 0, i);
 1672                 if (!j) {
 1673                         bus_release_resource(dev, SYS_RES_IOPORT,
 1674                                              mss->conf_rid, mss->conf_base);
 1675                         mss->conf_base = NULL;
 1676                         continue;
 1677                 }
 1678                 version = conf_rd(mss, OPL3SAx_MISC) & 0x07;
 1679                 return chipset[version];
 1680         }
 1681         return NULL;
 1682 }
 1683 
 1684 static int
 1685 mss_doattach(device_t dev, struct mss_info *mss)
 1686 {
 1687         int pdma, rdma, flags = device_get_flags(dev);
 1688         char status[SND_STATUSLEN], status2[SND_STATUSLEN];
 1689 
 1690         mss->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_mss softc");
 1691         mss->bufsize = pcm_getbuffersize(dev, 4096, MSS_DEFAULT_BUFSZ, 65536);
 1692         if (!mss_alloc_resources(mss, dev)) goto no;
 1693         mss_init(mss, dev);
 1694         pdma = rman_get_start(mss->drq1);
 1695         rdma = rman_get_start(mss->drq2);
 1696         if (flags & DV_F_TRUE_MSS) {
 1697                 /* has IRQ/DMA registers, set IRQ and DMA addr */
 1698                 static char     interrupt_bits[12] =
 1699                 {-1, -1, -1, -1, -1, 0x28, -1, 0x08, -1, 0x10, 0x18, 0x20};
 1700                 static char     pdma_bits[4] =  {1, 2, -1, 3};
 1701                 static char     valid_rdma[4] = {1, 0, -1, 0};
 1702                 char            bits;
 1703 
 1704                 if (!mss->irq || (bits = interrupt_bits[rman_get_start(mss->irq)]) == -1)
 1705                         goto no;
 1706                 io_wr(mss, 0, bits | 0x40);     /* config port */
 1707                 if ((io_rd(mss, 3) & 0x40) == 0) device_printf(dev, "IRQ Conflict?\n");
 1708                 /* Write IRQ+DMA setup */
 1709                 if (pdma_bits[pdma] == -1) goto no;
 1710                 bits |= pdma_bits[pdma];
 1711                 if (pdma != rdma) {
 1712                         if (rdma == valid_rdma[pdma]) bits |= 4;
 1713                         else {
 1714                                 printf("invalid dual dma config %d:%d\n", pdma, rdma);
 1715                                 goto no;
 1716                         }
 1717                 }
 1718                 io_wr(mss, 0, bits);
 1719                 printf("drq/irq conf %x\n", io_rd(mss, 0));
 1720         }
 1721         mixer_init(dev, (mss->bd_id == MD_YM0020)? &ymmix_mixer_class : &mssmix_mixer_class, mss);
 1722         switch (mss->bd_id) {
 1723         case MD_OPTI931:
 1724                 snd_setup_intr(dev, mss->irq, 0, opti931_intr, mss, &mss->ih);
 1725                 break;
 1726         default:
 1727                 snd_setup_intr(dev, mss->irq, 0, mss_intr, mss, &mss->ih);
 1728         }
 1729         if (pdma == rdma)
 1730                 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
 1731         if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
 1732                         /*boundary*/0,
 1733                         /*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
 1734                         /*highaddr*/BUS_SPACE_MAXADDR,
 1735                         /*filter*/NULL, /*filterarg*/NULL,
 1736                         /*maxsize*/mss->bufsize, /*nsegments*/1,
 1737                         /*maxsegz*/0x3ffff, /*flags*/0,
 1738                         /*lockfunc*/busdma_lock_mutex, /*lockarg*/&Giant,
 1739                         &mss->parent_dmat) != 0) {
 1740                 device_printf(dev, "unable to create dma tag\n");
 1741                 goto no;
 1742         }
 1743 
 1744         if (pdma != rdma)
 1745                 snprintf(status2, SND_STATUSLEN, ":%d", rdma);
 1746         else
 1747                 status2[0] = '\0';
 1748 
 1749         snprintf(status, SND_STATUSLEN, "at io 0x%jx irq %jd drq %d%s bufsz %u",
 1750                 rman_get_start(mss->io_base), rman_get_start(mss->irq), pdma, status2, mss->bufsize);
 1751 
 1752         if (pcm_register(dev, mss, 1, 1)) goto no;
 1753         pcm_addchan(dev, PCMDIR_REC, &msschan_class, mss);
 1754         pcm_addchan(dev, PCMDIR_PLAY, &msschan_class, mss);
 1755         pcm_setstatus(dev, status);
 1756 
 1757         return 0;
 1758 no:
 1759         mss_release_resources(mss, dev);
 1760         return ENXIO;
 1761 }
 1762 
 1763 static int
 1764 mss_detach(device_t dev)
 1765 {
 1766         int r;
 1767         struct mss_info *mss;
 1768 
 1769         r = pcm_unregister(dev);
 1770         if (r)
 1771                 return r;
 1772 
 1773         mss = pcm_getdevinfo(dev);
 1774         mss_release_resources(mss, dev);
 1775 
 1776         return 0;
 1777 }
 1778 
 1779 static int
 1780 mss_attach(device_t dev)
 1781 {
 1782         struct mss_info *mss;
 1783         int flags = device_get_flags(dev);
 1784 
 1785         mss = (struct mss_info *)malloc(sizeof *mss, M_DEVBUF, M_NOWAIT | M_ZERO);
 1786         if (!mss) return ENXIO;
 1787 
 1788         mss->io_rid = 0;
 1789         mss->conf_rid = -1;
 1790         mss->irq_rid = 0;
 1791         mss->drq1_rid = 0;
 1792         mss->drq2_rid = -1;
 1793         if (flags & DV_F_DUAL_DMA) {
 1794                 bus_set_resource(dev, SYS_RES_DRQ, 1,
 1795                                  flags & DV_F_DRQ_MASK, 1);
 1796                 mss->drq2_rid = 1;
 1797         }
 1798         mss->bd_id = (device_get_flags(dev) & DV_F_DEV_MASK) >> DV_F_DEV_SHIFT;
 1799         if (mss->bd_id == MD_YM0020) ymf_test(dev, mss);
 1800         return mss_doattach(dev, mss);
 1801 }
 1802 
 1803 /*
 1804  * mss_resume() is the code to allow a laptop to resume using the sound
 1805  * card.
 1806  *
 1807  * This routine re-sets the state of the board to the state before going
 1808  * to sleep.  According to the yamaha docs this is the right thing to do,
 1809  * but getting DMA restarted appears to be a bit of a trick, so the device
 1810  * has to be closed and re-opened to be re-used, but there is no skipping
 1811  * problem, and volume, bass/treble and most other things are restored
 1812  * properly.
 1813  *
 1814  */
 1815 
 1816 static int
 1817 mss_resume(device_t dev)
 1818 {
 1819         /*
 1820          * Restore the state taken below.
 1821          */
 1822         struct mss_info *mss;
 1823         int i;
 1824 
 1825         mss = pcm_getdevinfo(dev);
 1826 
 1827         if(mss->bd_id == MD_YM0020 || mss->bd_id == MD_CS423X) {
 1828                 /* This works on a Toshiba Libretto 100CT. */
 1829                 for (i = 0; i < MSS_INDEXED_REGS; i++)
 1830                         ad_write(mss, i, mss->mss_indexed_regs[i]);
 1831                 for (i = 0; i < OPL_INDEXED_REGS; i++)
 1832                         conf_wr(mss, i, mss->opl_indexed_regs[i]);
 1833                 mss_intr(mss);
 1834         }
 1835 
 1836         if (mss->bd_id == MD_CS423X) {
 1837                 /* Needed on IBM Thinkpad 600E */
 1838                 mss_lock(mss);
 1839                 mss_format(&mss->pch, mss->pch.channel->format);
 1840                 mss_speed(&mss->pch, mss->pch.channel->speed);
 1841                 mss_unlock(mss);
 1842         }
 1843 
 1844         return 0;
 1845 
 1846 }
 1847 
 1848 /*
 1849  * mss_suspend() is the code that gets called right before a laptop
 1850  * suspends.
 1851  *
 1852  * This code saves the state of the sound card right before shutdown
 1853  * so it can be restored above.
 1854  *
 1855  */
 1856 
 1857 static int
 1858 mss_suspend(device_t dev)
 1859 {
 1860         int i;
 1861         struct mss_info *mss;
 1862 
 1863         mss = pcm_getdevinfo(dev);
 1864 
 1865         if(mss->bd_id == MD_YM0020 || mss->bd_id == MD_CS423X)
 1866         {
 1867                 /* this stops playback. */
 1868                 conf_wr(mss, 0x12, 0x0c);
 1869                 for(i = 0; i < MSS_INDEXED_REGS; i++)
 1870                         mss->mss_indexed_regs[i] = ad_read(mss, i);
 1871                 for(i = 0; i < OPL_INDEXED_REGS; i++)
 1872                         mss->opl_indexed_regs[i] = conf_rd(mss, i);
 1873                 mss->opl_indexed_regs[0x12] = 0x0;
 1874         }
 1875         return 0;
 1876 }
 1877 
 1878 static device_method_t mss_methods[] = {
 1879         /* Device interface */
 1880         DEVMETHOD(device_probe,         mss_probe),
 1881         DEVMETHOD(device_attach,        mss_attach),
 1882         DEVMETHOD(device_detach,        mss_detach),
 1883         DEVMETHOD(device_suspend,       mss_suspend),
 1884         DEVMETHOD(device_resume,        mss_resume),
 1885 
 1886         { 0, 0 }
 1887 };
 1888 
 1889 static driver_t mss_driver = {
 1890         "pcm",
 1891         mss_methods,
 1892         PCM_SOFTC_SIZE,
 1893 };
 1894 
 1895 DRIVER_MODULE(snd_mss, isa, mss_driver, pcm_devclass, 0, 0);
 1896 MODULE_DEPEND(snd_mss, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
 1897 MODULE_VERSION(snd_mss, 1);
 1898 
 1899 static int
 1900 azt2320_mss_mode(struct mss_info *mss, device_t dev)
 1901 {
 1902         struct resource *sbport;
 1903         int             i, ret, rid;
 1904 
 1905         rid = 0;
 1906         ret = -1;
 1907         sbport = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
 1908         if (sbport) {
 1909                 for (i = 0; i < 1000; i++) {
 1910                         if ((port_rd(sbport, SBDSP_STATUS) & 0x80))
 1911                                 DELAY((i > 100) ? 1000 : 10);
 1912                         else {
 1913                                 port_wr(sbport, SBDSP_CMD, 0x09);
 1914                                 break;
 1915                         }
 1916                 }
 1917                 for (i = 0; i < 1000; i++) {
 1918                         if ((port_rd(sbport, SBDSP_STATUS) & 0x80))
 1919                                 DELAY((i > 100) ? 1000 : 10);
 1920                         else {
 1921                                 port_wr(sbport, SBDSP_CMD, 0x00);
 1922                                 ret = 0;
 1923                                 break;
 1924                         }
 1925                 }
 1926                 DELAY(1000);
 1927                 bus_release_resource(dev, SYS_RES_IOPORT, rid, sbport);
 1928         }
 1929         return ret;
 1930 }
 1931 
 1932 static struct isa_pnp_id pnpmss_ids[] = {
 1933         {0x0000630e, "CS423x"},                         /* CSC0000 */
 1934         {0x0001630e, "CS423x-PCI"},                     /* CSC0100 */
 1935         {0x01000000, "CMI8330"},                        /* @@@0001 */
 1936         {0x2100a865, "Yamaha OPL-SAx"},                 /* YMH0021 */
 1937         {0x1110d315, "ENSONIQ SoundscapeVIVO"},         /* ENS1011 */
 1938         {0x1093143e, "OPTi931"},                        /* OPT9310 */
 1939         {0x5092143e, "OPTi925"},                        /* OPT9250 XXX guess */
 1940         {0x0000143e, "OPTi924"},                        /* OPT0924 */
 1941         {0x1022b839, "Neomagic 256AV (non-ac97)"},      /* NMX2210 */
 1942         {0x01005407, "Aztech 2320"},                    /* AZT0001 */
 1943 #if 0
 1944         {0x0000561e, "GusPnP"},                         /* GRV0000 */
 1945 #endif
 1946         {0},
 1947 };
 1948 
 1949 static int
 1950 pnpmss_probe(device_t dev)
 1951 {
 1952         u_int32_t lid, vid;
 1953 
 1954         lid = isa_get_logicalid(dev);
 1955         vid = isa_get_vendorid(dev);
 1956         if (lid == 0x01000000 && vid != 0x0100a90d) /* CMI0001 */
 1957                 return ENXIO;
 1958         return ISA_PNP_PROBE(device_get_parent(dev), dev, pnpmss_ids);
 1959 }
 1960 
 1961 static int
 1962 pnpmss_attach(device_t dev)
 1963 {
 1964         struct mss_info *mss;
 1965 
 1966         mss = malloc(sizeof(*mss), M_DEVBUF, M_WAITOK | M_ZERO);
 1967         mss->io_rid = 0;
 1968         mss->conf_rid = -1;
 1969         mss->irq_rid = 0;
 1970         mss->drq1_rid = 0;
 1971         mss->drq2_rid = 1;
 1972         mss->bd_id = MD_CS42XX;
 1973 
 1974         switch (isa_get_logicalid(dev)) {
 1975         case 0x0000630e:                        /* CSC0000 */
 1976         case 0x0001630e:                        /* CSC0100 */
 1977             mss->bd_flags |= BD_F_MSS_OFFSET;
 1978             mss->bd_id = MD_CS423X;
 1979             break;
 1980 
 1981         case 0x2100a865:                        /* YHM0021 */
 1982             mss->io_rid = 1;
 1983             mss->conf_rid = 4;
 1984             mss->bd_id = MD_YM0020;
 1985             break;
 1986 
 1987         case 0x1110d315:                        /* ENS1011 */
 1988             mss->io_rid = 1;
 1989             mss->bd_id = MD_VIVO;
 1990             break;
 1991 
 1992         case 0x1093143e:                        /* OPT9310 */
 1993             mss->bd_flags |= BD_F_MSS_OFFSET;
 1994             mss->conf_rid = 3;
 1995             mss->bd_id = MD_OPTI931;
 1996             break;
 1997 
 1998         case 0x5092143e:                        /* OPT9250 XXX guess */
 1999             mss->io_rid = 1;
 2000             mss->conf_rid = 3;
 2001             mss->bd_id = MD_OPTI925;
 2002             break;
 2003 
 2004         case 0x0000143e:                        /* OPT0924 */
 2005             mss->password = 0xe5;
 2006             mss->passwdreg = 3;
 2007             mss->optibase = 0xf0c;
 2008             mss->io_rid = 2;
 2009             mss->conf_rid = 3;
 2010             mss->bd_id = MD_OPTI924;
 2011             mss->bd_flags |= BD_F_924PNP;
 2012             if(opti_init(dev, mss) != 0) {
 2013                     free(mss, M_DEVBUF);
 2014                     return ENXIO;
 2015             }
 2016             break;
 2017 
 2018         case 0x1022b839:                        /* NMX2210 */
 2019             mss->io_rid = 1;
 2020             break;
 2021 
 2022         case 0x01005407:                        /* AZT0001 */
 2023             /* put into MSS mode first (snatched from NetBSD) */
 2024             if (azt2320_mss_mode(mss, dev) == -1) {
 2025                     free(mss, M_DEVBUF);
 2026                     return ENXIO;
 2027             }
 2028 
 2029             mss->bd_flags |= BD_F_MSS_OFFSET;
 2030             mss->io_rid = 2;
 2031             break;
 2032             
 2033 #if 0
 2034         case 0x0000561e:                        /* GRV0000 */
 2035             mss->bd_flags |= BD_F_MSS_OFFSET;
 2036             mss->io_rid = 2;
 2037             mss->conf_rid = 1;
 2038             mss->drq1_rid = 1;
 2039             mss->drq2_rid = 0;
 2040             mss->bd_id = MD_GUSPNP;
 2041             break;
 2042 #endif
 2043         case 0x01000000:                        /* @@@0001 */
 2044             mss->drq2_rid = -1;
 2045             break;
 2046 
 2047         /* Unknown MSS default.  We could let the CSC0000 stuff match too */
 2048         default:
 2049             mss->bd_flags |= BD_F_MSS_OFFSET;
 2050             break;
 2051         }
 2052         return mss_doattach(dev, mss);
 2053 }
 2054 
 2055 static int
 2056 opti_init(device_t dev, struct mss_info *mss)
 2057 {
 2058         int flags = device_get_flags(dev);
 2059         int basebits = 0;
 2060 
 2061         if (!mss->conf_base) {
 2062                 bus_set_resource(dev, SYS_RES_IOPORT, mss->conf_rid,
 2063                         mss->optibase, 0x9);
 2064 
 2065                 mss->conf_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
 2066                         &mss->conf_rid, mss->optibase, mss->optibase+0x9,
 2067                         0x9, RF_ACTIVE);
 2068         }
 2069 
 2070         if (!mss->conf_base)
 2071                 return ENXIO;
 2072 
 2073         if (!mss->io_base)
 2074                 mss->io_base = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT,
 2075                         &mss->io_rid, 8, RF_ACTIVE);
 2076 
 2077         if (!mss->io_base)      /* No hint specified, use 0x530 */
 2078                 mss->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
 2079                         &mss->io_rid, 0x530, 0x537, 8, RF_ACTIVE);
 2080 
 2081         if (!mss->io_base)
 2082                 return ENXIO;
 2083 
 2084         switch (rman_get_start(mss->io_base)) {
 2085                 case 0x530:
 2086                         basebits = 0x0;
 2087                         break;
 2088                 case 0xe80:
 2089                         basebits = 0x10;
 2090                         break;
 2091                 case 0xf40:
 2092                         basebits = 0x20;
 2093                         break;
 2094                 case 0x604:
 2095                         basebits = 0x30;
 2096                         break;
 2097                 default:
 2098                         printf("opti_init: invalid MSS base address!\n");
 2099                         return ENXIO;
 2100         }
 2101 
 2102 
 2103         switch (mss->bd_id) {
 2104         case MD_OPTI924:
 2105                 opti_write(mss, 1, 0x80 | basebits);    /* MSS mode */
 2106                 opti_write(mss, 2, 0x00);       /* Disable CD */
 2107                 opti_write(mss, 3, 0xf0);       /* Disable SB IRQ */
 2108                 opti_write(mss, 4, 0xf0);
 2109                 opti_write(mss, 5, 0x00);
 2110                 opti_write(mss, 6, 0x02);       /* MPU stuff */
 2111                 break;
 2112 
 2113         case MD_OPTI930:
 2114                 opti_write(mss, 1, 0x00 | basebits);
 2115                 opti_write(mss, 3, 0x00);       /* Disable SB IRQ/DMA */
 2116                 opti_write(mss, 4, 0x52);       /* Empty FIFO */
 2117                 opti_write(mss, 5, 0x3c);       /* Mode 2 */
 2118                 opti_write(mss, 6, 0x02);       /* Enable MSS */
 2119                 break;
 2120         }
 2121 
 2122         if (mss->bd_flags & BD_F_924PNP) {
 2123                 u_int32_t irq = isa_get_irq(dev);
 2124                 u_int32_t drq = isa_get_drq(dev);
 2125                 bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1);
 2126                 bus_set_resource(dev, SYS_RES_DRQ, mss->drq1_rid, drq, 1);
 2127                 if (flags & DV_F_DUAL_DMA) {
 2128                         bus_set_resource(dev, SYS_RES_DRQ, 1,
 2129                                 flags & DV_F_DRQ_MASK, 1);
 2130                         mss->drq2_rid = 1;
 2131                 }
 2132         }
 2133 
 2134         /* OPTixxx has I/DRQ registers */
 2135 
 2136         device_set_flags(dev, device_get_flags(dev) | DV_F_TRUE_MSS);
 2137 
 2138         return 0;
 2139 }
 2140 
 2141 static void
 2142 opti_write(struct mss_info *mss, u_char reg, u_char val)
 2143 {
 2144         port_wr(mss->conf_base, mss->passwdreg, mss->password);
 2145 
 2146         switch(mss->bd_id) {
 2147         case MD_OPTI924:
 2148                 if (reg > 7) {          /* Indirect register */
 2149                         port_wr(mss->conf_base, mss->passwdreg, reg);
 2150                         port_wr(mss->conf_base, mss->passwdreg,
 2151                                 mss->password);
 2152                         port_wr(mss->conf_base, 9, val);
 2153                         return;
 2154                 }
 2155                 port_wr(mss->conf_base, reg, val);
 2156                 break;
 2157 
 2158         case MD_OPTI930:
 2159                 port_wr(mss->indir, 0, reg);
 2160                 port_wr(mss->conf_base, mss->passwdreg, mss->password);
 2161                 port_wr(mss->indir, 1, val);
 2162                 break;
 2163         }
 2164 }
 2165 
 2166 u_char
 2167 opti_read(struct mss_info *mss, u_char reg)
 2168 {
 2169         port_wr(mss->conf_base, mss->passwdreg, mss->password);
 2170 
 2171         switch(mss->bd_id) {
 2172         case MD_OPTI924:
 2173                 if (reg > 7) {          /* Indirect register */
 2174                         port_wr(mss->conf_base, mss->passwdreg, reg);
 2175                         port_wr(mss->conf_base, mss->passwdreg, mss->password);
 2176                         return(port_rd(mss->conf_base, 9));
 2177                 }
 2178                 return(port_rd(mss->conf_base, reg));
 2179                 break;
 2180 
 2181         case MD_OPTI930:
 2182                 port_wr(mss->indir, 0, reg);
 2183                 port_wr(mss->conf_base, mss->passwdreg, mss->password);
 2184                 return port_rd(mss->indir, 1);
 2185                 break;
 2186         }
 2187         return -1;
 2188 }
 2189 
 2190 static device_method_t pnpmss_methods[] = {
 2191         /* Device interface */
 2192         DEVMETHOD(device_probe,         pnpmss_probe),
 2193         DEVMETHOD(device_attach,        pnpmss_attach),
 2194         DEVMETHOD(device_detach,        mss_detach),
 2195         DEVMETHOD(device_suspend,       mss_suspend),
 2196         DEVMETHOD(device_resume,        mss_resume),
 2197 
 2198         { 0, 0 }
 2199 };
 2200 
 2201 static driver_t pnpmss_driver = {
 2202         "pcm",
 2203         pnpmss_methods,
 2204         PCM_SOFTC_SIZE,
 2205 };
 2206 
 2207 DRIVER_MODULE(snd_pnpmss, isa, pnpmss_driver, pcm_devclass, 0, 0);
 2208 DRIVER_MODULE(snd_pnpmss, acpi, pnpmss_driver, pcm_devclass, 0, 0);
 2209 MODULE_DEPEND(snd_pnpmss, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
 2210 MODULE_VERSION(snd_pnpmss, 1);
 2211 
 2212 static int
 2213 guspcm_probe(device_t dev)
 2214 {
 2215         struct sndcard_func *func;
 2216 
 2217         func = device_get_ivars(dev);
 2218         if (func == NULL || func->func != SCF_PCM)
 2219                 return ENXIO;
 2220 
 2221         device_set_desc(dev, "GUS CS4231");
 2222         return 0;
 2223 }
 2224 
 2225 static int
 2226 guspcm_attach(device_t dev)
 2227 {
 2228         device_t parent = device_get_parent(dev);
 2229         struct mss_info *mss;
 2230         int base, flags;
 2231         unsigned char ctl;
 2232 
 2233         mss = (struct mss_info *)malloc(sizeof *mss, M_DEVBUF, M_NOWAIT | M_ZERO);
 2234         if (mss == NULL)
 2235                 return ENOMEM;
 2236 
 2237         mss->bd_flags = BD_F_MSS_OFFSET;
 2238         mss->io_rid = 2;
 2239         mss->conf_rid = 1;
 2240         mss->irq_rid = 0;
 2241         mss->drq1_rid = 1;
 2242         mss->drq2_rid = -1;
 2243 
 2244         if (isa_get_logicalid(parent) == 0)
 2245                 mss->bd_id = MD_GUSMAX;
 2246         else {
 2247                 mss->bd_id = MD_GUSPNP;
 2248                 mss->drq2_rid = 0;
 2249                 goto skip_setup;
 2250         }
 2251 
 2252         flags = device_get_flags(parent);
 2253         if (flags & DV_F_DUAL_DMA)
 2254                 mss->drq2_rid = 0;
 2255 
 2256         mss->conf_base = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT,
 2257                                                      &mss->conf_rid,
 2258                                                      8, RF_ACTIVE);
 2259 
 2260         if (mss->conf_base == NULL) {
 2261                 mss_release_resources(mss, dev);
 2262                 return ENXIO;
 2263         }
 2264 
 2265         base = isa_get_port(parent);
 2266 
 2267         ctl = 0x40;                     /* CS4231 enable */
 2268         if (isa_get_drq(dev) > 3)
 2269                 ctl |= 0x10;            /* 16-bit dma channel 1 */
 2270         if ((flags & DV_F_DUAL_DMA) != 0 && (flags & DV_F_DRQ_MASK) > 3)
 2271                 ctl |= 0x20;            /* 16-bit dma channel 2 */
 2272         ctl |= (base >> 4) & 0x0f;      /* 2X0 -> 3XC */
 2273         port_wr(mss->conf_base, 6, ctl);
 2274 
 2275 skip_setup:
 2276         return mss_doattach(dev, mss);
 2277 }
 2278 
 2279 static device_method_t guspcm_methods[] = {
 2280         DEVMETHOD(device_probe,         guspcm_probe),
 2281         DEVMETHOD(device_attach,        guspcm_attach),
 2282         DEVMETHOD(device_detach,        mss_detach),
 2283 
 2284         { 0, 0 }
 2285 };
 2286 
 2287 static driver_t guspcm_driver = {
 2288         "pcm",
 2289         guspcm_methods,
 2290         PCM_SOFTC_SIZE,
 2291 };
 2292 
 2293 DRIVER_MODULE(snd_guspcm, gusc, guspcm_driver, pcm_devclass, 0, 0);
 2294 MODULE_DEPEND(snd_guspcm, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
 2295 MODULE_VERSION(snd_guspcm, 1);
 2296 ISA_PNP_INFO(pnpmss_ids);

Cache object: dcada011b10c78fd0ad6cc1e7fce9076


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.