root/dev/audio.c

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

DEFINITIONS

This source file includes following definitions.
  1. audioprobe
  2. audioattach
  3. audioactivate
  4. audiodetach
  5. au_portof
  6. au_check_ports
  7. audio_attach_mi
  8. audioprint
  9. audio_printsc
  10. audio_print_params
  11. audio_alloc_ring
  12. audio_free_ring
  13. audioopen
  14. audioclose
  15. audioread
  16. audiowrite
  17. audioioctl
  18. audiopoll
  19. audiommap
  20. audio_init_ringbuffer
  21. audio_initbufs
  22. audio_calcwater
  23. audio_sleep_timo
  24. audio_sleep
  25. audio_wakeup
  26. audio_open
  27. audio_init_record
  28. audio_init_play
  29. audio_drain
  30. audio_close
  31. audio_read
  32. audio_clear
  33. audio_calc_blksize
  34. audio_fill_silence
  35. audio_silence_copyout
  36. audio_write
  37. audio_ioctl
  38. audio_selwakeup
  39. audio_poll
  40. audio_mmap
  41. audiostartr
  42. audiostartp
  43. audio_pint_silence
  44. audio_pint
  45. audio_rint
  46. audio_check_params
  47. au_set_lr_value
  48. au_set_gain
  49. au_get_lr_value
  50. au_get_gain
  51. au_set_port
  52. au_get_port
  53. audiosetinfo
  54. audiogetinfo
  55. mixer_open
  56. mixer_remove
  57. mixer_signal
  58. mixer_close
  59. mixer_ioctl
  60. audiokqfilter
  61. filt_audiordetach
  62. filt_audioread
  63. filt_audiowdetach
  64. filt_audiowrite
  65. wskbd_get_mixerdev
  66. wskbd_set_mixervolume

    1 /*      $OpenBSD: audio.c,v 1.72 2007/08/08 05:51:23 jakemsr Exp $      */
    2 /*      $NetBSD: audio.c,v 1.119 1999/11/09 16:50:47 augustss 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  * This is a (partially) SunOS-compatible /dev/audio driver for NetBSD.
   39  *
   40  * This code tries to do something half-way sensible with
   41  * half-duplex hardware, such as with the SoundBlaster hardware.  With
   42  * half-duplex hardware allowing O_RDWR access doesn't really make
   43  * sense.  However, closing and opening the device to "turn around the
   44  * line" is relatively expensive and costs a card reset (which can
   45  * take some time, at least for the SoundBlaster hardware).  Instead
   46  * we allow O_RDWR access, and provide an ioctl to set the "mode",
   47  * i.e. playing or recording.
   48  *
   49  * If you write to a half-duplex device in record mode, the data is
   50  * tossed.  If you read from the device in play mode, you get silence
   51  * filled buffers at the rate at which samples are naturally
   52  * generated.
   53  *
   54  * If you try to set both play and record mode on a half-duplex
   55  * device, playing takes precedence.
   56  */
   57 
   58 /*
   59  * Todo:
   60  * - Add softaudio() isr processing for wakeup, poll, signals,
   61  *   and silence fill.
   62  */
   63 
   64 #include "audio.h"
   65 #if NAUDIO > 0
   66 
   67 #include <sys/param.h>
   68 #include <sys/ioctl.h>
   69 #include <sys/fcntl.h>
   70 #include <sys/vnode.h>
   71 #include <sys/selinfo.h>
   72 #include <sys/poll.h>
   73 #include <sys/malloc.h>
   74 #include <sys/proc.h>
   75 #include <sys/systm.h>
   76 #include <sys/syslog.h>
   77 #include <sys/kernel.h>
   78 #include <sys/signalvar.h>
   79 #include <sys/conf.h>
   80 #include <sys/audioio.h>
   81 #include <sys/device.h>
   82 
   83 #include <dev/audio_if.h>
   84 #include <dev/audiovar.h>
   85 
   86 #include <dev/rndvar.h>
   87 
   88 #include <machine/endian.h>
   89 
   90 #include "wskbd.h"      /* NWSKBD (mixer tuning using keyboard) */
   91 
   92 #ifdef AUDIO_DEBUG
   93 #define DPRINTF(x)      if (audiodebug) printf x
   94 #define DPRINTFN(n,x)   if (audiodebug>(n)) printf x
   95 int     audiodebug = 0;
   96 #else
   97 #define DPRINTF(x)
   98 #define DPRINTFN(n,x)
   99 #endif
  100 
  101 #define ROUNDSIZE(x) x &= -16   /* round to nice boundary */
  102 
  103 int     audio_blk_ms = AUDIO_BLK_MS;
  104 
  105 int     audiosetinfo(struct audio_softc *, struct audio_info *);
  106 int     audiogetinfo(struct audio_softc *, struct audio_info *);
  107 
  108 int     audio_open(dev_t, struct audio_softc *, int, int, struct proc *);
  109 int     audio_close(dev_t, int, int, struct proc *);
  110 int     audio_read(dev_t, struct uio *, int);
  111 int     audio_write(dev_t, struct uio *, int);
  112 int     audio_ioctl(dev_t, u_long, caddr_t, int, struct proc *);
  113 int     audio_poll(dev_t, int, struct proc *);
  114 paddr_t audio_mmap(dev_t, off_t, int);
  115 
  116 int     mixer_open(dev_t, struct audio_softc *, int, int, struct proc *);
  117 int     mixer_close(dev_t, int, int, struct proc *);
  118 int     mixer_ioctl(dev_t, u_long, caddr_t, int, struct proc *);
  119 static  void mixer_remove(struct audio_softc *, struct proc *p);
  120 static  void mixer_signal(struct audio_softc *);
  121 
  122 void    audio_init_record(struct audio_softc *);
  123 void    audio_init_play(struct audio_softc *);
  124 int     audiostartr(struct audio_softc *);
  125 int     audiostartp(struct audio_softc *);
  126 void    audio_rint(void *);
  127 void    audio_pint(void *);
  128 int     audio_check_params(struct audio_params *);
  129 
  130 void    audio_calc_blksize(struct audio_softc *, int);
  131 void    audio_fill_silence(struct audio_params *, u_char *, int);
  132 int     audio_silence_copyout(struct audio_softc *, int, struct uio *);
  133 
  134 void    audio_init_ringbuffer(struct audio_ringbuffer *);
  135 int     audio_initbufs(struct audio_softc *);
  136 void    audio_calcwater(struct audio_softc *);
  137 static __inline int audio_sleep_timo(int *, char *, int);
  138 static __inline int audio_sleep(int *, char *);
  139 static __inline void audio_wakeup(int *);
  140 void    audio_selwakeup(struct audio_softc *sc, int play);
  141 int     audio_drain(struct audio_softc *);
  142 void    audio_clear(struct audio_softc *);
  143 static __inline void audio_pint_silence(struct audio_softc *, struct audio_ringbuffer *, u_char *, int);
  144 
  145 int     audio_alloc_ring(struct audio_softc *, struct audio_ringbuffer *, int, int);
  146 void    audio_free_ring(struct audio_softc *, struct audio_ringbuffer *);
  147 
  148 int     audioprint(void *, const char *);
  149 
  150 int     audioprobe(struct device *, void *, void *);
  151 void    audioattach(struct device *, struct device *, void *);
  152 int     audiodetach(struct device *, int);
  153 int     audioactivate(struct device *, enum devact);
  154 
  155 struct portname {
  156         char    *name;
  157         int     mask;
  158 };
  159 static struct portname itable[] = {
  160         { AudioNmicrophone,     AUDIO_MICROPHONE },
  161         { AudioNline,           AUDIO_LINE_IN },
  162         { AudioNcd,             AUDIO_CD },
  163         { 0 }
  164 };
  165 static struct portname otable[] = {
  166         { AudioNspeaker,        AUDIO_SPEAKER },
  167         { AudioNheadphone,      AUDIO_HEADPHONE },
  168         { AudioNline,           AUDIO_LINE_OUT },
  169         { 0 }
  170 };
  171 void    au_check_ports(struct audio_softc *, struct au_mixer_ports *,
  172                             mixer_devinfo_t *, int, char *, char *,
  173                             struct portname *);
  174 int     au_set_gain(struct audio_softc *, struct au_mixer_ports *,
  175                          int, int);
  176 void    au_get_gain(struct audio_softc *, struct au_mixer_ports *,
  177                          u_int *, u_char *);
  178 int     au_set_port(struct audio_softc *, struct au_mixer_ports *,
  179                          u_int);
  180 int     au_get_port(struct audio_softc *, struct au_mixer_ports *);
  181 int     au_get_lr_value(struct audio_softc *, mixer_ctrl_t *,
  182                              int *, int *r);
  183 int     au_set_lr_value(struct audio_softc *, mixer_ctrl_t *,
  184                              int, int);
  185 int     au_portof(struct audio_softc *, char *);
  186 
  187 
  188 /* The default audio mode: 8 kHz mono ulaw */
  189 struct audio_params audio_default =
  190         { 8000, AUDIO_ENCODING_ULAW, 8, 1, 0, 1 };
  191 
  192 struct cfattach audio_ca = {
  193         sizeof(struct audio_softc), audioprobe, audioattach,
  194         audiodetach, audioactivate
  195 };
  196 
  197 struct cfdriver audio_cd = {
  198         NULL, "audio", DV_DULL
  199 };
  200 
  201 void filt_audiowdetach(struct knote *);
  202 int filt_audiowrite(struct knote *, long);
  203 
  204 struct filterops audiowrite_filtops =
  205         { 1, NULL, filt_audiowdetach, filt_audiowrite};
  206 
  207 void filt_audiordetach(struct knote *);
  208 int filt_audioread(struct knote *, long);
  209 
  210 struct filterops audioread_filtops =
  211         { 1, NULL, filt_audiordetach, filt_audioread};
  212 
  213 #if NWSKBD > 0
  214 /* Mixer manipulation using keyboard */
  215 int wskbd_get_mixerdev(struct audio_softc *, int, int *);
  216 int wskbd_set_mixervolume(long);
  217 #endif
  218 
  219 int
  220 audioprobe(struct device *parent, void *match, void *aux)
  221 {
  222         struct audio_attach_args *sa = aux;
  223 
  224         DPRINTF(("audioprobe: type=%d sa=%p hw=%p\n",
  225                    sa->type, sa, sa->hwif));
  226         return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0;
  227 }
  228 
  229 void
  230 audioattach(struct device *parent, struct device *self, void *aux)
  231 {
  232         struct audio_softc *sc = (void *)self;
  233         struct audio_attach_args *sa = aux;
  234         struct audio_hw_if *hwp = sa->hwif;
  235         void *hdlp = sa->hdl;
  236         int error;
  237         mixer_devinfo_t mi;
  238         int iclass, oclass, mclass;
  239 
  240         printf("\n");
  241 
  242 #ifdef DIAGNOSTIC
  243         if (hwp == 0 ||
  244             hwp->open == 0 ||
  245             hwp->close == 0 ||
  246             hwp->query_encoding == 0 ||
  247             hwp->set_params == 0 ||
  248             (hwp->start_output == 0 && hwp->trigger_output == 0) ||
  249             (hwp->start_input == 0 && hwp->trigger_input == 0) ||
  250             hwp->halt_output == 0 ||
  251             hwp->halt_input == 0 ||
  252             hwp->getdev == 0 ||
  253             hwp->set_port == 0 ||
  254             hwp->get_port == 0 ||
  255             hwp->query_devinfo == 0 ||
  256             hwp->get_props == 0) {
  257                 printf("audio: missing method\n");
  258                 sc->hw_if = 0;
  259                 return;
  260         }
  261 #endif
  262 
  263         sc->hw_if = hwp;
  264         sc->hw_hdl = hdlp;
  265         sc->sc_dev = parent;
  266 
  267         error = audio_alloc_ring(sc, &sc->sc_pr, AUMODE_PLAY, AU_RING_SIZE);
  268         if (error) {
  269                 sc->hw_if = 0;
  270                 printf("audio: could not allocate play buffer\n");
  271                 return;
  272         }
  273         error = audio_alloc_ring(sc, &sc->sc_rr, AUMODE_RECORD, AU_RING_SIZE);
  274         if (error) {
  275                 audio_free_ring(sc, &sc->sc_pr);
  276                 sc->hw_if = 0;
  277                 printf("audio: could not allocate record buffer\n");
  278                 return;
  279         }
  280 
  281         /*
  282          * Set default softc params
  283          */
  284         sc->sc_pparams = audio_default;
  285         sc->sc_rparams = audio_default;
  286 
  287         /* Set up some default values */
  288         sc->sc_blkset = 0;
  289         audio_calc_blksize(sc, AUMODE_RECORD);
  290         audio_calc_blksize(sc, AUMODE_PLAY);
  291         audio_init_ringbuffer(&sc->sc_rr);
  292         audio_init_ringbuffer(&sc->sc_pr);
  293         audio_calcwater(sc);
  294 
  295         iclass = oclass = mclass = -1;
  296         sc->sc_inports.index = -1;
  297         sc->sc_inports.nports = 0;
  298         sc->sc_inports.isenum = 0;
  299         sc->sc_inports.allports = 0;
  300         sc->sc_outports.index = -1;
  301         sc->sc_outports.nports = 0;
  302         sc->sc_outports.isenum = 0;
  303         sc->sc_outports.allports = 0;
  304         sc->sc_monitor_port = -1;
  305         for(mi.index = 0; ; mi.index++) {
  306                 if (hwp->query_devinfo(hdlp, &mi) != 0)
  307                         break;
  308                 if (mi.type == AUDIO_MIXER_CLASS &&
  309                     strcmp(mi.label.name, AudioCrecord) == 0)
  310                         iclass = mi.index;
  311                 if (mi.type == AUDIO_MIXER_CLASS &&
  312                     strcmp(mi.label.name, AudioCmonitor) == 0)
  313                         mclass = mi.index;
  314                 if (mi.type == AUDIO_MIXER_CLASS &&
  315                     strcmp(mi.label.name, AudioCoutputs) == 0)
  316                         oclass = mi.index;
  317         }
  318         for(mi.index = 0; ; mi.index++) {
  319                 if (hwp->query_devinfo(hdlp, &mi) != 0)
  320                         break;
  321                 if (mi.type == AUDIO_MIXER_CLASS)
  322                         continue;
  323                 au_check_ports(sc, &sc->sc_inports,  &mi, iclass,
  324                     AudioNsource, AudioNrecord, itable);
  325                 au_check_ports(sc, &sc->sc_outports, &mi, oclass,
  326                     AudioNoutput, AudioNmaster, otable);
  327                 if (mi.mixer_class == mclass &&
  328                     (strcmp(mi.label.name, AudioNmonitor) == 0))
  329                         sc->sc_monitor_port = mi.index;
  330                 if ((sc->sc_monitor_port == -1) && (mi.mixer_class == oclass) &&
  331                     (strcmp(mi.label.name, AudioNmonitor) == 0))
  332                         sc->sc_monitor_port = mi.index;
  333         }
  334         DPRINTF(("audio_attach: inputs ports=0x%x, output ports=0x%x\n",
  335                  sc->sc_inports.allports, sc->sc_outports.allports));
  336 }
  337 
  338 int
  339 audioactivate(struct device *self, enum devact act)
  340 {
  341         struct audio_softc *sc = (struct audio_softc *)self;
  342 
  343         switch (act) {
  344         case DVACT_ACTIVATE:
  345                 break;
  346 
  347         case DVACT_DEACTIVATE:
  348                 sc->sc_dying = 1;
  349                 break;
  350         }
  351         return (0);
  352 }
  353 
  354 int
  355 audiodetach(struct device *self, int flags)
  356 {
  357         struct audio_softc *sc = (struct audio_softc *)self;
  358         int maj, mn;
  359         int s;
  360 
  361         DPRINTF(("audio_detach: sc=%p flags=%d\n", sc, flags));
  362 
  363         sc->sc_dying = 1;
  364 
  365         wakeup(&sc->sc_wchan);
  366         wakeup(&sc->sc_rchan);
  367         s = splaudio();
  368         if (--sc->sc_refcnt >= 0) {
  369                 if (tsleep(&sc->sc_refcnt, PZERO, "auddet", hz * 120))
  370                         printf("audiodetach: %s didn't detach\n",
  371                             sc->dev.dv_xname);
  372         }
  373         splx(s);
  374 
  375         /* free resources */
  376         audio_free_ring(sc, &sc->sc_pr);
  377         audio_free_ring(sc, &sc->sc_rr);
  378 
  379         /* locate the major number */
  380         for (maj = 0; maj < nchrdev; maj++)
  381                 if (cdevsw[maj].d_open == audioopen)
  382                         break;
  383 
  384         /* Nuke the vnodes for any open instances (calls close). */
  385         mn = self->dv_unit;
  386         vdevgone(maj, mn | SOUND_DEVICE,    mn | SOUND_DEVICE, VCHR);
  387         vdevgone(maj, mn | AUDIO_DEVICE,    mn | AUDIO_DEVICE, VCHR);
  388         vdevgone(maj, mn | AUDIOCTL_DEVICE, mn | AUDIOCTL_DEVICE, VCHR);
  389         vdevgone(maj, mn | MIXER_DEVICE,    mn | MIXER_DEVICE, VCHR);
  390 
  391         return (0);
  392 }
  393 
  394 int
  395 au_portof(struct audio_softc *sc, char *name)
  396 {
  397         mixer_devinfo_t mi;
  398 
  399         for(mi.index = 0;
  400             sc->hw_if->query_devinfo(sc->hw_hdl, &mi) == 0;
  401             mi.index++)
  402                 if (strcmp(mi.label.name, name) == 0)
  403                         return mi.index;
  404         return -1;
  405 }
  406 
  407 void
  408 au_check_ports(struct audio_softc *sc, struct au_mixer_ports *ports,
  409     mixer_devinfo_t *mi, int cls, char *name, char *mname, struct portname *tbl)
  410 {
  411         int i, j;
  412 
  413         if (mi->mixer_class != cls)
  414                 return;
  415         if (strcmp(mi->label.name, mname) == 0) {
  416                 ports->master = mi->index;
  417                 return;
  418         }
  419         if (strcmp(mi->label.name, name) != 0)
  420                 return;
  421         if (mi->type == AUDIO_MIXER_ENUM) {
  422             ports->index = mi->index;
  423             for(i = 0; tbl[i].name; i++) {
  424                 for(j = 0; j < mi->un.e.num_mem; j++) {
  425                     if (strcmp(mi->un.e.member[j].label.name,
  426                             tbl[i].name) == 0) {
  427                         ports->aumask[ports->nports] = tbl[i].mask;
  428                         ports->misel [ports->nports] = mi->un.e.member[j].ord;
  429                         ports->miport[ports->nports++] =
  430                                 au_portof(sc, mi->un.e.member[j].label.name);
  431                         ports->allports |= tbl[i].mask;
  432                     }
  433                 }
  434             }
  435             ports->isenum = 1;
  436         } else if (mi->type == AUDIO_MIXER_SET) {
  437             ports->index = mi->index;
  438             for(i = 0; tbl[i].name; i++) {
  439                 for(j = 0; j < mi->un.s.num_mem; j++) {
  440                     if (strcmp(mi->un.s.member[j].label.name,
  441                             tbl[i].name) == 0) {
  442                         ports->aumask[ports->nports] = tbl[i].mask;
  443                         ports->misel [ports->nports] = mi->un.s.member[j].mask;
  444                         ports->miport[ports->nports++] =
  445                                 au_portof(sc, mi->un.s.member[j].label.name);
  446                         ports->allports |= tbl[i].mask;
  447                     }
  448                 }
  449             }
  450         }
  451 }
  452 
  453 /*
  454  * Called from hardware driver.  This is where the MI audio driver gets
  455  * probed/attached to the hardware driver.
  456  */
  457 struct device *
  458 audio_attach_mi(struct audio_hw_if *ahwp, void *hdlp, struct device *dev)
  459 {
  460         struct audio_attach_args arg;
  461 
  462 #ifdef DIAGNOSTIC
  463         if (ahwp == NULL) {
  464                 printf ("audio_attach_mi: NULL\n");
  465                 return 0;
  466         }
  467 #endif
  468 
  469         arg.type = AUDIODEV_TYPE_AUDIO;
  470         arg.hwif = ahwp;
  471         arg.hdl = hdlp;
  472         return config_found(dev, &arg, audioprint);
  473 }
  474 
  475 #if NAUDIO > 0
  476 int
  477 audioprint(void *aux, const char *pnp)
  478 {
  479         struct audio_attach_args *arg = aux;
  480         const char *type;
  481 
  482         if (pnp != NULL) {
  483                 switch (arg->type) {
  484                 case AUDIODEV_TYPE_AUDIO:
  485                         type = "audio";
  486                         break;
  487                 case AUDIODEV_TYPE_OPL:
  488                         type = "opl";
  489                         break;
  490                 case AUDIODEV_TYPE_MPU:
  491                         type = "mpu";
  492                         break;
  493                 default:
  494                         panic("audioprint: unknown type %d", arg->type);
  495                 }
  496                 printf("%s at %s", type, pnp);
  497         }
  498         return (UNCONF);
  499 }
  500 
  501 #endif /* NAUDIO > 0 */
  502 
  503 #ifdef AUDIO_DEBUG
  504 void    audio_printsc(struct audio_softc *);
  505 void    audio_print_params(char *, struct audio_params *);
  506 
  507 void
  508 audio_printsc(struct audio_softc *sc)
  509 {
  510         printf("hwhandle %p hw_if %p ", sc->hw_hdl, sc->hw_if);
  511         printf("open 0x%x mode 0x%x\n", sc->sc_open, sc->sc_mode);
  512         printf("rchan 0x%x wchan 0x%x ", sc->sc_rchan, sc->sc_wchan);
  513         printf("rring used 0x%x pring used=%d\n", sc->sc_rr.used, sc->sc_pr.used);
  514         printf("rbus 0x%x pbus 0x%x ", sc->sc_rbus, sc->sc_pbus);
  515         printf("blksize %d", sc->sc_pr.blksize);
  516         printf("hiwat %d lowat %d\n", sc->sc_pr.usedhigh, sc->sc_pr.usedlow);
  517 }
  518 
  519 void
  520 audio_print_params(char *s, struct audio_params *p)
  521 {
  522         printf("audio: %s sr=%ld, enc=%d, chan=%d, prec=%d\n", s,
  523             p->sample_rate, p->encoding, p->channels, p->precision);
  524 }
  525 #endif
  526 
  527 int
  528 audio_alloc_ring(struct audio_softc *sc, struct audio_ringbuffer *r,
  529     int direction, int bufsize)
  530 {
  531         struct audio_hw_if *hw = sc->hw_if;
  532         void *hdl = sc->hw_hdl;
  533         /*
  534          * Alloc DMA play and record buffers
  535          */
  536         if (bufsize < AUMINBUF)
  537                 bufsize = AUMINBUF;
  538         ROUNDSIZE(bufsize);
  539         if (hw->round_buffersize)
  540                 bufsize = hw->round_buffersize(hdl, direction, bufsize);
  541         r->bufsize = bufsize;
  542         if (hw->allocm)
  543                 r->start = hw->allocm(hdl, direction, r->bufsize, M_DEVBUF,
  544                     M_WAITOK);
  545         else
  546                 r->start = malloc(bufsize, M_DEVBUF, M_WAITOK);
  547         if (r->start == 0)
  548                 return ENOMEM;
  549         return 0;
  550 }
  551 
  552 void
  553 audio_free_ring(struct audio_softc *sc, struct audio_ringbuffer *r)
  554 {
  555         if (sc->hw_if->freem) {
  556                 sc->hw_if->freem(sc->hw_hdl, r->start, M_DEVBUF);
  557         } else {
  558                 free(r->start, M_DEVBUF);
  559         }
  560 }
  561 
  562 int
  563 audioopen(dev_t dev, int flags, int ifmt, struct proc *p)
  564 {
  565         int unit = AUDIOUNIT(dev);
  566         struct audio_softc *sc;
  567         int error;
  568 
  569         if (unit >= audio_cd.cd_ndevs ||
  570             (sc = audio_cd.cd_devs[unit]) == NULL)
  571                 return ENXIO;
  572 
  573         if (sc->sc_dying)
  574                 return (EIO);
  575 
  576         if (!sc->hw_if)
  577                 return (ENXIO);
  578 
  579         sc->sc_refcnt ++;
  580         switch (AUDIODEV(dev)) {
  581         case SOUND_DEVICE:
  582         case AUDIO_DEVICE:
  583         case AUDIOCTL_DEVICE:
  584                 error = audio_open(dev, sc, flags, ifmt, p);
  585                 break;
  586         case MIXER_DEVICE:
  587                 error = mixer_open(dev, sc, flags, ifmt, p);
  588                 break;
  589         default:
  590                 error = ENXIO;
  591                 break;
  592         }
  593 
  594         if (--sc->sc_refcnt < 0)
  595                 wakeup(&sc->sc_refcnt);
  596 
  597         return (error);
  598 }
  599 
  600 int
  601 audioclose(dev_t dev, int flags, int ifmt, struct proc *p)
  602 {
  603 
  604         switch (AUDIODEV(dev)) {
  605         case SOUND_DEVICE:
  606         case AUDIO_DEVICE:
  607                 return (audio_close(dev, flags, ifmt, p));
  608         case MIXER_DEVICE:
  609                 return (mixer_close(dev, flags, ifmt, p));
  610         case AUDIOCTL_DEVICE:
  611                 return 0;
  612         default:
  613                 return (ENXIO);
  614         }
  615 }
  616 
  617 int
  618 audioread(dev_t dev, struct uio *uio, int ioflag)
  619 {
  620         int unit = AUDIOUNIT(dev);
  621         struct audio_softc *sc;
  622         int error;
  623 
  624         if (unit >= audio_cd.cd_ndevs ||
  625             (sc = audio_cd.cd_devs[unit]) == NULL)
  626                 return ENXIO;
  627 
  628         if (sc->sc_dying)
  629                 return (EIO);
  630 
  631         sc->sc_refcnt ++;
  632         switch (AUDIODEV(dev)) {
  633         case SOUND_DEVICE:
  634         case AUDIO_DEVICE:
  635                 error = audio_read(dev, uio, ioflag);
  636                 break;
  637         case AUDIOCTL_DEVICE:
  638         case MIXER_DEVICE:
  639                 error = ENODEV;
  640                 break;
  641         default:
  642                 error = ENXIO;
  643                 break;
  644         }
  645 
  646         if (--sc->sc_refcnt < 0)
  647                 wakeup(&sc->sc_refcnt);
  648         return (error);
  649 }
  650 
  651 int
  652 audiowrite(dev_t dev, struct uio *uio, int ioflag)
  653 {
  654         int unit = AUDIOUNIT(dev);
  655         struct audio_softc *sc;
  656         int error;
  657 
  658         if (unit >= audio_cd.cd_ndevs ||
  659             (sc = audio_cd.cd_devs[unit]) == NULL)
  660                 return ENXIO;
  661 
  662         if (sc->sc_dying)
  663                 return (EIO);
  664 
  665         sc->sc_refcnt ++;
  666         switch (AUDIODEV(dev)) {
  667         case SOUND_DEVICE:
  668         case AUDIO_DEVICE:
  669                 error = audio_write(dev, uio, ioflag);
  670                 break;
  671         case AUDIOCTL_DEVICE:
  672         case MIXER_DEVICE:
  673                 error = ENODEV;
  674                 break;
  675         default:
  676                 error = ENXIO;
  677                 break;
  678         }
  679 
  680         if (--sc->sc_refcnt < 0)
  681                 wakeup(&sc->sc_refcnt);
  682         return (error);
  683 }
  684 
  685 int
  686 audioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
  687 {
  688         int unit = AUDIOUNIT(dev);
  689         struct audio_softc *sc;
  690         int error;
  691 
  692         if (unit >= audio_cd.cd_ndevs ||
  693             (sc = audio_cd.cd_devs[unit]) == NULL)
  694                 return ENXIO;
  695 
  696         if (sc->sc_dying)
  697                 return (EIO);
  698 
  699         sc->sc_refcnt ++;
  700         switch (AUDIODEV(dev)) {
  701         case SOUND_DEVICE:
  702         case AUDIO_DEVICE:
  703         case AUDIOCTL_DEVICE:
  704                 error = audio_ioctl(dev, cmd, addr, flag, p);
  705                 break;
  706         case MIXER_DEVICE:
  707                 error = mixer_ioctl(dev, cmd, addr, flag, p);
  708                 break;
  709         default:
  710                 error = ENXIO;
  711                 break;
  712         }
  713 
  714         if (--sc->sc_refcnt < 0)
  715                 wakeup(&sc->sc_refcnt);
  716         return (error);
  717 }
  718 
  719 int
  720 audiopoll(dev_t dev, int events, struct proc *p)
  721 {
  722         int unit = AUDIOUNIT(dev);
  723         struct audio_softc *sc;
  724         int error;
  725 
  726         if (unit >= audio_cd.cd_ndevs ||
  727             (sc = audio_cd.cd_devs[unit]) == NULL)
  728                 return POLLERR;
  729 
  730         if (sc->sc_dying)
  731                 return POLLERR;
  732 
  733         sc->sc_refcnt ++;
  734         switch (AUDIODEV(dev)) {
  735         case SOUND_DEVICE:
  736         case AUDIO_DEVICE:
  737                 error = audio_poll(dev, events, p);
  738                 break;
  739         case AUDIOCTL_DEVICE:
  740         case MIXER_DEVICE:
  741                 error = 0;
  742                 break;
  743         default:
  744                 error = 0;
  745                 break;
  746         }
  747 
  748         if (--sc->sc_refcnt < 0)
  749                 wakeup(&sc->sc_refcnt);
  750         return (error);
  751 }
  752 
  753 paddr_t
  754 audiommap(dev_t dev, off_t off, int prot)
  755 {
  756         int unit = AUDIOUNIT(dev);
  757         struct audio_softc *sc;
  758         int ret;
  759 
  760         if (unit >= audio_cd.cd_ndevs ||
  761             (sc = audio_cd.cd_devs[unit]) == NULL)
  762                 return (-1);
  763 
  764         if (sc->sc_dying)
  765                 return (-1);
  766 
  767         sc->sc_refcnt ++;
  768         switch (AUDIODEV(dev)) {
  769         case SOUND_DEVICE:
  770         case AUDIO_DEVICE:
  771                 ret = audio_mmap(dev, off, prot);
  772                 break;
  773         case AUDIOCTL_DEVICE:
  774         case MIXER_DEVICE:
  775                 ret = -1;
  776                 break;
  777         default:
  778                 ret = -1;
  779                 break;
  780         }
  781 
  782         if (--sc->sc_refcnt < 0)
  783                 wakeup(&sc->sc_refcnt);
  784         return (ret);
  785 }
  786 
  787 /*
  788  * Audio driver
  789  */
  790 void
  791 audio_init_ringbuffer(struct audio_ringbuffer *rp)
  792 {
  793         int nblks;
  794         int blksize = rp->blksize;
  795 
  796         if (blksize < AUMINBLK)
  797                 blksize = AUMINBLK;
  798         nblks = rp->bufsize / blksize;
  799         if (nblks < AUMINNOBLK) {
  800                 nblks = AUMINNOBLK;
  801                 blksize = rp->bufsize / nblks;
  802                 ROUNDSIZE(blksize);
  803         }
  804         DPRINTF(("audio_init_ringbuffer: blksize=%d\n", blksize));
  805         rp->blksize = blksize;
  806         rp->maxblks = nblks;
  807         rp->used = 0;
  808         rp->end = rp->start + nblks * blksize;
  809         rp->inp = rp->outp = rp->start;
  810         rp->stamp = 0;
  811         rp->stamp_last = 0;
  812         rp->drops = 0;
  813         rp->pdrops = 0;
  814         rp->copying = 0;
  815         rp->needfill = 0;
  816         rp->mmapped = 0;
  817 }
  818 
  819 int
  820 audio_initbufs(struct audio_softc *sc)
  821 {
  822         struct audio_hw_if *hw = sc->hw_if;
  823         int error;
  824 
  825         DPRINTF(("audio_initbufs: mode=0x%x\n", sc->sc_mode));
  826         audio_init_ringbuffer(&sc->sc_rr);
  827         if (hw->init_input && (sc->sc_mode & AUMODE_RECORD)) {
  828                 error = hw->init_input(sc->hw_hdl, sc->sc_rr.start,
  829                     sc->sc_rr.end - sc->sc_rr.start);
  830                 if (error)
  831                         return error;
  832         }
  833 
  834         audio_init_ringbuffer(&sc->sc_pr);
  835         sc->sc_sil_count = 0;
  836         if (hw->init_output && (sc->sc_mode & AUMODE_PLAY)) {
  837                 error = hw->init_output(sc->hw_hdl, sc->sc_pr.start,
  838                                         sc->sc_pr.end - sc->sc_pr.start);
  839                 if (error)
  840                         return error;
  841         }
  842 
  843 #ifdef AUDIO_INTR_TIME
  844         sc->sc_pnintr = 0;
  845         sc->sc_pblktime = (u_long)(
  846             (u_long)sc->sc_pr.blksize * 100000 /
  847             (u_long)(sc->sc_pparams.precision / NBBY *
  848                 sc->sc_pparams.channels *
  849                 sc->sc_pparams.sample_rate)) * 10;
  850         DPRINTF(("audio: play blktime = %lu for %d\n",
  851                  sc->sc_pblktime, sc->sc_pr.blksize));
  852         sc->sc_rnintr = 0;
  853         sc->sc_rblktime = (u_long)(
  854             (u_long)sc->sc_rr.blksize * 100000 /
  855             (u_long)(sc->sc_rparams.precision / NBBY *
  856                 sc->sc_rparams.channels *
  857                 sc->sc_rparams.sample_rate)) * 10;
  858         DPRINTF(("audio: record blktime = %lu for %d\n",
  859                  sc->sc_rblktime, sc->sc_rr.blksize));
  860 #endif
  861 
  862         return 0;
  863 }
  864 
  865 void
  866 audio_calcwater(struct audio_softc *sc)
  867 {
  868         sc->sc_pr.usedhigh = sc->sc_pr.end - sc->sc_pr.start;
  869         sc->sc_pr.usedlow = sc->sc_pr.usedhigh * 3 / 4; /* set lowater at 75% */
  870         if (sc->sc_pr.usedlow == sc->sc_pr.usedhigh)
  871                 sc->sc_pr.usedlow -= sc->sc_pr.blksize;
  872         sc->sc_rr.usedhigh = sc->sc_rr.end - sc->sc_rr.start - sc->sc_rr.blksize;
  873         sc->sc_rr.usedlow = 0;
  874 }
  875 
  876 static __inline int
  877 audio_sleep_timo(int *chan, char *label, int timo)
  878 {
  879         int st;
  880 
  881         if (!label)
  882                 label = "audio";
  883 
  884         DPRINTFN(3, ("audio_sleep_timo: chan=%p, label=%s, timo=%d\n",
  885             chan, label, timo));
  886         *chan = 1;
  887         st = tsleep(chan, PWAIT | PCATCH, label, timo);
  888         *chan = 0;
  889 #ifdef AUDIO_DEBUG
  890         if (st != 0)
  891             printf("audio_sleep: woke up st=%d\n", st);
  892 #endif
  893         return (st);
  894 }
  895 
  896 static __inline int
  897 audio_sleep(int *chan, char *label)
  898 {
  899         return audio_sleep_timo(chan, label, 0);
  900 }
  901 
  902 /* call at splaudio() */
  903 static __inline void
  904 audio_wakeup(int *chan)
  905 {
  906         DPRINTFN(3, ("audio_wakeup: chan=%p, *chan=%d\n", chan, *chan));
  907         if (*chan) {
  908                 wakeup(chan);
  909                 *chan = 0;
  910         }
  911 }
  912 
  913 int
  914 audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
  915     struct proc *p)
  916 {
  917         int error;
  918         int mode;
  919         struct audio_info ai;
  920 
  921         DPRINTF(("audio_open: dev=0x%x flags=0x%x sc=%p hdl=%p\n", dev, flags, sc, sc->hw_hdl));
  922 
  923         if (ISDEVAUDIOCTL(dev))
  924                 return 0;
  925 
  926         if ((sc->sc_open & (AUOPEN_READ|AUOPEN_WRITE)) != 0)
  927                 return (EBUSY);
  928 
  929         error = sc->hw_if->open(sc->hw_hdl, flags);
  930         if (error)
  931                 return (error);
  932 
  933         sc->sc_async_audio = 0;
  934         sc->sc_rchan = 0;
  935         sc->sc_wchan = 0;
  936         sc->sc_blkset = 0; /* Block sizes not set yet */
  937         sc->sc_sil_count = 0;
  938         sc->sc_rbus = 0;
  939         sc->sc_pbus = 0;
  940         sc->sc_eof = 0;
  941         sc->sc_playdrop = 0;
  942 
  943         sc->sc_full_duplex = 0;
  944 /* doesn't always work right on SB.
  945                 (flags & (FWRITE|FREAD)) == (FWRITE|FREAD) &&
  946                 (sc->hw_if->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX);
  947 */
  948 
  949         mode = 0;
  950         if (flags & FREAD) {
  951                 sc->sc_open |= AUOPEN_READ;
  952                 mode |= AUMODE_RECORD;
  953         }
  954         if (flags & FWRITE) {
  955                 sc->sc_open |= AUOPEN_WRITE;
  956                 mode |= AUMODE_PLAY | AUMODE_PLAY_ALL;
  957         }
  958 
  959         /*
  960          * Multiplex device: /dev/audio (MU-Law) and /dev/sound (linear)
  961          * The /dev/audio is always (re)set to 8-bit MU-Law mono
  962          * For the other devices, you get what they were last set to.
  963          */
  964         if (ISDEVAUDIO(dev)) {
  965                 /* /dev/audio */
  966                 sc->sc_rparams = audio_default;
  967                 sc->sc_pparams = audio_default;
  968         }
  969 #ifdef DIAGNOSTIC
  970         /*
  971          * Sample rate and precision are supposed to be set to proper
  972          * default values by the hardware driver, so that it may give
  973          * us these values.
  974          */
  975         if (sc->sc_rparams.precision == 0 || sc->sc_pparams.precision == 0) {
  976                 printf("audio_open: 0 precision\n");
  977                 error = EINVAL;
  978                 goto bad;
  979         }
  980 #endif
  981 
  982         AUDIO_INITINFO(&ai);
  983         ai.record.sample_rate = sc->sc_rparams.sample_rate;
  984         ai.record.encoding    = sc->sc_rparams.encoding;
  985         ai.record.channels    = sc->sc_rparams.channels;
  986         ai.record.precision   = sc->sc_rparams.precision;
  987         ai.record.pause       = 0;
  988         ai.play.sample_rate   = sc->sc_pparams.sample_rate;
  989         ai.play.encoding       = sc->sc_pparams.encoding;
  990         ai.play.channels      = sc->sc_pparams.channels;
  991         ai.play.precision     = sc->sc_pparams.precision;
  992         ai.play.pause         = 0;
  993         ai.mode               = mode;
  994         sc->sc_pr.blksize = sc->sc_rr.blksize = 0; /* force recalculation */
  995         error = audiosetinfo(sc, &ai);
  996         if (error)
  997                 goto bad;
  998 
  999         DPRINTF(("audio_open: done sc_mode = 0x%x\n", sc->sc_mode));
 1000 
 1001         return 0;
 1002 
 1003 bad:
 1004         sc->hw_if->close(sc->hw_hdl);
 1005         sc->sc_open = 0;
 1006         sc->sc_mode = 0;
 1007         sc->sc_full_duplex = 0;
 1008         return error;
 1009 }
 1010 
 1011 /*
 1012  * Must be called from task context.
 1013  */
 1014 void
 1015 audio_init_record(struct audio_softc *sc)
 1016 {
 1017         int s = splaudio();
 1018 
 1019         if (sc->hw_if->speaker_ctl &&
 1020             (!sc->sc_full_duplex || (sc->sc_mode & AUMODE_PLAY) == 0))
 1021                 sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_OFF);
 1022         splx(s);
 1023 }
 1024 
 1025 /*
 1026  * Must be called from task context.
 1027  */
 1028 void
 1029 audio_init_play(struct audio_softc *sc)
 1030 {
 1031         int s = splaudio();
 1032 
 1033         sc->sc_wstamp = sc->sc_pr.stamp;
 1034         if (sc->hw_if->speaker_ctl)
 1035                 sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_ON);
 1036         splx(s);
 1037 }
 1038 
 1039 int
 1040 audio_drain(struct audio_softc *sc)
 1041 {
 1042         int error, drops;
 1043         struct audio_ringbuffer *cb = &sc->sc_pr;
 1044         int s;
 1045 
 1046         DPRINTF(("audio_drain: enter busy=%d used=%d\n",
 1047             sc->sc_pbus, sc->sc_pr.used));
 1048         if (sc->sc_pr.mmapped || sc->sc_pr.used <= 0)
 1049                 return 0;
 1050         if (!sc->sc_pbus) {
 1051                 /* We've never started playing, probably because the
 1052                  * block was too short.  Pad it and start now.
 1053                  */
 1054                 int cc;
 1055                 u_char *inp = cb->inp;
 1056 
 1057                 cc = cb->blksize - (inp - cb->start) % cb->blksize;
 1058                 if (sc->sc_pparams.sw_code) {
 1059                         int ncc = cc / sc->sc_pparams.factor;
 1060                         audio_fill_silence(&sc->sc_pparams, inp, ncc);
 1061                         sc->sc_pparams.sw_code(sc->hw_hdl, inp, ncc);
 1062                 } else
 1063                         audio_fill_silence(&sc->sc_pparams, inp, cc);
 1064                 inp += cc;
 1065                 if (inp >= cb->end)
 1066                         inp = cb->start;
 1067                 s = splaudio();
 1068                 cb->used += cc;
 1069                 cb->inp = inp;
 1070                 error = audiostartp(sc);
 1071                 splx(s);
 1072                 if (error)
 1073                         return error;
 1074         }
 1075         /*
 1076          * Play until a silence block has been played, then we
 1077          * know all has been drained.
 1078          * XXX This should be done some other way to avoid
 1079          * playing silence.
 1080          */
 1081 #ifdef DIAGNOSTIC
 1082         if (cb->copying) {
 1083                 printf("audio_drain: copying in progress!?!\n");
 1084                 cb->copying = 0;
 1085         }
 1086 #endif
 1087         drops = cb->drops;
 1088         error = 0;
 1089         s = splaudio();
 1090         while (cb->drops == drops && !error) {
 1091                 DPRINTF(("audio_drain: used=%d, drops=%ld\n", sc->sc_pr.used, cb->drops));
 1092                 /*
 1093                  * When the process is exiting, it ignores all signals and
 1094                  * we can't interrupt this sleep, so we set a timeout just in case.
 1095                  */
 1096                 error = audio_sleep_timo(&sc->sc_wchan, "aud_dr", 30*hz);
 1097                 if (sc->sc_dying)
 1098                         error = EIO;
 1099         }
 1100         splx(s);
 1101         return error;
 1102 }
 1103 
 1104 /*
 1105  * Close an audio chip.
 1106  */
 1107 /* ARGSUSED */
 1108 int
 1109 audio_close(dev_t dev, int flags, int ifmt, struct proc *p)
 1110 {
 1111         int unit = AUDIOUNIT(dev);
 1112         struct audio_softc *sc = audio_cd.cd_devs[unit];
 1113         struct audio_hw_if *hw = sc->hw_if;
 1114         int s;
 1115 
 1116         DPRINTF(("audio_close: unit=%d flags=0x%x\n", unit, flags));
 1117 
 1118         s = splaudio();
 1119         /* Stop recording. */
 1120         if ((flags & FREAD) && sc->sc_rbus) {
 1121                 /*
 1122                  * XXX Some drivers (e.g. SB) use the same routine
 1123                  * to halt input and output so don't halt input if
 1124                  * in full duplex mode.  These drivers should be fixed.
 1125                  */
 1126                 if (!sc->sc_full_duplex || sc->hw_if->halt_input != sc->hw_if->halt_output)
 1127                         sc->hw_if->halt_input(sc->hw_hdl);
 1128                 sc->sc_rbus = 0;
 1129         }
 1130         /*
 1131          * Block until output drains, but allow ^C interrupt.
 1132          */
 1133         sc->sc_pr.usedlow = sc->sc_pr.blksize;  /* avoid excessive wakeups */
 1134         /*
 1135          * If there is pending output, let it drain (unless
 1136          * the output is paused).
 1137          */
 1138         if ((flags & FWRITE) && sc->sc_pbus) {
 1139                 if (!sc->sc_pr.pause && !audio_drain(sc) && hw->drain)
 1140                         (void)hw->drain(sc->hw_hdl);
 1141                 sc->hw_if->halt_output(sc->hw_hdl);
 1142                 sc->sc_pbus = 0;
 1143         }
 1144 
 1145         hw->close(sc->hw_hdl);
 1146 
 1147         /*
 1148          * If flags has neither read nor write then reset both
 1149          * directions. Encountered when someone runs revoke(2).
 1150          */
 1151 
 1152         if ((flags & FREAD) || ((flags & (FREAD|FWRITE)) == 0)) {
 1153                 sc->sc_open &= ~AUOPEN_READ;
 1154                 sc->sc_mode &= ~AUMODE_RECORD;
 1155         }
 1156         if ((flags & FWRITE) || ((flags & (FREAD|FWRITE)) == 0)) {
 1157                 sc->sc_open &= ~AUOPEN_WRITE;
 1158                 sc->sc_mode &= ~(AUMODE_PLAY|AUMODE_PLAY_ALL);
 1159         }
 1160 
 1161         sc->sc_async_audio = 0;
 1162         sc->sc_full_duplex = 0;
 1163         splx(s);
 1164         DPRINTF(("audio_close: done\n"));
 1165 
 1166         return (0);
 1167 }
 1168 
 1169 int
 1170 audio_read(dev_t dev, struct uio *uio, int ioflag)
 1171 {
 1172         int unit = AUDIOUNIT(dev);
 1173         struct audio_softc *sc = audio_cd.cd_devs[unit];
 1174         struct audio_ringbuffer *cb = &sc->sc_rr;
 1175         u_char *outp;
 1176         int error, s, used, cc, n;
 1177 
 1178         if (cb->mmapped)
 1179                 return EINVAL;
 1180 
 1181         DPRINTFN(1,("audio_read: cc=%d mode=%d\n",
 1182             uio->uio_resid, sc->sc_mode));
 1183 
 1184         error = 0;
 1185         /*
 1186          * If hardware is half-duplex and currently playing, return
 1187          * silence blocks based on the number of blocks we have output.
 1188          */
 1189         if (!sc->sc_full_duplex &&
 1190             (sc->sc_mode & AUMODE_PLAY)) {
 1191                 while (uio->uio_resid > 0 && !error) {
 1192                         s = splaudio();
 1193                         for(;;) {
 1194                                 cc = sc->sc_pr.stamp - sc->sc_wstamp;
 1195                                 if (cc > 0)
 1196                                         break;
 1197                                 DPRINTF(("audio_read: stamp=%lu, wstamp=%lu\n",
 1198                                          sc->sc_pr.stamp, sc->sc_wstamp));
 1199                                 if (ioflag & IO_NDELAY) {
 1200                                         splx(s);
 1201                                         return EWOULDBLOCK;
 1202                                 }
 1203                                 error = audio_sleep(&sc->sc_rchan, "aud_hr");
 1204                                 if (sc->sc_dying)
 1205                                         error = EIO;
 1206                                 if (error) {
 1207                                         splx(s);
 1208                                         return error;
 1209                                 }
 1210                         }
 1211                         splx(s);
 1212 
 1213                         if (uio->uio_resid < cc / sc->sc_rparams.factor)
 1214                                 cc = uio->uio_resid * sc->sc_rparams.factor;
 1215                         DPRINTFN(1, ("audio_read: reading in write mode, cc=%d\n", cc));
 1216                         error = audio_silence_copyout(sc,
 1217                             cc / sc->sc_rparams.factor, uio);
 1218                         sc->sc_wstamp += cc;
 1219                 }
 1220                 return (error);
 1221         }
 1222         while (uio->uio_resid > 0 && !error) {
 1223                 s = splaudio();
 1224                 while (cb->used <= 0) {
 1225                         if (!sc->sc_rbus && !sc->sc_rr.pause) {
 1226                                 error = audiostartr(sc);
 1227                                 if (error) {
 1228                                         splx(s);
 1229                                         return error;
 1230                                 }
 1231                         }
 1232                         if (ioflag & IO_NDELAY) {
 1233                                 splx(s);
 1234                                 return (EWOULDBLOCK);
 1235                         }
 1236                         DPRINTFN(2, ("audio_read: sleep used=%d\n", cb->used));
 1237                         error = audio_sleep(&sc->sc_rchan, "aud_rd");
 1238                         if (sc->sc_dying)
 1239                                 error = EIO;
 1240                         if (error) {
 1241                                 splx(s);
 1242                                 return error;
 1243                         }
 1244                 }
 1245                 used = cb->used;
 1246                 outp = cb->outp;
 1247                 cb->copying = 1;
 1248                 splx(s);
 1249                 cc = used - cb->usedlow; /* maximum to read */
 1250                 n = cb->end - outp;
 1251                 if (n < cc)
 1252                         cc = n; /* don't read beyond end of buffer */
 1253 
 1254                  /* and no more than we want */
 1255                 if (uio->uio_resid < cc / sc->sc_rparams.factor)
 1256                         cc = uio->uio_resid * sc->sc_rparams.factor;
 1257 
 1258                 if (sc->sc_rparams.sw_code)
 1259                         sc->sc_rparams.sw_code(sc->hw_hdl, outp, cc);
 1260                 DPRINTFN(1,("audio_read: outp=%p, cc=%d\n", outp, cc));
 1261                 error = uiomove(outp, cc / sc->sc_rparams.factor, uio);
 1262                 used -= cc;
 1263                 outp += cc;
 1264                 if (outp >= cb->end)
 1265                         outp = cb->start;
 1266                 s = splaudio();
 1267                 cb->outp = outp;
 1268                 cb->used = used;
 1269                 cb->copying = 0;
 1270                 splx(s);
 1271         }
 1272         return (error);
 1273 }
 1274 
 1275 void
 1276 audio_clear(struct audio_softc *sc)
 1277 {
 1278         int s = splaudio();
 1279 
 1280         if (sc->sc_rbus) {
 1281                 audio_wakeup(&sc->sc_rchan);
 1282                 sc->hw_if->halt_input(sc->hw_hdl);
 1283                 sc->sc_rbus = 0;
 1284         }
 1285         if (sc->sc_pbus) {
 1286                 audio_wakeup(&sc->sc_wchan);
 1287                 sc->hw_if->halt_output(sc->hw_hdl);
 1288                 sc->sc_pbus = 0;
 1289         }
 1290         splx(s);
 1291 }
 1292 
 1293 void
 1294 audio_calc_blksize(struct audio_softc *sc, int mode)
 1295 {
 1296         struct audio_hw_if *hw = sc->hw_if;
 1297         struct audio_params *parm;
 1298         struct audio_ringbuffer *rb;
 1299         int bs;
 1300 
 1301         if (sc->sc_blkset)
 1302                 return;
 1303 
 1304         if (mode == AUMODE_PLAY) {
 1305                 parm = &sc->sc_pparams;
 1306                 rb = &sc->sc_pr;
 1307         } else {
 1308                 parm = &sc->sc_rparams;
 1309                 rb = &sc->sc_rr;
 1310         }
 1311 
 1312         bs = parm->sample_rate * audio_blk_ms / 1000 *
 1313              parm->channels * parm->precision / NBBY *
 1314              parm->factor;
 1315         ROUNDSIZE(bs);
 1316         if (hw->round_blocksize)
 1317                 bs = hw->round_blocksize(sc->hw_hdl, bs);
 1318         rb->blksize = bs;
 1319 
 1320         DPRINTF(("audio_calc_blksize: %s blksize=%d\n",
 1321                  mode == AUMODE_PLAY ? "play" : "record", bs));
 1322 }
 1323 
 1324 void
 1325 audio_fill_silence(struct audio_params *params, u_char *p, int n)
 1326 {
 1327         u_char auzero0, auzero1 = 0; /* initialize to please gcc */
 1328         int nfill = 1;
 1329 
 1330         switch (params->encoding) {
 1331         case AUDIO_ENCODING_ULAW:
 1332                 auzero0 = 0x7f;
 1333                 break;
 1334         case AUDIO_ENCODING_ALAW:
 1335                 auzero0 = 0x55;
 1336                 break;
 1337         case AUDIO_ENCODING_MPEG_L1_STREAM:
 1338         case AUDIO_ENCODING_MPEG_L1_PACKETS:
 1339         case AUDIO_ENCODING_MPEG_L1_SYSTEM:
 1340         case AUDIO_ENCODING_MPEG_L2_STREAM:
 1341         case AUDIO_ENCODING_MPEG_L2_PACKETS:
 1342         case AUDIO_ENCODING_MPEG_L2_SYSTEM:
 1343         case AUDIO_ENCODING_ADPCM: /* is this right XXX */
 1344         case AUDIO_ENCODING_SLINEAR_LE:
 1345         case AUDIO_ENCODING_SLINEAR_BE:
 1346                 auzero0 = 0;    /* fortunately this works for both 8 and 16 bits */
 1347                 break;
 1348         case AUDIO_ENCODING_ULINEAR_LE:
 1349         case AUDIO_ENCODING_ULINEAR_BE:
 1350                 if (params->precision == 16) {
 1351                         nfill = 2;
 1352                         if (params->encoding == AUDIO_ENCODING_ULINEAR_LE) {
 1353                                 auzero0 = 0;
 1354                                 auzero1 = 0x80;
 1355                         } else {
 1356                                 auzero0 = 0x80;
 1357                                 auzero1 = 0;
 1358                         }
 1359                 } else
 1360                         auzero0 = 0x80;
 1361                 break;
 1362         default:
 1363                 DPRINTF(("audio: bad encoding %d\n", params->encoding));
 1364                 auzero0 = 0;
 1365                 break;
 1366         }
 1367         if (nfill == 1) {
 1368                 while (--n >= 0)
 1369                         *p++ = auzero0; /* XXX memset */
 1370         } else /* nfill must be 2 */ {
 1371                 while (n > 1) {
 1372                         *p++ = auzero0;
 1373                         *p++ = auzero1;
 1374                         n -= 2;
 1375                 }
 1376         }
 1377 }
 1378 
 1379 int
 1380 audio_silence_copyout(struct audio_softc *sc, int n, struct uio *uio)
 1381 {
 1382         int error;
 1383         int k;
 1384         u_char zerobuf[128];
 1385 
 1386         audio_fill_silence(&sc->sc_rparams, zerobuf, sizeof zerobuf);
 1387 
 1388         error = 0;
 1389         while (n > 0 && uio->uio_resid > 0 && !error) {
 1390                 k = min(n, min(uio->uio_resid, sizeof zerobuf));
 1391                 error = uiomove(zerobuf, k, uio);
 1392                 n -= k;
 1393         }
 1394         return (error);
 1395 }
 1396 
 1397 int
 1398 audio_write(dev_t dev, struct uio *uio, int ioflag)
 1399 {
 1400         int unit = AUDIOUNIT(dev);
 1401         struct audio_softc *sc = audio_cd.cd_devs[unit];
 1402         struct audio_ringbuffer *cb = &sc->sc_pr;
 1403         u_char *inp, *einp;
 1404         int saveerror, error, s, n, cc, used;
 1405 
 1406         DPRINTFN(2, ("audio_write: sc=%p(unit=%d) count=%d used=%d(hi=%d)\n", sc, unit,
 1407                  uio->uio_resid, sc->sc_pr.used, sc->sc_pr.usedhigh));
 1408 
 1409         if (cb->mmapped)
 1410                 return EINVAL;
 1411 
 1412         if (uio->uio_resid == 0) {
 1413                 sc->sc_eof++;
 1414                 return 0;
 1415         }
 1416 
 1417         /*
 1418          * If half-duplex and currently recording, throw away data.
 1419          */
 1420         if (!sc->sc_full_duplex &&
 1421             (sc->sc_mode & AUMODE_RECORD)) {
 1422                 uio->uio_offset += uio->uio_resid;
 1423                 uio->uio_resid = 0;
 1424                 DPRINTF(("audio_write: half-dpx read busy\n"));
 1425                 return (0);
 1426         }
 1427 
 1428         if (!(sc->sc_mode & AUMODE_PLAY_ALL) && sc->sc_playdrop > 0) {
 1429                 n = min(sc->sc_playdrop, uio->uio_resid * sc->sc_pparams.factor);
 1430                 DPRINTF(("audio_write: playdrop %d\n", n));
 1431                 uio->uio_offset += n / sc->sc_pparams.factor;
 1432                 uio->uio_resid -= n / sc->sc_pparams.factor;
 1433                 sc->sc_playdrop -= n;
 1434                 if (uio->uio_resid == 0)
 1435                         return 0;
 1436         }
 1437 
 1438         DPRINTFN(1, ("audio_write: sr=%ld, enc=%d, prec=%d, chan=%d, sw=%p, fact=%d\n",
 1439             sc->sc_pparams.sample_rate, sc->sc_pparams.encoding,
 1440             sc->sc_pparams.precision, sc->sc_pparams.channels,
 1441             sc->sc_pparams.sw_code, sc->sc_pparams.factor));
 1442 
 1443         error = 0;
 1444         while (uio->uio_resid > 0 && !error) {
 1445                 s = splaudio();
 1446                 while (cb->used >= cb->usedhigh) {
 1447                         DPRINTFN(2, ("audio_write: sleep used=%d lowat=%d hiwat=%d\n",
 1448                                  cb->used, cb->usedlow, cb->usedhigh));
 1449                         if (ioflag & IO_NDELAY) {
 1450                                 splx(s);
 1451                                 return (EWOULDBLOCK);
 1452                         }
 1453                         error = audio_sleep(&sc->sc_wchan, "aud_wr");
 1454                         if (sc->sc_dying)
 1455                                 error = EIO;
 1456                         if (error) {
 1457                                 splx(s);
 1458                                 return error;
 1459                         }
 1460                 }
 1461                 used = cb->used;
 1462                 inp = cb->inp;
 1463                 cb->copying = 1;
 1464                 splx(s);
 1465                 cc = cb->usedhigh - used;       /* maximum to write */
 1466                 n = cb->end - inp;
 1467                 if (sc->sc_pparams.factor != 1) {
 1468                         /* Compensate for software coding expansion factor. */
 1469                         n /= sc->sc_pparams.factor;
 1470                         cc /= sc->sc_pparams.factor;
 1471                 }
 1472                 if (n < cc)
 1473                         cc = n;                 /* don't write beyond end of buffer */
 1474                 if (uio->uio_resid < cc)
 1475                         cc = uio->uio_resid;    /* and no more than we have */
 1476 
 1477 #ifdef DIAGNOSTIC
 1478                 /*
 1479                  * This should never happen since the block size and and
 1480                  * block pointers are always nicely aligned.
 1481                  */
 1482                 if (cc == 0) {
 1483                         printf("audio_write: cc == 0, swcode=%p, factor=%d\n",
 1484                             sc->sc_pparams.sw_code, sc->sc_pparams.factor);
 1485                         cb->copying = 0;
 1486                         return EINVAL;
 1487                 }
 1488 #endif
 1489                 DPRINTFN(1, ("audio_write: uiomove cc=%d inp=%p, left=%d\n",
 1490                     cc, inp, uio->uio_resid));
 1491                 n = uio->uio_resid;
 1492                 error = uiomove(inp, cc, uio);
 1493                 cc = n - uio->uio_resid; /* number of bytes actually moved */
 1494 #ifdef AUDIO_DEBUG
 1495                 if (error)
 1496                         printf("audio_write:(1) uiomove failed %d; cc=%d inp=%p\n",
 1497                             error, cc, inp);
 1498 #endif
 1499                 /*
 1500                  * Continue even if uiomove() failed because we may have
 1501                  * gotten a partial block.
 1502                  */
 1503 
 1504                 if (sc->sc_pparams.sw_code) {
 1505                         sc->sc_pparams.sw_code(sc->hw_hdl, inp, cc);
 1506                         /* Adjust count after the expansion. */
 1507                         cc *= sc->sc_pparams.factor;
 1508                         DPRINTFN(1, ("audio_write: expanded cc=%d\n", cc));
 1509                 }
 1510 
 1511                 einp = cb->inp + cc;
 1512                 if (einp >= cb->end)
 1513                         einp = cb->start;
 1514 
 1515                 s = splaudio();
 1516                 /*
 1517                  * This is a very suboptimal way of keeping track of
 1518                  * silence in the buffer, but it is simple.
 1519                  */
 1520                 sc->sc_sil_count = 0;
 1521 
 1522                 cb->inp = einp;
 1523                 cb->used += cc;
 1524                 /* If the interrupt routine wants the last block filled AND
 1525                  * the copy did not fill the last block completely it needs to
 1526                  * be padded.
 1527                  */
 1528                 if (cb->needfill &&
 1529                     (inp  - cb->start) / cb->blksize ==
 1530                     (einp - cb->start) / cb->blksize) {
 1531                         /* Figure out how many bytes there is to a block boundary. */
 1532                         cc = cb->blksize - (einp - cb->start) % cb->blksize;
 1533                         DPRINTF(("audio_write: partial fill %d\n", cc));
 1534                 } else
 1535                         cc = 0;
 1536                 cb->needfill = 0;
 1537                 cb->copying = 0;
 1538                 if (!sc->sc_pbus && !cb->pause) {
 1539                         saveerror = error;
 1540                         error = audiostartp(sc);
 1541                         if (saveerror != 0) {
 1542                                 /* Report the first error that occurred. */
 1543                                 error = saveerror;
 1544                         }
 1545                 }
 1546                 splx(s);
 1547                 if (cc) {
 1548                         DPRINTFN(1, ("audio_write: fill %d\n", cc));
 1549                         if (sc->sc_pparams.sw_code) {
 1550                                 int ncc = cc / sc->sc_pparams.factor;
 1551                                 audio_fill_silence(&sc->sc_pparams, einp, ncc);
 1552                                 sc->sc_pparams.sw_code(sc->hw_hdl, einp, ncc);
 1553                         } else
 1554                                 audio_fill_silence(&sc->sc_pparams, einp, cc);
 1555                 }
 1556         }
 1557         return (error);
 1558 }
 1559 
 1560 int
 1561 audio_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
 1562 {
 1563         int unit = AUDIOUNIT(dev);
 1564         struct audio_softc *sc = audio_cd.cd_devs[unit];
 1565         struct audio_hw_if *hw = sc->hw_if;
 1566         struct audio_offset *ao;
 1567         int error = 0, s, offs, fd;
 1568         int rbus, pbus;
 1569 
 1570         DPRINTF(("audio_ioctl(%d,'%c',%d)\n",
 1571             IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff));
 1572         switch (cmd) {
 1573         case FIONBIO:
 1574                 /* All handled in the upper FS layer. */
 1575                 break;
 1576 
 1577         case FIOASYNC:
 1578                 if (*(int *)addr) {
 1579                         if (sc->sc_async_audio)
 1580                                 return (EBUSY);
 1581                         sc->sc_async_audio = p;
 1582                         DPRINTF(("audio_ioctl: FIOASYNC %p\n", p));
 1583                 } else
 1584                         sc->sc_async_audio = 0;
 1585                 break;
 1586 
 1587         case AUDIO_FLUSH:
 1588                 DPRINTF(("AUDIO_FLUSH\n"));
 1589                 rbus = sc->sc_rbus;
 1590                 pbus = sc->sc_pbus;
 1591                 audio_clear(sc);
 1592                 s = splaudio();
 1593                 error = audio_initbufs(sc);
 1594                 if (error) {
 1595                         splx(s);
 1596                         return error;
 1597                 }
 1598                 sc->sc_rr.pause = 0;
 1599                 sc->sc_pr.pause = 0;
 1600                 if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_pbus && pbus)
 1601                         error = audiostartp(sc);
 1602                 if (!error &&
 1603                     (sc->sc_mode & AUMODE_RECORD) && !sc->sc_rbus && rbus)
 1604                         error = audiostartr(sc);
 1605                 splx(s);
 1606                 break;
 1607 
 1608         /*
 1609          * Number of read (write) samples dropped.  We don't know where or
 1610          * when they were dropped.
 1611          * 
 1612          * The audio_ringbuffer->drops count is the number of buffer
 1613          * sample size bytes.  Convert it to userland sample size bytes,
 1614          * then convert to samples.  There is no easy way to get the
 1615          * buffer sample size, but the userland sample size can be
 1616          * calculated with userland channels and userland precision.
 1617          *
 1618          * original formula:
 1619          *  sc->sc_rr.drops /
 1620          *  sc->sc_rparams.factor /
 1621          *  (sc->sc_rparams.channels * (sc->sc_rparams.precision / NBBY))
 1622          */
 1623         case AUDIO_RERROR:
 1624                 *(int *)addr = (sc->sc_rr.drops * NBBY) /
 1625                     (sc->sc_rparams.factor * sc->sc_rparams.channels *
 1626                     sc->sc_rparams.precision);
 1627                 break;
 1628 
 1629         case AUDIO_PERROR:
 1630                 *(int *)addr = (sc->sc_pr.drops * NBBY) /
 1631                     (sc->sc_pparams.factor * sc->sc_pparams.channels *
 1632                     sc->sc_pparams.precision);
 1633                 break;
 1634 
 1635         /*
 1636          * Offsets into buffer.
 1637          */
 1638         case AUDIO_GETIOFFS:
 1639                 s = splaudio();
 1640                 /* figure out where next DMA will start */
 1641                 ao = (struct audio_offset *)addr;
 1642                 ao->samples = sc->sc_rr.stamp;
 1643                 ao->deltablks = (sc->sc_rr.stamp - sc->sc_rr.stamp_last) / sc->sc_rr.blksize;
 1644                 sc->sc_rr.stamp_last = sc->sc_rr.stamp;
 1645                 ao->offset = sc->sc_rr.inp - sc->sc_rr.start;
 1646                 splx(s);
 1647                 break;
 1648 
 1649         case AUDIO_GETOOFFS:
 1650                 s = splaudio();
 1651                 /* figure out where next DMA will start */
 1652                 ao = (struct audio_offset *)addr;
 1653                 offs = sc->sc_pr.outp - sc->sc_pr.start + sc->sc_pr.blksize;
 1654                 if (sc->sc_pr.start + offs >= sc->sc_pr.end)
 1655                         offs = 0;
 1656                 ao->samples = sc->sc_pr.stamp;
 1657                 ao->deltablks = (sc->sc_pr.stamp - sc->sc_pr.stamp_last) / sc->sc_pr.blksize;
 1658                 sc->sc_pr.stamp_last = sc->sc_pr.stamp;
 1659                 ao->offset = offs;
 1660                 splx(s);
 1661                 break;
 1662 
 1663         /*
 1664          * How many bytes will elapse until mike hears the first
 1665          * sample of what we write next?
 1666          */
 1667         case AUDIO_WSEEK:
 1668                 *(u_long *)addr = sc->sc_pr.used / sc->sc_pparams.factor;
 1669                 break;
 1670 
 1671         case AUDIO_SETINFO:
 1672                 DPRINTF(("AUDIO_SETINFO mode=0x%x\n", sc->sc_mode));
 1673                 error = audiosetinfo(sc, (struct audio_info *)addr);
 1674                 break;
 1675 
 1676         case AUDIO_GETINFO:
 1677                 DPRINTF(("AUDIO_GETINFO\n"));
 1678                 error = audiogetinfo(sc, (struct audio_info *)addr);
 1679                 break;
 1680 
 1681         case AUDIO_DRAIN:
 1682                 DPRINTF(("AUDIO_DRAIN\n"));
 1683                 error = audio_drain(sc);
 1684                 if (!error && hw->drain)
 1685                     error = hw->drain(sc->hw_hdl);
 1686                 break;
 1687 
 1688         case AUDIO_GETDEV:
 1689                 DPRINTF(("AUDIO_GETDEV\n"));
 1690                 error = hw->getdev(sc->hw_hdl, (audio_device_t *)addr);
 1691                 break;
 1692 
 1693         case AUDIO_GETENC:
 1694                 DPRINTF(("AUDIO_GETENC\n"));
 1695                 /* Pass read/write info down to query_encoding */
 1696                 ((struct audio_encoding *)addr)->flags = sc->sc_open;
 1697                 error = hw->query_encoding(sc->hw_hdl, (struct audio_encoding *)addr);
 1698                 break;
 1699 
 1700         case AUDIO_GETFD:
 1701                 DPRINTF(("AUDIO_GETFD\n"));
 1702                 *(int *)addr = sc->sc_full_duplex;
 1703                 break;
 1704 
 1705         case AUDIO_SETFD:
 1706                 DPRINTF(("AUDIO_SETFD\n"));
 1707                 fd = *(int *)addr;
 1708                 if (hw->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX) {
 1709                         if (hw->setfd)
 1710                                 error = hw->setfd(sc->hw_hdl, fd);
 1711                         else
 1712                                 error = 0;
 1713                         if (!error)
 1714                                 sc->sc_full_duplex = fd;
 1715                 } else {
 1716                         if (fd)
 1717                                 error = ENOTTY;
 1718                         else
 1719                                 error = 0;
 1720                 }
 1721                 break;
 1722 
 1723         case AUDIO_GETPROPS:
 1724                 DPRINTF(("AUDIO_GETPROPS\n"));
 1725                 *(int *)addr = hw->get_props(sc->hw_hdl);
 1726                 break;
 1727 
 1728         default:
 1729                 DPRINTF(("audio_ioctl: unknown ioctl\n"));
 1730                 error = ENOTTY;
 1731                 break;
 1732         }
 1733         DPRINTF(("audio_ioctl(%d,'%c',%d) result %d\n",
 1734             IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff, error));
 1735         return (error);
 1736 }
 1737 
 1738 void
 1739 audio_selwakeup(struct audio_softc *sc, int play)
 1740 {
 1741         struct selinfo *si;
 1742 
 1743         si = play? &sc->sc_wsel : &sc->sc_rsel;
 1744 
 1745         audio_wakeup(play? &sc->sc_wchan : &sc->sc_rchan);
 1746         selwakeup(si);
 1747         if (sc->sc_async_audio)
 1748                 psignal(sc->sc_async_audio, SIGIO);
 1749         KNOTE(&si->si_note, 0);
 1750 }
 1751 
 1752 #define AUDIO_FILTREAD(sc) ( \
 1753     (!sc->sc_full_duplex && (sc->sc_mode & AUMODE_PLAY)) ? \
 1754     sc->sc_pr.stamp > sc->sc_wstamp : sc->sc_rr.used > sc->sc_rr.usedlow)
 1755     
 1756 #define AUDIO_FILTWRITE(sc) ( \
 1757     (!sc->sc_full_duplex && (sc->sc_mode & AUMODE_RECORD)) ||           \
 1758     (!(sc->sc_mode & AUMODE_PLAY_ALL) && sc->sc_playdrop > 0) ||        \
 1759     (sc->sc_pr.used <= sc->sc_pr.usedlow))
 1760 
 1761 int
 1762 audio_poll(dev_t dev, int events, struct proc *p)
 1763 {
 1764         int unit = AUDIOUNIT(dev);
 1765         struct audio_softc *sc = audio_cd.cd_devs[unit];
 1766         int revents = 0, s = splaudio();
 1767 
 1768         DPRINTF(("audio_poll: events=0x%x mode=%d\n", events, sc->sc_mode));
 1769 
 1770         if (events & (POLLIN | POLLRDNORM)) {
 1771                 if (AUDIO_FILTREAD(sc))
 1772                         revents |= events & (POLLIN | POLLRDNORM);
 1773         }
 1774         if (events & (POLLOUT | POLLWRNORM)) {
 1775                 if (AUDIO_FILTWRITE(sc))
 1776                         revents |= events & (POLLOUT | POLLWRNORM);
 1777         }
 1778         if (revents == 0) {
 1779                 if (events & (POLLIN | POLLRDNORM))
 1780                         selrecord(p, &sc->sc_rsel);
 1781                 if (events & (POLLOUT | POLLWRNORM))
 1782                         selrecord(p, &sc->sc_wsel);
 1783         }
 1784         splx(s);
 1785         return (revents);
 1786 }
 1787 
 1788 paddr_t
 1789 audio_mmap(dev_t dev, off_t off, int prot)
 1790 {
 1791         int s;
 1792         int unit = AUDIOUNIT(dev);
 1793         struct audio_softc *sc = audio_cd.cd_devs[unit];
 1794         struct audio_hw_if *hw = sc->hw_if;
 1795         struct audio_ringbuffer *cb;
 1796 
 1797         DPRINTF(("audio_mmap: off=%d, prot=%d\n", off, prot));
 1798 
 1799         if (!(hw->get_props(sc->hw_hdl) & AUDIO_PROP_MMAP) || !hw->mappage)
 1800                 return -1;
 1801 #if 0
 1802 /* XXX
 1803  * The idea here was to use the protection to determine if
 1804  * we are mapping the read or write buffer, but it fails.
 1805  * The VM system is broken in (at least) two ways.
 1806  * 1) If you map memory VM_PROT_WRITE you SIGSEGV
 1807  *    when writing to it, so VM_PROT_READ|VM_PROT_WRITE
 1808  *    has to be used for mmapping the play buffer.
 1809  * 2) Even if calling mmap() with VM_PROT_READ|VM_PROT_WRITE
 1810  *    audio_mmap will get called at some point with VM_PROT_READ
 1811  *    only.
 1812  * So, alas, we always map the play buffer for now.
 1813  */
 1814         if (prot == (VM_PROT_READ|VM_PROT_WRITE) ||
 1815             prot == VM_PROT_WRITE)
 1816                 cb = &sc->sc_pr;
 1817         else if (prot == VM_PROT_READ)
 1818                 cb = &sc->sc_rr;
 1819         else
 1820                 return -1;
 1821 #else
 1822         cb = &sc->sc_pr;
 1823 #endif
 1824 
 1825         if ((u_int)off >= cb->bufsize)
 1826                 return -1;
 1827         if (!cb->mmapped) {
 1828                 cb->mmapped = 1;
 1829                 if (cb == &sc->sc_pr) {
 1830                         audio_fill_silence(&sc->sc_pparams, cb->start, cb->bufsize);
 1831                         s = splaudio();
 1832                         if (!sc->sc_pbus && !sc->sc_pr.pause)
 1833                                 (void)audiostartp(sc);
 1834                         splx(s);
 1835                 } else {
 1836                         s = splaudio();
 1837                         if (!sc->sc_rbus && !sc->sc_rr.pause)
 1838                                 (void)audiostartr(sc);
 1839                         splx(s);
 1840                 }
 1841         }
 1842 
 1843         return hw->mappage(sc->hw_hdl, cb->start, off, prot);
 1844 }
 1845 
 1846 int
 1847 audiostartr(struct audio_softc *sc)
 1848 {
 1849         int error;
 1850 
 1851         DPRINTF(("audiostartr: start=%p used=%d(hi=%d) mmapped=%d\n",
 1852                  sc->sc_rr.start, sc->sc_rr.used, sc->sc_rr.usedhigh,
 1853                  sc->sc_rr.mmapped));
 1854 
 1855         if (sc->hw_if->trigger_input)
 1856                 error = sc->hw_if->trigger_input(sc->hw_hdl, sc->sc_rr.start,
 1857                     sc->sc_rr.end, sc->sc_rr.blksize,
 1858                     audio_rint, (void *)sc, &sc->sc_rparams);
 1859         else
 1860                 error = sc->hw_if->start_input(sc->hw_hdl, sc->sc_rr.start,
 1861                     sc->sc_rr.blksize, audio_rint, (void *)sc);
 1862         if (error) {
 1863                 DPRINTF(("audiostartr failed: %d\n", error));
 1864                 return error;
 1865         }
 1866         sc->sc_rbus = 1;
 1867         return 0;
 1868 }
 1869 
 1870 int
 1871 audiostartp(struct audio_softc *sc)
 1872 {
 1873         int error;
 1874 
 1875         DPRINTF(("audiostartp: start=%p used=%d(hi=%d) mmapped=%d\n",
 1876                  sc->sc_pr.start, sc->sc_pr.used, sc->sc_pr.usedhigh,
 1877                  sc->sc_pr.mmapped));
 1878 
 1879         if (!sc->sc_pr.mmapped && sc->sc_pr.used < sc->sc_pr.blksize)
 1880                 return 0;
 1881 
 1882         if (sc->hw_if->trigger_output)
 1883                 error = sc->hw_if->trigger_output(sc->hw_hdl, sc->sc_pr.start,
 1884                     sc->sc_pr.end, sc->sc_pr.blksize,
 1885                     audio_pint, (void *)sc, &sc->sc_pparams);
 1886         else
 1887                 error = sc->hw_if->start_output(sc->hw_hdl, sc->sc_pr.outp,
 1888                     sc->sc_pr.blksize, audio_pint, (void *)sc);
 1889         if (error) {
 1890                 DPRINTF(("audiostartp failed: %d\n", error));
 1891                 return error;
 1892         }
 1893         sc->sc_pbus = 1;
 1894         return 0;
 1895 }
 1896 
 1897 /*
 1898  * When the play interrupt routine finds that the write isn't keeping
 1899  * the buffer filled it will insert silence in the buffer to make up
 1900  * for this.  The part of the buffer that is filled with silence
 1901  * is kept track of in a very approximate way: it starts at sc_sil_start
 1902  * and extends sc_sil_count bytes.  If there is already silence in
 1903  * the requested area nothing is done; so when the whole buffer is
 1904  * silent nothing happens.  When the writer starts again sc_sil_count
 1905  * is set to 0.
 1906  */
 1907 /* XXX
 1908  * Putting silence into the output buffer should not really be done
 1909  * at splaudio, but there is no softaudio level to do it at yet.
 1910  */
 1911 static __inline void
 1912 audio_pint_silence(struct audio_softc *sc, struct audio_ringbuffer *cb,
 1913     u_char *inp, int cc)
 1914 {
 1915         u_char *s, *e, *p, *q;
 1916 
 1917         if (sc->sc_sil_count > 0) {
 1918                 s = sc->sc_sil_start; /* start of silence */
 1919                 e = s + sc->sc_sil_count; /* end of silence, may be beyond end */
 1920                 p = inp;        /* adjusted pointer to area to fill */
 1921                 if (p < s)
 1922                         p += cb->end - cb->start;
 1923                 q = p+cc;
 1924                 /* Check if there is already silence. */
 1925                 if (!(s <= p && p <  e &&
 1926                       s <= q && q <= e)) {
 1927                         if (s <= p)
 1928                                 sc->sc_sil_count = max(sc->sc_sil_count, q-s);
 1929                         DPRINTFN(5, ("audio_pint_silence: fill cc=%d inp=%p, count=%d size=%d\n",
 1930                             cc, inp, sc->sc_sil_count, (int)(cb->end - cb->start)));
 1931 
 1932                         if (sc->sc_pparams.sw_code) {
 1933                                 int ncc = cc / sc->sc_pparams.factor;
 1934                                 audio_fill_silence(&sc->sc_pparams, inp, ncc);
 1935                                 sc->sc_pparams.sw_code(sc->hw_hdl, inp, ncc);
 1936                         } else
 1937                                 audio_fill_silence(&sc->sc_pparams, inp, cc);
 1938 
 1939                 } else {
 1940                         DPRINTFN(5, ("audio_pint_silence: already silent cc=%d inp=%p\n", cc, inp));
 1941 
 1942                 }
 1943         } else {
 1944                 sc->sc_sil_start = inp;
 1945                 sc->sc_sil_count = cc;
 1946                 DPRINTFN(5, ("audio_pint_silence: start fill %p %d\n",
 1947                     inp, cc));
 1948 
 1949                 if (sc->sc_pparams.sw_code) {
 1950                         int ncc = cc / sc->sc_pparams.factor;
 1951                         audio_fill_silence(&sc->sc_pparams, inp, ncc);
 1952                         sc->sc_pparams.sw_code(sc->hw_hdl, inp, ncc);
 1953                 } else
 1954                         audio_fill_silence(&sc->sc_pparams, inp, cc);
 1955 
 1956         }
 1957 }
 1958 
 1959 /*
 1960  * Called from HW driver module on completion of dma output.
 1961  * Start output of new block, wrap in ring buffer if needed.
 1962  * If no more buffers to play, output zero instead.
 1963  * Do a wakeup if necessary.
 1964  */
 1965 void
 1966 audio_pint(void *v)
 1967 {
 1968         struct audio_softc *sc = v;
 1969         struct audio_hw_if *hw = sc->hw_if;
 1970         struct audio_ringbuffer *cb = &sc->sc_pr;
 1971         u_char *inp;
 1972         int cc;
 1973         int blksize;
 1974         int error;
 1975 
 1976         if (!sc->sc_open)
 1977                 return;         /* ignore interrupt if not open */
 1978 
 1979         blksize = cb->blksize;
 1980 
 1981         add_audio_randomness((long)cb);
 1982 
 1983         cb->outp += blksize;
 1984         if (cb->outp >= cb->end)
 1985                 cb->outp = cb->start;
 1986         cb->stamp += blksize;
 1987         if (cb->mmapped) {
 1988                 DPRINTFN(5, ("audio_pint: mmapped outp=%p cc=%d inp=%p\n",
 1989                     cb->outp, blksize, cb->inp));
 1990                 if (!hw->trigger_output)
 1991                         (void)hw->start_output(sc->hw_hdl, cb->outp,
 1992                             blksize, audio_pint, (void *)sc);
 1993                 return;
 1994         }
 1995 
 1996 #ifdef AUDIO_INTR_TIME
 1997         {
 1998                 struct timeval tv;
 1999                 u_long t;
 2000                 microtime(&tv);
 2001                 t = tv.tv_usec + 1000000 * tv.tv_sec;
 2002                 if (sc->sc_pnintr) {
 2003                         long lastdelta, totdelta;
 2004                         lastdelta = t - sc->sc_plastintr - sc->sc_pblktime;
 2005                         if (lastdelta > sc->sc_pblktime / 3) {
 2006                                 printf("audio: play interrupt(%d) off relative by %ld us (%lu)\n",
 2007                                     sc->sc_pnintr, lastdelta, sc->sc_pblktime);
 2008                         }
 2009                         totdelta = t - sc->sc_pfirstintr - sc->sc_pblktime * sc->sc_pnintr;
 2010                         if (totdelta > sc->sc_pblktime) {
 2011                                 printf("audio: play interrupt(%d) off absolute by %ld us (%lu) (LOST)\n",
 2012                                     sc->sc_pnintr, totdelta, sc->sc_pblktime);
 2013                                 sc->sc_pnintr++; /* avoid repeated messages */
 2014                         }
 2015                 } else
 2016                         sc->sc_pfirstintr = t;
 2017                 sc->sc_plastintr = t;
 2018                 sc->sc_pnintr++;
 2019         }
 2020 #endif
 2021 
 2022         cb->used -= blksize;
 2023         if (cb->used < blksize) {
 2024                 /* we don't have a full block to use */
 2025                 if (cb->copying) {
 2026                         /* writer is in progress, don't disturb */
 2027                         cb->needfill = 1;
 2028                         DPRINTFN(1, ("audio_pint: copying in progress\n"));
 2029                 } else {
 2030                         inp = cb->inp;
 2031                         cc = blksize - (inp - cb->start) % blksize;
 2032                         if (cb->pause)
 2033                                 cb->pdrops += cc;
 2034                         else {
 2035                                 cb->drops += cc;
 2036                                 sc->sc_playdrop += cc;
 2037                         }
 2038                         audio_pint_silence(sc, cb, inp, cc);
 2039                         inp += cc;
 2040                         if (inp >= cb->end)
 2041                                 inp = cb->start;
 2042                         cb->inp = inp;
 2043                         cb->used += cc;
 2044 
 2045                         /* Clear next block so we keep ahead of the DMA. */
 2046                         if (cb->used + cc < cb->usedhigh)
 2047                                 audio_pint_silence(sc, cb, inp, blksize);
 2048                 }
 2049         }
 2050 
 2051         DPRINTFN(5, ("audio_pint: outp=%p cc=%d\n", cb->outp, blksize));
 2052         if (!hw->trigger_output) {
 2053                 error = hw->start_output(sc->hw_hdl, cb->outp, blksize,
 2054                     audio_pint, (void *)sc);
 2055                 if (error) {
 2056                         /* XXX does this really help? */
 2057                         DPRINTF(("audio_pint restart failed: %d\n", error));
 2058                         audio_clear(sc);
 2059                 }
 2060         }
 2061 
 2062         DPRINTFN(2, ("audio_pint: mode=%d pause=%d used=%d lowat=%d\n",
 2063             sc->sc_mode, cb->pause, cb->used, cb->usedlow));
 2064         if ((sc->sc_mode & AUMODE_PLAY) && !cb->pause &&
 2065             cb->used <= cb->usedlow)
 2066                 audio_selwakeup(sc, 1);
 2067 
 2068         /* Possible to return one or more "phantom blocks" now. */
 2069         if (!sc->sc_full_duplex && sc->sc_rchan)
 2070                 audio_selwakeup(sc, 0);
 2071 }
 2072 
 2073 /*
 2074  * Called from HW driver module on completion of dma input.
 2075  * Mark it as input in the ring buffer (fiddle pointers).
 2076  * Do a wakeup if necessary.
 2077  */
 2078 void
 2079 audio_rint(void *v)
 2080 {
 2081         struct audio_softc *sc = v;
 2082         struct audio_hw_if *hw = sc->hw_if;
 2083         struct audio_ringbuffer *cb = &sc->sc_rr;
 2084         int blksize;
 2085         int error;
 2086 
 2087         if (!sc->sc_open)
 2088                 return;         /* ignore interrupt if not open */
 2089 
 2090         add_audio_randomness((long)cb);
 2091 
 2092         blksize = cb->blksize;
 2093 
 2094         cb->inp += blksize;
 2095         if (cb->inp >= cb->end)
 2096                 cb->inp = cb->start;
 2097         cb->stamp += blksize;
 2098         if (cb->mmapped) {
 2099                 DPRINTFN(2, ("audio_rint: mmapped inp=%p cc=%d\n",
 2100                     cb->inp, blksize));
 2101                 if (!hw->trigger_input)
 2102                         (void)hw->start_input(sc->hw_hdl, cb->inp, blksize,
 2103                             audio_rint, (void *)sc);
 2104                 return;
 2105         }
 2106 
 2107 #ifdef AUDIO_INTR_TIME
 2108         {
 2109                 struct timeval tv;
 2110                 u_long t;
 2111                 microtime(&tv);
 2112                 t = tv.tv_usec + 1000000 * tv.tv_sec;
 2113                 if (sc->sc_rnintr) {
 2114                         long lastdelta, totdelta;
 2115                         lastdelta = t - sc->sc_rlastintr - sc->sc_rblktime;
 2116                         if (lastdelta > sc->sc_rblktime / 5) {
 2117                                 printf("audio: record interrupt(%d) off relative by %ld us (%lu)\n",
 2118                                     sc->sc_rnintr, lastdelta, sc->sc_rblktime);
 2119                         }
 2120                         totdelta = t - sc->sc_rfirstintr - sc->sc_rblktime * sc->sc_rnintr;
 2121                         if (totdelta > sc->sc_rblktime / 2) {
 2122                                 sc->sc_rnintr++;
 2123                                 printf("audio: record interrupt(%d) off absolute by %ld us (%lu)\n",
 2124                                     sc->sc_rnintr, totdelta, sc->sc_rblktime);
 2125                                 sc->sc_rnintr++; /* avoid repeated messages */
 2126                         }
 2127                 } else
 2128                         sc->sc_rfirstintr = t;
 2129                 sc->sc_rlastintr = t;
 2130                 sc->sc_rnintr++;
 2131         }
 2132 #endif
 2133 
 2134         cb->used += blksize;
 2135         if (cb->pause) {
 2136                 DPRINTFN(1, ("audio_rint: pdrops %lu\n", cb->pdrops));
 2137                 cb->pdrops += blksize;
 2138                 cb->outp += blksize;
 2139                 cb->used -= blksize;
 2140         } else if (cb->used + blksize >= cb->usedhigh && !cb->copying) {
 2141                 DPRINTFN(1, ("audio_rint: drops %lu\n", cb->drops));
 2142                 cb->drops += blksize;
 2143                 cb->outp += blksize;
 2144                 cb->used -= blksize;
 2145         }
 2146 
 2147         DPRINTFN(2, ("audio_rint: inp=%p cc=%d used=%d\n",
 2148             cb->inp, blksize, cb->used));
 2149         if (!hw->trigger_input) {
 2150                 error = hw->start_input(sc->hw_hdl, cb->inp, blksize,
 2151                     audio_rint, (void *)sc);
 2152                 if (error) {
 2153                         /* XXX does this really help? */
 2154                         DPRINTF(("audio_rint: restart failed: %d\n", error));
 2155                         audio_clear(sc);
 2156                 }
 2157         }
 2158 
 2159         audio_selwakeup(sc, 0);
 2160 }
 2161 
 2162 int
 2163 audio_check_params(struct audio_params *p)
 2164 {
 2165         if (p->encoding == AUDIO_ENCODING_PCM16) {
 2166                 if (p->precision == 8)
 2167                         p->encoding = AUDIO_ENCODING_ULINEAR;
 2168                 else
 2169                         p->encoding = AUDIO_ENCODING_SLINEAR;
 2170         } else if (p->encoding == AUDIO_ENCODING_PCM8) {
 2171                 if (p->precision == 8)
 2172                         p->encoding = AUDIO_ENCODING_ULINEAR;
 2173                 else
 2174                         return EINVAL;
 2175         }
 2176 
 2177         if (p->encoding == AUDIO_ENCODING_SLINEAR)
 2178 #if BYTE_ORDER == LITTLE_ENDIAN
 2179                 p->encoding = AUDIO_ENCODING_SLINEAR_LE;
 2180 #else
 2181                 p->encoding = AUDIO_ENCODING_SLINEAR_BE;
 2182 #endif
 2183         if (p->encoding == AUDIO_ENCODING_ULINEAR)
 2184 #if BYTE_ORDER == LITTLE_ENDIAN
 2185                 p->encoding = AUDIO_ENCODING_ULINEAR_LE;
 2186 #else
 2187                 p->encoding = AUDIO_ENCODING_ULINEAR_BE;
 2188 #endif
 2189 
 2190         switch (p->encoding) {
 2191         case AUDIO_ENCODING_ULAW:
 2192         case AUDIO_ENCODING_ALAW:
 2193         case AUDIO_ENCODING_ADPCM:
 2194                 if (p->precision != 8)
 2195                         return (EINVAL);
 2196                 break;
 2197         case AUDIO_ENCODING_SLINEAR_LE:
 2198         case AUDIO_ENCODING_SLINEAR_BE:
 2199         case AUDIO_ENCODING_ULINEAR_LE:
 2200         case AUDIO_ENCODING_ULINEAR_BE:
 2201                 if (p->precision != 8 && p->precision != 16)
 2202                         return (EINVAL);
 2203                 break;
 2204         case AUDIO_ENCODING_MPEG_L1_STREAM:
 2205         case AUDIO_ENCODING_MPEG_L1_PACKETS:
 2206         case AUDIO_ENCODING_MPEG_L1_SYSTEM:
 2207         case AUDIO_ENCODING_MPEG_L2_STREAM:
 2208         case AUDIO_ENCODING_MPEG_L2_PACKETS:
 2209         case AUDIO_ENCODING_MPEG_L2_SYSTEM:
 2210                 break;
 2211         default:
 2212                 return (EINVAL);
 2213         }
 2214 
 2215         if (p->channels < 1 || p->channels > 8) /* sanity check # of channels */
 2216                 return (EINVAL);
 2217 
 2218         return (0);
 2219 }
 2220 
 2221 int
 2222 au_set_lr_value(struct audio_softc *sc, mixer_ctrl_t *ct, int l, int r)
 2223 {
 2224         ct->type = AUDIO_MIXER_VALUE;
 2225         ct->un.value.num_channels = 2;
 2226         ct->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l;
 2227         ct->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r;
 2228         if (sc->hw_if->set_port(sc->hw_hdl, ct) == 0)
 2229                 return 0;
 2230         ct->un.value.num_channels = 1;
 2231         ct->un.value.level[AUDIO_MIXER_LEVEL_MONO] = (l+r)/2;
 2232         return sc->hw_if->set_port(sc->hw_hdl, ct);
 2233 }
 2234 
 2235 int
 2236 au_set_gain(struct audio_softc *sc, struct au_mixer_ports *ports, int gain,
 2237     int balance)
 2238 {
 2239         mixer_ctrl_t ct;
 2240         int i, error;
 2241         int l, r;
 2242         u_int mask;
 2243         int nset;
 2244 
 2245         if (balance == AUDIO_MID_BALANCE) {
 2246                 l = r = gain;
 2247         } else if (balance < AUDIO_MID_BALANCE) {
 2248                 r = gain;
 2249                 l = (balance * gain) / AUDIO_MID_BALANCE;
 2250         } else {
 2251                 l = gain;
 2252                 r = ((AUDIO_RIGHT_BALANCE - balance) * gain)
 2253                     / AUDIO_MID_BALANCE;
 2254         }
 2255         DPRINTF(("au_set_gain: gain=%d balance=%d, l=%d r=%d\n",
 2256                  gain, balance, l, r));
 2257 
 2258         if (ports->index == -1) {
 2259         usemaster:
 2260                 if (ports->master == -1)
 2261                         return 0; /* just ignore it silently */
 2262                 ct.dev = ports->master;
 2263                 error = au_set_lr_value(sc, &ct, l, r);
 2264         } else {
 2265                 ct.dev = ports->index;
 2266                 if (ports->isenum) {
 2267                         ct.type = AUDIO_MIXER_ENUM;
 2268                         error = sc->hw_if->get_port(sc->hw_hdl, &ct);
 2269                         if (error)
 2270                                 return error;
 2271                         for(i = 0; i < ports->nports; i++) {
 2272                                 if (ports->misel[i] == ct.un.ord) {
 2273                                         ct.dev = ports->miport[i];
 2274                                         if (ct.dev == -1 ||
 2275                                             au_set_lr_value(sc, &ct, l, r))
 2276                                                 goto usemaster;
 2277                                         else
 2278                                                 break;
 2279                                 }
 2280                         }
 2281                 } else {
 2282                         ct.type = AUDIO_MIXER_SET;
 2283                         error = sc->hw_if->get_port(sc->hw_hdl, &ct);
 2284                         if (error)
 2285                                 return error;
 2286                         mask = ct.un.mask;
 2287                         nset = 0;
 2288                         for(i = 0; i < ports->nports; i++) {
 2289                                 if (ports->misel[i] & mask) {
 2290                                     ct.dev = ports->miport[i];
 2291                                     if (ct.dev != -1 &&
 2292                                         au_set_lr_value(sc, &ct, l, r) == 0)
 2293                                             nset++;
 2294                                 }
 2295                         }
 2296                         if (nset == 0)
 2297                                 goto usemaster;
 2298                 }
 2299         }
 2300         if (!error)
 2301                 mixer_signal(sc);
 2302         return error;
 2303 }
 2304 
 2305 int
 2306 au_get_lr_value(struct audio_softc *sc, mixer_ctrl_t *ct, int *l, int *r)
 2307 {
 2308         int error;
 2309 
 2310         ct->un.value.num_channels = 2;
 2311         if (sc->hw_if->get_port(sc->hw_hdl, ct) == 0) {
 2312                 *l = ct->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
 2313                 *r = ct->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
 2314         } else {
 2315                 ct->un.value.num_channels = 1;
 2316                 error = sc->hw_if->get_port(sc->hw_hdl, ct);
 2317                 if (error)
 2318                         return error;
 2319                 *r = *l = ct->un.value.level[AUDIO_MIXER_LEVEL_MONO];
 2320         }
 2321         return 0;
 2322 }
 2323 
 2324 void
 2325 au_get_gain(struct audio_softc *sc, struct au_mixer_ports *ports, u_int *pgain,
 2326     u_char *pbalance)
 2327 {
 2328         mixer_ctrl_t ct;
 2329         int i, l, r, n;
 2330         int lgain = AUDIO_MAX_GAIN/2, rgain = AUDIO_MAX_GAIN/2;
 2331 
 2332         if (ports->index == -1) {
 2333         usemaster:
 2334                 if (ports->master == -1)
 2335                         goto bad;
 2336                 ct.dev = ports->master;
 2337                 ct.type = AUDIO_MIXER_VALUE;
 2338                 if (au_get_lr_value(sc, &ct, &lgain, &rgain))
 2339                         goto bad;
 2340         } else {
 2341                 ct.dev = ports->index;
 2342                 if (ports->isenum) {
 2343                         ct.type = AUDIO_MIXER_ENUM;
 2344                         if (sc->hw_if->get_port(sc->hw_hdl, &ct))
 2345                                 goto bad;
 2346                         ct.type = AUDIO_MIXER_VALUE;
 2347                         for(i = 0; i < ports->nports; i++) {
 2348                                 if (ports->misel[i] == ct.un.ord) {
 2349                                         ct.dev = ports->miport[i];
 2350                                         if (ct.dev == -1 ||
 2351                                             au_get_lr_value(sc, &ct,
 2352                                                             &lgain, &rgain))
 2353                                                 goto usemaster;
 2354                                         else
 2355                                                 break;
 2356                                 }
 2357                         }
 2358                 } else {
 2359                         ct.type = AUDIO_MIXER_SET;
 2360                         if (sc->hw_if->get_port(sc->hw_hdl, &ct))
 2361                                 goto bad;
 2362                         ct.type = AUDIO_MIXER_VALUE;
 2363                         lgain = rgain = n = 0;
 2364                         for(i = 0; i < ports->nports; i++) {
 2365                                 if (ports->misel[i] & ct.un.mask) {
 2366                                         ct.dev = ports->miport[i];
 2367                                         if (ct.dev == -1 ||
 2368                                             au_get_lr_value(sc, &ct, &l, &r))
 2369                                                 goto usemaster;
 2370                                         else {
 2371                                                 lgain += l;
 2372                                                 rgain += r;
 2373                                                 n++;
 2374                                         }
 2375                                 }
 2376                         }
 2377                         if (n != 0) {
 2378                                 lgain /= n;
 2379                                 rgain /= n;
 2380                         }
 2381                 }
 2382         }
 2383 bad:
 2384         if (lgain == rgain) {   /* handles lgain==rgain==0 */
 2385                 *pgain = lgain;
 2386                 *pbalance = AUDIO_MID_BALANCE;
 2387         } else if (lgain < rgain) {
 2388                 *pgain = rgain;
 2389                 *pbalance = (AUDIO_MID_BALANCE * lgain) / rgain;
 2390         } else /* lgain > rgain */ {
 2391                 *pgain = lgain;
 2392                 *pbalance = AUDIO_RIGHT_BALANCE -
 2393                             (AUDIO_MID_BALANCE * rgain) / lgain;
 2394         }
 2395 }
 2396 
 2397 int
 2398 au_set_port(struct audio_softc *sc, struct au_mixer_ports *ports, u_int port)
 2399 {
 2400         mixer_ctrl_t ct;
 2401         int i, error;
 2402 
 2403         if (port == 0)  /* allow this special case */
 2404                 return 0;
 2405 
 2406         if (ports->index == -1)
 2407                 return EINVAL;
 2408         ct.dev = ports->index;
 2409         if (ports->isenum) {
 2410                 if (port & (port-1))
 2411                         return EINVAL; /* Only one port allowed */
 2412                 ct.type = AUDIO_MIXER_ENUM;
 2413                 error = EINVAL;
 2414                 for(i = 0; i < ports->nports; i++)
 2415                         if (ports->aumask[i] == port) {
 2416                                 ct.un.ord = ports->misel[i];
 2417                                 error = sc->hw_if->set_port(sc->hw_hdl, &ct);
 2418                                 break;
 2419                         }
 2420         } else {
 2421                 ct.type = AUDIO_MIXER_SET;
 2422                 ct.un.mask = 0;
 2423                 for(i = 0; i < ports->nports; i++)
 2424                         if (ports->aumask[i] & port)
 2425                                 ct.un.mask |= ports->misel[i];
 2426                 if (port != 0 && ct.un.mask == 0)
 2427                         error = EINVAL;
 2428                 else
 2429                         error = sc->hw_if->set_port(sc->hw_hdl, &ct);
 2430         }
 2431         if (!error)
 2432                 mixer_signal(sc);
 2433         return error;
 2434 }
 2435 
 2436 int
 2437 au_get_port(struct audio_softc *sc, struct au_mixer_ports *ports)
 2438 {
 2439         mixer_ctrl_t ct;
 2440         int i, aumask;
 2441 
 2442         if (ports->index == -1)
 2443                 return 0;
 2444         ct.dev = ports->index;
 2445         ct.type = ports->isenum ? AUDIO_MIXER_ENUM : AUDIO_MIXER_SET;
 2446         if (sc->hw_if->get_port(sc->hw_hdl, &ct))
 2447                 return 0;
 2448         aumask = 0;
 2449         if (ports->isenum) {
 2450                 for(i = 0; i < ports->nports; i++)
 2451                         if (ct.un.ord == ports->misel[i])
 2452                                 aumask = ports->aumask[i];
 2453         } else {
 2454                 for(i = 0; i < ports->nports; i++)
 2455                         if (ct.un.mask & ports->misel[i])
 2456                                 aumask |= ports->aumask[i];
 2457         }
 2458         return aumask;
 2459 }
 2460 
 2461 int
 2462 audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
 2463 {
 2464         struct audio_prinfo *r = &ai->record, *p = &ai->play;
 2465         int cleared;
 2466         int s, setmode, modechange = 0;
 2467         int error;
 2468         struct audio_hw_if *hw = sc->hw_if;
 2469         struct audio_params pp, rp;
 2470         int np, nr;
 2471         unsigned int blks;
 2472         int oldpblksize, oldrblksize;
 2473         int rbus, pbus;
 2474         u_int gain;
 2475         u_char balance;
 2476 
 2477         if (hw == 0)            /* HW has not attached */
 2478                 return(ENXIO);
 2479 
 2480         rbus = sc->sc_rbus;
 2481         pbus = sc->sc_pbus;
 2482         error = 0;
 2483         cleared = 0;
 2484 
 2485         pp = sc->sc_pparams;    /* Temporary encoding storage in */
 2486         rp = sc->sc_rparams;    /* case setting the modes fails. */
 2487         nr = np = 0;
 2488 
 2489         if (p->sample_rate != ~0) {
 2490                 pp.sample_rate = p->sample_rate;
 2491                 np++;
 2492         }
 2493         if (r->sample_rate != ~0) {
 2494                 rp.sample_rate = r->sample_rate;
 2495                 nr++;
 2496         }
 2497         if (p->encoding != ~0) {
 2498                 pp.encoding = p->encoding;
 2499                 np++;
 2500         }
 2501         if (r->encoding != ~0) {
 2502                 rp.encoding = r->encoding;
 2503                 nr++;
 2504         }
 2505         if (p->precision != ~0) {
 2506                 pp.precision = p->precision;
 2507                 np++;
 2508         }
 2509         if (r->precision != ~0) {
 2510                 rp.precision = r->precision;
 2511                 nr++;
 2512         }
 2513         if (p->channels != ~0) {
 2514                 pp.channels = p->channels;
 2515                 np++;
 2516         }
 2517         if (r->channels != ~0) {
 2518                 rp.channels = r->channels;
 2519                 nr++;
 2520         }
 2521 #ifdef AUDIO_DEBUG
 2522         if (audiodebug && nr)
 2523             audio_print_params("Setting record params", &rp);
 2524         if (audiodebug && np)
 2525             audio_print_params("Setting play params", &pp);
 2526 #endif
 2527         if (nr && (error = audio_check_params(&rp)))
 2528                 return error;
 2529         if (np && (error = audio_check_params(&pp)))
 2530                 return error;
 2531         setmode = 0;
 2532         if (nr) {
 2533                 if (!cleared)
 2534                         audio_clear(sc);
 2535                 modechange = cleared = 1;
 2536                 rp.sw_code = 0;
 2537                 rp.factor = 1;
 2538                 setmode |= AUMODE_RECORD;
 2539         }
 2540         if (np) {
 2541                 if (!cleared)
 2542                         audio_clear(sc);
 2543                 modechange = cleared = 1;
 2544                 pp.sw_code = 0;
 2545                 pp.factor = 1;
 2546                 setmode |= AUMODE_PLAY;
 2547         }
 2548 
 2549         if (ai->mode != ~0) {
 2550                 if (!cleared)
 2551                         audio_clear(sc);
 2552                 modechange = cleared = 1;
 2553                 sc->sc_mode = ai->mode;
 2554                 if (sc->sc_mode & AUMODE_PLAY_ALL)
 2555                         sc->sc_mode |= AUMODE_PLAY;
 2556                 if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_full_duplex)
 2557                         /* Play takes precedence */
 2558                         sc->sc_mode &= ~AUMODE_RECORD;
 2559         }
 2560 
 2561         if (modechange) {
 2562                 int indep = hw->get_props(sc->hw_hdl) & AUDIO_PROP_INDEPENDENT;
 2563                 if (!indep) {
 2564                         if (setmode == AUMODE_RECORD)
 2565                                 pp = rp;
 2566                         else if (setmode == AUMODE_PLAY)
 2567                                 rp = pp;
 2568                 }
 2569                 error = hw->set_params(sc->hw_hdl, setmode,
 2570                     sc->sc_mode & (AUMODE_PLAY | AUMODE_RECORD), &pp, &rp);
 2571                 if (error)
 2572                         return (error);
 2573                 if (!indep) {
 2574                         if (setmode == AUMODE_RECORD) {
 2575                                 pp.sample_rate = rp.sample_rate;
 2576                                 pp.encoding    = rp.encoding;
 2577                                 pp.channels    = rp.channels;
 2578                                 pp.precision   = rp.precision;
 2579                         } else if (setmode == AUMODE_PLAY) {
 2580                                 rp.sample_rate = pp.sample_rate;
 2581                                 rp.encoding    = pp.encoding;
 2582                                 rp.channels    = pp.channels;
 2583                                 rp.precision   = pp.precision;
 2584                         }
 2585                 }
 2586                 sc->sc_rparams = rp;
 2587                 sc->sc_pparams = pp;
 2588         }
 2589 
 2590         oldpblksize = sc->sc_pr.blksize;
 2591         oldrblksize = sc->sc_rr.blksize;
 2592         /* Play params can affect the record params, so recalculate blksize. */
 2593         if (nr || np) {
 2594                 audio_calc_blksize(sc, AUMODE_RECORD);
 2595                 audio_calc_blksize(sc, AUMODE_PLAY);
 2596         }
 2597 #ifdef AUDIO_DEBUG
 2598         if (audiodebug > 1 && nr)
 2599             audio_print_params("After setting record params", &sc->sc_rparams);
 2600         if (audiodebug > 1 && np)
 2601             audio_print_params("After setting play params", &sc->sc_pparams);
 2602 #endif
 2603 
 2604         if (p->port != ~0) {
 2605                 if (!cleared)
 2606                         audio_clear(sc);
 2607                 cleared = 1;
 2608 
 2609                 error = au_set_port(sc, &sc->sc_outports, p->port);
 2610                 if (error)
 2611                         return(error);
 2612         }
 2613         if (r->port != ~0) {
 2614                 if (!cleared)
 2615                         audio_clear(sc);
 2616                 cleared = 1;
 2617 
 2618                 error = au_set_port(sc, &sc->sc_inports, r->port);
 2619                 if (error)
 2620                         return(error);
 2621         }
 2622         if (p->gain != ~0) {
 2623                 au_get_gain(sc, &sc->sc_outports, &gain, &balance);
 2624                 error = au_set_gain(sc, &sc->sc_outports, p->gain, balance);
 2625                 if (error)
 2626                         return(error);
 2627         }
 2628         if (r->gain != ~0) {
 2629                 au_get_gain(sc, &sc->sc_inports, &gain, &balance);
 2630                 error = au_set_gain(sc, &sc->sc_inports, r->gain, balance);
 2631                 if (error)
 2632                         return(error);
 2633         }
 2634 
 2635         if (p->balance != (u_char)~0) {
 2636                 au_get_gain(sc, &sc->sc_outports, &gain, &balance);
 2637                 error = au_set_gain(sc, &sc->sc_outports, gain, p->balance);
 2638                 if (error)
 2639                         return(error);
 2640         }
 2641         if (r->balance != (u_char)~0) {
 2642                 au_get_gain(sc, &sc->sc_inports, &gain, &balance);
 2643                 error = au_set_gain(sc, &sc->sc_inports, gain, r->balance);
 2644                 if (error)
 2645                         return(error);
 2646         }
 2647 
 2648         if (ai->monitor_gain != ~0 &&
 2649             sc->sc_monitor_port != -1) {
 2650                 mixer_ctrl_t ct;
 2651 
 2652                 ct.dev = sc->sc_monitor_port;
 2653                 ct.type = AUDIO_MIXER_VALUE;
 2654                 ct.un.value.num_channels = 1;
 2655                 ct.un.value.level[AUDIO_MIXER_LEVEL_MONO] = ai->monitor_gain;
 2656                 error = sc->hw_if->set_port(sc->hw_hdl, &ct);
 2657                 if (error)
 2658                         return(error);
 2659         }
 2660 
 2661         if (ai->blocksize != ~0) {
 2662                 /* Block size specified explicitly. */
 2663                 if (!cleared)
 2664                         audio_clear(sc);
 2665                 cleared = 1;
 2666 
 2667                 if (ai->blocksize == 0) {
 2668                         audio_calc_blksize(sc, AUMODE_RECORD);
 2669                         audio_calc_blksize(sc, AUMODE_PLAY);
 2670                         sc->sc_blkset = 0;
 2671                 } else {
 2672                         int rbs = ai->blocksize * sc->sc_rparams.factor;
 2673                         int pbs = ai->blocksize * sc->sc_pparams.factor;
 2674                         if (hw->round_blocksize) {
 2675                                 rbs = hw->round_blocksize(sc->hw_hdl, rbs);
 2676                                 pbs = hw->round_blocksize(sc->hw_hdl, pbs);
 2677                         }
 2678                         sc->sc_rr.blksize = rbs;
 2679                         sc->sc_pr.blksize = pbs;
 2680                         sc->sc_blkset = 1;
 2681                 }
 2682         }
 2683 
 2684         if (ai->mode != ~0) {
 2685                 if (sc->sc_mode & AUMODE_PLAY)
 2686                         audio_init_play(sc);
 2687                 if (sc->sc_mode & AUMODE_RECORD)
 2688                         audio_init_record(sc);
 2689         }
 2690 
 2691         if (hw->commit_settings) {
 2692                 error = hw->commit_settings(sc->hw_hdl);
 2693                 if (error)
 2694                         return (error);
 2695         }
 2696 
 2697         if (cleared) {
 2698                 s = splaudio();
 2699                 error = audio_initbufs(sc);
 2700                 if (error) goto err;
 2701                 if (sc->sc_pr.blksize != oldpblksize ||
 2702                     sc->sc_rr.blksize != oldrblksize)
 2703                         audio_calcwater(sc);
 2704                 if ((sc->sc_mode & AUMODE_PLAY) &&
 2705                     pbus && !sc->sc_pbus && !sc->sc_pr.pause)
 2706                         error = audiostartp(sc);
 2707                 if (!error &&
 2708                     (sc->sc_mode & AUMODE_RECORD) &&
 2709                     rbus && !sc->sc_rbus && !sc->sc_rr.pause)
 2710                         error = audiostartr(sc);
 2711         err:
 2712                 splx(s);
 2713                 if (error)
 2714                         return error;
 2715         }
 2716 
 2717         /* Change water marks after initializing the buffers. */
 2718         if (ai->hiwat != ~0) {
 2719                 blks = ai->hiwat;
 2720                 if (blks > sc->sc_pr.maxblks)
 2721                         blks = sc->sc_pr.maxblks;
 2722                 if (blks < 2)
 2723                         blks = 2;
 2724                 sc->sc_pr.usedhigh = blks * sc->sc_pr.blksize;
 2725         }
 2726         if (ai->lowat != ~0) {
 2727                 blks = ai->lowat;
 2728                 if (blks > sc->sc_pr.maxblks - 1)
 2729                         blks = sc->sc_pr.maxblks - 1;
 2730                 sc->sc_pr.usedlow = blks * sc->sc_pr.blksize;
 2731         }
 2732         if (ai->hiwat != ~0 || ai->lowat != ~0) {
 2733                 if (sc->sc_pr.usedlow > sc->sc_pr.usedhigh - sc->sc_pr.blksize)
 2734                         sc->sc_pr.usedlow = sc->sc_pr.usedhigh - sc->sc_pr.blksize;
 2735         }
 2736 
 2737         if (p->pause != (u_char)~0) {
 2738                 sc->sc_pr.pause = p->pause;
 2739                 if (!p->pause && !sc->sc_pbus && (sc->sc_mode & AUMODE_PLAY)) {
 2740                         s = splaudio();
 2741                         error = audiostartp(sc);
 2742                         splx(s);
 2743                         if (error)
 2744                                 return error;
 2745                 }
 2746         }
 2747         if (r->pause != (u_char)~0) {
 2748                 sc->sc_rr.pause = r->pause;
 2749                 if (!r->pause && !sc->sc_rbus && (sc->sc_mode & AUMODE_RECORD)) {
 2750                         s = splaudio();
 2751                         error = audiostartr(sc);
 2752                         splx(s);
 2753                         if (error)
 2754                                 return error;
 2755                 }
 2756         }
 2757 
 2758         return (0);
 2759 }
 2760 
 2761 int
 2762 audiogetinfo(struct audio_softc *sc, struct audio_info *ai)
 2763 {
 2764         struct audio_prinfo *r = &ai->record, *p = &ai->play;
 2765         struct audio_hw_if *hw = sc->hw_if;
 2766 
 2767         if (hw == 0)            /* HW has not attached */
 2768                 return(ENXIO);
 2769 
 2770         p->sample_rate = sc->sc_pparams.sample_rate;
 2771         r->sample_rate = sc->sc_rparams.sample_rate;
 2772         p->channels = sc->sc_pparams.channels;
 2773         r->channels = sc->sc_rparams.channels;
 2774         p->precision = sc->sc_pparams.precision;
 2775         r->precision = sc->sc_rparams.precision;
 2776         p->encoding = sc->sc_pparams.encoding;
 2777         r->encoding = sc->sc_rparams.encoding;
 2778 
 2779         r->port = au_get_port(sc, &sc->sc_inports);
 2780         p->port = au_get_port(sc, &sc->sc_outports);
 2781 
 2782         r->avail_ports = sc->sc_inports.allports;
 2783         p->avail_ports = sc->sc_outports.allports;
 2784 
 2785         au_get_gain(sc, &sc->sc_inports,  &r->gain, &r->balance);
 2786         au_get_gain(sc, &sc->sc_outports, &p->gain, &p->balance);
 2787 
 2788         if (sc->sc_monitor_port != -1) {
 2789                 mixer_ctrl_t ct;
 2790 
 2791                 ct.dev = sc->sc_monitor_port;
 2792                 ct.type = AUDIO_MIXER_VALUE;
 2793                 ct.un.value.num_channels = 1;
 2794                 if (sc->hw_if->get_port(sc->hw_hdl, &ct))
 2795                         ai->monitor_gain = 0;
 2796                 else
 2797                         ai->monitor_gain =
 2798                                 ct.un.value.level[AUDIO_MIXER_LEVEL_MONO];
 2799         } else
 2800                 ai->monitor_gain = 0;
 2801 
 2802         p->seek = sc->sc_pr.used / sc->sc_pparams.factor;
 2803         r->seek = sc->sc_rr.used / sc->sc_rparams.factor;
 2804 
 2805         p->samples = sc->sc_pr.stamp - sc->sc_pr.drops;
 2806         r->samples = sc->sc_rr.stamp - sc->sc_rr.drops;
 2807 
 2808         p->eof = sc->sc_eof;
 2809         r->eof = 0;
 2810 
 2811         p->pause = sc->sc_pr.pause;
 2812         r->pause = sc->sc_rr.pause;
 2813 
 2814         p->error = sc->sc_pr.drops != 0;
 2815         r->error = sc->sc_rr.drops != 0;
 2816 
 2817         p->waiting = r->waiting = 0;            /* open never hangs */
 2818 
 2819         p->open = (sc->sc_open & AUOPEN_WRITE) != 0;
 2820         r->open = (sc->sc_open & AUOPEN_READ) != 0;
 2821 
 2822         p->active = sc->sc_pbus;
 2823         r->active = sc->sc_rbus;
 2824 
 2825         p->buffer_size = sc->sc_pr.bufsize / sc->sc_pparams.factor;
 2826         r->buffer_size = sc->sc_rr.bufsize / sc->sc_rparams.factor;
 2827 
 2828         if ((ai->blocksize = sc->sc_pr.blksize / sc->sc_pparams.factor) != 0) {
 2829                 ai->hiwat = sc->sc_pr.usedhigh / sc->sc_pr.blksize;
 2830                 ai->lowat = sc->sc_pr.usedlow / sc->sc_pr.blksize;
 2831         } else {
 2832                 ai->hiwat = ai->lowat = 0;
 2833         }
 2834         ai->mode = sc->sc_mode;
 2835 
 2836         return (0);
 2837 }
 2838 
 2839 /*
 2840  * Mixer driver
 2841  */
 2842 int
 2843 mixer_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
 2844     struct proc *p)
 2845 {
 2846         DPRINTF(("mixer_open: dev=0x%x flags=0x%x sc=%p\n", dev, flags, sc));
 2847 
 2848         return (0);
 2849 }
 2850 
 2851 /*
 2852  * Remove a process from those to be signalled on mixer activity.
 2853  */
 2854 static void
 2855 mixer_remove(struct audio_softc *sc, struct proc *p)
 2856 {
 2857         struct mixer_asyncs **pm, *m;
 2858 
 2859         for(pm = &sc->sc_async_mixer; *pm; pm = &(*pm)->next) {
 2860                 if ((*pm)->proc == p) {
 2861                         m = *pm;
 2862                         *pm = m->next;
 2863                         free(m, M_DEVBUF);
 2864                         return;
 2865                 }
 2866         }
 2867 }
 2868 
 2869 /*
 2870  * Signal all processes waitinf for the mixer.
 2871  */
 2872 static void
 2873 mixer_signal(struct audio_softc *sc)
 2874 {
 2875         struct mixer_asyncs *m;
 2876 
 2877         for(m = sc->sc_async_mixer; m; m = m->next)
 2878                 psignal(m->proc, SIGIO);
 2879 }
 2880 
 2881 /*
 2882  * Close a mixer device
 2883  */
 2884 /* ARGSUSED */
 2885 int
 2886 mixer_close(dev_t dev, int flags, int ifmt, struct proc *p)
 2887 {
 2888         int unit = AUDIOUNIT(dev);
 2889         struct audio_softc *sc = audio_cd.cd_devs[unit];
 2890 
 2891         DPRINTF(("mixer_close: unit %d\n", AUDIOUNIT(dev)));
 2892 
 2893         mixer_remove(sc, p);
 2894 
 2895         return (0);
 2896 }
 2897 
 2898 int
 2899 mixer_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
 2900 {
 2901         int unit = AUDIOUNIT(dev);
 2902         struct audio_softc *sc = audio_cd.cd_devs[unit];
 2903         struct audio_hw_if *hw = sc->hw_if;
 2904         int error = EINVAL;
 2905 
 2906         DPRINTF(("mixer_ioctl(%d,'%c',%d)\n",
 2907                  IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff));
 2908 
 2909         switch (cmd) {
 2910         case FIOASYNC:
 2911                 mixer_remove(sc, p); /* remove old entry */
 2912                 if (*(int *)addr) {
 2913                         struct mixer_asyncs *ma;
 2914                         ma = malloc(sizeof (struct mixer_asyncs),
 2915                             M_DEVBUF, M_WAITOK);
 2916                         ma->next = sc->sc_async_mixer;
 2917                         ma->proc = p;
 2918                         sc->sc_async_mixer = ma;
 2919                 }
 2920                 error = 0;
 2921                 break;
 2922 
 2923         case AUDIO_GETDEV:
 2924                 DPRINTF(("AUDIO_GETDEV\n"));
 2925                 error = hw->getdev(sc->hw_hdl, (audio_device_t *)addr);
 2926                 break;
 2927 
 2928         case AUDIO_MIXER_DEVINFO:
 2929                 DPRINTF(("AUDIO_MIXER_DEVINFO\n"));
 2930                 ((mixer_devinfo_t *)addr)->un.v.delta = 0; /* default */
 2931                 error = hw->query_devinfo(sc->hw_hdl, (mixer_devinfo_t *)addr);
 2932                 break;
 2933 
 2934         case AUDIO_MIXER_READ:
 2935                 DPRINTF(("AUDIO_MIXER_READ\n"));
 2936                 error = hw->get_port(sc->hw_hdl, (mixer_ctrl_t *)addr);
 2937                 break;
 2938 
 2939         case AUDIO_MIXER_WRITE:
 2940                 if (!(flag & FWRITE))
 2941                         return (EACCES);
 2942                 DPRINTF(("AUDIO_MIXER_WRITE\n"));
 2943                 error = hw->set_port(sc->hw_hdl, (mixer_ctrl_t *)addr);
 2944                 if (!error && hw->commit_settings)
 2945                         error = hw->commit_settings(sc->hw_hdl);
 2946                 if (!error)
 2947                         mixer_signal(sc);
 2948                 break;
 2949 
 2950         default:
 2951                 error = ENOTTY;
 2952                 break;
 2953         }
 2954         DPRINTF(("mixer_ioctl(%d,'%c',%d) result %d\n",
 2955                  IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff, error));
 2956         return (error);
 2957 }
 2958 #endif
 2959 
 2960 int
 2961 audiokqfilter(dev_t dev, struct knote *kn)
 2962 {
 2963         int unit = AUDIOUNIT(dev);
 2964         struct audio_softc *sc = audio_cd.cd_devs[unit];
 2965         struct klist *klist;
 2966         int s;
 2967 
 2968         switch (kn->kn_filter) {
 2969         case EVFILT_READ:
 2970                 klist = &sc->sc_rsel.si_note;
 2971                 kn->kn_fop = &audioread_filtops;
 2972                 break;
 2973         case EVFILT_WRITE:
 2974                 klist = &sc->sc_wsel.si_note;
 2975                 kn->kn_fop = &audiowrite_filtops;
 2976                 break;
 2977         default:
 2978                 return (1);
 2979         }
 2980         kn->kn_hook = (void *)sc;
 2981 
 2982         s = splaudio();
 2983         SLIST_INSERT_HEAD(klist, kn, kn_selnext);
 2984         splx(s);
 2985 
 2986         return (0);
 2987 }
 2988 
 2989 void
 2990 filt_audiordetach(struct knote *kn)
 2991 {
 2992         struct audio_softc *sc = (struct audio_softc *)kn->kn_hook;
 2993         int s = splaudio();
 2994 
 2995         SLIST_REMOVE(&sc->sc_rsel.si_note, kn, knote, kn_selnext);
 2996         splx(s);
 2997 }
 2998 
 2999 int
 3000 filt_audioread(struct knote *kn, long hint)
 3001 {
 3002         struct audio_softc *sc = (struct audio_softc *)kn->kn_hook;
 3003 
 3004         return AUDIO_FILTREAD(sc);
 3005 }
 3006 
 3007 void
 3008 filt_audiowdetach(struct knote *kn)
 3009 {
 3010         struct audio_softc *sc = (struct audio_softc *)kn->kn_hook;
 3011         int s = splaudio();
 3012 
 3013         SLIST_REMOVE(&sc->sc_wsel.si_note, kn, knote, kn_selnext);
 3014         splx(s);
 3015 }
 3016 
 3017 int
 3018 filt_audiowrite(struct knote *kn, long hint)
 3019 {
 3020         struct audio_softc *sc = (struct audio_softc *)kn->kn_hook;
 3021 
 3022         return AUDIO_FILTWRITE(sc);
 3023 }
 3024 
 3025 #if NAUDIO > 0 && NWSKBD > 0
 3026 int
 3027 wskbd_get_mixerdev(struct audio_softc *sc, int dir, int *index)
 3028 {
 3029         mixer_devinfo_t mi;
 3030         int mixer_class;
 3031         int error;
 3032 
 3033         /* looking for ``outputs'' */
 3034         for (mi.index = 0; ; mi.index++) {
 3035                 error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
 3036                 if (error != 0)
 3037                         return (-1);
 3038 
 3039                 if (mi.type == AUDIO_MIXER_CLASS &&
 3040                     strcmp(mi.label.name, AudioCoutputs) == 0) {
 3041                         mixer_class = mi.mixer_class;
 3042                         break;
 3043                 }
 3044         }
 3045 
 3046         /*
 3047          * looking for ``outputs.master''
 3048          * start mi.index from 0 because ''outputs.master'' can precede
 3049          * ''outputs''.
 3050          */
 3051         for (mi.index = 0; ; mi.index++) {
 3052                 error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
 3053                 if (error != 0)
 3054                         return (-1);
 3055 
 3056                 if (mi.type == AUDIO_MIXER_VALUE &&
 3057                     mi.mixer_class == mixer_class &&
 3058                     strcmp(mi.label.name, AudioNmaster) == 0) {
 3059                         if (dir == 0) {
 3060                                 /* looking for ``outputs.master.mute'' */
 3061                                 if (mi.next < 0)
 3062                                         return (-1);
 3063 
 3064                                 mi.index = mi.next;
 3065                                 error = sc->hw_if->query_devinfo(sc->hw_hdl,
 3066                                     &mi);
 3067                                 if (error != 0)
 3068                                         return (-1);
 3069 
 3070                                 if (mi.type != AUDIO_MIXER_ENUM ||
 3071                                     strcmp(mi.label.name, AudioNmute) != 0)
 3072                                         return (-1);
 3073                         }
 3074 
 3075                         *index = mi.index;
 3076                         return (0);
 3077                 }
 3078         }
 3079 
 3080         return (-1);
 3081 }
 3082 
 3083 int
 3084 wskbd_set_mixervolume(long dir)
 3085 {
 3086         struct audio_softc *sc;
 3087         mixer_devinfo_t mi;
 3088         mixer_ctrl_t ct;
 3089         int l, r;
 3090         int error;
 3091 
 3092         if (audio_cd.cd_ndevs == 0 || (sc = audio_cd.cd_devs[0]) == NULL) {
 3093                 DPRINTF(("wskbd_set_mixervolume: audio_cd\n"));
 3094                 return (ENXIO);
 3095         }
 3096 
 3097         error = wskbd_get_mixerdev(sc, dir, &ct.dev);
 3098         if (error == -1) {
 3099                 DPRINTF(("wskbd_set_mixervolume: wskbd_get_mixerdev\n"));
 3100                 return (ENXIO);
 3101         }
 3102 
 3103         if (dir == 0) {
 3104                 /*
 3105                  * Mute.
 3106                  * Use mixer_ioctl() for writing. It does many things for us.
 3107                  */
 3108                 ct.type = AUDIO_MIXER_ENUM;
 3109                 error = sc->hw_if->get_port(sc->hw_hdl, &ct);
 3110                 if (error != 0) {
 3111                         DPRINTF(("wskbd_set_mixervolume:"
 3112                             " get_port: %d\n", error));
 3113                         return (error);
 3114                 }
 3115 
 3116                 ct.un.ord = !ct.un.ord; /* toggle */
 3117 
 3118                 error = mixer_ioctl(MIXER_DEVICE,
 3119                     AUDIO_MIXER_WRITE, (caddr_t)&ct, FWRITE, curproc);
 3120                 if (error != 0) {
 3121                         DPRINTF(("wskbd_set_mixervolume:"
 3122                             " mixer_ioctl: %d\n", error));
 3123                         return (error);
 3124                 }
 3125         } else {
 3126                 mi.index = ct.dev;
 3127                 error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
 3128                 if (error != 0) {
 3129                         DPRINTF(("wskbd_set_mixervolume:"
 3130                             " query_devinfo: %d\n", error));
 3131                         return (error);
 3132                 }
 3133 
 3134                 ct.type = AUDIO_MIXER_VALUE;
 3135 
 3136                 error = au_get_lr_value(sc, &ct, &l, &r);
 3137                 if (error != 0) {
 3138                         DPRINTF(("wskbd_set_mixervolume:"
 3139                             " au_get_lr_value: %d\n", error));
 3140                         return (error);
 3141                 }
 3142 
 3143                 if (dir > 0) {
 3144                         /*
 3145                          * Raise volume
 3146                          */
 3147                         if (l > AUDIO_MAX_GAIN - mi.un.v.delta)
 3148                                 l = AUDIO_MAX_GAIN;
 3149                         else
 3150                                 l += mi.un.v.delta;
 3151 
 3152                         if (r > AUDIO_MAX_GAIN - mi.un.v.delta)
 3153                                 r = AUDIO_MAX_GAIN;
 3154                         else
 3155                                 r += mi.un.v.delta;
 3156 
 3157                 } else {
 3158                         /*
 3159                          * Lower volume
 3160                          */
 3161                         if (l < AUDIO_MIN_GAIN + mi.un.v.delta)
 3162                                 l = AUDIO_MIN_GAIN;
 3163                         else
 3164                                 l -= mi.un.v.delta;
 3165 
 3166                         if (r < AUDIO_MIN_GAIN + mi.un.v.delta)
 3167                                 r = AUDIO_MIN_GAIN;
 3168                         else
 3169                                 r -= mi.un.v.delta;
 3170                 }
 3171 
 3172                 error = au_set_lr_value(sc, &ct, l, r);
 3173                 if (error != 0) {
 3174                         DPRINTF(("wskbd_set_mixervolume:"
 3175                             " au_set_lr_value: %d\n", error));
 3176                         return (error);
 3177                 }
 3178         }
 3179 
 3180         return (0);
 3181 }
 3182 #endif /* NAUDIO > 0 && NWSKBD > 0 */

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