root/dev/pci/eso.c

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

DEFINITIONS

This source file includes following definitions.
  1. eso_match
  2. eso_attach
  3. eso_setup
  4. eso_defer
  5. eso_write_cmd
  6. eso_write_ctlreg
  7. eso_read_rdr
  8. eso_read_ctlreg
  9. eso_write_mixreg
  10. eso_read_mixreg
  11. eso_intr
  12. eso_reset
  13. eso_open
  14. eso_close
  15. eso_query_encoding
  16. eso_set_params
  17. eso_round_blocksize
  18. eso_halt_output
  19. eso_halt_input
  20. eso_getdev
  21. eso_set_port
  22. eso_get_port
  23. eso_query_devinfo
  24. eso_allocmem
  25. eso_freemem
  26. eso_allocm
  27. eso_freem
  28. eso_round_buffersize
  29. eso_mappage
  30. eso_get_props
  31. eso_trigger_output
  32. eso_trigger_input
  33. eso_set_recsrc
  34. eso_set_gain
  35. eso_powerhook

    1 /*      $OpenBSD: eso.c,v 1.22 2005/08/09 04:10:11 mickey Exp $ */
    2 /*      $NetBSD: eso.c,v 1.3 1999/08/02 17:37:43 augustss Exp $ */
    3 
    4 /*
    5  * Copyright (c) 1999 Klaus J. Klein
    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. The name of the author may not be used to endorse or promote products
   17  *    derived from this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   24  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * ESS Technology Inc. Solo-1 PCI AudioDrive (ES1938/1946) device driver.
   34  */
   35 
   36 #ifdef __OpenBSD__
   37 #define HIDE
   38 #define MATCH_ARG_2_T void *
   39 #else
   40 #define HIDE static
   41 #define MATCH_ARG_2_T struct cfdata *
   42 #endif
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/kernel.h>
   47 #include <sys/malloc.h>
   48 #include <sys/device.h>
   49 #include <sys/proc.h>
   50 
   51 #include <dev/pci/pcidevs.h>
   52 #include <dev/pci/pcivar.h>
   53 
   54 #include <sys/audioio.h>
   55 #include <dev/audio_if.h>
   56 #include <dev/midi_if.h>
   57 
   58 #include <dev/mulaw.h>
   59 #include <dev/auconv.h>
   60 
   61 #include <dev/ic/mpuvar.h>
   62 #include <dev/ic/i8237reg.h>
   63 #include <dev/pci/esoreg.h>
   64 #include <dev/pci/esovar.h>
   65 #include <dev/audiovar.h>
   66 
   67 #include <machine/bus.h>
   68 #include <machine/intr.h>
   69 
   70 #if defined(AUDIO_DEBUG) || defined(DEBUG)
   71 #define DPRINTF(x) printf x
   72 #else
   73 #define DPRINTF(x)
   74 #endif
   75 
   76 struct eso_dma {
   77         bus_dmamap_t            ed_map;
   78         caddr_t                 ed_addr;
   79         bus_dma_segment_t       ed_segs[1];
   80         int                     ed_nsegs;
   81         size_t                  ed_size;
   82         struct eso_dma *        ed_next;
   83 };
   84 
   85 #define KVADDR(dma)     ((void *)(dma)->ed_addr)
   86 #define DMAADDR(dma)    ((dma)->ed_map->dm_segs[0].ds_addr)
   87 
   88 /* Autoconfiguration interface */
   89 HIDE int eso_match(struct device *, MATCH_ARG_2_T, void *);
   90 HIDE void eso_attach(struct device *, struct device *, void *);
   91 HIDE void eso_defer(struct device *);
   92 
   93 struct cfattach eso_ca = {
   94         sizeof (struct eso_softc), eso_match, eso_attach
   95 };
   96 
   97 #ifdef __OpenBSD__
   98 struct cfdriver eso_cd = {
   99         NULL, "eso", DV_DULL
  100 };
  101 #endif
  102 
  103 /* PCI interface */
  104 HIDE int eso_intr(void *);
  105 
  106 /* MI audio layer interface */
  107 HIDE int        eso_open(void *, int);
  108 HIDE void       eso_close(void *);
  109 HIDE int        eso_query_encoding(void *, struct audio_encoding *);
  110 HIDE int        eso_set_params(void *, int, int, struct audio_params *,
  111                     struct audio_params *);
  112 HIDE int        eso_round_blocksize(void *, int);
  113 HIDE int        eso_halt_output(void *);
  114 HIDE int        eso_halt_input(void *);
  115 HIDE int        eso_getdev(void *, struct audio_device *);
  116 HIDE int        eso_set_port(void *, mixer_ctrl_t *);
  117 HIDE int        eso_get_port(void *, mixer_ctrl_t *);
  118 HIDE int        eso_query_devinfo(void *, mixer_devinfo_t *);
  119 HIDE void *     eso_allocm(void *, int, size_t, int, int);
  120 HIDE void       eso_freem(void *, void *, int);
  121 HIDE size_t     eso_round_buffersize(void *, int, size_t);
  122 HIDE paddr_t    eso_mappage(void *, void *, off_t, int);
  123 HIDE int        eso_get_props(void *);
  124 HIDE int        eso_trigger_output(void *, void *, void *, int,
  125                     void (*)(void *), void *, struct audio_params *);
  126 HIDE int        eso_trigger_input(void *, void *, void *, int,
  127                     void (*)(void *), void *, struct audio_params *);
  128 HIDE void       eso_setup(struct eso_softc *, int);
  129 
  130 HIDE void       eso_powerhook(int, void *);
  131 
  132 
  133 HIDE struct audio_hw_if eso_hw_if = {
  134         eso_open,
  135         eso_close,
  136         NULL,                   /* drain */
  137         eso_query_encoding,
  138         eso_set_params,
  139         eso_round_blocksize,
  140         NULL,                   /* commit_settings */
  141         NULL,                   /* init_output */
  142         NULL,                   /* init_input */
  143         NULL,                   /* start_output */
  144         NULL,                   /* start_input */
  145         eso_halt_output,
  146         eso_halt_input,
  147         NULL,                   /* speaker_ctl */
  148         eso_getdev,
  149         NULL,                   /* setfd */
  150         eso_set_port,
  151         eso_get_port,
  152         eso_query_devinfo,
  153         eso_allocm,
  154         eso_freem,
  155         eso_round_buffersize,
  156         eso_mappage,
  157         eso_get_props,
  158         eso_trigger_output,
  159         eso_trigger_input,
  160 };
  161 
  162 HIDE const char * const eso_rev2model[] = {
  163         "ES1938",
  164         "ES1946",
  165         "ES1946 rev E"
  166 };
  167 
  168 
  169 /*
  170  * Utility routines
  171  */
  172 /* Register access etc. */
  173 HIDE uint8_t    eso_read_ctlreg(struct eso_softc *, uint8_t);
  174 HIDE uint8_t    eso_read_mixreg(struct eso_softc *, uint8_t);
  175 HIDE uint8_t    eso_read_rdr(struct eso_softc *);
  176 HIDE int        eso_reset(struct eso_softc *);
  177 HIDE void       eso_set_gain(struct eso_softc *, unsigned int);
  178 HIDE int        eso_set_recsrc(struct eso_softc *, unsigned int);
  179 HIDE void       eso_write_cmd(struct eso_softc *, uint8_t);
  180 HIDE void       eso_write_ctlreg(struct eso_softc *, uint8_t, uint8_t);
  181 HIDE void       eso_write_mixreg(struct eso_softc *, uint8_t, uint8_t);
  182 /* DMA memory allocation */
  183 HIDE int        eso_allocmem(struct eso_softc *, size_t, size_t, size_t,
  184                     int, struct eso_dma *);
  185 HIDE void       eso_freemem(struct eso_softc *, struct eso_dma *);
  186 
  187 
  188 HIDE int
  189 eso_match(parent, match, aux)
  190         struct device *parent;
  191         MATCH_ARG_2_T match;
  192         void *aux;
  193 {
  194         struct pci_attach_args *pa = aux;
  195 
  196         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ESSTECH &&
  197             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ESSTECH_SOLO1)
  198                 return (1);
  199 
  200         return (0);
  201 }
  202 
  203 HIDE void
  204 eso_attach(parent, self, aux)
  205         struct device *parent, *self;
  206         void *aux;
  207 {
  208         struct eso_softc *sc = (struct eso_softc *)self;
  209         struct pci_attach_args *pa = aux;
  210         struct audio_attach_args aa;
  211         pci_intr_handle_t ih;
  212         bus_addr_t vcbase;
  213         const char *intrstring;
  214 
  215         sc->sc_revision = PCI_REVISION(pa->pa_class);
  216 
  217         if (sc->sc_revision <
  218             sizeof (eso_rev2model) / sizeof (eso_rev2model[0]))
  219                 printf(": %s", eso_rev2model[sc->sc_revision]);
  220         else
  221                 printf(": (unknown rev. 0x%02x)", sc->sc_revision);
  222 
  223         /* Map I/O registers. */
  224         if (pci_mapreg_map(pa, ESO_PCI_BAR_IO, PCI_MAPREG_TYPE_IO, 0,
  225             &sc->sc_iot, &sc->sc_ioh, NULL, NULL, 0)) {
  226                 printf(", can't map I/O space\n");
  227                 return;
  228         }
  229         if (pci_mapreg_map(pa, ESO_PCI_BAR_SB, PCI_MAPREG_TYPE_IO, 0,
  230             &sc->sc_sb_iot, &sc->sc_sb_ioh, NULL, NULL, 0)) {
  231                 printf(", can't map SB I/O space\n");
  232                 return;
  233         }
  234         if (pci_mapreg_map(pa, ESO_PCI_BAR_VC, PCI_MAPREG_TYPE_IO, 0,
  235             &sc->sc_dmac_iot, &sc->sc_dmac_ioh, &vcbase, &sc->sc_vcsize, 0)) {
  236                 vcbase = 0;
  237                 sc->sc_vcsize = 0x10; /* From the data sheet. */
  238         }
  239 
  240         if (pci_mapreg_map(pa, ESO_PCI_BAR_MPU, PCI_MAPREG_TYPE_IO, 0,
  241             &sc->sc_mpu_iot, &sc->sc_mpu_ioh, NULL, NULL, 0)) {
  242                 printf(", can't map MPU I/O space\n");
  243                 return;
  244         }
  245         if (pci_mapreg_map(pa, ESO_PCI_BAR_GAME, PCI_MAPREG_TYPE_IO, 0,
  246             &sc->sc_game_iot, &sc->sc_game_ioh, NULL, NULL, 0)) {
  247                 printf(", can't map Game I/O space\n");
  248                 return;
  249         }
  250 
  251         sc->sc_dmat = pa->pa_dmat;
  252         sc->sc_dmas = NULL;
  253         sc->sc_dmac_configured = 0;
  254 
  255         sc->sc_pa = *pa;
  256 
  257         eso_setup(sc, 1);
  258 
  259         /* map and establish the interrupt. */
  260         if (pci_intr_map(pa, &ih)) {
  261                 printf(", couldn't map interrupt\n");
  262                 return;
  263         }
  264         intrstring = pci_intr_string(pa->pa_pc, ih);
  265 #ifdef __OpenBSD__
  266         sc->sc_ih  = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, eso_intr, sc,
  267                                         sc->sc_dev.dv_xname);
  268 #else
  269         sc->sc_ih  = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, eso_intr, sc);
  270 #endif
  271         if (sc->sc_ih == NULL) {
  272                 printf(", couldn't establish interrupt");
  273                 if (intrstring != NULL)
  274                         printf(" at %s", intrstring);
  275                 printf("\n");
  276                 return;
  277         }
  278         printf(", %s\n", intrstring);
  279 
  280         /*
  281          * Set up the DDMA Control register; a suitable I/O region has been
  282          * supposedly mapped in the VC base address register.
  283          *
  284          * The Solo-1 has an ... interesting silicon bug that causes it to
  285          * not respond to I/O space accesses to the Audio 1 DMA controller
  286          * if the latter's mapping base address is aligned on a 1K boundary.
  287          * As a consequence, it is quite possible for the mapping provided
  288          * in the VC BAR to be useless.  To work around this, we defer this
  289          * part until all autoconfiguration on our parent bus is completed
  290          * and then try to map it ourselves in fulfillment of the constraint.
  291          * 
  292          * According to the register map we may write to the low 16 bits
  293          * only, but experimenting has shown we're safe.
  294          * -kjk
  295          */
  296 
  297         if (ESO_VALID_DDMAC_BASE(vcbase)) {
  298                 pci_conf_write(pa->pa_pc, pa->pa_tag, ESO_PCI_DDMAC,
  299                                vcbase | ESO_PCI_DDMAC_DE);
  300                 sc->sc_dmac_configured = 1;
  301                 
  302                 printf("%s: mapping Audio 1 DMA using VC I/O space at 0x%lx\n",
  303                        sc->sc_dev.dv_xname, (unsigned long)vcbase);
  304         } else {
  305                 DPRINTF(("%s: VC I/O space at 0x%lx not suitable, deferring\n",
  306                          sc->sc_dev.dv_xname, (unsigned long)vcbase));
  307                 config_defer((struct device *)sc, eso_defer);
  308         }
  309         
  310         audio_attach_mi(&eso_hw_if, sc, &sc->sc_dev);
  311 
  312         aa.type = AUDIODEV_TYPE_OPL;
  313         aa.hwif = NULL;
  314         aa.hdl = NULL;
  315         (void)config_found(&sc->sc_dev, &aa, audioprint);
  316 
  317         sc->sc_powerhook = powerhook_establish(&eso_powerhook, sc);
  318 
  319 #if 0
  320         aa.type = AUDIODEV_TYPE_MPU;
  321         aa.hwif = NULL;
  322         aa.hdl = NULL;
  323         sc->sc_mpudev = config_found(&sc->sc_dev, &aa, audioprint);
  324 #endif
  325 }
  326 
  327 HIDE void
  328 eso_setup(sc, verbose)
  329         struct eso_softc *sc;
  330         int verbose;
  331 {
  332         struct pci_attach_args *pa = &sc->sc_pa;        
  333         uint8_t a2mode;
  334         int idx; 
  335 
  336         /* Reset the device; bail out upon failure. */
  337         if (eso_reset(sc) != 0) {
  338                 if (verbose) printf(", can't reset\n");
  339                 return;
  340         }
  341         
  342         /* Select the DMA/IRQ policy: DDMA, ISA IRQ emulation disabled. */
  343         pci_conf_write(pa->pa_pc, pa->pa_tag, ESO_PCI_S1C,
  344                        pci_conf_read(pa->pa_pc, pa->pa_tag, ESO_PCI_S1C) &
  345                        ~(ESO_PCI_S1C_IRQP_MASK | ESO_PCI_S1C_DMAP_MASK));
  346 
  347         /* Enable the relevant DMA interrupts. */
  348         bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_IRQCTL,
  349                           ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ);
  350         
  351         /* Set up A1's sample rate generator for new-style parameters. */
  352         a2mode = eso_read_mixreg(sc, ESO_MIXREG_A2MODE);
  353         a2mode |= ESO_MIXREG_A2MODE_NEWA1 | ESO_MIXREG_A2MODE_ASYNC;
  354         eso_write_mixreg(sc, ESO_MIXREG_A2MODE, a2mode);
  355 
  356         /* Set mixer regs to something reasonable, needs work. */
  357         for (idx = 0; idx < ESO_NGAINDEVS; idx++) {
  358                 int v;
  359                 
  360                 switch (idx) {
  361                 case ESO_MIC_PLAY_VOL:
  362                 case ESO_LINE_PLAY_VOL:
  363                 case ESO_CD_PLAY_VOL:
  364                 case ESO_MONO_PLAY_VOL:
  365                 case ESO_AUXB_PLAY_VOL:
  366                 case ESO_DAC_REC_VOL:
  367                 case ESO_LINE_REC_VOL:
  368                 case ESO_SYNTH_REC_VOL:
  369                 case ESO_CD_REC_VOL:
  370                 case ESO_MONO_REC_VOL:
  371                 case ESO_AUXB_REC_VOL:
  372                 case ESO_SPATIALIZER:
  373                         v = 0;
  374                         break;
  375                 case ESO_MASTER_VOL:
  376                         v = ESO_GAIN_TO_6BIT(AUDIO_MAX_GAIN / 2);
  377                         break;
  378                 default:
  379                         v = ESO_GAIN_TO_4BIT(AUDIO_MAX_GAIN / 2);
  380                         break;
  381                 }
  382                 sc->sc_gain[idx][ESO_LEFT] = sc->sc_gain[idx][ESO_RIGHT] = v;
  383                 eso_set_gain(sc, idx);
  384         }
  385         eso_set_recsrc(sc, ESO_MIXREG_ERS_MIC);
  386 }
  387 
  388 HIDE void
  389 eso_defer(self)
  390         struct device *self;
  391 {
  392         struct eso_softc *sc = (struct eso_softc *)self;
  393         struct pci_attach_args *pa = &sc->sc_pa;
  394         bus_addr_t addr, start;
  395 
  396         printf("%s: ", sc->sc_dev.dv_xname);
  397 
  398         /*
  399          * This is outright ugly, but since we must not make assumptions
  400          * on the underlying allocator's behaviour it's the most straight-
  401          * forward way to implement it.  Note that we skip over the first
  402          * 1K region, which is typically occupied by an attached ISA bus.
  403          */
  404         for (start = 0x0400; start < 0xffff; start += 0x0400) {
  405                 if (bus_space_alloc(sc->sc_iot,
  406                     start + sc->sc_vcsize, start + 0x0400 - 1,
  407                     sc->sc_vcsize, sc->sc_vcsize, 0, 0, &addr,
  408                     &sc->sc_dmac_ioh) != 0)
  409                         continue;
  410 
  411                 pci_conf_write(pa->pa_pc, pa->pa_tag, ESO_PCI_DDMAC,
  412                     addr | ESO_PCI_DDMAC_DE);
  413                 sc->sc_dmac_iot = sc->sc_iot;
  414                 sc->sc_dmac_configured = 1;
  415                 printf("mapping Audio 1 DMA using I/O space at 0x%lx\n",
  416                     (unsigned long)addr);
  417 
  418                 return;
  419         }
  420         
  421         printf("can't map Audio 1 DMA into I/O space\n");
  422 }
  423 
  424 HIDE void
  425 eso_write_cmd(sc, cmd)
  426         struct eso_softc *sc;
  427         uint8_t cmd;
  428 {
  429         int i;
  430 
  431         /* Poll for busy indicator to become clear. */
  432         for (i = 0; i < ESO_WDR_TIMEOUT; i++) {
  433                 if ((bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_RSR)
  434                     & ESO_SB_RSR_BUSY) == 0) {
  435                         bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh,
  436                             ESO_SB_WDR, cmd);
  437                         return;
  438                 } else {
  439                         delay(10);
  440                 }
  441         }
  442 
  443         printf("%s: WDR timeout\n", sc->sc_dev.dv_xname);
  444         return;
  445 }
  446 
  447 /* Write to a controller register */
  448 HIDE void
  449 eso_write_ctlreg(sc, reg, val)
  450         struct eso_softc *sc;
  451         uint8_t reg, val;
  452 {
  453 
  454         /* DPRINTF(("ctlreg 0x%02x = 0x%02x\n", reg, val)); */
  455         
  456         eso_write_cmd(sc, reg);
  457         eso_write_cmd(sc, val);
  458 }
  459 
  460 /* Read out the Read Data Register */
  461 HIDE uint8_t
  462 eso_read_rdr(sc)
  463         struct eso_softc *sc;
  464 {
  465         int i;
  466 
  467         for (i = 0; i < ESO_RDR_TIMEOUT; i++) {
  468                 if (bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh,
  469                     ESO_SB_RBSR) & ESO_SB_RBSR_RDAV) {
  470                         return (bus_space_read_1(sc->sc_sb_iot,
  471                             sc->sc_sb_ioh, ESO_SB_RDR));
  472                 } else {
  473                         delay(10);
  474                 }
  475         }
  476 
  477         printf("%s: RDR timeout\n", sc->sc_dev.dv_xname);
  478         return (-1);
  479 }
  480 
  481 
  482 HIDE uint8_t
  483 eso_read_ctlreg(sc, reg)
  484         struct eso_softc *sc;
  485         uint8_t reg;
  486 {
  487 
  488         eso_write_cmd(sc, ESO_CMD_RCR);
  489         eso_write_cmd(sc, reg);
  490         return (eso_read_rdr(sc));
  491 }
  492 
  493 HIDE void
  494 eso_write_mixreg(sc, reg, val)
  495         struct eso_softc *sc;
  496         uint8_t reg, val;
  497 {
  498         int s;
  499 
  500         /* DPRINTF(("mixreg 0x%02x = 0x%02x\n", reg, val)); */
  501         
  502         s = splaudio();
  503         bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERADDR, reg);
  504         bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERDATA, val);
  505         splx(s);
  506 }
  507 
  508 HIDE uint8_t
  509 eso_read_mixreg(sc, reg)
  510         struct eso_softc *sc;
  511         uint8_t reg;
  512 {
  513         int s;
  514         uint8_t val;
  515 
  516         s = splaudio();
  517         bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERADDR, reg);
  518         val = bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_MIXERDATA);
  519         splx(s);
  520         
  521         return (val);
  522 }
  523 
  524 HIDE int
  525 eso_intr(hdl)
  526         void *hdl;
  527 {
  528         struct eso_softc *sc = hdl;
  529         uint8_t irqctl;
  530 
  531         irqctl = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ESO_IO_IRQCTL);
  532 
  533         /* If it wasn't ours, that's all she wrote. */
  534         if ((irqctl & (ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ)) == 0)
  535                 return (0);
  536         
  537         if (irqctl & ESO_IO_IRQCTL_A1IRQ) {
  538                 /* Clear interrupt. */
  539                 (void)bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh,
  540                     ESO_SB_RBSR);
  541         
  542                 if (sc->sc_rintr)
  543                         sc->sc_rintr(sc->sc_rarg);
  544                 else
  545                         wakeup(&sc->sc_rintr);
  546         }
  547 
  548         if (irqctl & ESO_IO_IRQCTL_A2IRQ) {
  549                 /*
  550                  * Clear the A2 IRQ latch: the cached value reflects the
  551                  * current DAC settings with the IRQ latch bit not set.
  552                  */
  553                 eso_write_mixreg(sc, ESO_MIXREG_A2C2, sc->sc_a2c2);
  554 
  555                 if (sc->sc_pintr)
  556                         sc->sc_pintr(sc->sc_parg);
  557                 else
  558                         wakeup(&sc->sc_pintr);
  559         }
  560 
  561 #if 0
  562         if ((irqctl & ESO_IO_IRQCTL_MPUIRQ) && sc->sc_mpudev != 0)
  563                 mpu_intr(sc->sc_mpudev);
  564 #endif
  565  
  566         return (1);
  567 }
  568 
  569 /* Perform a software reset, including DMA FIFOs. */
  570 HIDE int
  571 eso_reset(sc)
  572         struct eso_softc *sc;
  573 {
  574         int i;
  575 
  576         bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_RESET,
  577             ESO_SB_RESET_SW | ESO_SB_RESET_FIFO);
  578         /* `Delay' suggested in the data sheet. */
  579         (void)bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_STATUS);
  580         bus_space_write_1(sc->sc_sb_iot, sc->sc_sb_ioh, ESO_SB_RESET, 0);
  581 
  582         /* Wait for reset to take effect. */
  583         for (i = 0; i < ESO_RESET_TIMEOUT; i++) {
  584                 /* Poll for data to become available. */
  585                 if ((bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh,
  586                     ESO_SB_RBSR) & ESO_SB_RBSR_RDAV) != 0 &&
  587                     bus_space_read_1(sc->sc_sb_iot, sc->sc_sb_ioh,
  588                         ESO_SB_RDR) == ESO_SB_RDR_RESETMAGIC) {
  589 
  590                         /* Activate Solo-1 extension commands. */
  591                         eso_write_cmd(sc, ESO_CMD_EXTENB);
  592                         /* Reset mixer registers. */
  593                         eso_write_mixreg(sc, ESO_MIXREG_RESET,
  594                             ESO_MIXREG_RESET_RESET);
  595 
  596                         return (0);
  597                 } else {
  598                         delay(1000);
  599                 }
  600         }
  601         
  602         printf("%s: reset timeout\n", sc->sc_dev.dv_xname);
  603         return (-1);
  604 }
  605 
  606 
  607 /* ARGSUSED */
  608 HIDE int
  609 eso_open(hdl, flags)
  610         void *hdl;
  611         int flags;
  612 {
  613         struct eso_softc *sc = hdl;
  614         
  615         DPRINTF(("%s: open\n", sc->sc_dev.dv_xname));
  616 
  617         sc->sc_pintr = NULL;
  618         sc->sc_rintr = NULL;
  619         
  620         return (0);
  621 }
  622 
  623 HIDE void
  624 eso_close(hdl)
  625         void *hdl;
  626 {
  627 
  628         DPRINTF(("%s: close\n", ((struct eso_softc *)hdl)->sc_dev.dv_xname));
  629 }
  630 
  631 HIDE int
  632 eso_query_encoding(hdl, fp)
  633         void *hdl;
  634         struct audio_encoding *fp;
  635 {
  636         
  637         switch (fp->index) {
  638         case 0:
  639                 strlcpy(fp->name, AudioEulinear, sizeof fp->name);
  640                 fp->encoding = AUDIO_ENCODING_ULINEAR;
  641                 fp->precision = 8;
  642                 fp->flags = 0;
  643                 break;
  644         case 1:
  645                 strlcpy(fp->name, AudioEslinear, sizeof fp->name);
  646                 fp->encoding = AUDIO_ENCODING_SLINEAR;
  647                 fp->precision = 8;
  648                 fp->flags = 0;
  649                 break;
  650         case 2:
  651                 fp->precision = 16;
  652                 if (fp->flags & AUOPEN_READ) {
  653                         strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
  654                         fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
  655                         if (fp->flags & AUOPEN_WRITE)
  656                                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  657                         else
  658                                 fp->flags = 0;
  659                 } else {
  660                         strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
  661                         fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
  662                         fp->flags = 0;
  663                 }
  664                 break;
  665         case 3:
  666                 fp->precision = 16;
  667                 if (fp->flags & AUOPEN_READ) {
  668                         strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
  669                         fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
  670                         if (fp->flags & AUOPEN_WRITE)
  671                                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  672                         else
  673                                 fp->flags = 0;
  674                 } else {
  675                         strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
  676                         fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
  677                         fp->flags = 0;
  678                 }
  679                 break;
  680         case 4:
  681                 fp->precision = 16;
  682                 if (fp->flags & AUOPEN_READ) {
  683                         strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
  684                         fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
  685                 } else {
  686                         strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
  687                         fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
  688                 }
  689                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  690                 break;
  691         case 5:
  692                 fp->precision = 16;
  693                 if (fp->flags & AUOPEN_READ) {
  694                         strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
  695                         fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
  696                 } else {
  697                         strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
  698                         fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
  699                 }
  700                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  701                 break;
  702         case 6:
  703                 strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
  704                 fp->encoding = AUDIO_ENCODING_ULAW;
  705                 fp->precision = 8;
  706                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  707                 break;
  708         case 7:
  709                 strlcpy(fp->name, AudioEalaw, sizeof fp->name);
  710                 fp->encoding = AUDIO_ENCODING_ALAW;
  711                 fp->precision = 8;
  712                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  713                 break;
  714         default:
  715                 return (EINVAL);
  716         }
  717 
  718         return (0);
  719 }
  720 
  721 HIDE int
  722 eso_set_params(hdl, setmode, usemode, play, rec)
  723         void *hdl;
  724         int setmode, usemode;
  725         struct audio_params *play, *rec;
  726 {
  727         struct eso_softc *sc = hdl;
  728         struct audio_params *p;
  729         int mode, r[2], rd[2], clk;
  730         unsigned int srg, fltdiv;
  731         
  732         for (mode = AUMODE_RECORD; mode != -1; 
  733              mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
  734                 if ((setmode & mode) == 0)
  735                         continue;
  736 
  737                 p = (mode == AUMODE_PLAY) ? play : rec;
  738 
  739                 if (p->sample_rate < ESO_MINRATE ||
  740                     p->sample_rate > ESO_MAXRATE ||
  741                     (p->precision != 8 && p->precision != 16) ||
  742                     (p->channels != 1 && p->channels != 2))
  743                         return (EINVAL);
  744                 
  745                 p->factor = 1;
  746                 p->sw_code = NULL;
  747                 switch (p->encoding) {
  748                 case AUDIO_ENCODING_SLINEAR_BE:
  749                 case AUDIO_ENCODING_ULINEAR_BE:
  750                         if (mode == AUMODE_PLAY && p->precision == 16)
  751                                 p->sw_code = swap_bytes;
  752                         break;
  753                 case AUDIO_ENCODING_SLINEAR_LE:
  754                 case AUDIO_ENCODING_ULINEAR_LE:
  755                         if (mode == AUMODE_RECORD && p->precision == 16)
  756                                 p->sw_code = swap_bytes;
  757                         break;
  758                 case AUDIO_ENCODING_ULAW:
  759                         if (mode == AUMODE_PLAY) {
  760                                 p->factor = 2;
  761                                 p->sw_code = mulaw_to_ulinear16;
  762                         } else {
  763                                 p->sw_code = ulinear8_to_mulaw;
  764                         }
  765                         break;
  766                 case AUDIO_ENCODING_ALAW:
  767                         if (mode == AUMODE_PLAY) {
  768                                 p->factor = 2;
  769                                 p->sw_code = alaw_to_ulinear16;
  770                         } else {
  771                                 p->sw_code = ulinear8_to_alaw;
  772                         }
  773                         break;
  774                 default:
  775                         return (EINVAL);
  776                 }
  777 
  778                 /*
  779                  * We'll compute both possible sample rate dividers and pick
  780                  * the one with the least error.
  781                  */
  782 #define ABS(x) ((x) < 0 ? -(x) : (x))
  783                 r[0] = ESO_CLK0 /
  784                     (128 - (rd[0] = 128 - ESO_CLK0 / p->sample_rate));
  785                 r[1] = ESO_CLK1 /
  786                     (128 - (rd[1] = 128 - ESO_CLK1 / p->sample_rate));
  787 
  788                 clk = ABS(p->sample_rate - r[0]) > ABS(p->sample_rate - r[1]);
  789                 srg = rd[clk] | (clk == 1 ? ESO_CLK1_SELECT : 0x00);
  790 
  791                 /* Roll-off frequency of 87%, as in the ES1888 driver. */
  792                 fltdiv = 256 - 200279L / p->sample_rate;
  793 
  794                 /* Update to reflect the possibly inexact rate. */
  795                 p->sample_rate = r[clk];
  796         
  797                 if (mode == AUMODE_RECORD) {
  798                         /* Audio 1 */
  799                         DPRINTF(("A1 srg 0x%02x fdiv 0x%02x\n", srg, fltdiv));
  800                         eso_write_ctlreg(sc, ESO_CTLREG_SRG, srg);
  801                         eso_write_ctlreg(sc, ESO_CTLREG_FLTDIV, fltdiv);
  802                 } else {
  803                         /* Audio 2 */
  804                         DPRINTF(("A2 srg 0x%02x fdiv 0x%02x\n", srg, fltdiv));
  805                         eso_write_mixreg(sc, ESO_MIXREG_A2SRG, srg);
  806                         eso_write_mixreg(sc, ESO_MIXREG_A2FLTDIV, fltdiv);
  807                 }
  808 #undef ABS
  809 
  810         }
  811 
  812         return (0);
  813 }
  814 
  815 HIDE int
  816 eso_round_blocksize(hdl, blk)
  817         void *hdl;
  818         int blk;
  819 {
  820 
  821         return ((blk + 31) & -32); /* keep good alignment; at least 16 req'd */
  822 }
  823 
  824 HIDE int
  825 eso_halt_output(hdl)
  826         void *hdl;
  827 {
  828         struct eso_softc *sc = hdl;
  829         int error, s;
  830         
  831         DPRINTF(("%s: halt_output\n", sc->sc_dev.dv_xname));
  832 
  833         /*
  834          * Disable auto-initialize DMA, allowing the FIFO to drain and then
  835          * stop.  The interrupt callback pointer is cleared at this
  836          * point so that an outstanding FIFO interrupt for the remaining data
  837          * will be acknowledged without further processing.
  838          *
  839          * This does not immediately `abort' an operation in progress (c.f.
  840          * audio(9)) but is the method to leave the FIFO behind in a clean
  841          * state with the least hair.  (Besides, that item needs to be
  842          * rephrased for trigger_*()-based DMA environments.)
  843          */
  844         s = splaudio();
  845         eso_write_mixreg(sc, ESO_MIXREG_A2C1,
  846             ESO_MIXREG_A2C1_FIFOENB | ESO_MIXREG_A2C1_DMAENB);
  847         bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM,
  848             ESO_IO_A2DMAM_DMAENB);
  849 
  850         sc->sc_pintr = NULL;
  851         error = tsleep(&sc->sc_pintr, PCATCH | PWAIT, "esoho", hz);
  852         splx(s);
  853         
  854         /* Shut down DMA completely. */
  855         eso_write_mixreg(sc, ESO_MIXREG_A2C1, 0);
  856         bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM, 0);
  857         
  858         return (error == EWOULDBLOCK ? 0 : error);
  859 }
  860 
  861 HIDE int
  862 eso_halt_input(hdl)
  863         void *hdl;
  864 {
  865         struct eso_softc *sc = hdl;
  866         int error, s;
  867         
  868         DPRINTF(("%s: halt_input\n", sc->sc_dev.dv_xname));
  869 
  870         /* Just like eso_halt_output(), but for Audio 1. */
  871         s = splaudio();
  872         eso_write_ctlreg(sc, ESO_CTLREG_A1C2,
  873             ESO_CTLREG_A1C2_READ | ESO_CTLREG_A1C2_ADC |
  874             ESO_CTLREG_A1C2_DMAENB);
  875         bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MODE,
  876             DMA37MD_WRITE | DMA37MD_DEMAND);
  877 
  878         sc->sc_rintr = NULL;
  879         error = tsleep(&sc->sc_rintr, PCATCH | PWAIT, "esohi", hz);
  880         splx(s);
  881 
  882         /* Shut down DMA completely. */
  883         eso_write_ctlreg(sc, ESO_CTLREG_A1C2,
  884             ESO_CTLREG_A1C2_READ | ESO_CTLREG_A1C2_ADC);
  885         bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK,
  886             ESO_DMAC_MASK_MASK);
  887 
  888         return (error == EWOULDBLOCK ? 0 : error);
  889 }
  890 
  891 /* ARGSUSED */
  892 HIDE int
  893 eso_getdev(hdl, retp)
  894         void *hdl;
  895         struct audio_device *retp;
  896 {
  897         struct eso_softc *sc = hdl;
  898 
  899         strlcpy(retp->name, "ESS Solo-1", sizeof retp->name);
  900         snprintf(retp->version, sizeof retp->version, "0x%02x",
  901             sc->sc_revision);
  902         if (sc->sc_revision <=
  903             sizeof (eso_rev2model) / sizeof (eso_rev2model[0]))
  904                 strlcpy(retp->config, eso_rev2model[sc->sc_revision],
  905                     sizeof retp->config);
  906         else
  907                 strlcpy(retp->config, "unknown", sizeof retp->config);
  908         
  909         return (0);
  910 }
  911 
  912 HIDE int
  913 eso_set_port(hdl, cp)
  914         void *hdl;
  915         mixer_ctrl_t *cp;
  916 {
  917         struct eso_softc *sc = hdl;
  918         unsigned int lgain, rgain;
  919         uint8_t tmp;
  920         
  921         switch (cp->dev) {
  922         case ESO_DAC_PLAY_VOL:
  923         case ESO_MIC_PLAY_VOL:
  924         case ESO_LINE_PLAY_VOL:
  925         case ESO_SYNTH_PLAY_VOL:
  926         case ESO_CD_PLAY_VOL:
  927         case ESO_AUXB_PLAY_VOL:
  928         case ESO_RECORD_VOL:
  929         case ESO_DAC_REC_VOL:
  930         case ESO_MIC_REC_VOL:
  931         case ESO_LINE_REC_VOL:
  932         case ESO_SYNTH_REC_VOL:
  933         case ESO_CD_REC_VOL:
  934         case ESO_AUXB_REC_VOL:
  935                 if (cp->type != AUDIO_MIXER_VALUE)
  936                         return (EINVAL);
  937                 
  938                 /*
  939                  * Stereo-capable mixer ports: if we get a single-channel
  940                  * gain value passed in, then we duplicate it to both left
  941                  * and right channels.
  942                  */
  943                 switch (cp->un.value.num_channels) {
  944                 case 1:
  945                         lgain = rgain = ESO_GAIN_TO_4BIT(
  946                             cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
  947                         break;
  948                 case 2:
  949                         lgain = ESO_GAIN_TO_4BIT(
  950                             cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
  951                         rgain = ESO_GAIN_TO_4BIT(
  952                             cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
  953                         break;
  954                 default:
  955                         return (EINVAL);
  956                 }
  957 
  958                 sc->sc_gain[cp->dev][ESO_LEFT] = lgain;
  959                 sc->sc_gain[cp->dev][ESO_RIGHT] = rgain;
  960                 eso_set_gain(sc, cp->dev);
  961                 break;
  962 
  963         case ESO_MASTER_VOL:
  964                 if (cp->type != AUDIO_MIXER_VALUE)
  965                         return (EINVAL);
  966 
  967                 /* Like above, but a precision of 6 bits. */
  968                 switch (cp->un.value.num_channels) {
  969                 case 1:
  970                         lgain = rgain = ESO_GAIN_TO_6BIT(
  971                             cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
  972                         break;
  973                 case 2:
  974                         lgain = ESO_GAIN_TO_6BIT(
  975                             cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
  976                         rgain = ESO_GAIN_TO_6BIT(
  977                             cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
  978                         break;
  979                 default:
  980                         return (EINVAL);
  981                 }
  982 
  983                 sc->sc_gain[cp->dev][ESO_LEFT] = lgain;
  984                 sc->sc_gain[cp->dev][ESO_RIGHT] = rgain;
  985                 eso_set_gain(sc, cp->dev);
  986                 break;
  987 
  988         case ESO_SPATIALIZER:
  989                 if (cp->type != AUDIO_MIXER_VALUE ||
  990                     cp->un.value.num_channels != 1)
  991                         return (EINVAL);
  992 
  993                 sc->sc_gain[cp->dev][ESO_LEFT] =
  994                     sc->sc_gain[cp->dev][ESO_RIGHT] =
  995                     ESO_GAIN_TO_6BIT(
  996                         cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
  997                 eso_set_gain(sc, cp->dev);
  998                 break;
  999                 
 1000         case ESO_MONO_PLAY_VOL:
 1001         case ESO_MONO_REC_VOL:
 1002                 if (cp->type != AUDIO_MIXER_VALUE ||
 1003                     cp->un.value.num_channels != 1)
 1004                         return (EINVAL);
 1005 
 1006                 sc->sc_gain[cp->dev][ESO_LEFT] =
 1007                     sc->sc_gain[cp->dev][ESO_RIGHT] =
 1008                     ESO_GAIN_TO_4BIT(
 1009                         cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
 1010                 eso_set_gain(sc, cp->dev);
 1011                 break;
 1012                 
 1013         case ESO_PCSPEAKER_VOL:
 1014                 if (cp->type != AUDIO_MIXER_VALUE ||
 1015                     cp->un.value.num_channels != 1)
 1016                         return (EINVAL);
 1017 
 1018                 sc->sc_gain[cp->dev][ESO_LEFT] =
 1019                     sc->sc_gain[cp->dev][ESO_RIGHT] =
 1020                     ESO_GAIN_TO_3BIT(
 1021                         cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
 1022                 eso_set_gain(sc, cp->dev);
 1023                 break;
 1024 
 1025         case ESO_SPATIALIZER_ENABLE:
 1026                 if (cp->type != AUDIO_MIXER_ENUM)
 1027                         return (EINVAL);
 1028 
 1029                 sc->sc_spatializer = (cp->un.ord != 0);
 1030 
 1031                 tmp = eso_read_mixreg(sc, ESO_MIXREG_SPAT);
 1032                 if (sc->sc_spatializer)
 1033                         tmp |= ESO_MIXREG_SPAT_ENB;
 1034                 else
 1035                         tmp &= ~ESO_MIXREG_SPAT_ENB;
 1036                 eso_write_mixreg(sc, ESO_MIXREG_SPAT,
 1037                     tmp | ESO_MIXREG_SPAT_RSTREL);
 1038                 break;
 1039                 
 1040         case ESO_MONOOUT_SOURCE:
 1041                 if (cp->type != AUDIO_MIXER_ENUM)
 1042                         return (EINVAL);
 1043 
 1044                 sc->sc_monooutsrc = cp->un.ord;
 1045 
 1046                 tmp = eso_read_mixreg(sc, ESO_MIXREG_MPM);
 1047                 tmp &= ~ESO_MIXREG_MPM_MOMASK;
 1048                 tmp |= sc->sc_monooutsrc;
 1049                 eso_write_mixreg(sc, ESO_MIXREG_MPM, tmp);
 1050                 break;
 1051                 
 1052         case ESO_RECORD_MONITOR:
 1053                 if (cp->type != AUDIO_MIXER_ENUM)
 1054                         return (EINVAL);
 1055 
 1056                 sc->sc_recmon = (cp->un.ord != 0);
 1057                 
 1058                 tmp = eso_read_ctlreg(sc, ESO_CTLREG_ACTL);
 1059                 if (sc->sc_recmon)
 1060                         tmp |= ESO_CTLREG_ACTL_RECMON;
 1061                 else
 1062                         tmp &= ~ESO_CTLREG_ACTL_RECMON;
 1063                 eso_write_ctlreg(sc, ESO_CTLREG_ACTL, tmp);
 1064                 break;
 1065 
 1066         case ESO_RECORD_SOURCE:
 1067                 if (cp->type != AUDIO_MIXER_ENUM)
 1068                         return (EINVAL);
 1069 
 1070                 return (eso_set_recsrc(sc, cp->un.ord));
 1071 
 1072         case ESO_MIC_PREAMP:
 1073                 if (cp->type != AUDIO_MIXER_ENUM)
 1074                         return (EINVAL);
 1075 
 1076                 sc->sc_preamp = (cp->un.ord != 0);
 1077                 
 1078                 tmp = eso_read_mixreg(sc, ESO_MIXREG_MPM);
 1079                 tmp &= ~ESO_MIXREG_MPM_RESV0;
 1080                 if (sc->sc_preamp)
 1081                         tmp |= ESO_MIXREG_MPM_PREAMP;
 1082                 else
 1083                         tmp &= ~ESO_MIXREG_MPM_PREAMP;
 1084                 eso_write_mixreg(sc, ESO_MIXREG_MPM, tmp);
 1085                 break;
 1086                 
 1087         default:
 1088                 return (EINVAL);
 1089         }
 1090         
 1091         return (0);
 1092 }
 1093 
 1094 HIDE int
 1095 eso_get_port(hdl, cp)
 1096         void *hdl;
 1097         mixer_ctrl_t *cp;
 1098 {
 1099         struct eso_softc *sc = hdl;
 1100 
 1101         switch (cp->dev) {
 1102         case ESO_DAC_PLAY_VOL:
 1103         case ESO_MIC_PLAY_VOL:
 1104         case ESO_LINE_PLAY_VOL:
 1105         case ESO_SYNTH_PLAY_VOL:
 1106         case ESO_CD_PLAY_VOL:
 1107         case ESO_AUXB_PLAY_VOL:
 1108         case ESO_MASTER_VOL:
 1109         case ESO_RECORD_VOL:
 1110         case ESO_DAC_REC_VOL:
 1111         case ESO_MIC_REC_VOL:
 1112         case ESO_LINE_REC_VOL:
 1113         case ESO_SYNTH_REC_VOL:
 1114         case ESO_CD_REC_VOL:
 1115         case ESO_AUXB_REC_VOL:
 1116                 /*
 1117                  * Stereo-capable ports: if a single-channel query is made,
 1118                  * just return the left channel's value (since single-channel
 1119                  * settings themselves are applied to both channels).
 1120                  */
 1121                 switch (cp->un.value.num_channels) {
 1122                 case 1:
 1123                         cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
 1124                             sc->sc_gain[cp->dev][ESO_LEFT];
 1125                         break;
 1126                 case 2:
 1127                         cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
 1128                             sc->sc_gain[cp->dev][ESO_LEFT];
 1129                         cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
 1130                             sc->sc_gain[cp->dev][ESO_RIGHT];
 1131                         break;
 1132                 default:
 1133                         return (EINVAL);
 1134                 }
 1135                 break;
 1136                 
 1137         case ESO_MONO_PLAY_VOL:
 1138         case ESO_PCSPEAKER_VOL:
 1139         case ESO_MONO_REC_VOL:
 1140         case ESO_SPATIALIZER:
 1141                 if (cp->un.value.num_channels != 1)
 1142                         return (EINVAL);
 1143                 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
 1144                     sc->sc_gain[cp->dev][ESO_LEFT];
 1145                 break;
 1146 
 1147         case ESO_RECORD_MONITOR:
 1148                 cp->un.ord = sc->sc_recmon;
 1149                 break;
 1150                 
 1151         case ESO_RECORD_SOURCE:
 1152                 cp->un.ord = sc->sc_recsrc;
 1153                 break;
 1154 
 1155         case ESO_MONOOUT_SOURCE:
 1156                 cp->un.ord = sc->sc_monooutsrc;
 1157                 break;
 1158                 
 1159         case ESO_SPATIALIZER_ENABLE:
 1160                 cp->un.ord = sc->sc_spatializer;
 1161                 break;
 1162                 
 1163         case ESO_MIC_PREAMP:
 1164                 cp->un.ord = sc->sc_preamp;
 1165                 break;
 1166 
 1167         default:
 1168                 return (EINVAL);
 1169         }
 1170 
 1171 
 1172         return (0);
 1173         
 1174 }
 1175 
 1176 HIDE int
 1177 eso_query_devinfo(hdl, dip)
 1178         void *hdl;
 1179         mixer_devinfo_t *dip;
 1180 {
 1181 
 1182         switch (dip->index) {
 1183         case ESO_DAC_PLAY_VOL:
 1184                 dip->mixer_class = ESO_INPUT_CLASS;
 1185                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1186                 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
 1187                 dip->type = AUDIO_MIXER_VALUE;
 1188                 dip->un.v.num_channels = 2;
 1189                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1190                     sizeof dip->un.v.units.name);
 1191                 break;
 1192         case ESO_MIC_PLAY_VOL:
 1193                 dip->mixer_class = ESO_INPUT_CLASS;
 1194                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1195                 strlcpy(dip->label.name, AudioNmicrophone,
 1196                     sizeof dip->label.name);
 1197                 dip->type = AUDIO_MIXER_VALUE;
 1198                 dip->un.v.num_channels = 2;
 1199                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1200                     sizeof dip->un.v.units.name);
 1201                 break;
 1202         case ESO_LINE_PLAY_VOL:
 1203                 dip->mixer_class = ESO_INPUT_CLASS;
 1204                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1205                 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
 1206                 dip->type = AUDIO_MIXER_VALUE;
 1207                 dip->un.v.num_channels = 2;
 1208                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1209                     sizeof dip->un.v.units.name);
 1210                 break;
 1211         case ESO_SYNTH_PLAY_VOL:
 1212                 dip->mixer_class = ESO_INPUT_CLASS;
 1213                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1214                 strlcpy(dip->label.name, AudioNfmsynth,
 1215                     sizeof dip->label.name);
 1216                 dip->type = AUDIO_MIXER_VALUE;
 1217                 dip->un.v.num_channels = 2;
 1218                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1219                     sizeof dip->un.v.units.name);
 1220                 break;
 1221         case ESO_MONO_PLAY_VOL:
 1222                 dip->mixer_class = ESO_INPUT_CLASS;
 1223                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1224                 strlcpy(dip->label.name, "mono_in", sizeof dip->label.name);
 1225                 dip->type = AUDIO_MIXER_VALUE;
 1226                 dip->un.v.num_channels = 1;
 1227                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1228                     sizeof dip->un.v.units.name);
 1229                 break;
 1230         case ESO_CD_PLAY_VOL:
 1231                 dip->mixer_class = ESO_INPUT_CLASS;
 1232                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1233                 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
 1234                 dip->type = AUDIO_MIXER_VALUE;
 1235                 dip->un.v.num_channels = 2;
 1236                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1237                     sizeof dip->un.v.units.name);
 1238                 break;
 1239         case ESO_AUXB_PLAY_VOL:
 1240                 dip->mixer_class = ESO_INPUT_CLASS;
 1241                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1242                 strlcpy(dip->label.name, "auxb", sizeof dip->label.name);
 1243                 dip->type = AUDIO_MIXER_VALUE;
 1244                 dip->un.v.num_channels = 2;
 1245                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1246                     sizeof dip->un.v.units.name);
 1247                 break;
 1248 
 1249         case ESO_MIC_PREAMP:
 1250                 dip->mixer_class = ESO_MICROPHONE_CLASS;
 1251                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1252                 strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name);
 1253                 dip->type = AUDIO_MIXER_ENUM;
 1254                 dip->un.e.num_mem = 2;
 1255                 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
 1256                     sizeof dip->un.e.member[0].label.name);
 1257                 dip->un.e.member[0].ord = 0;
 1258                 strlcpy(dip->un.e.member[1].label.name, AudioNon,
 1259                     sizeof dip->un.e.member[1].label.name);
 1260                 dip->un.e.member[1].ord = 1;
 1261                 break;
 1262         case ESO_MICROPHONE_CLASS:
 1263                 dip->mixer_class = ESO_MICROPHONE_CLASS;
 1264                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1265                 strlcpy(dip->label.name, AudioNmicrophone,
 1266                     sizeof dip->label.name);
 1267                 dip->type = AUDIO_MIXER_CLASS;
 1268                 break;
 1269                 
 1270         case ESO_INPUT_CLASS:
 1271                 dip->mixer_class = ESO_INPUT_CLASS;
 1272                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1273                 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
 1274                 dip->type = AUDIO_MIXER_CLASS;
 1275                 break;
 1276                 
 1277         case ESO_MASTER_VOL:
 1278                 dip->mixer_class = ESO_OUTPUT_CLASS;
 1279                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1280                 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
 1281                 dip->type = AUDIO_MIXER_VALUE;
 1282                 dip->un.v.num_channels = 2;
 1283                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1284                     sizeof dip->un.v.units.name);
 1285                 break;
 1286         case ESO_PCSPEAKER_VOL:
 1287                 dip->mixer_class = ESO_OUTPUT_CLASS;
 1288                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1289                 strlcpy(dip->label.name, "pc_speaker", sizeof dip->label.name);
 1290                 dip->type = AUDIO_MIXER_VALUE;
 1291                 dip->un.v.num_channels = 1;
 1292                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1293                     sizeof dip->un.v.units.name);
 1294                 break;
 1295         case ESO_MONOOUT_SOURCE:
 1296                 dip->mixer_class = ESO_OUTPUT_CLASS;
 1297                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1298                 strlcpy(dip->label.name, "mono_out", sizeof dip->label.name);
 1299                 dip->type = AUDIO_MIXER_ENUM;
 1300                 dip->un.e.num_mem = 3;
 1301                 strlcpy(dip->un.e.member[0].label.name, AudioNmute,
 1302                     sizeof dip->un.e.member[0].label.name);
 1303                 dip->un.e.member[0].ord = ESO_MIXREG_MPM_MOMUTE;
 1304                 strlcpy(dip->un.e.member[1].label.name, AudioNdac,
 1305                     sizeof dip->un.e.member[1].label.name);
 1306                 dip->un.e.member[1].ord = ESO_MIXREG_MPM_MOA2R;
 1307                 strlcpy(dip->un.e.member[2].label.name, AudioNmixerout,
 1308                     sizeof dip->un.e.member[2].label.name);
 1309                 dip->un.e.member[2].ord = ESO_MIXREG_MPM_MOREC;
 1310                 break;
 1311         case ESO_SPATIALIZER:
 1312                 dip->mixer_class = ESO_OUTPUT_CLASS;
 1313                 dip->prev = AUDIO_MIXER_LAST;
 1314                 dip->next = ESO_SPATIALIZER_ENABLE;
 1315                 strlcpy(dip->label.name, AudioNspatial,
 1316                     sizeof dip->label.name);
 1317                 dip->type = AUDIO_MIXER_VALUE;
 1318                 dip->un.v.num_channels = 1;
 1319                 strlcpy(dip->un.v.units.name, "level",
 1320                     sizeof dip->un.v.units.name);
 1321                 break;
 1322         case ESO_SPATIALIZER_ENABLE:
 1323                 dip->mixer_class = ESO_OUTPUT_CLASS;
 1324                 dip->prev = ESO_SPATIALIZER;
 1325                 dip->next = AUDIO_MIXER_LAST;
 1326                 strlcpy(dip->label.name, "enable", sizeof dip->label.name);
 1327                 dip->type = AUDIO_MIXER_ENUM;
 1328                 dip->un.e.num_mem = 2;
 1329                 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
 1330                     sizeof dip->un.e.member[0].label.name);
 1331                 dip->un.e.member[0].ord = 0;
 1332                 strlcpy(dip->un.e.member[1].label.name, AudioNon,
 1333                     sizeof dip->un.e.member[1].label.name);
 1334                 dip->un.e.member[1].ord = 1;
 1335                 break;
 1336         
 1337         case ESO_OUTPUT_CLASS:
 1338                 dip->mixer_class = ESO_OUTPUT_CLASS;
 1339                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1340                 strlcpy(dip->label.name, AudioCoutputs,
 1341                     sizeof dip->label.name);
 1342                 dip->type = AUDIO_MIXER_CLASS;
 1343                 break;
 1344 
 1345         case ESO_RECORD_MONITOR:
 1346                 dip->mixer_class = ESO_MONITOR_CLASS;
 1347                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1348                 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
 1349                 dip->type = AUDIO_MIXER_ENUM;
 1350                 dip->un.e.num_mem = 2;
 1351                 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
 1352                     sizeof dip->un.e.member[0].label.name);
 1353                 dip->un.e.member[0].ord = 0;
 1354                 strlcpy(dip->un.e.member[1].label.name, AudioNon,
 1355                     sizeof dip->un.e.member[1].label.name);
 1356                 dip->un.e.member[1].ord = 1;
 1357                 break;
 1358         case ESO_MONITOR_CLASS:
 1359                 dip->mixer_class = ESO_MONITOR_CLASS;
 1360                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1361                 strlcpy(dip->label.name, AudioCmonitor,
 1362                     sizeof dip->label.name);
 1363                 dip->type = AUDIO_MIXER_CLASS;
 1364                 break;
 1365 
 1366         case ESO_RECORD_VOL:
 1367                 dip->mixer_class = ESO_RECORD_CLASS;
 1368                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1369                 strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name);
 1370                 dip->type = AUDIO_MIXER_VALUE;
 1371                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1372                     sizeof dip->un.v.units.name);
 1373                 break;
 1374         case ESO_RECORD_SOURCE:
 1375                 dip->mixer_class = ESO_RECORD_CLASS;
 1376                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1377                 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
 1378                 dip->type = AUDIO_MIXER_ENUM;
 1379                 dip->un.e.num_mem = 4;
 1380                 strlcpy(dip->un.e.member[0].label.name, AudioNmicrophone,
 1381                     sizeof dip->un.e.member[0].label.name);
 1382                 dip->un.e.member[0].ord = ESO_MIXREG_ERS_MIC;
 1383                 strlcpy(dip->un.e.member[1].label.name, AudioNline,
 1384                     sizeof dip->un.e.member[1].label.name);
 1385                 dip->un.e.member[1].ord = ESO_MIXREG_ERS_LINE;
 1386                 strlcpy(dip->un.e.member[2].label.name, AudioNcd,
 1387                     sizeof dip->un.e.member[2].label.name);
 1388                 dip->un.e.member[2].ord = ESO_MIXREG_ERS_CD;
 1389                 strlcpy(dip->un.e.member[3].label.name, AudioNmixerout,
 1390                     sizeof dip->un.e.member[3].label.name);
 1391                 dip->un.e.member[3].ord = ESO_MIXREG_ERS_MIXER;
 1392                 break;
 1393         case ESO_DAC_REC_VOL:
 1394                 dip->mixer_class = ESO_RECORD_CLASS;
 1395                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1396                 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
 1397                 dip->type = AUDIO_MIXER_VALUE;
 1398                 dip->un.v.num_channels = 2;
 1399                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1400                     sizeof dip->un.v.units.name);
 1401                 break;
 1402         case ESO_MIC_REC_VOL:
 1403                 dip->mixer_class = ESO_RECORD_CLASS;
 1404                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1405                 strlcpy(dip->label.name, AudioNmicrophone,
 1406                     sizeof dip->label.name);
 1407                 dip->type = AUDIO_MIXER_VALUE;
 1408                 dip->un.v.num_channels = 2;
 1409                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1410                     sizeof dip->un.v.units.name);
 1411                 break;
 1412         case ESO_LINE_REC_VOL:
 1413                 dip->mixer_class = ESO_RECORD_CLASS;
 1414                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1415                 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
 1416                 dip->type = AUDIO_MIXER_VALUE;
 1417                 dip->un.v.num_channels = 2;
 1418                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1419                     sizeof dip->un.v.units.name);
 1420                 break;
 1421         case ESO_SYNTH_REC_VOL:
 1422                 dip->mixer_class = ESO_RECORD_CLASS;
 1423                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1424                 strlcpy(dip->label.name, AudioNfmsynth,
 1425                     sizeof dip->label.name);
 1426                 dip->type = AUDIO_MIXER_VALUE;
 1427                 dip->un.v.num_channels = 2;
 1428                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1429                     sizeof dip->un.v.units.name);
 1430                 break;
 1431         case ESO_MONO_REC_VOL:
 1432                 dip->mixer_class = ESO_RECORD_CLASS;
 1433                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1434                 strlcpy(dip->label.name, "mono_in", sizeof dip->label.name);
 1435                 dip->type = AUDIO_MIXER_VALUE;
 1436                 dip->un.v.num_channels = 1; /* No lies */
 1437                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1438                     sizeof dip->un.v.units.name);
 1439                 break;
 1440         case ESO_CD_REC_VOL:
 1441                 dip->mixer_class = ESO_RECORD_CLASS;
 1442                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1443                 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
 1444                 dip->type = AUDIO_MIXER_VALUE;
 1445                 dip->un.v.num_channels = 2;
 1446                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1447                     sizeof dip->un.v.units.name);
 1448                 break;
 1449         case ESO_AUXB_REC_VOL:
 1450                 dip->mixer_class = ESO_RECORD_CLASS;
 1451                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1452                 strlcpy(dip->label.name, "auxb", sizeof dip->label.name);
 1453                 dip->type = AUDIO_MIXER_VALUE;
 1454                 dip->un.v.num_channels = 2;
 1455                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1456                     sizeof dip->un.v.units.name);
 1457                 break;
 1458         case ESO_RECORD_CLASS:
 1459                 dip->mixer_class = ESO_RECORD_CLASS;
 1460                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1461                 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
 1462                 dip->type = AUDIO_MIXER_CLASS;
 1463                 break;
 1464                 
 1465         default:
 1466                 return (ENXIO);
 1467         }
 1468 
 1469         return (0);
 1470 }
 1471 
 1472 HIDE int
 1473 eso_allocmem(sc, size, align, boundary, flags, ed)
 1474         struct eso_softc *sc;
 1475         size_t size;
 1476         size_t align;
 1477         size_t boundary;
 1478         int flags;
 1479         struct eso_dma *ed;
 1480 {
 1481         int error, wait;
 1482 
 1483         wait = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
 1484         ed->ed_size = size;
 1485         
 1486         error = bus_dmamem_alloc(sc->sc_dmat, ed->ed_size, align, boundary,
 1487             ed->ed_segs, sizeof (ed->ed_segs) / sizeof (ed->ed_segs[0]),
 1488             &ed->ed_nsegs, wait);
 1489         if (error)
 1490                 goto out;
 1491 
 1492         error = bus_dmamem_map(sc->sc_dmat, ed->ed_segs, ed->ed_nsegs,
 1493             ed->ed_size, &ed->ed_addr, wait | BUS_DMA_COHERENT);
 1494         if (error)
 1495                 goto free;
 1496 
 1497         error = bus_dmamap_create(sc->sc_dmat, ed->ed_size, 1, ed->ed_size, 0,
 1498             wait, &ed->ed_map);
 1499         if (error)
 1500                 goto unmap;
 1501 
 1502         error = bus_dmamap_load(sc->sc_dmat, ed->ed_map, ed->ed_addr,
 1503             ed->ed_size, NULL, wait);
 1504         if (error)
 1505                 goto destroy;
 1506 
 1507         return (0);
 1508 
 1509  destroy:
 1510         bus_dmamap_destroy(sc->sc_dmat, ed->ed_map);
 1511  unmap:
 1512         bus_dmamem_unmap(sc->sc_dmat, ed->ed_addr, ed->ed_size);
 1513  free:
 1514         bus_dmamem_free(sc->sc_dmat, ed->ed_segs, ed->ed_nsegs);
 1515  out:
 1516         return (error);
 1517 }
 1518 
 1519 HIDE void
 1520 eso_freemem(sc, ed)
 1521         struct eso_softc *sc;
 1522         struct eso_dma *ed;
 1523 {
 1524 
 1525         bus_dmamap_unload(sc->sc_dmat, ed->ed_map);
 1526         bus_dmamap_destroy(sc->sc_dmat, ed->ed_map);
 1527         bus_dmamem_unmap(sc->sc_dmat, ed->ed_addr, ed->ed_size);
 1528         bus_dmamem_free(sc->sc_dmat, ed->ed_segs, ed->ed_nsegs);
 1529 }
 1530         
 1531 HIDE void *
 1532 eso_allocm(hdl, direction, size, type, flags)
 1533         void *hdl;
 1534         int direction;
 1535         size_t size;
 1536         int type, flags;
 1537 {
 1538         struct eso_softc *sc = hdl;
 1539         struct eso_dma *ed;
 1540         size_t boundary;
 1541         int error;
 1542 
 1543         if ((ed = malloc(size, type, flags)) == NULL)
 1544                 return (NULL);
 1545 
 1546         /*
 1547          * Apparently the Audio 1 DMA controller's current address
 1548          * register can't roll over a 64K address boundary, so we have to
 1549          * take care of that ourselves.  The second channel DMA controller
 1550          * doesn't have that restriction, however.
 1551          */
 1552         if (direction == AUMODE_RECORD)
 1553                 boundary = 0x10000;
 1554         else
 1555                 boundary = 0;
 1556 
 1557 
 1558         error = eso_allocmem(sc, size, 32, boundary, flags, ed);
 1559         if (error) {
 1560                 free(ed, type);
 1561                 return (NULL);
 1562         }
 1563         ed->ed_next = sc->sc_dmas;
 1564         sc->sc_dmas = ed;
 1565 
 1566         return (KVADDR(ed));
 1567 }
 1568 
 1569 HIDE void
 1570 eso_freem(hdl, addr, type)
 1571         void *hdl;
 1572         void *addr;
 1573         int type;
 1574 {
 1575         struct eso_softc *sc = hdl;
 1576         struct eso_dma *p, **pp;
 1577 
 1578         for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->ed_next) {
 1579                 if (KVADDR(p) == addr) {
 1580                         eso_freemem(sc, p);
 1581                         *pp = p->ed_next;
 1582                         free(p, type);
 1583                         return;
 1584                 }
 1585         }
 1586 }
 1587 
 1588 HIDE size_t
 1589 eso_round_buffersize(hdl, direction, bufsize)
 1590         void *hdl;
 1591         int direction;
 1592         size_t bufsize;
 1593 {
 1594 
 1595         /* 64K restriction: ISA at eleven? */
 1596         if (bufsize > 65536)
 1597                 bufsize = 65536;
 1598 
 1599         return (bufsize);
 1600 }
 1601 
 1602 HIDE paddr_t
 1603 eso_mappage(hdl, addr, offs, prot)
 1604         void *hdl;
 1605         void *addr;
 1606         off_t offs;
 1607         int prot;
 1608 {
 1609         struct eso_softc *sc = hdl;
 1610         struct eso_dma *ed;
 1611 
 1612         if (offs < 0)
 1613                 return (-1);
 1614         for (ed = sc->sc_dmas; ed != NULL && KVADDR(ed) == addr;
 1615              ed = ed->ed_next)
 1616                 ;
 1617         if (ed == NULL)
 1618                 return (-1);
 1619         
 1620         return (bus_dmamem_mmap(sc->sc_dmat, ed->ed_segs, ed->ed_nsegs,
 1621             offs, prot, BUS_DMA_WAITOK));
 1622 }
 1623 
 1624 /* ARGSUSED */
 1625 HIDE int
 1626 eso_get_props(hdl)
 1627         void *hdl;
 1628 {
 1629 
 1630         return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT |
 1631             AUDIO_PROP_FULLDUPLEX);
 1632 }
 1633 
 1634 HIDE int
 1635 eso_trigger_output(hdl, start, end, blksize, intr, arg, param)
 1636         void *hdl;
 1637         void *start, *end;
 1638         int blksize;
 1639         void (*intr)(void *);
 1640         void *arg;
 1641         struct audio_params *param;
 1642 {
 1643         struct eso_softc *sc = hdl;
 1644         struct eso_dma *ed;
 1645         uint8_t a2c1;
 1646         
 1647         DPRINTF((
 1648             "%s: trigger_output: start %p, end %p, blksize %d, intr %p(%p)\n",
 1649             sc->sc_dev.dv_xname, start, end, blksize, intr, arg));
 1650         DPRINTF(("%s: param: rate %lu, encoding %u, precision %u, channels %u, sw_code %p, factor %d\n",
 1651             sc->sc_dev.dv_xname, param->sample_rate, param->encoding,
 1652             param->precision, param->channels, param->sw_code, param->factor));
 1653         
 1654         /* Find DMA buffer. */
 1655         for (ed = sc->sc_dmas; ed != NULL && KVADDR(ed) != start;
 1656              ed = ed->ed_next)
 1657                 ;
 1658         if (ed == NULL) {
 1659                 printf("%s: trigger_output: bad addr %p\n",
 1660                     sc->sc_dev.dv_xname, start);
 1661                 return (EINVAL);
 1662         }
 1663         
 1664         sc->sc_pintr = intr;
 1665         sc->sc_parg = arg;
 1666 
 1667         /* DMA transfer count (in `words'!) reload using 2's complement. */
 1668         blksize = -(blksize >> 1);
 1669         eso_write_mixreg(sc, ESO_MIXREG_A2TCRLO, blksize & 0xff);
 1670         eso_write_mixreg(sc, ESO_MIXREG_A2TCRHI, blksize >> 8);
 1671 
 1672         /* Update DAC to reflect DMA count and audio parameters. */
 1673         /* Note: we cache A2C2 in order to avoid r/m/w at interrupt time. */
 1674         if (param->precision * param->factor == 16)
 1675                 sc->sc_a2c2 |= ESO_MIXREG_A2C2_16BIT;
 1676         else
 1677                 sc->sc_a2c2 &= ~ESO_MIXREG_A2C2_16BIT;
 1678         if (param->channels == 2)
 1679                 sc->sc_a2c2 |= ESO_MIXREG_A2C2_STEREO;
 1680         else
 1681                 sc->sc_a2c2 &= ~ESO_MIXREG_A2C2_STEREO;
 1682         if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
 1683             param->encoding == AUDIO_ENCODING_SLINEAR_LE)
 1684                 sc->sc_a2c2 |= ESO_MIXREG_A2C2_SIGNED;
 1685         else
 1686                 sc->sc_a2c2 &= ~ESO_MIXREG_A2C2_SIGNED;
 1687         /* Unmask IRQ. */
 1688         sc->sc_a2c2 |= ESO_MIXREG_A2C2_IRQM;
 1689         eso_write_mixreg(sc, ESO_MIXREG_A2C2, sc->sc_a2c2);
 1690         
 1691         /* Set up DMA controller. */
 1692         bus_space_write_4(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAA, DMAADDR(ed));
 1693         bus_space_write_2(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAC,
 1694             (uint8_t *)end - (uint8_t *)start);
 1695         bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM,
 1696             ESO_IO_A2DMAM_DMAENB | ESO_IO_A2DMAM_AUTO);
 1697         
 1698         /* Start DMA. */
 1699         a2c1 = eso_read_mixreg(sc, ESO_MIXREG_A2C1);
 1700         a2c1 &= ~ESO_MIXREG_A2C1_RESV0; /* Paranoia? XXX bit 5 */
 1701         a2c1 |= ESO_MIXREG_A2C1_FIFOENB | ESO_MIXREG_A2C1_DMAENB |
 1702             ESO_MIXREG_A2C1_AUTO;
 1703         eso_write_mixreg(sc, ESO_MIXREG_A2C1, a2c1);
 1704         
 1705         return (0);
 1706 }
 1707 
 1708 HIDE int
 1709 eso_trigger_input(hdl, start, end, blksize, intr, arg, param)
 1710         void *hdl;
 1711         void *start, *end;
 1712         int blksize;
 1713         void (*intr)(void *);
 1714         void *arg;
 1715         struct audio_params *param;
 1716 {
 1717         struct eso_softc *sc = hdl;
 1718         struct eso_dma *ed;
 1719         uint8_t actl, a1c1;
 1720 
 1721         DPRINTF((
 1722             "%s: trigger_input: start %p, end %p, blksize %d, intr %p(%p)\n",
 1723             sc->sc_dev.dv_xname, start, end, blksize, intr, arg));
 1724         DPRINTF(("%s: param: rate %lu, encoding %u, precision %u, channels %u, sw_code %p, factor %d\n",
 1725             sc->sc_dev.dv_xname, param->sample_rate, param->encoding,
 1726             param->precision, param->channels, param->sw_code, param->factor));
 1727 
 1728         /*
 1729          * If we failed to configure the Audio 1 DMA controller, bail here
 1730          * while retaining availability of the DAC direction (in Audio 2).
 1731          */
 1732         if (!sc->sc_dmac_configured)
 1733                 return (EIO);
 1734 
 1735         /* Find DMA buffer. */
 1736         for (ed = sc->sc_dmas; ed != NULL && KVADDR(ed) != start;
 1737              ed = ed->ed_next)
 1738                 ;
 1739         if (ed == NULL) {
 1740                 printf("%s: trigger_output: bad addr %p\n",
 1741                     sc->sc_dev.dv_xname, start);
 1742                 return (EINVAL);
 1743         }
 1744 
 1745         sc->sc_rintr = intr;
 1746         sc->sc_rarg = arg;
 1747 
 1748         /* Set up ADC DMA converter parameters. */
 1749         actl = eso_read_ctlreg(sc, ESO_CTLREG_ACTL);
 1750         if (param->channels == 2) {
 1751                 actl &= ~ESO_CTLREG_ACTL_MONO;
 1752                 actl |= ESO_CTLREG_ACTL_STEREO;
 1753         } else {
 1754                 actl &= ~ESO_CTLREG_ACTL_STEREO;
 1755                 actl |= ESO_CTLREG_ACTL_MONO;
 1756         }
 1757         eso_write_ctlreg(sc, ESO_CTLREG_ACTL, actl);
 1758 
 1759         /* Set up Transfer Type: maybe move to attach time? */
 1760         eso_write_ctlreg(sc, ESO_CTLREG_A1TT, ESO_CTLREG_A1TT_DEMAND4);
 1761 
 1762         /* DMA transfer count reload using 2's complement. */
 1763         blksize = -blksize;
 1764         eso_write_ctlreg(sc, ESO_CTLREG_A1TCRLO, blksize & 0xff);
 1765         eso_write_ctlreg(sc, ESO_CTLREG_A1TCRHI, blksize >> 8);
 1766 
 1767         /* Set up and enable Audio 1 DMA FIFO. */
 1768         a1c1 = ESO_CTLREG_A1C1_RESV1 | ESO_CTLREG_A1C1_FIFOENB;
 1769         if (param->precision * param->factor == 16)
 1770                 a1c1 |= ESO_CTLREG_A1C1_16BIT;
 1771         if (param->channels == 2)
 1772                 a1c1 |= ESO_CTLREG_A1C1_STEREO;
 1773         else
 1774                 a1c1 |= ESO_CTLREG_A1C1_MONO;
 1775         if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
 1776             param->encoding == AUDIO_ENCODING_SLINEAR_LE)
 1777                 a1c1 |= ESO_CTLREG_A1C1_SIGNED;
 1778         eso_write_ctlreg(sc, ESO_CTLREG_A1C1, a1c1);
 1779 
 1780         /* Set up ADC IRQ/DRQ parameters. */
 1781         eso_write_ctlreg(sc, ESO_CTLREG_LAIC,
 1782             ESO_CTLREG_LAIC_PINENB | ESO_CTLREG_LAIC_EXTENB);
 1783         eso_write_ctlreg(sc, ESO_CTLREG_DRQCTL,
 1784             ESO_CTLREG_DRQCTL_ENB1 | ESO_CTLREG_DRQCTL_EXTENB);
 1785 
 1786         /* Set up and enable DMA controller. */
 1787         bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_CLEAR, 0);
 1788         bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK,
 1789             ESO_DMAC_MASK_MASK);
 1790         bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MODE,
 1791             DMA37MD_WRITE | DMA37MD_LOOP | DMA37MD_DEMAND);
 1792         bus_space_write_4(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_DMAA,
 1793             DMAADDR(ed));
 1794         bus_space_write_2(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_DMAC,
 1795             (uint8_t *)end - (uint8_t *)start - 1);
 1796         bus_space_write_1(sc->sc_dmac_iot, sc->sc_dmac_ioh, ESO_DMAC_MASK, 0);
 1797 
 1798         /* Start DMA. */
 1799         eso_write_ctlreg(sc, ESO_CTLREG_A1C2,
 1800             ESO_CTLREG_A1C2_DMAENB | ESO_CTLREG_A1C2_READ |
 1801             ESO_CTLREG_A1C2_AUTO | ESO_CTLREG_A1C2_ADC);
 1802 
 1803         return (0);
 1804 }
 1805 
 1806 HIDE int
 1807 eso_set_recsrc(sc, recsrc)
 1808         struct eso_softc *sc;
 1809         unsigned int recsrc;
 1810 {
 1811 
 1812         eso_write_mixreg(sc, ESO_MIXREG_ERS, recsrc);
 1813         sc->sc_recsrc = recsrc;
 1814         return (0);
 1815 }
 1816 
 1817 HIDE void
 1818 eso_set_gain(sc, port)
 1819         struct eso_softc *sc;
 1820         unsigned int port;
 1821 {
 1822         uint8_t mixreg, tmp;
 1823 
 1824         switch (port) {
 1825         case ESO_DAC_PLAY_VOL:
 1826                 mixreg = ESO_MIXREG_PVR_A2;
 1827                 break;
 1828         case ESO_MIC_PLAY_VOL:
 1829                 mixreg = ESO_MIXREG_PVR_MIC;
 1830                 break;
 1831         case ESO_LINE_PLAY_VOL:
 1832                 mixreg = ESO_MIXREG_PVR_LINE;
 1833                 break;
 1834         case ESO_SYNTH_PLAY_VOL:
 1835                 mixreg = ESO_MIXREG_PVR_SYNTH;
 1836                 break;
 1837         case ESO_CD_PLAY_VOL:
 1838                 mixreg = ESO_MIXREG_PVR_CD;
 1839                 break;
 1840         case ESO_AUXB_PLAY_VOL:
 1841                 mixreg = ESO_MIXREG_PVR_AUXB;
 1842                 break;
 1843                     
 1844         case ESO_DAC_REC_VOL:
 1845                 mixreg = ESO_MIXREG_RVR_A2;
 1846                 break;
 1847         case ESO_MIC_REC_VOL:
 1848                 mixreg = ESO_MIXREG_RVR_MIC;
 1849                 break;
 1850         case ESO_LINE_REC_VOL:
 1851                 mixreg = ESO_MIXREG_RVR_LINE;
 1852                 break;
 1853         case ESO_SYNTH_REC_VOL:
 1854                 mixreg = ESO_MIXREG_RVR_SYNTH;
 1855                 break;
 1856         case ESO_CD_REC_VOL:
 1857                 mixreg = ESO_MIXREG_RVR_CD;
 1858                 break;
 1859         case ESO_AUXB_REC_VOL:
 1860                 mixreg = ESO_MIXREG_RVR_AUXB;
 1861                 break;
 1862         case ESO_MONO_PLAY_VOL:
 1863                 mixreg = ESO_MIXREG_PVR_MONO;
 1864                 break;
 1865         case ESO_MONO_REC_VOL:
 1866                 mixreg = ESO_MIXREG_RVR_MONO;
 1867                 break;
 1868                 
 1869         case ESO_PCSPEAKER_VOL:
 1870                 /* Special case - only 3-bit, mono, and reserved bits. */
 1871                 tmp = eso_read_mixreg(sc, ESO_MIXREG_PCSVR);
 1872                 tmp &= ESO_MIXREG_PCSVR_RESV;
 1873                 /* Map bits 7:5 -> 2:0. */
 1874                 tmp |= (sc->sc_gain[port][ESO_LEFT] >> 5);
 1875                 eso_write_mixreg(sc, ESO_MIXREG_PCSVR, tmp);
 1876                 return;
 1877 
 1878         case ESO_MASTER_VOL:
 1879                 /* Special case - separate regs, and 6-bit precision. */
 1880                 /* Map bits 7:2 -> 5:0. */
 1881                 eso_write_mixreg(sc, ESO_MIXREG_LMVM,
 1882                     sc->sc_gain[port][ESO_LEFT] >> 2);
 1883                 eso_write_mixreg(sc, ESO_MIXREG_RMVM,
 1884                     sc->sc_gain[port][ESO_RIGHT] >> 2);
 1885                 return;
 1886 
 1887         case ESO_SPATIALIZER:
 1888                 /* Special case - only `mono', and higher precision. */
 1889                 eso_write_mixreg(sc, ESO_MIXREG_SPATLVL,
 1890                     sc->sc_gain[port][ESO_LEFT]);
 1891                 return;
 1892                 
 1893         case ESO_RECORD_VOL:
 1894                 /* Very Special case, controller register. */
 1895                 eso_write_ctlreg(sc, ESO_CTLREG_RECLVL,ESO_4BIT_GAIN_TO_STEREO(
 1896                    sc->sc_gain[port][ESO_LEFT], sc->sc_gain[port][ESO_RIGHT]));
 1897                 return;
 1898 
 1899         default:
 1900 #ifdef DIAGNOSTIC               
 1901                 panic("eso_set_gain: bad port %u", port);
 1902                 /* NOTREACHED */
 1903 #else
 1904                 return;
 1905 #endif          
 1906                 }
 1907 
 1908         eso_write_mixreg(sc, mixreg, ESO_4BIT_GAIN_TO_STEREO(
 1909             sc->sc_gain[port][ESO_LEFT], sc->sc_gain[port][ESO_RIGHT]));
 1910 }
 1911 
 1912 
 1913 HIDE void
 1914 eso_powerhook(why, self)
 1915         int why;
 1916         void *self;
 1917 {
 1918         struct eso_softc *sc = (struct eso_softc *)self;        
 1919 
 1920         if (why != PWR_RESUME) {
 1921                 eso_halt_output(sc);
 1922                 eso_halt_input(sc);
 1923                 
 1924                 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ESO_IO_A2DMAM, 0);
 1925                 bus_space_write_1(sc->sc_dmac_iot,
 1926                                   sc->sc_dmac_ioh, ESO_DMAC_CLEAR, 0);
 1927                 bus_space_write_1(sc->sc_sb_iot,
 1928                                   sc->sc_sb_ioh, ESO_SB_STATUSFLAGS, 3);
 1929                 
 1930                 /* shut down dma */
 1931                 pci_conf_write(sc->sc_pa.pa_pc,
 1932                                sc->sc_pa.pa_tag, ESO_PCI_DDMAC, 0);
 1933         } else
 1934                 eso_setup(sc, 0);
 1935 }

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