root/dev/pci/cmpci.c

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

DEFINITIONS

This source file includes following definitions.
  1. cmpci_mixerreg_read
  2. cmpci_mixerreg_write
  3. cmpci_reg_partial_write_1
  4. cmpci_reg_partial_write_4
  5. cmpci_reg_set_1
  6. cmpci_reg_clear_1
  7. cmpci_reg_set_4
  8. cmpci_reg_clear_4
  9. cmpci_reg_set_reg_misc
  10. cmpci_reg_clear_reg_misc
  11. cmpci_rate_to_index
  12. cmpci_index_to_rate
  13. cmpci_index_to_divider
  14. cmpci_match
  15. cmpci_attach
  16. cmpci_intr
  17. cmpci_open
  18. cmpci_close
  19. cmpci_query_encoding
  20. cmpci_set_params
  21. cmpci_round_blocksize
  22. cmpci_halt_output
  23. cmpci_halt_input
  24. cmpci_getdev
  25. cmpci_query_devinfo
  26. cmpci_alloc_dmamem
  27. cmpci_free_dmamem
  28. cmpci_find_dmamem
  29. cmpci_print_dmamem
  30. cmpci_malloc
  31. cmpci_free
  32. cmpci_adjust
  33. cmpci_set_mixer_gain
  34. cmpci_set_out_ports
  35. cmpci_set_in_ports
  36. cmpci_set_port
  37. cmpci_get_port
  38. cmpci_round_buffersize
  39. cmpci_mappage
  40. cmpci_get_props
  41. cmpci_trigger_output
  42. cmpci_trigger_input

    1 /*      $OpenBSD: cmpci.c,v 1.14 2006/07/27 00:45:59 brad Exp $ */
    2 /*      $NetBSD: cmpci.c,v 1.25 2004/10/26 06:32:20 xtraeme Exp $       */
    3 
    4 /*
    5  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Takuya SHIOZAKI <tshiozak@NetBSD.org> .
   10  *
   11  * This code is derived from software contributed to The NetBSD Foundation
   12  * by ITOH Yasufumi.
   13  *
   14  * Redistribution and use in source and binary forms, with or without
   15  * modification, are permitted provided that the following conditions
   16  * are met:
   17  * 1. Redistributions of source code must retain the above copyright
   18  *    notice, this list of conditions and the following disclaimer.
   19  * 2. Redistributions in binary form must reproduce the above copyright
   20  *    notice, this list of conditions and the following disclaimer in the
   21  *    documentation and/or other materials provided with the distribution.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  *
   35  */
   36 
   37 /*
   38  * C-Media CMI8x38 Audio Chip Support.
   39  *
   40  * TODO:
   41  *   - 4ch / 6ch support.
   42  *   - Joystick support.
   43  *
   44  */
   45 
   46 #if 0
   47 #include <sys/cdefs.h>
   48 __KERNEL_RCSID(0, "$NetBSD: cmpci.c,v 1.25 2004/10/26 06:32:20 xtraeme Exp $");
   49 #endif
   50 
   51 #if defined(AUDIO_DEBUG) || defined(DEBUG)
   52 #define DPRINTF(x) if (cmpcidebug) printf x
   53 int cmpcidebug = 0;
   54 #else
   55 #define DPRINTF(x)
   56 #endif
   57 
   58 #include <sys/param.h>
   59 #include <sys/systm.h>
   60 #include <sys/kernel.h>
   61 #include <sys/malloc.h>
   62 #include <sys/device.h>
   63 #include <sys/proc.h>
   64 
   65 #include <dev/pci/pcidevs.h>
   66 #include <dev/pci/pcivar.h>
   67 
   68 #include <sys/audioio.h>
   69 #include <dev/audio_if.h>
   70 #include <dev/midi_if.h>
   71 
   72 #include <dev/mulaw.h>
   73 #include <dev/auconv.h>
   74 #include <dev/pci/cmpcireg.h>
   75 #include <dev/pci/cmpcivar.h>
   76 
   77 #include <dev/ic/mpuvar.h>
   78 #include <machine/bus.h>
   79 #include <machine/intr.h>
   80 
   81 /*
   82  * Low-level HW interface
   83  */
   84 __inline uint8_t cmpci_mixerreg_read(struct cmpci_softc *,
   85                                                  uint8_t);
   86 __inline void cmpci_mixerreg_write(struct cmpci_softc *,
   87                                                uint8_t, uint8_t);
   88 __inline void cmpci_reg_partial_write_1(struct cmpci_softc *,
   89                                                     int, int,
   90                                                     unsigned, unsigned);
   91 __inline void cmpci_reg_partial_write_4(struct cmpci_softc *,
   92                                                     int, int,
   93                                                     uint32_t, uint32_t);
   94 __inline void cmpci_reg_set_1(struct cmpci_softc *,
   95                                           int, uint8_t);
   96 __inline void cmpci_reg_clear_1(struct cmpci_softc *,
   97                                             int, uint8_t);
   98 __inline void cmpci_reg_set_4(struct cmpci_softc *,
   99                                           int, uint32_t);
  100 __inline void cmpci_reg_clear_4(struct cmpci_softc *,
  101                                             int, uint32_t);
  102 __inline void cmpci_reg_set_reg_misc(struct cmpci_softc *,
  103                                                  uint32_t);
  104 __inline void cmpci_reg_clear_reg_misc(struct cmpci_softc *,
  105                                                    uint32_t);
  106 int cmpci_rate_to_index(int);
  107 __inline int cmpci_index_to_rate(int);
  108 __inline int cmpci_index_to_divider(int);
  109 
  110 int cmpci_adjust(int, int);
  111 void cmpci_set_mixer_gain(struct cmpci_softc *, int);
  112 void cmpci_set_out_ports(struct cmpci_softc *);
  113 int cmpci_set_in_ports(struct cmpci_softc *);
  114 
  115 /*
  116  * autoconf interface
  117  */
  118 int cmpci_match(struct device *, void *, void *);
  119 void cmpci_attach(struct device *, struct device *, void *);
  120 
  121 struct cfdriver cmpci_cd = {
  122         NULL, "cmpci", DV_DULL
  123 };
  124 
  125 struct cfattach cmpci_ca = {
  126         sizeof (struct cmpci_softc), cmpci_match, cmpci_attach
  127 };
  128 
  129 /* interrupt */
  130 int cmpci_intr(void *);
  131 
  132 /*
  133  * DMA stuff
  134  */
  135 int cmpci_alloc_dmamem(struct cmpci_softc *,
  136                                    size_t, int,
  137                                    int, caddr_t *);
  138 int cmpci_free_dmamem(struct cmpci_softc *, caddr_t,
  139                                   int);
  140 struct cmpci_dmanode * cmpci_find_dmamem(struct cmpci_softc *,
  141                                                      caddr_t);
  142 
  143 /*
  144  * Interface to machine independent layer
  145  */
  146 int cmpci_open(void *, int);
  147 void cmpci_close(void *);
  148 int cmpci_query_encoding(void *, struct audio_encoding *);
  149 int cmpci_set_params(void *, int, int,
  150                                  struct audio_params *,
  151                                  struct audio_params *);
  152 int cmpci_round_blocksize(void *, int);
  153 int cmpci_halt_output(void *);
  154 int cmpci_halt_input(void *);
  155 int cmpci_getdev(void *, struct audio_device *);
  156 int cmpci_set_port(void *, mixer_ctrl_t *);
  157 int cmpci_get_port(void *, mixer_ctrl_t *);
  158 int cmpci_query_devinfo(void *, mixer_devinfo_t *);
  159 void *cmpci_malloc(void *, int, size_t, int, int);
  160 void cmpci_free(void *, void *, int);
  161 size_t cmpci_round_buffersize(void *, int, size_t);
  162 paddr_t cmpci_mappage(void *, void *, off_t, int);
  163 int cmpci_get_props(void *);
  164 int cmpci_trigger_output(void *, void *, void *, int,
  165                                      void (*)(void *), void *,
  166                                      struct audio_params *);
  167 int cmpci_trigger_input(void *, void *, void *, int,
  168                                     void (*)(void *), void *,
  169                                     struct audio_params *);
  170 
  171 struct audio_hw_if cmpci_hw_if = {
  172         cmpci_open,             /* open */
  173         cmpci_close,            /* close */
  174         NULL,                   /* drain */
  175         cmpci_query_encoding,   /* query_encoding */
  176         cmpci_set_params,       /* set_params */
  177         cmpci_round_blocksize,  /* round_blocksize */
  178         NULL,                   /* commit_settings */
  179         NULL,                   /* init_output */
  180         NULL,                   /* init_input */
  181         NULL,                   /* start_output */
  182         NULL,                   /* start_input */
  183         cmpci_halt_output,      /* halt_output */
  184         cmpci_halt_input,       /* halt_input */
  185         NULL,                   /* speaker_ctl */
  186         cmpci_getdev,           /* getdev */
  187         NULL,                   /* setfd */
  188         cmpci_set_port,         /* set_port */
  189         cmpci_get_port,         /* get_port */
  190         cmpci_query_devinfo,    /* query_devinfo */
  191         cmpci_malloc,           /* malloc */
  192         cmpci_free,             /* free */
  193         cmpci_round_buffersize,/* round_buffersize */
  194         cmpci_mappage,          /* mappage */
  195         cmpci_get_props,        /* get_props */
  196         cmpci_trigger_output,   /* trigger_output */
  197         cmpci_trigger_input,    /* trigger_input */
  198 };
  199 
  200 /*
  201  * Low-level HW interface
  202  */
  203 
  204 /* mixer register read/write */
  205 __inline uint8_t
  206 cmpci_mixerreg_read(struct cmpci_softc *sc, uint8_t no)
  207 {
  208         uint8_t ret;
  209 
  210         bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBADDR, no);
  211         delay(10);
  212         ret = bus_space_read_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBDATA);
  213         delay(10);
  214         return ret;
  215 }
  216 
  217 __inline void
  218 cmpci_mixerreg_write(struct cmpci_softc *sc, uint8_t no, uint8_t val)
  219 {
  220         bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBADDR, no);
  221         delay(10);
  222         bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBDATA, val);
  223         delay(10);
  224 }
  225 
  226 /* register partial write */
  227 __inline void
  228 cmpci_reg_partial_write_1(struct cmpci_softc *sc, int no, int shift,
  229     unsigned mask, unsigned val)
  230 {
  231         bus_space_write_1(sc->sc_iot, sc->sc_ioh, no,
  232             (val<<shift) |
  233             (bus_space_read_1(sc->sc_iot, sc->sc_ioh, no) & ~(mask<<shift)));
  234         delay(10);
  235 }
  236 
  237 __inline void
  238 cmpci_reg_partial_write_4(struct cmpci_softc *sc, int no, int shift,
  239     uint32_t mask, uint32_t val)
  240 {
  241         bus_space_write_4(sc->sc_iot, sc->sc_ioh, no,
  242             (val<<shift) |
  243             (bus_space_read_4(sc->sc_iot, sc->sc_ioh, no) & ~(mask<<shift)));
  244         delay(10);
  245 }
  246 
  247 /* register set/clear bit */
  248 __inline void
  249 cmpci_reg_set_1(struct cmpci_softc *sc, int no, uint8_t mask)
  250 {
  251         bus_space_write_1(sc->sc_iot, sc->sc_ioh, no,
  252             (bus_space_read_1(sc->sc_iot, sc->sc_ioh, no) | mask));
  253         delay(10);
  254 }
  255 
  256 __inline void
  257 cmpci_reg_clear_1(struct cmpci_softc *sc, int no, uint8_t mask)
  258 {
  259         bus_space_write_1(sc->sc_iot, sc->sc_ioh, no,
  260             (bus_space_read_1(sc->sc_iot, sc->sc_ioh, no) & ~mask));
  261         delay(10);
  262 }
  263 
  264 __inline void
  265 cmpci_reg_set_4(struct cmpci_softc *sc, int no, uint32_t mask)
  266 {
  267         /* use cmpci_reg_set_reg_misc() for CMPCI_REG_MISC */
  268         KDASSERT(no != CMPCI_REG_MISC);
  269 
  270         bus_space_write_4(sc->sc_iot, sc->sc_ioh, no,
  271             (bus_space_read_4(sc->sc_iot, sc->sc_ioh, no) | mask));
  272         delay(10);
  273 }
  274 
  275 __inline void
  276 cmpci_reg_clear_4(struct cmpci_softc *sc, int no, uint32_t mask)
  277 {
  278         /* use cmpci_reg_clear_reg_misc() for CMPCI_REG_MISC */
  279         KDASSERT(no != CMPCI_REG_MISC);
  280 
  281         bus_space_write_4(sc->sc_iot, sc->sc_ioh, no,
  282             (bus_space_read_4(sc->sc_iot, sc->sc_ioh, no) & ~mask));
  283         delay(10);
  284 }
  285 
  286 /*
  287  * The CMPCI_REG_MISC register needs special handling, since one of
  288  * its bits has different read/write values.
  289  */
  290 __inline void
  291 cmpci_reg_set_reg_misc(struct cmpci_softc *sc, uint32_t mask)
  292 {
  293         sc->sc_reg_misc |= mask;
  294         bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_MISC,
  295             sc->sc_reg_misc);
  296         delay(10);
  297 }
  298 
  299 __inline void
  300 cmpci_reg_clear_reg_misc(struct cmpci_softc *sc, uint32_t mask)
  301 {
  302         sc->sc_reg_misc &= ~mask;
  303         bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_MISC,
  304             sc->sc_reg_misc);
  305         delay(10);
  306 }
  307 
  308 /* rate */
  309 static const struct {
  310         int rate;
  311         int divider;
  312 } cmpci_rate_table[CMPCI_REG_NUMRATE] = {
  313 #define _RATE(n) { n, CMPCI_REG_RATE_ ## n }
  314         _RATE(5512),
  315         _RATE(8000),
  316         _RATE(11025),
  317         _RATE(16000),
  318         _RATE(22050),
  319         _RATE(32000),
  320         _RATE(44100),
  321         _RATE(48000)
  322 #undef  _RATE
  323 };
  324 
  325 int
  326 cmpci_rate_to_index(int rate)
  327 {
  328         int i;
  329 
  330         for (i = 0; i < CMPCI_REG_NUMRATE - 1; i++)
  331                 if (rate <=
  332                     (cmpci_rate_table[i].rate + cmpci_rate_table[i+1].rate) / 2)
  333                         return i;
  334         return i;  /* 48000 */
  335 }
  336 
  337 __inline int
  338 cmpci_index_to_rate(int index)
  339 {
  340         return cmpci_rate_table[index].rate;
  341 }
  342 
  343 __inline int
  344 cmpci_index_to_divider(int index)
  345 {
  346         return cmpci_rate_table[index].divider;
  347 }
  348 
  349 const struct pci_matchid cmpci_devices[] = {
  350         { PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8338A },
  351         { PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8338B },
  352         { PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8738 },
  353         { PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8738B }
  354 };
  355 
  356 /*
  357  * interface to configure the device.
  358  */
  359 
  360 int
  361 cmpci_match(struct device *parent, void *match, void *aux)
  362 {
  363         return (pci_matchbyid((struct pci_attach_args *)aux, cmpci_devices,
  364             sizeof(cmpci_devices)/sizeof(cmpci_devices[0])));
  365 }
  366 
  367 void
  368 cmpci_attach(struct device *parent, struct device *self, void *aux)
  369 {
  370         struct cmpci_softc *sc = (struct cmpci_softc *)self;
  371         struct pci_attach_args *pa = (struct pci_attach_args *)aux;
  372         struct audio_attach_args aa;
  373         pci_intr_handle_t ih;
  374         char const *intrstr;
  375         int i, v;
  376 
  377         sc->sc_id = pa->pa_id;
  378         sc->sc_class = pa->pa_class;
  379         switch (PCI_PRODUCT(sc->sc_id)) {
  380         case PCI_PRODUCT_CMI_CMI8338A:
  381                 /*FALLTHROUGH*/
  382         case PCI_PRODUCT_CMI_CMI8338B:
  383                 sc->sc_capable = CMPCI_CAP_CMI8338;
  384                 break;
  385         case PCI_PRODUCT_CMI_CMI8738:
  386                 /*FALLTHROUGH*/
  387         case PCI_PRODUCT_CMI_CMI8738B:
  388                 sc->sc_capable = CMPCI_CAP_CMI8738;
  389                 break;
  390         }
  391 
  392         /* map I/O space */
  393         if (pci_mapreg_map(pa, CMPCI_PCI_IOBASEREG, PCI_MAPREG_TYPE_IO, 0,
  394                            &sc->sc_iot, &sc->sc_ioh, NULL, NULL, 0)) {
  395                 printf(": failed to map I/O space\n");
  396                 return;
  397         }
  398 
  399         /* interrupt */
  400         if (pci_intr_map(pa, &ih)) {
  401                 printf(": failed to map interrupt\n");
  402                 return;
  403         }
  404         intrstr = pci_intr_string(pa->pa_pc, ih);
  405         sc->sc_ih=pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, cmpci_intr, sc,
  406             sc->sc_dev.dv_xname);
  407         if (sc->sc_ih == NULL) {
  408                 printf(": failed to establish interrupt");
  409                 if (intrstr != NULL)
  410                         printf(" at %s", intrstr);
  411                 printf("\n");
  412                 return;
  413         }
  414         printf(": %s\n", intrstr);
  415 
  416         sc->sc_dmat = pa->pa_dmat;
  417 
  418         audio_attach_mi(&cmpci_hw_if, sc, &sc->sc_dev);
  419 
  420         /* attach OPL device */
  421         aa.type = AUDIODEV_TYPE_OPL;
  422         aa.hwif = NULL;
  423         aa.hdl = NULL;
  424         (void)config_found(&sc->sc_dev, &aa, audioprint);
  425 
  426         /* attach MPU-401 device */
  427         aa.type = AUDIODEV_TYPE_MPU;
  428         aa.hwif = NULL;
  429         aa.hdl = NULL;
  430         if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
  431             CMPCI_REG_MPU_BASE, CMPCI_REG_MPU_SIZE, &sc->sc_mpu_ioh) == 0)
  432                 sc->sc_mpudev = config_found(&sc->sc_dev, &aa, audioprint);
  433 
  434         /* get initial value (this is 0 and may be omitted but just in case) */
  435         sc->sc_reg_misc = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
  436             CMPCI_REG_MISC) & ~CMPCI_REG_SPDIF48K;
  437 
  438         cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_RESET, 0);
  439         cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, 0);
  440         cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, 0);
  441         cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX,
  442             CMPCI_SB16_SW_CD|CMPCI_SB16_SW_MIC|CMPCI_SB16_SW_LINE);
  443         for (i = 0; i < CMPCI_NDEVS; i++) {
  444                 switch(i) {
  445                 /*
  446                  * CMI8738 defaults are
  447                  *  master:     0xe0    (0x00 - 0xf8)
  448                  *  FM, DAC:    0xc0    (0x00 - 0xf8)
  449                  *  PC speaker: 0x80    (0x00 - 0xc0)
  450                  *  others:     0
  451                  */
  452                 /* volume */
  453                 case CMPCI_MASTER_VOL:
  454                         v = 128;        /* 224 */
  455                         break;
  456                 case CMPCI_FM_VOL:
  457                 case CMPCI_DAC_VOL:
  458                         v = 192;
  459                         break;
  460                 case CMPCI_PCSPEAKER:
  461                         v = 128;
  462                         break;
  463 
  464                 /* booleans, set to true */
  465                 case CMPCI_CD_MUTE:
  466                 case CMPCI_MIC_MUTE:
  467                 case CMPCI_LINE_IN_MUTE:
  468                 case CMPCI_AUX_IN_MUTE:
  469                         v = 1;
  470                         break;
  471 
  472                 /* volume with inital value 0 */
  473                 case CMPCI_CD_VOL:
  474                 case CMPCI_LINE_IN_VOL:
  475                 case CMPCI_AUX_IN_VOL:
  476                 case CMPCI_MIC_VOL:
  477                 case CMPCI_MIC_RECVOL:
  478                         /* FALLTHROUGH */
  479 
  480                 /* others are cleared */
  481                 case CMPCI_MIC_PREAMP:
  482                 case CMPCI_RECORD_SOURCE:
  483                 case CMPCI_PLAYBACK_MODE:
  484                 case CMPCI_SPDIF_IN_SELECT:
  485                 case CMPCI_SPDIF_IN_PHASE:
  486                 case CMPCI_SPDIF_LOOP:
  487                 case CMPCI_SPDIF_OUT_PLAYBACK:
  488                 case CMPCI_SPDIF_OUT_VOLTAGE:
  489                 case CMPCI_MONITOR_DAC:
  490                 case CMPCI_REAR:
  491                 case CMPCI_INDIVIDUAL:
  492                 case CMPCI_REVERSE:
  493                 case CMPCI_SURROUND:
  494                 default:
  495                         v = 0;
  496                         break;
  497                 }
  498                 sc->sc_gain[i][CMPCI_LEFT] = sc->sc_gain[i][CMPCI_RIGHT] = v;
  499                 cmpci_set_mixer_gain(sc, i);
  500         }
  501 }
  502 
  503 int
  504 cmpci_intr(void *handle)
  505 {
  506         struct cmpci_softc *sc = handle;
  507         uint32_t intrstat;
  508 
  509         intrstat = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
  510             CMPCI_REG_INTR_STATUS);
  511 
  512         if (!(intrstat & CMPCI_REG_ANY_INTR))
  513                 return 0;
  514 
  515         delay(10);
  516 
  517         /* disable and reset intr */
  518         if (intrstat & CMPCI_REG_CH0_INTR)
  519                 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL,
  520                    CMPCI_REG_CH0_INTR_ENABLE);
  521         if (intrstat & CMPCI_REG_CH1_INTR)
  522                 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL,
  523                     CMPCI_REG_CH1_INTR_ENABLE);
  524 
  525         if (intrstat & CMPCI_REG_CH0_INTR) {
  526                 if (sc->sc_play.intr != NULL)
  527                         (*sc->sc_play.intr)(sc->sc_play.intr_arg);
  528         }
  529         if (intrstat & CMPCI_REG_CH1_INTR) {
  530                 if (sc->sc_rec.intr != NULL)
  531                         (*sc->sc_rec.intr)(sc->sc_rec.intr_arg);
  532         }
  533 
  534         /* enable intr */
  535         if (intrstat & CMPCI_REG_CH0_INTR)
  536                 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL,
  537                     CMPCI_REG_CH0_INTR_ENABLE);
  538         if (intrstat & CMPCI_REG_CH1_INTR)
  539                 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL,
  540                     CMPCI_REG_CH1_INTR_ENABLE);
  541 
  542 #if 0
  543         if (intrstat & CMPCI_REG_UART_INTR && sc->sc_mpudev != NULL)
  544                 mpu_intr(sc->sc_mpudev);
  545 #endif
  546 
  547         return 1;
  548 }
  549 
  550 /* open/close */
  551 int
  552 cmpci_open(void *handle, int flags)
  553 {
  554         return 0;
  555 }
  556 
  557 void
  558 cmpci_close(void *handle)
  559 {
  560 }
  561 
  562 int
  563 cmpci_query_encoding(void *handle, struct audio_encoding *fp)
  564 {
  565         switch (fp->index) {
  566         case 0:
  567                 strlcpy(fp->name, AudioEulinear, sizeof fp->name);
  568                 fp->encoding = AUDIO_ENCODING_ULINEAR;
  569                 fp->precision = 8;
  570                 fp->flags = 0;
  571                 break;
  572         case 1:
  573                 strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
  574                 fp->encoding = AUDIO_ENCODING_ULAW;
  575                 fp->precision = 8;
  576                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  577                 break;
  578         case 2:
  579                 strlcpy(fp->name, AudioEalaw, sizeof fp->name);
  580                 fp->encoding = AUDIO_ENCODING_ALAW;
  581                 fp->precision = 8;
  582                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  583                 break;
  584         case 3:
  585                 strlcpy(fp->name, AudioEslinear, sizeof fp->name);
  586                 fp->encoding = AUDIO_ENCODING_SLINEAR;
  587                 fp->precision = 8;
  588                 fp->flags = 0;
  589                 break;
  590         case 4:
  591                 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
  592                 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
  593                 fp->precision = 16;
  594                 fp->flags = 0;
  595                 break;
  596         case 5:
  597                 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
  598                 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
  599                 fp->precision = 16;
  600                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  601                 break;
  602         case 6:
  603                 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
  604                 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
  605                 fp->precision = 16;
  606                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  607                 break;
  608         case 7:
  609                 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
  610                 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
  611                 fp->precision = 16;
  612                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  613                 break;
  614         default:
  615                 return EINVAL;
  616         }
  617         return 0;
  618 }
  619 
  620 int
  621 cmpci_set_params(void *handle, int setmode, int usemode,
  622     struct audio_params *play, struct audio_params *rec)
  623 {
  624         int i;
  625         struct cmpci_softc *sc = handle;
  626 
  627         for (i = 0; i < 2; i++) {
  628                 int md_format;
  629                 int md_divide;
  630                 int md_index;
  631                 int mode;
  632                 struct audio_params *p;
  633 
  634                 switch (i) {
  635                 case 0:
  636                         mode = AUMODE_PLAY;
  637                         p = play;
  638                         break;
  639                 case 1:
  640                         mode = AUMODE_RECORD;
  641                         p = rec;
  642                         break;
  643                 default:
  644                         return EINVAL;
  645                 }
  646 
  647                 if (!(setmode & mode))
  648                         continue;
  649 
  650                 /* format */
  651                 p->sw_code = NULL;
  652                 switch (p->channels) {
  653                 case 1:
  654                         md_format = CMPCI_REG_FORMAT_MONO;
  655                         break;
  656                 case 2:
  657                         md_format = CMPCI_REG_FORMAT_STEREO;
  658                         break;
  659                 default:
  660                         return (EINVAL);
  661                 }
  662                 switch (p->encoding) {
  663                 case AUDIO_ENCODING_ULAW:
  664                         if (p->precision != 8)
  665                                 return (EINVAL);
  666                         if (mode & AUMODE_PLAY) {
  667                                 p->factor = 2;
  668                                 p->sw_code = mulaw_to_slinear16_le;
  669                                 md_format |= CMPCI_REG_FORMAT_16BIT;
  670                         } else {
  671                                 p->sw_code = ulinear8_to_mulaw;
  672                                 md_format |= CMPCI_REG_FORMAT_8BIT;
  673                         }
  674                         break;
  675                 case AUDIO_ENCODING_ALAW:
  676                         if (p->precision != 8)
  677                                 return (EINVAL);
  678                         if (mode & AUMODE_PLAY) {
  679                                 p->factor = 2;
  680                                 p->sw_code = alaw_to_slinear16_le;
  681                                 md_format |= CMPCI_REG_FORMAT_16BIT;
  682                         } else {
  683                                 p->sw_code = ulinear8_to_alaw;
  684                                 md_format |= CMPCI_REG_FORMAT_8BIT;
  685                         }
  686                         break;
  687                 case AUDIO_ENCODING_SLINEAR_LE:
  688                         switch (p->precision) {
  689                         case 8:
  690                                 p->sw_code = change_sign8;
  691                                 md_format |= CMPCI_REG_FORMAT_8BIT;
  692                                 break;
  693                         case 16:
  694                                 md_format |= CMPCI_REG_FORMAT_16BIT;
  695                                 break;
  696                         default:
  697                                 return (EINVAL);
  698                         }
  699                         break;
  700                 case AUDIO_ENCODING_SLINEAR_BE:
  701                         switch (p->precision) {
  702                         case 8:
  703                                 md_format |= CMPCI_REG_FORMAT_8BIT;
  704                                 p->sw_code = change_sign8;
  705                                 break;
  706                         case 16:
  707                                 md_format |= CMPCI_REG_FORMAT_16BIT;
  708                                 p->sw_code = swap_bytes;
  709                                 break;
  710                         default:
  711                                 return (EINVAL);
  712                         }
  713                         break;
  714                 case AUDIO_ENCODING_ULINEAR_LE:
  715                         switch (p->precision) {
  716                         case 8:
  717                                 md_format |= CMPCI_REG_FORMAT_8BIT;
  718                                 break;
  719                         case 16:
  720                                 md_format |= CMPCI_REG_FORMAT_16BIT;
  721                                 p->sw_code = change_sign16_le;
  722                                 break;
  723                         default:
  724                                 return (EINVAL);
  725                         }
  726                         break;
  727                 case AUDIO_ENCODING_ULINEAR_BE:
  728                         switch (p->precision) {
  729                         case 8:
  730                                 md_format |= CMPCI_REG_FORMAT_8BIT;
  731                                 break;
  732                         case 16:
  733                                 md_format |= CMPCI_REG_FORMAT_16BIT;
  734                                 if (mode & AUMODE_PLAY)
  735                                         p->sw_code =
  736                                             swap_bytes_change_sign16_le;
  737                                 else
  738                                         p->sw_code =
  739                                             change_sign16_swap_bytes_le;
  740                                 break;
  741                         default:
  742                                 return (EINVAL);
  743                         }
  744                         break;
  745                 default:
  746                         return (EINVAL);
  747                 }
  748                 if (mode & AUMODE_PLAY)
  749                         cmpci_reg_partial_write_4(sc,
  750                            CMPCI_REG_CHANNEL_FORMAT,
  751                            CMPCI_REG_CH0_FORMAT_SHIFT,
  752                            CMPCI_REG_CH0_FORMAT_MASK, md_format);
  753                 else
  754                         cmpci_reg_partial_write_4(sc,
  755                            CMPCI_REG_CHANNEL_FORMAT,
  756                            CMPCI_REG_CH1_FORMAT_SHIFT,
  757                            CMPCI_REG_CH1_FORMAT_MASK, md_format);
  758                 /* sample rate */
  759                 md_index = cmpci_rate_to_index(p->sample_rate);
  760                 md_divide = cmpci_index_to_divider(md_index);
  761                 p->sample_rate = cmpci_index_to_rate(md_index);
  762                 DPRINTF(("%s: sample:%d, divider=%d\n",
  763                          sc->sc_dev.dv_xname, (int)p->sample_rate, md_divide));
  764                 if (mode & AUMODE_PLAY) {
  765                         cmpci_reg_partial_write_4(sc,
  766                             CMPCI_REG_FUNC_1, CMPCI_REG_DAC_FS_SHIFT,
  767                             CMPCI_REG_DAC_FS_MASK, md_divide);
  768                         sc->sc_play.md_divide = md_divide;
  769                 } else {
  770                         cmpci_reg_partial_write_4(sc,
  771                             CMPCI_REG_FUNC_1, CMPCI_REG_ADC_FS_SHIFT,
  772                             CMPCI_REG_ADC_FS_MASK, md_divide);
  773                         sc->sc_rec.md_divide = md_divide;
  774                 }
  775                 cmpci_set_out_ports(sc);
  776                 cmpci_set_in_ports(sc);
  777         }
  778         return 0;
  779 }
  780 
  781 /* ARGSUSED */
  782 int
  783 cmpci_round_blocksize(void *handle, int block)
  784 {
  785         return ((block + 3) & -4);
  786 }
  787 
  788 int
  789 cmpci_halt_output(void *handle)
  790 {
  791         struct cmpci_softc *sc = handle;
  792         int s;
  793 
  794         s = splaudio();
  795         sc->sc_play.intr = NULL;
  796         cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE);
  797         cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_ENABLE);
  798         /* wait for reset DMA */
  799         cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET);
  800         delay(10);
  801         cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET);
  802         splx(s);
  803 
  804         return 0;
  805 }
  806 
  807 int
  808 cmpci_halt_input(void *handle)
  809 {
  810         struct cmpci_softc *sc = handle;
  811         int s;
  812 
  813         s = splaudio();
  814         sc->sc_rec.intr = NULL;
  815         cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
  816         cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE);
  817         /* wait for reset DMA */
  818         cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET);
  819         delay(10);
  820         cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET);
  821         splx(s);
  822 
  823         return 0;
  824 }
  825 
  826 /* get audio device information */
  827 int
  828 cmpci_getdev(void *handle, struct audio_device *ad)
  829 {
  830         struct cmpci_softc *sc = handle;
  831 
  832         strncpy(ad->name, "CMI PCI Audio", sizeof(ad->name));
  833         snprintf(ad->version, sizeof(ad->version), "0x%02x",
  834                  PCI_REVISION(sc->sc_class));
  835         switch (PCI_PRODUCT(sc->sc_id)) {
  836         case PCI_PRODUCT_CMI_CMI8338A:
  837                 strncpy(ad->config, "CMI8338A", sizeof(ad->config));
  838                 break;
  839         case PCI_PRODUCT_CMI_CMI8338B:
  840                 strncpy(ad->config, "CMI8338B", sizeof(ad->config));
  841                 break;
  842         case PCI_PRODUCT_CMI_CMI8738:
  843                 strncpy(ad->config, "CMI8738", sizeof(ad->config));
  844                 break;
  845         case PCI_PRODUCT_CMI_CMI8738B:
  846                 strncpy(ad->config, "CMI8738B", sizeof(ad->config));
  847                 break;
  848         default:
  849                 strncpy(ad->config, "unknown", sizeof(ad->config));
  850         }
  851 
  852         return 0;
  853 }
  854 
  855 /* mixer device information */
  856 int
  857 cmpci_query_devinfo(void *handle, mixer_devinfo_t *dip)
  858 {
  859         static const char *const mixer_port_names[] = {
  860                 AudioNdac, AudioNfmsynth, AudioNcd, AudioNline, AudioNaux,
  861                 AudioNmicrophone
  862         };
  863         static const char *const mixer_classes[] = {
  864                 AudioCinputs, AudioCoutputs, AudioCrecord, CmpciCplayback,
  865                 CmpciCspdif
  866         };
  867         struct cmpci_softc *sc = handle;
  868         int i;
  869 
  870         dip->prev = dip->next = AUDIO_MIXER_LAST;
  871 
  872         switch (dip->index) {
  873         case CMPCI_INPUT_CLASS:
  874         case CMPCI_OUTPUT_CLASS:
  875         case CMPCI_RECORD_CLASS:
  876         case CMPCI_PLAYBACK_CLASS:
  877         case CMPCI_SPDIF_CLASS:
  878                 dip->type = AUDIO_MIXER_CLASS;
  879                 dip->mixer_class = dip->index;
  880                 strlcpy(dip->label.name,
  881                     mixer_classes[dip->index - CMPCI_INPUT_CLASS],
  882                     sizeof dip->label.name);
  883                 return 0;
  884 
  885         case CMPCI_AUX_IN_VOL:
  886                 dip->un.v.delta = 1 << (8 - CMPCI_REG_AUX_VALBITS);
  887                 goto vol1;
  888         case CMPCI_DAC_VOL:
  889         case CMPCI_FM_VOL:
  890         case CMPCI_CD_VOL:
  891         case CMPCI_LINE_IN_VOL:
  892         case CMPCI_MIC_VOL:
  893                 dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_VALBITS);
  894         vol1:   dip->mixer_class = CMPCI_INPUT_CLASS;
  895                 dip->next = dip->index + 6;     /* CMPCI_xxx_MUTE */
  896                 strlcpy(dip->label.name, mixer_port_names[dip->index],
  897                     sizeof dip->label.name);
  898                 dip->un.v.num_channels = (dip->index == CMPCI_MIC_VOL ? 1 : 2);
  899         vol:
  900                 dip->type = AUDIO_MIXER_VALUE;
  901                 strlcpy(dip->un.v.units.name, AudioNvolume,
  902                     sizeof dip->un.v.units.name);
  903                 return 0;
  904 
  905         case CMPCI_MIC_MUTE:
  906                 dip->next = CMPCI_MIC_PREAMP;
  907                 /* FALLTHROUGH */
  908         case CMPCI_DAC_MUTE:
  909         case CMPCI_FM_MUTE:
  910         case CMPCI_CD_MUTE:
  911         case CMPCI_LINE_IN_MUTE:
  912         case CMPCI_AUX_IN_MUTE:
  913                 dip->prev = dip->index - 6;     /* CMPCI_xxx_VOL */
  914                 dip->mixer_class = CMPCI_INPUT_CLASS;
  915                 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
  916                 goto on_off;
  917         on_off:
  918                 dip->type = AUDIO_MIXER_ENUM;
  919                 dip->un.e.num_mem = 2;
  920                 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
  921                     sizeof dip->un.e.member[0].label.name);
  922                 dip->un.e.member[0].ord = 0;
  923                 strlcpy(dip->un.e.member[1].label.name, AudioNon,
  924                     sizeof dip->un.e.member[1].label.name);
  925                 dip->un.e.member[1].ord = 1;
  926                 return 0;
  927 
  928         case CMPCI_MIC_PREAMP:
  929                 dip->mixer_class = CMPCI_INPUT_CLASS;
  930                 dip->prev = CMPCI_MIC_MUTE;
  931                 strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name);
  932                 goto on_off;
  933         case CMPCI_PCSPEAKER:
  934                 dip->mixer_class = CMPCI_INPUT_CLASS;
  935                 strlcpy(dip->label.name, AudioNspeaker, sizeof dip->label.name);
  936                 dip->un.v.num_channels = 1;
  937                 dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_SPEAKER_VALBITS);
  938                 goto vol;
  939         case CMPCI_RECORD_SOURCE:
  940                 dip->mixer_class = CMPCI_RECORD_CLASS;
  941                 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
  942                 dip->type = AUDIO_MIXER_SET;
  943                 dip->un.s.num_mem = 7;
  944                 strlcpy(dip->un.s.member[0].label.name, AudioNmicrophone,
  945                     sizeof dip->un.s.member[0].label.name);
  946                 dip->un.s.member[0].mask = CMPCI_RECORD_SOURCE_MIC;
  947                 strlcpy(dip->un.s.member[1].label.name, AudioNcd,
  948                     sizeof dip->un.s.member[1].label.name);
  949                 dip->un.s.member[1].mask = CMPCI_RECORD_SOURCE_CD;
  950                 strlcpy(dip->un.s.member[2].label.name, AudioNline,
  951                     sizeof dip->un.s.member[2].label.name);
  952                 dip->un.s.member[2].mask = CMPCI_RECORD_SOURCE_LINE_IN;
  953                 strlcpy(dip->un.s.member[3].label.name, AudioNaux,
  954                     sizeof dip->un.s.member[3].label.name);
  955                 dip->un.s.member[3].mask = CMPCI_RECORD_SOURCE_AUX_IN;
  956                 strlcpy(dip->un.s.member[4].label.name, AudioNwave,
  957                     sizeof dip->un.s.member[4].label.name);
  958                 dip->un.s.member[4].mask = CMPCI_RECORD_SOURCE_WAVE;
  959                 strlcpy(dip->un.s.member[5].label.name, AudioNfmsynth,
  960                     sizeof dip->un.s.member[5].label.name);
  961                 dip->un.s.member[5].mask = CMPCI_RECORD_SOURCE_FM;
  962                 strlcpy(dip->un.s.member[6].label.name, CmpciNspdif,
  963                     sizeof dip->un.s.member[6].label.name);
  964                 dip->un.s.member[6].mask = CMPCI_RECORD_SOURCE_SPDIF;
  965                 return 0;
  966         case CMPCI_MIC_RECVOL:
  967                 dip->mixer_class = CMPCI_RECORD_CLASS;
  968                 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
  969                 dip->un.v.num_channels = 1;
  970                 dip->un.v.delta = 1 << (8 - CMPCI_REG_ADMIC_VALBITS);
  971                 goto vol;
  972 
  973         case CMPCI_PLAYBACK_MODE:
  974                 dip->mixer_class = CMPCI_PLAYBACK_CLASS;
  975                 dip->type = AUDIO_MIXER_ENUM;
  976                 strlcpy(dip->label.name, AudioNmode, sizeof dip->label.name);
  977                 dip->un.e.num_mem = 2;
  978                 strlcpy(dip->un.e.member[0].label.name, AudioNdac,
  979                     sizeof dip->un.e.member[0].label.name);
  980                 dip->un.e.member[0].ord = CMPCI_PLAYBACK_MODE_WAVE;
  981                 strlcpy(dip->un.e.member[1].label.name, CmpciNspdif,
  982                     sizeof dip->un.e.member[1].label.name);
  983                 dip->un.e.member[1].ord = CMPCI_PLAYBACK_MODE_SPDIF;
  984                 return 0;
  985         case CMPCI_SPDIF_IN_SELECT:
  986                 dip->mixer_class = CMPCI_SPDIF_CLASS;
  987                 dip->type = AUDIO_MIXER_ENUM;
  988                 dip->next = CMPCI_SPDIF_IN_PHASE;
  989                 strlcpy(dip->label.name, AudioNinput, sizeof dip->label.name);
  990                 i = 0;
  991                 strlcpy(dip->un.e.member[i].label.name, CmpciNspdin1,
  992                     sizeof dip->un.e.member[i].label.name);
  993                 dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDIN1;
  994                 if (CMPCI_ISCAP(sc, 2ND_SPDIN)) {
  995                         strlcpy(dip->un.e.member[i].label.name, CmpciNspdin2,
  996                             sizeof dip->un.e.member[i].label.name);
  997                         dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDIN2;
  998                 }
  999                 strlcpy(dip->un.e.member[i].label.name, CmpciNspdout,
 1000                     sizeof dip->un.e.member[i].label.name);
 1001                 dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDOUT;
 1002                 dip->un.e.num_mem = i;
 1003                 return 0;
 1004         case CMPCI_SPDIF_IN_PHASE:
 1005                 dip->mixer_class = CMPCI_SPDIF_CLASS;
 1006                 dip->prev = CMPCI_SPDIF_IN_SELECT;
 1007                 strlcpy(dip->label.name, CmpciNphase, sizeof dip->label.name);
 1008                 dip->type = AUDIO_MIXER_ENUM;
 1009                 dip->un.e.num_mem = 2;
 1010                 strlcpy(dip->un.e.member[0].label.name, CmpciNpositive,
 1011                     sizeof dip->un.e.member[0].label.name);
 1012                 dip->un.e.member[0].ord = CMPCI_SPDIF_IN_PHASE_POSITIVE;
 1013                 strlcpy(dip->un.e.member[1].label.name, CmpciNnegative,
 1014                     sizeof dip->un.e.member[1].label.name);
 1015                 dip->un.e.member[1].ord = CMPCI_SPDIF_IN_PHASE_NEGATIVE;
 1016                 return 0;
 1017         case CMPCI_SPDIF_LOOP:
 1018                 dip->mixer_class = CMPCI_SPDIF_CLASS;
 1019                 dip->next = CMPCI_SPDIF_OUT_PLAYBACK;
 1020                 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
 1021                 dip->type = AUDIO_MIXER_ENUM;
 1022                 dip->un.e.num_mem = 2;
 1023                 strlcpy(dip->un.e.member[0].label.name, CmpciNplayback,
 1024                     sizeof dip->un.e.member[0].label.name);
 1025                 dip->un.e.member[0].ord = CMPCI_SPDIF_LOOP_OFF;
 1026                 strlcpy(dip->un.e.member[1].label.name, CmpciNspdin,
 1027                     sizeof dip->un.e.member[1].label.name);
 1028                 dip->un.e.member[1].ord = CMPCI_SPDIF_LOOP_ON;
 1029                 return 0;
 1030         case CMPCI_SPDIF_OUT_PLAYBACK:
 1031                 dip->mixer_class = CMPCI_SPDIF_CLASS;
 1032                 dip->prev = CMPCI_SPDIF_LOOP;
 1033                 dip->next = CMPCI_SPDIF_OUT_VOLTAGE;
 1034                 strlcpy(dip->label.name, CmpciNplayback, sizeof dip->label.name);
 1035                 dip->type = AUDIO_MIXER_ENUM;
 1036                 dip->un.e.num_mem = 2;
 1037                 strlcpy(dip->un.e.member[0].label.name, AudioNwave,
 1038                     sizeof dip->un.e.member[0].label.name);
 1039                 dip->un.e.member[0].ord = CMPCI_SPDIF_OUT_PLAYBACK_WAVE;
 1040                 strlcpy(dip->un.e.member[1].label.name, CmpciNlegacy,
 1041                     sizeof dip->un.e.member[1].label.name);
 1042                 dip->un.e.member[1].ord = CMPCI_SPDIF_OUT_PLAYBACK_LEGACY;
 1043                 return 0;
 1044         case CMPCI_SPDIF_OUT_VOLTAGE:
 1045                 dip->mixer_class = CMPCI_SPDIF_CLASS;
 1046                 dip->prev = CMPCI_SPDIF_OUT_PLAYBACK;
 1047                 strlcpy(dip->label.name, CmpciNvoltage, sizeof dip->label.name);
 1048                 dip->type = AUDIO_MIXER_ENUM;
 1049                 dip->un.e.num_mem = 2;
 1050                 strlcpy(dip->un.e.member[0].label.name, CmpciNhigh_v,
 1051                     sizeof dip->un.e.member[0].label.name);
 1052                 dip->un.e.member[0].ord = CMPCI_SPDIF_OUT_VOLTAGE_HIGH;
 1053                 strlcpy(dip->un.e.member[1].label.name, CmpciNlow_v,
 1054                     sizeof dip->un.e.member[1].label.name);
 1055                 dip->un.e.member[1].ord = CMPCI_SPDIF_OUT_VOLTAGE_LOW;
 1056                 return 0;
 1057         case CMPCI_MONITOR_DAC:
 1058                 dip->mixer_class = CMPCI_SPDIF_CLASS;
 1059                 strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name);
 1060                 dip->type = AUDIO_MIXER_ENUM;
 1061                 dip->un.e.num_mem = 3;
 1062                 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
 1063                     sizeof dip->un.e.member[0].label.name);
 1064                 dip->un.e.member[0].ord = CMPCI_MONITOR_DAC_OFF;
 1065                 strlcpy(dip->un.e.member[1].label.name, CmpciNspdin,
 1066                     sizeof dip->un.e.member[1].label.name);
 1067                 dip->un.e.member[1].ord = CMPCI_MONITOR_DAC_SPDIN;
 1068                 strlcpy(dip->un.e.member[2].label.name, CmpciNspdout,
 1069                     sizeof dip->un.e.member[2].label.name);
 1070                 dip->un.e.member[2].ord = CMPCI_MONITOR_DAC_SPDOUT;
 1071                 return 0;
 1072 
 1073         case CMPCI_MASTER_VOL:
 1074                 dip->mixer_class = CMPCI_OUTPUT_CLASS;
 1075                 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
 1076                 dip->un.v.num_channels = 2;
 1077                 dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_VALBITS);
 1078                 goto vol;
 1079         case CMPCI_REAR:
 1080                 dip->mixer_class = CMPCI_OUTPUT_CLASS;
 1081                 dip->next = CMPCI_INDIVIDUAL;
 1082                 strlcpy(dip->label.name, CmpciNrear, sizeof dip->label.name);
 1083                 goto on_off;
 1084         case CMPCI_INDIVIDUAL:
 1085                 dip->mixer_class = CMPCI_OUTPUT_CLASS;
 1086                 dip->prev = CMPCI_REAR;
 1087                 dip->next = CMPCI_REVERSE;
 1088                 strlcpy(dip->label.name, CmpciNindividual, sizeof dip->label.name);
 1089                 goto on_off;
 1090         case CMPCI_REVERSE:
 1091                 dip->mixer_class = CMPCI_OUTPUT_CLASS;
 1092                 dip->prev = CMPCI_INDIVIDUAL;
 1093                 strlcpy(dip->label.name, CmpciNreverse, sizeof dip->label.name);
 1094                 goto on_off;
 1095         case CMPCI_SURROUND:
 1096                 dip->mixer_class = CMPCI_OUTPUT_CLASS;
 1097                 strlcpy(dip->label.name, CmpciNsurround, sizeof dip->label.name);
 1098                 goto on_off;
 1099         }
 1100 
 1101         return ENXIO;
 1102 }
 1103 
 1104 int
 1105 cmpci_alloc_dmamem(struct cmpci_softc *sc, size_t size, int type, int flags,
 1106     caddr_t *r_addr)
 1107 {
 1108         int error = 0;
 1109         struct cmpci_dmanode *n;
 1110         int w;
 1111 
 1112         n = malloc(sizeof(struct cmpci_dmanode), type, flags);
 1113         if (n == NULL) {
 1114                 error = ENOMEM;
 1115                 goto quit;
 1116         }
 1117 
 1118         w = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
 1119 #define CMPCI_DMABUF_ALIGN    0x4
 1120 #define CMPCI_DMABUF_BOUNDARY 0x0
 1121         n->cd_tag = sc->sc_dmat;
 1122         n->cd_size = size;
 1123         error = bus_dmamem_alloc(n->cd_tag, n->cd_size,
 1124             CMPCI_DMABUF_ALIGN, CMPCI_DMABUF_BOUNDARY, n->cd_segs,
 1125             sizeof(n->cd_segs)/sizeof(n->cd_segs[0]), &n->cd_nsegs, w);
 1126         if (error)
 1127                 goto mfree;
 1128         error = bus_dmamem_map(n->cd_tag, n->cd_segs, n->cd_nsegs, n->cd_size,
 1129             &n->cd_addr, w | BUS_DMA_COHERENT);
 1130         if (error)
 1131                 goto dmafree;
 1132         error = bus_dmamap_create(n->cd_tag, n->cd_size, 1, n->cd_size, 0,
 1133             w, &n->cd_map);
 1134         if (error)
 1135                 goto unmap;
 1136         error = bus_dmamap_load(n->cd_tag, n->cd_map, n->cd_addr, n->cd_size,
 1137             NULL, w);
 1138         if (error)
 1139                 goto destroy;
 1140 
 1141         n->cd_next = sc->sc_dmap;
 1142         sc->sc_dmap = n;
 1143         *r_addr = KVADDR(n);
 1144         return 0;
 1145 
 1146  destroy:
 1147         bus_dmamap_destroy(n->cd_tag, n->cd_map);
 1148  unmap:
 1149         bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size);
 1150  dmafree:
 1151         bus_dmamem_free(n->cd_tag,
 1152                         n->cd_segs, sizeof(n->cd_segs)/sizeof(n->cd_segs[0]));
 1153  mfree:
 1154         free(n, type);
 1155  quit:
 1156         return error;
 1157 }
 1158 
 1159 int
 1160 cmpci_free_dmamem(struct cmpci_softc *sc, caddr_t addr, int type)
 1161 {
 1162         struct cmpci_dmanode **nnp;
 1163 
 1164         for (nnp = &sc->sc_dmap; *nnp; nnp = &(*nnp)->cd_next) {
 1165                 if ((*nnp)->cd_addr == addr) {
 1166                         struct cmpci_dmanode *n = *nnp;
 1167                         bus_dmamap_unload(n->cd_tag, n->cd_map);
 1168                         bus_dmamap_destroy(n->cd_tag, n->cd_map);
 1169                         bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size);
 1170                         bus_dmamem_free(n->cd_tag, n->cd_segs,
 1171                             sizeof(n->cd_segs)/sizeof(n->cd_segs[0]));
 1172                         free(n, type);
 1173                         return 0;
 1174                 }
 1175         }
 1176         return -1;
 1177 }
 1178 
 1179 struct cmpci_dmanode *
 1180 cmpci_find_dmamem(struct cmpci_softc *sc, caddr_t addr)
 1181 {
 1182         struct cmpci_dmanode *p;
 1183 
 1184         for (p = sc->sc_dmap; p; p = p->cd_next) {
 1185                 if (KVADDR(p) == (void *)addr)
 1186                         break;
 1187         }
 1188         return p;
 1189 }
 1190 
 1191 #if 0
 1192 void cmpci_print_dmamem(struct cmpci_dmanode *p);
 1193 
 1194 void
 1195 cmpci_print_dmamem(struct cmpci_dmanode *p)
 1196 {
 1197         DPRINTF(("DMA at virt:%p, dmaseg:%p, mapseg:%p, size:%p\n",
 1198                  (void *)p->cd_addr, (void *)p->cd_segs[0].ds_addr,
 1199                  (void *)DMAADDR(p), (void *)p->cd_size));
 1200 }
 1201 #endif /* DEBUG */
 1202 
 1203 void *
 1204 cmpci_malloc(void *handle, int direction, size_t size, int type,
 1205     int flags)
 1206 {
 1207         caddr_t addr;
 1208 
 1209         if (cmpci_alloc_dmamem(handle, size, type, flags, &addr))
 1210                 return NULL;
 1211         return addr;
 1212 }
 1213 
 1214 void
 1215 cmpci_free(void *handle, void *addr, int type)
 1216 {
 1217         cmpci_free_dmamem(handle, addr, type);
 1218 }
 1219 
 1220 #define MAXVAL 256
 1221 int
 1222 cmpci_adjust(int val, int mask)
 1223 {
 1224         val += (MAXVAL - mask) >> 1;
 1225         if (val >= MAXVAL)
 1226                 val = MAXVAL-1;
 1227         return val & mask;
 1228 }
 1229 
 1230 void
 1231 cmpci_set_mixer_gain(struct cmpci_softc *sc, int port)
 1232 {
 1233         int src;
 1234         int bits, mask;
 1235 
 1236         switch (port) {
 1237         case CMPCI_MIC_VOL:
 1238                 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_MIC,
 1239                     CMPCI_ADJUST_MIC_GAIN(sc, sc->sc_gain[port][CMPCI_LR]));
 1240                 return;
 1241         case CMPCI_MASTER_VOL:
 1242                 src = CMPCI_SB16_MIXER_MASTER_L;
 1243                 break;
 1244         case CMPCI_LINE_IN_VOL:
 1245                 src = CMPCI_SB16_MIXER_LINE_L;
 1246                 break;
 1247         case CMPCI_AUX_IN_VOL:
 1248                 bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_MIXER_AUX,
 1249                     CMPCI_ADJUST_AUX_GAIN(sc, sc->sc_gain[port][CMPCI_LEFT],
 1250                                               sc->sc_gain[port][CMPCI_RIGHT]));
 1251                 return;
 1252         case CMPCI_MIC_RECVOL:
 1253                 cmpci_reg_partial_write_1(sc, CMPCI_REG_MIXER25,
 1254                     CMPCI_REG_ADMIC_SHIFT, CMPCI_REG_ADMIC_MASK,
 1255                     CMPCI_ADJUST_ADMIC_GAIN(sc, sc->sc_gain[port][CMPCI_LR]));
 1256                 return;
 1257         case CMPCI_DAC_VOL:
 1258                 src = CMPCI_SB16_MIXER_VOICE_L;
 1259                 break;
 1260         case CMPCI_FM_VOL:
 1261                 src = CMPCI_SB16_MIXER_FM_L;
 1262                 break;
 1263         case CMPCI_CD_VOL:
 1264                 src = CMPCI_SB16_MIXER_CDDA_L;
 1265                 break;
 1266         case CMPCI_PCSPEAKER:
 1267                 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_SPEAKER,
 1268                     CMPCI_ADJUST_2_GAIN(sc, sc->sc_gain[port][CMPCI_LR]));
 1269                 return;
 1270         case CMPCI_MIC_PREAMP:
 1271                 if (sc->sc_gain[port][CMPCI_LR])
 1272                         cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25,
 1273                             CMPCI_REG_MICGAINZ);
 1274                 else
 1275                         cmpci_reg_set_1(sc, CMPCI_REG_MIXER25,
 1276                             CMPCI_REG_MICGAINZ);
 1277                 return;
 1278 
 1279         case CMPCI_DAC_MUTE:
 1280                 if (sc->sc_gain[port][CMPCI_LR])
 1281                         cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
 1282                             CMPCI_REG_WSMUTE);
 1283                 else
 1284                         cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
 1285                             CMPCI_REG_WSMUTE);
 1286                 return;
 1287         case CMPCI_FM_MUTE:
 1288                 if (sc->sc_gain[port][CMPCI_LR])
 1289                         cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
 1290                             CMPCI_REG_FMMUTE);
 1291                 else
 1292                         cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
 1293                             CMPCI_REG_FMMUTE);
 1294                 return;
 1295         case CMPCI_AUX_IN_MUTE:
 1296                 if (sc->sc_gain[port][CMPCI_LR])
 1297                         cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25,
 1298                             CMPCI_REG_VAUXRM|CMPCI_REG_VAUXLM);
 1299                 else
 1300                         cmpci_reg_set_1(sc, CMPCI_REG_MIXER25,
 1301                             CMPCI_REG_VAUXRM|CMPCI_REG_VAUXLM);
 1302                 return;
 1303         case CMPCI_CD_MUTE:
 1304                 mask = CMPCI_SB16_SW_CD;
 1305                 goto sbmute;
 1306         case CMPCI_MIC_MUTE:
 1307                 mask = CMPCI_SB16_SW_MIC;
 1308                 goto sbmute;
 1309         case CMPCI_LINE_IN_MUTE:
 1310                 mask = CMPCI_SB16_SW_LINE;
 1311         sbmute:
 1312                 bits = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_OUTMIX);
 1313                 if (sc->sc_gain[port][CMPCI_LR])
 1314                         bits = bits & ~mask;
 1315                 else
 1316                         bits = bits | mask;
 1317                 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX, bits);
 1318                 return;
 1319 
 1320         case CMPCI_SPDIF_IN_SELECT:
 1321         case CMPCI_MONITOR_DAC:
 1322         case CMPCI_PLAYBACK_MODE:
 1323         case CMPCI_SPDIF_LOOP:
 1324         case CMPCI_SPDIF_OUT_PLAYBACK:
 1325                 cmpci_set_out_ports(sc);
 1326                 return;
 1327         case CMPCI_SPDIF_OUT_VOLTAGE:
 1328                 if (CMPCI_ISCAP(sc, SPDOUT_VOLTAGE)) {
 1329                         if (sc->sc_gain[CMPCI_SPDIF_OUT_VOLTAGE][CMPCI_LR]
 1330                             == CMPCI_SPDIF_OUT_VOLTAGE_HIGH)
 1331                                 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_5V);
 1332                         else
 1333                                 cmpci_reg_set_reg_misc(sc, CMPCI_REG_5V);
 1334                 }
 1335                 return;
 1336         case CMPCI_SURROUND:
 1337                 if (CMPCI_ISCAP(sc, SURROUND)) {
 1338                         if (sc->sc_gain[CMPCI_SURROUND][CMPCI_LR])
 1339                                 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
 1340                                                 CMPCI_REG_SURROUND);
 1341                         else
 1342                                 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
 1343                                                   CMPCI_REG_SURROUND);
 1344                 }
 1345                 return;
 1346         case CMPCI_REAR:
 1347                 if (CMPCI_ISCAP(sc, REAR)) {
 1348                         if (sc->sc_gain[CMPCI_REAR][CMPCI_LR])
 1349                                 cmpci_reg_set_reg_misc(sc, CMPCI_REG_N4SPK3D);
 1350                         else
 1351                                 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_N4SPK3D);
 1352                 }
 1353                 return;
 1354         case CMPCI_INDIVIDUAL:
 1355                 if (CMPCI_ISCAP(sc, INDIVIDUAL_REAR)) {
 1356                         if (sc->sc_gain[CMPCI_REAR][CMPCI_LR])
 1357                                 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
 1358                                                 CMPCI_REG_INDIVIDUAL);
 1359                         else
 1360                                 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
 1361                                                   CMPCI_REG_INDIVIDUAL);
 1362                 }
 1363                 return;
 1364         case CMPCI_REVERSE:
 1365                 if (CMPCI_ISCAP(sc, REVERSE_FR)) {
 1366                         if (sc->sc_gain[CMPCI_REVERSE][CMPCI_LR])
 1367                                 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
 1368                                                 CMPCI_REG_REVERSE_FR);
 1369                         else
 1370                                 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
 1371                                                   CMPCI_REG_REVERSE_FR);
 1372                 }
 1373                 return;
 1374         case CMPCI_SPDIF_IN_PHASE:
 1375                 if (CMPCI_ISCAP(sc, SPDIN_PHASE)) {
 1376                         if (sc->sc_gain[CMPCI_SPDIF_IN_PHASE][CMPCI_LR]
 1377                             == CMPCI_SPDIF_IN_PHASE_POSITIVE)
 1378                                 cmpci_reg_clear_1(sc, CMPCI_REG_CHANNEL_FORMAT,
 1379                                                   CMPCI_REG_SPDIN_PHASE);
 1380                         else
 1381                                 cmpci_reg_set_1(sc, CMPCI_REG_CHANNEL_FORMAT,
 1382                                                 CMPCI_REG_SPDIN_PHASE);
 1383                 }
 1384                 return;
 1385         default:
 1386                 return;
 1387         }
 1388 
 1389         cmpci_mixerreg_write(sc, src,
 1390             CMPCI_ADJUST_GAIN(sc, sc->sc_gain[port][CMPCI_LEFT]));
 1391         cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_L_TO_R(src),
 1392             CMPCI_ADJUST_GAIN(sc, sc->sc_gain[port][CMPCI_RIGHT]));
 1393 }
 1394 
 1395 void
 1396 cmpci_set_out_ports(struct cmpci_softc *sc)
 1397 {
 1398         u_int8_t v;
 1399         int enspdout = 0;
 1400 
 1401         if (!CMPCI_ISCAP(sc, SPDLOOP))
 1402                 return;
 1403 
 1404         /* SPDIF/out select */
 1405         if (sc->sc_gain[CMPCI_SPDIF_LOOP][CMPCI_LR] == CMPCI_SPDIF_LOOP_OFF) {
 1406                 /* playback */
 1407                 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP);
 1408         } else {
 1409                 /* monitor SPDIF/in */
 1410                 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP);
 1411         }
 1412 
 1413         /* SPDIF in select */
 1414         v = sc->sc_gain[CMPCI_SPDIF_IN_SELECT][CMPCI_LR];
 1415         if (v & CMPCI_SPDIFIN_SPDIFIN2)
 1416                 cmpci_reg_set_reg_misc(sc, CMPCI_REG_2ND_SPDIFIN);
 1417         else
 1418                 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_2ND_SPDIFIN);
 1419         if (v & CMPCI_SPDIFIN_SPDIFOUT)
 1420                 cmpci_reg_set_reg_misc(sc, CMPCI_REG_SPDFLOOPI);
 1421         else
 1422                 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_SPDFLOOPI);
 1423 
 1424         /* playback to ... */
 1425         if (CMPCI_ISCAP(sc, SPDOUT) &&
 1426             sc->sc_gain[CMPCI_PLAYBACK_MODE][CMPCI_LR]
 1427                 == CMPCI_PLAYBACK_MODE_SPDIF &&
 1428             (sc->sc_play.md_divide == CMPCI_REG_RATE_44100 ||
 1429                 (CMPCI_ISCAP(sc, SPDOUT_48K) &&
 1430                     sc->sc_play.md_divide==CMPCI_REG_RATE_48000))) {
 1431                 /* playback to SPDIF */
 1432                 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF0_ENABLE);
 1433                 enspdout = 1;
 1434                 if (sc->sc_play.md_divide==CMPCI_REG_RATE_48000)
 1435                         cmpci_reg_set_reg_misc(sc,
 1436                                 CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K);
 1437                 else
 1438                         cmpci_reg_clear_reg_misc(sc,
 1439                                 CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K);
 1440         } else {
 1441                 /* playback to DAC */
 1442                 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1,
 1443                                   CMPCI_REG_SPDIF0_ENABLE);
 1444                 if (CMPCI_ISCAP(sc, SPDOUT_48K))
 1445                         cmpci_reg_clear_reg_misc(sc,
 1446                                 CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K);
 1447         }
 1448 
 1449         /* legacy to SPDIF/out or not */
 1450         if (CMPCI_ISCAP(sc, SPDLEGACY)) {
 1451                 if (sc->sc_gain[CMPCI_SPDIF_OUT_PLAYBACK][CMPCI_LR]
 1452                     == CMPCI_SPDIF_OUT_PLAYBACK_WAVE)
 1453                         cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL,
 1454                                         CMPCI_REG_LEGACY_SPDIF_ENABLE);
 1455                 else {
 1456                         cmpci_reg_set_4(sc, CMPCI_REG_LEGACY_CTRL,
 1457                                         CMPCI_REG_LEGACY_SPDIF_ENABLE);
 1458                         enspdout = 1;
 1459                 }
 1460         }
 1461 
 1462         /* enable/disable SPDIF/out */
 1463         if (CMPCI_ISCAP(sc, XSPDOUT) && enspdout)
 1464                 cmpci_reg_set_4(sc, CMPCI_REG_LEGACY_CTRL,
 1465                                 CMPCI_REG_XSPDIF_ENABLE);
 1466         else
 1467                 cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL,
 1468                                 CMPCI_REG_XSPDIF_ENABLE);
 1469 
 1470         /* SPDIF monitor (digital to analog output) */
 1471         if (CMPCI_ISCAP(sc, SPDIN_MONITOR)) {
 1472                 v = sc->sc_gain[CMPCI_MONITOR_DAC][CMPCI_LR];
 1473                 if (!(v & CMPCI_MONDAC_ENABLE))
 1474                         cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
 1475                                         CMPCI_REG_SPDIN_MONITOR);
 1476                 if (v & CMPCI_MONDAC_SPDOUT)
 1477                         cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1,
 1478                                         CMPCI_REG_SPDIFOUT_DAC);
 1479                 else
 1480                         cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1,
 1481                                         CMPCI_REG_SPDIFOUT_DAC);
 1482                 if (v & CMPCI_MONDAC_ENABLE)
 1483                         cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
 1484                                         CMPCI_REG_SPDIN_MONITOR);
 1485         }
 1486 }
 1487 
 1488 int
 1489 cmpci_set_in_ports(struct cmpci_softc *sc)
 1490 {
 1491         int mask;
 1492         int bitsl, bitsr;
 1493 
 1494         mask = sc->sc_in_mask;
 1495 
 1496         /*
 1497          * Note CMPCI_RECORD_SOURCE_CD, CMPCI_RECORD_SOURCE_LINE_IN and
 1498          * CMPCI_RECORD_SOURCE_FM are defined to the corresponding bit
 1499          * of the mixer register.
 1500          */
 1501         bitsr = mask & (CMPCI_RECORD_SOURCE_CD | CMPCI_RECORD_SOURCE_LINE_IN |
 1502             CMPCI_RECORD_SOURCE_FM);
 1503 
 1504         bitsl = CMPCI_SB16_MIXER_SRC_R_TO_L(bitsr);
 1505         if (mask & CMPCI_RECORD_SOURCE_MIC) {
 1506                 bitsl |= CMPCI_SB16_MIXER_MIC_SRC;
 1507                 bitsr |= CMPCI_SB16_MIXER_MIC_SRC;
 1508         }
 1509         cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, bitsl);
 1510         cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, bitsr);
 1511 
 1512         if (mask & CMPCI_RECORD_SOURCE_AUX_IN)
 1513                 cmpci_reg_set_1(sc, CMPCI_REG_MIXER25,
 1514                     CMPCI_REG_RAUXREN | CMPCI_REG_RAUXLEN);
 1515         else
 1516                 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25,
 1517                     CMPCI_REG_RAUXREN | CMPCI_REG_RAUXLEN);
 1518 
 1519         if (mask & CMPCI_RECORD_SOURCE_WAVE)
 1520                 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24,
 1521                     CMPCI_REG_WAVEINL | CMPCI_REG_WAVEINR);
 1522         else
 1523                 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24,
 1524                     CMPCI_REG_WAVEINL | CMPCI_REG_WAVEINR);
 1525 
 1526         if (CMPCI_ISCAP(sc, SPDIN) &&
 1527             (sc->sc_rec.md_divide == CMPCI_REG_RATE_44100 ||
 1528                 (CMPCI_ISCAP(sc, SPDOUT_48K) &&
 1529                     sc->sc_rec.md_divide == CMPCI_REG_RATE_48000/* XXX? */))) {
 1530                 if (mask & CMPCI_RECORD_SOURCE_SPDIF) {
 1531                         /* enable SPDIF/in */
 1532                         cmpci_reg_set_4(sc,
 1533                                         CMPCI_REG_FUNC_1,
 1534                                         CMPCI_REG_SPDIF1_ENABLE);
 1535                 } else {
 1536                         cmpci_reg_clear_4(sc,
 1537                                         CMPCI_REG_FUNC_1,
 1538                                         CMPCI_REG_SPDIF1_ENABLE);
 1539                 }
 1540         }
 1541 
 1542         return 0;
 1543 }
 1544 
 1545 int
 1546 cmpci_set_port(void *handle, mixer_ctrl_t *cp)
 1547 {
 1548         struct cmpci_softc *sc = handle;
 1549         int lgain, rgain;
 1550 
 1551         switch (cp->dev) {
 1552         case CMPCI_MIC_VOL:
 1553         case CMPCI_PCSPEAKER:
 1554         case CMPCI_MIC_RECVOL:
 1555                 if (cp->un.value.num_channels != 1)
 1556                         return EINVAL;
 1557                 /* FALLTHROUGH */
 1558         case CMPCI_DAC_VOL:
 1559         case CMPCI_FM_VOL:
 1560         case CMPCI_CD_VOL:
 1561         case CMPCI_LINE_IN_VOL:
 1562         case CMPCI_AUX_IN_VOL:
 1563         case CMPCI_MASTER_VOL:
 1564                 if (cp->type != AUDIO_MIXER_VALUE)
 1565                         return EINVAL;
 1566                 switch (cp->un.value.num_channels) {
 1567                 case 1:
 1568                         lgain = rgain =
 1569                             cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
 1570                         break;
 1571                 case 2:
 1572                         lgain = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
 1573                         rgain = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
 1574                         break;
 1575                 default:
 1576                         return EINVAL;
 1577                 }
 1578                 sc->sc_gain[cp->dev][CMPCI_LEFT]  = lgain;
 1579                 sc->sc_gain[cp->dev][CMPCI_RIGHT] = rgain;
 1580 
 1581                 cmpci_set_mixer_gain(sc, cp->dev);
 1582                 break;
 1583 
 1584         case CMPCI_RECORD_SOURCE:
 1585                 if (cp->type != AUDIO_MIXER_SET)
 1586                         return EINVAL;
 1587 
 1588                 if (cp->un.mask & ~(CMPCI_RECORD_SOURCE_MIC |
 1589                     CMPCI_RECORD_SOURCE_CD | CMPCI_RECORD_SOURCE_LINE_IN |
 1590                     CMPCI_RECORD_SOURCE_AUX_IN | CMPCI_RECORD_SOURCE_WAVE |
 1591                     CMPCI_RECORD_SOURCE_FM | CMPCI_RECORD_SOURCE_SPDIF))
 1592                         return EINVAL;
 1593 
 1594                 if (cp->un.mask & CMPCI_RECORD_SOURCE_SPDIF)
 1595                         cp->un.mask = CMPCI_RECORD_SOURCE_SPDIF;
 1596 
 1597                 sc->sc_in_mask = cp->un.mask;
 1598                 return cmpci_set_in_ports(sc);
 1599 
 1600         /* boolean */
 1601         case CMPCI_DAC_MUTE:
 1602         case CMPCI_FM_MUTE:
 1603         case CMPCI_CD_MUTE:
 1604         case CMPCI_LINE_IN_MUTE:
 1605         case CMPCI_AUX_IN_MUTE:
 1606         case CMPCI_MIC_MUTE:
 1607         case CMPCI_MIC_PREAMP:
 1608         case CMPCI_PLAYBACK_MODE:
 1609         case CMPCI_SPDIF_IN_PHASE:
 1610         case CMPCI_SPDIF_LOOP:
 1611         case CMPCI_SPDIF_OUT_PLAYBACK:
 1612         case CMPCI_SPDIF_OUT_VOLTAGE:
 1613         case CMPCI_REAR:
 1614         case CMPCI_INDIVIDUAL:
 1615         case CMPCI_REVERSE:
 1616         case CMPCI_SURROUND:
 1617                 if (cp->type != AUDIO_MIXER_ENUM)
 1618                         return EINVAL;
 1619                 sc->sc_gain[cp->dev][CMPCI_LR] = cp->un.ord != 0;
 1620                 cmpci_set_mixer_gain(sc, cp->dev);
 1621                 break;
 1622 
 1623         case CMPCI_SPDIF_IN_SELECT:
 1624                 switch (cp->un.ord) {
 1625                 case CMPCI_SPDIF_IN_SPDIN1:
 1626                 case CMPCI_SPDIF_IN_SPDIN2:
 1627                 case CMPCI_SPDIF_IN_SPDOUT:
 1628                         break;
 1629                 default:
 1630                         return EINVAL;
 1631                 }
 1632                 goto xenum;
 1633         case CMPCI_MONITOR_DAC:
 1634                 switch (cp->un.ord) {
 1635                 case CMPCI_MONITOR_DAC_OFF:
 1636                 case CMPCI_MONITOR_DAC_SPDIN:
 1637                 case CMPCI_MONITOR_DAC_SPDOUT:
 1638                         break;
 1639                 default:
 1640                         return EINVAL;
 1641                 }
 1642         xenum:
 1643                 if (cp->type != AUDIO_MIXER_ENUM)
 1644                         return EINVAL;
 1645                 sc->sc_gain[cp->dev][CMPCI_LR] = cp->un.ord;
 1646                 cmpci_set_mixer_gain(sc, cp->dev);
 1647                 break;
 1648 
 1649         default:
 1650             return EINVAL;
 1651         }
 1652 
 1653         return 0;
 1654 }
 1655 
 1656 int
 1657 cmpci_get_port(void *handle, mixer_ctrl_t *cp)
 1658 {
 1659         struct cmpci_softc *sc = handle;
 1660 
 1661         switch (cp->dev) {
 1662         case CMPCI_MIC_VOL:
 1663         case CMPCI_PCSPEAKER:
 1664         case CMPCI_MIC_RECVOL:
 1665                 if (cp->un.value.num_channels != 1)
 1666                         return EINVAL;
 1667                 /*FALLTHROUGH*/
 1668         case CMPCI_DAC_VOL:
 1669         case CMPCI_FM_VOL:
 1670         case CMPCI_CD_VOL:
 1671         case CMPCI_LINE_IN_VOL:
 1672         case CMPCI_AUX_IN_VOL:
 1673         case CMPCI_MASTER_VOL:
 1674                 switch (cp->un.value.num_channels) {
 1675                 case 1:
 1676                         cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
 1677                                 sc->sc_gain[cp->dev][CMPCI_LEFT];
 1678                         break;
 1679                 case 2:
 1680                         cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
 1681                                 sc->sc_gain[cp->dev][CMPCI_LEFT];
 1682                         cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
 1683                                 sc->sc_gain[cp->dev][CMPCI_RIGHT];
 1684                         break;
 1685                 default:
 1686                         return EINVAL;
 1687                 }
 1688                 break;
 1689 
 1690         case CMPCI_RECORD_SOURCE:
 1691                 cp->un.mask = sc->sc_in_mask;
 1692                 break;
 1693 
 1694         case CMPCI_DAC_MUTE:
 1695         case CMPCI_FM_MUTE:
 1696         case CMPCI_CD_MUTE:
 1697         case CMPCI_LINE_IN_MUTE:
 1698         case CMPCI_AUX_IN_MUTE:
 1699         case CMPCI_MIC_MUTE:
 1700         case CMPCI_MIC_PREAMP:
 1701         case CMPCI_PLAYBACK_MODE:
 1702         case CMPCI_SPDIF_IN_SELECT:
 1703         case CMPCI_SPDIF_IN_PHASE:
 1704         case CMPCI_SPDIF_LOOP:
 1705         case CMPCI_SPDIF_OUT_PLAYBACK:
 1706         case CMPCI_SPDIF_OUT_VOLTAGE:
 1707         case CMPCI_MONITOR_DAC:
 1708         case CMPCI_REAR:
 1709         case CMPCI_INDIVIDUAL:
 1710         case CMPCI_REVERSE:
 1711         case CMPCI_SURROUND:
 1712                 cp->un.ord = sc->sc_gain[cp->dev][CMPCI_LR];
 1713                 break;
 1714 
 1715         default:
 1716                 return EINVAL;
 1717         }
 1718 
 1719         return 0;
 1720 }
 1721 
 1722 /* ARGSUSED */
 1723 size_t
 1724 cmpci_round_buffersize(void *handle, int direction, size_t bufsize)
 1725 {
 1726         if (bufsize > 0x10000)
 1727                 bufsize = 0x10000;
 1728 
 1729         return bufsize;
 1730 }
 1731 
 1732 paddr_t
 1733 cmpci_mappage(void *handle, void *addr, off_t offset, int prot)
 1734 {
 1735         struct cmpci_softc *sc = handle;
 1736         struct cmpci_dmanode *p;
 1737 
 1738         if (offset < 0 || NULL == (p = cmpci_find_dmamem(sc, addr)))
 1739                 return -1;
 1740 
 1741         return bus_dmamem_mmap(p->cd_tag, p->cd_segs,
 1742                    sizeof(p->cd_segs)/sizeof(p->cd_segs[0]),
 1743                    offset, prot, BUS_DMA_WAITOK);
 1744 }
 1745 
 1746 /* ARGSUSED */
 1747 int
 1748 cmpci_get_props(void *handle)
 1749 {
 1750         return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
 1751 }
 1752 
 1753 int
 1754 cmpci_trigger_output(void *handle, void *start, void *end, int blksize,
 1755     void (*intr)(void *), void *arg, struct audio_params *param)
 1756 {
 1757         struct cmpci_softc *sc = handle;
 1758         struct cmpci_dmanode *p;
 1759         int bps;
 1760 
 1761         sc->sc_play.intr = intr;
 1762         sc->sc_play.intr_arg = arg;
 1763         bps = param->channels * param->precision * param->factor / 8;
 1764         if (!bps)
 1765                 return EINVAL;
 1766 
 1767         /* set DMA frame */
 1768         if (!(p = cmpci_find_dmamem(sc, start)))
 1769                 return EINVAL;
 1770         bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA0_BASE,
 1771             DMAADDR(p));
 1772         delay(10);
 1773         bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA0_BYTES,
 1774             ((caddr_t)end - (caddr_t)start + 1) / bps - 1);
 1775         delay(10);
 1776 
 1777         /* set interrupt count */
 1778         bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA0_SAMPLES,
 1779                           (blksize + bps - 1) / bps - 1);
 1780         delay(10);
 1781 
 1782         /* start DMA */
 1783         cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_DIR); /* PLAY */
 1784         cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE);
 1785         cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_ENABLE);
 1786 
 1787         return 0;
 1788 }
 1789 
 1790 int
 1791 cmpci_trigger_input(void *handle, void *start, void *end, int blksize,
 1792     void (*intr)(void *), void *arg, struct audio_params *param)
 1793 {
 1794         struct cmpci_softc *sc = handle;
 1795         struct cmpci_dmanode *p;
 1796         int bps;
 1797 
 1798         sc->sc_rec.intr = intr;
 1799         sc->sc_rec.intr_arg = arg;
 1800         bps = param->channels*param->precision*param->factor/8;
 1801         if (!bps)
 1802                 return EINVAL;
 1803 
 1804         /* set DMA frame */
 1805         if (!(p = cmpci_find_dmamem(sc, start)))
 1806                 return EINVAL;
 1807         bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BASE,
 1808             DMAADDR(p));
 1809         delay(10);
 1810         bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BYTES,
 1811             ((caddr_t)end - (caddr_t)start + 1) / bps - 1);
 1812         delay(10);
 1813 
 1814         /* set interrupt count */
 1815         bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_SAMPLES,
 1816             (blksize + bps - 1) / bps - 1);
 1817         delay(10);
 1818 
 1819         /* start DMA */
 1820         cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_DIR); /* REC */
 1821         cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
 1822         cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE);
 1823 
 1824         return 0;
 1825 }
 1826 
 1827 /* end of file */

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