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/isa/sb.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: sb.c,v 1.35 2022/11/02 10:41:34 kn Exp $      */
    2 /*      $NetBSD: sb.c,v 1.57 1998/01/12 09:43:46 thorpej Exp $  */
    3 
    4 /*
    5  * Copyright (c) 1991-1993 Regents of the University of California.
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by the Computer Systems
   19  *      Engineering Group at Lawrence Berkeley Laboratory.
   20  * 4. Neither the name of the University nor of the Laboratory may be used
   21  *    to endorse or promote products derived from this software without
   22  *    specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  *
   36  */
   37 
   38 #include "midi.h"
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/errno.h>
   43 #include <sys/ioctl.h>
   44 #include <sys/syslog.h>
   45 #include <sys/device.h>
   46 
   47 #include <machine/cpu.h>
   48 #include <machine/intr.h>
   49 #include <machine/bus.h>
   50 
   51 #include <sys/audioio.h>
   52 #include <dev/audio_if.h>
   53 #include <dev/midi_if.h>
   54 
   55 #include <dev/isa/isavar.h>
   56 #include <dev/isa/isadmavar.h>
   57 
   58 #include <dev/isa/sbreg.h>
   59 #include <dev/isa/sbvar.h>
   60 #include <dev/isa/sbdspvar.h>
   61 
   62 struct cfdriver sb_cd = {
   63         NULL, "sb", DV_DULL
   64 };
   65 
   66 #if NMIDI > 0
   67 int     sb_mpu401_open(void *, int, void (*iintr)(void *, int),
   68                        void (*ointr)(void *), void *arg);
   69 void    sb_mpu401_close(void *);
   70 int     sb_mpu401_output(void *, int);
   71 void    sb_mpu401_getinfo(void *, struct midi_info *);
   72 
   73 const struct midi_hw_if sb_midi_hw_if = {
   74         sbdsp_midi_open,
   75         sbdsp_midi_close,
   76         sbdsp_midi_output,
   77         0,                      /* flush */
   78         sbdsp_midi_getinfo,
   79         0,                      /* ioctl */
   80 };
   81 
   82 const struct midi_hw_if sb_mpu401_hw_if = {
   83         sb_mpu401_open,
   84         sb_mpu401_close,
   85         sb_mpu401_output,
   86         0,                      /* flush */
   87         sb_mpu401_getinfo,
   88         0,                      /* ioctl */
   89 };
   90 #endif
   91 
   92 /*
   93  * Define our interface to the higher level audio driver.
   94  */
   95 
   96 const struct audio_hw_if sb_hw_if = {
   97         .open = sbdsp_open,
   98         .close = sbdsp_close,
   99         .set_params = sbdsp_set_params,
  100         .round_blocksize = sbdsp_round_blocksize,
  101         .halt_output = sbdsp_haltdma,
  102         .halt_input = sbdsp_haltdma,
  103         .set_port = sbdsp_mixer_set_port,
  104         .get_port = sbdsp_mixer_get_port,
  105         .query_devinfo = sbdsp_mixer_query_devinfo,
  106         .allocm = sb_malloc,
  107         .freem = sb_free,
  108         .round_buffersize = sb_round,
  109         .trigger_output = sbdsp_trigger_output,
  110         .trigger_input = sbdsp_trigger_input,
  111 };
  112 
  113 #ifdef AUDIO_DEBUG
  114 #define DPRINTF(x)      if (sbdebug) printf x
  115 int     sbdebug = 0;
  116 #else
  117 #define DPRINTF(x)
  118 #endif
  119 
  120 /*
  121  * Probe / attach routines.
  122  */
  123 
  124 
  125 int
  126 sbmatch(struct sbdsp_softc *sc)
  127 {
  128         static u_char drq_conf[8] = {
  129                 0x01, 0x02, -1, 0x08, -1, 0x20, 0x40, 0x80
  130         };
  131 
  132         static u_char irq_conf[11] = {
  133                 -1, -1, 0x01, -1, -1, 0x02, -1, 0x04, -1, 0x01, 0x08
  134         };
  135 
  136         if (sbdsp_probe(sc) == 0)
  137                 return 0;
  138 
  139         /*
  140          * Cannot auto-discover DMA channel.
  141          */
  142         if (ISSBPROCLASS(sc)) {
  143                 if (!SBP_DRQ_VALID(sc->sc_drq8)) {
  144                         DPRINTF(("%s: configured dma chan %d invalid\n",
  145                             sc->sc_dev.dv_xname, sc->sc_drq8));
  146                         return 0;
  147                 }
  148         } else {
  149                 if (!SB_DRQ_VALID(sc->sc_drq8)) {
  150                         DPRINTF(("%s: configured dma chan %d invalid\n",
  151                             sc->sc_dev.dv_xname, sc->sc_drq8));
  152                         return 0;
  153                 }
  154         }
  155 
  156         if (0 <= sc->sc_drq16 && sc->sc_drq16 <= 3)
  157                 /* 
  158                  * XXX Some ViBRA16 cards seem to have two 8 bit DMA 
  159                  * channels.  I've no clue how to use them, so ignore
  160                  * one of them for now.  -- augustss@netbsd.org
  161                  */
  162                 sc->sc_drq16 = -1;
  163 
  164         if (ISSB16CLASS(sc)) {
  165                 if (sc->sc_drq16 == -1)
  166                         sc->sc_drq16 = sc->sc_drq8;
  167                 if (!SB16_DRQ_VALID(sc->sc_drq16)) {
  168                         DPRINTF(("%s: configured dma chan %d invalid\n",
  169                             sc->sc_dev.dv_xname, sc->sc_drq16));
  170                         return 0;
  171                 }
  172         } else
  173                 sc->sc_drq16 = sc->sc_drq8;
  174         
  175         if (ISSBPROCLASS(sc)) {
  176                 if (!SBP_IRQ_VALID(sc->sc_irq)) {
  177                         DPRINTF(("%s: configured irq %d invalid\n",
  178                             sc->sc_dev.dv_xname, sc->sc_irq));
  179                         return 0;
  180                 }
  181         } else {
  182                 if (!SB_IRQ_VALID(sc->sc_irq)) {
  183                         DPRINTF(("%s: configured irq %d invalid\n",
  184                             sc->sc_dev.dv_xname, sc->sc_irq));
  185                         return 0;
  186                 }
  187         }
  188 
  189         if (ISSB16CLASS(sc)) {
  190                 int w, r;
  191 #if 0
  192                 DPRINTF(("%s: old drq conf %02x\n", sc->sc_dev.dv_xname,
  193                     sbdsp_mix_read(sc, SBP_SET_DRQ)));
  194                 DPRINTF(("%s: try drq conf %02x\n", sc->sc_dev.dv_xname,
  195                     drq_conf[sc->sc_drq16] | drq_conf[sc->sc_drq8]));
  196 #endif
  197                 w = drq_conf[sc->sc_drq16] | drq_conf[sc->sc_drq8];
  198                 sbdsp_mix_write(sc, SBP_SET_DRQ, w);
  199                 r = sbdsp_mix_read(sc, SBP_SET_DRQ) & 0xeb;
  200                 if (r != w) {
  201                         DPRINTF(("%s: setting drq mask %02x failed, got %02x\n", sc->sc_dev.dv_xname, w, r));
  202                         return 0;
  203                 }
  204 #if 0
  205                 DPRINTF(("%s: new drq conf %02x\n", sc->sc_dev.dv_xname,
  206                     sbdsp_mix_read(sc, SBP_SET_DRQ)));
  207 #endif
  208 
  209 #if 0
  210                 DPRINTF(("%s: old irq conf %02x\n", sc->sc_dev.dv_xname,
  211                     sbdsp_mix_read(sc, SBP_SET_IRQ)));
  212                 DPRINTF(("%s: try irq conf %02x\n", sc->sc_dev.dv_xname,
  213                     irq_conf[sc->sc_irq]));
  214 #endif
  215                 w = irq_conf[sc->sc_irq];
  216                 sbdsp_mix_write(sc, SBP_SET_IRQ, w);
  217                 r = sbdsp_mix_read(sc, SBP_SET_IRQ) & 0x0f;
  218                 if (r != w) {
  219                         DPRINTF(("%s: setting irq mask %02x failed, got %02x\n",
  220                             sc->sc_dev.dv_xname, w, r));
  221                         return 0;
  222                 }
  223 #if 0
  224                 DPRINTF(("%s: new irq conf %02x\n", sc->sc_dev.dv_xname,
  225                     sbdsp_mix_read(sc, SBP_SET_IRQ)));
  226 #endif
  227         }
  228 
  229         return 1;
  230 }
  231 
  232 
  233 void
  234 sbattach(struct sbdsp_softc *sc)
  235 {
  236         struct audio_attach_args arg;
  237 #if NMIDI > 0
  238         const struct midi_hw_if *mhw = &sb_midi_hw_if;
  239 #endif
  240 
  241         sc->sc_ih = isa_intr_establish(sc->sc_ic, sc->sc_irq,
  242             IST_EDGE, IPL_AUDIO | IPL_MPSAFE,
  243             sbdsp_intr, sc, sc->sc_dev.dv_xname);
  244 
  245         sbdsp_attach(sc);
  246 
  247 #if NMIDI > 0
  248         sc->sc_hasmpu = 0;
  249         if (ISSB16CLASS(sc) && sc->sc_mpu_sc.iobase != 0) {
  250                 sc->sc_mpu_sc.iot = sc->sc_iot;
  251                 if (mpu_find(&sc->sc_mpu_sc)) {
  252                         sc->sc_hasmpu = 1;
  253                         mhw = &sb_mpu401_hw_if;
  254                 }
  255         }
  256         midi_attach_mi(mhw, sc, &sc->sc_dev);
  257 #endif
  258 
  259         audio_attach_mi(&sb_hw_if, sc, NULL, &sc->sc_dev);
  260 
  261         arg.type = AUDIODEV_TYPE_OPL;
  262         arg.hwif = 0;
  263         arg.hdl = 0;
  264         (void)config_found(&sc->sc_dev, &arg, audioprint);
  265 }
  266 
  267 /*
  268  * Various routines to interface to higher level audio driver
  269  */
  270 
  271 #if NMIDI > 0
  272 
  273 #define SBMPU(a) (&((struct sbdsp_softc *)addr)->sc_mpu_sc)
  274 
  275 int
  276 sb_mpu401_open(void *addr, int flags, void (*iintr)(void *, int),
  277     void (*ointr)(void *), void *arg)
  278 {
  279         return mpu_open(SBMPU(addr), flags, iintr, ointr, arg);
  280 }
  281 
  282 int
  283 sb_mpu401_output(void *addr, int d)
  284 {
  285         return mpu_output(SBMPU(addr), d);
  286 }
  287 
  288 void
  289 sb_mpu401_close(void *addr)
  290 {
  291         mpu_close(SBMPU(addr));
  292 }
  293 
  294 void
  295 sb_mpu401_getinfo(void *addr, struct midi_info *mi)
  296 {
  297         mi->name = "SB MPU-401 UART";
  298         mi->props = 0;
  299 }
  300 #endif

Cache object: 4c7c49446faa0d554f99b56cfdbfc3c0


[ 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.