LCOV - code coverage report
Current view: top level - dev/pci - emuxki.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1134 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 71 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: emuxki.c,v 1.53 2018/09/13 04:07:20 miko Exp $        */
       2             : /*      $NetBSD: emuxki.c,v 1.1 2001/10/17 18:39:41 jdolecek Exp $      */
       3             : 
       4             : /*-
       5             :  * Copyright (c) 2001 The NetBSD Foundation, Inc.
       6             :  * All rights reserved.
       7             :  *
       8             :  * This code is derived from software contributed to The NetBSD Foundation
       9             :  * by Yannick Montulet.
      10             :  *
      11             :  * Redistribution and use in source and binary forms, with or without
      12             :  * modification, are permitted provided that the following conditions
      13             :  * are met:
      14             :  * 1. Redistributions of source code must retain the above copyright
      15             :  *    notice, this list of conditions and the following disclaimer.
      16             :  * 2. Redistributions in binary form must reproduce the above copyright
      17             :  *    notice, this list of conditions and the following disclaimer in the
      18             :  *    documentation and/or other materials provided with the distribution.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      21             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      22             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      23             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      24             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      25             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      26             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      27             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      28             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      29             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      30             :  * POSSIBILITY OF SUCH DAMAGE.
      31             :  */
      32             : 
      33             : /*
      34             :  * Driver for Creative Labs SBLive! series and probably PCI512.
      35             :  * 
      36             :  * Known bugs:
      37             :  * - inversed stereo at ac97 codec level
      38             :  *   (XXX jdolecek - don't see the problem? maybe because auvia(4) has
      39             :  *    it swapped too?)
      40             :  * - bass disappear when you plug rear jack-in on Cambridge FPS2000 speakers
      41             :  *   (and presumably all speakers that support front and rear jack-in)
      42             :  *
      43             :  * TODO:
      44             :  * - Digital Outputs
      45             :  * - (midi/mpu),joystick support
      46             :  * - Multiple voices play (problem with /dev/audio architecture)
      47             :  * - Multiple sources recording (Pb with audio(4))
      48             :  * - Independent modification of each channel's parameters (via mixer ?)
      49             :  * - DSP FX patches (to make fx like chipmunk)
      50             :  */
      51             : 
      52             : #include <sys/param.h>
      53             : #include <sys/device.h>
      54             : #include <sys/errno.h>
      55             : #include <sys/fcntl.h>
      56             : #include <sys/malloc.h>
      57             : #include <sys/systm.h>
      58             : #include <sys/audioio.h>
      59             : 
      60             : #include <dev/pci/pcireg.h>
      61             : #include <dev/pci/pcivar.h>
      62             : #include <dev/pci/pcidevs.h>
      63             : 
      64             : #include <dev/audio_if.h>
      65             : #include <dev/ic/ac97.h>
      66             : 
      67             : #include <dev/pci/emuxkireg.h>
      68             : #include <dev/pci/emuxkivar.h>
      69             : 
      70             : /* autconf goo */
      71             : int  emuxki_match(struct device *, void *, void *);
      72             : void emuxki_attach(struct device *, struct device *, void *);
      73             : int  emuxki_detach(struct device *, int);
      74             : int  emuxki_activate(struct device *, int);
      75             : int  emuxki_scinit(struct emuxki_softc *sc, int);
      76             : void emuxki_pci_shutdown(struct emuxki_softc *sc);
      77             : 
      78             : /* dma mem mgmt */
      79             : struct dmamem *emuxki_dmamem_alloc(bus_dma_tag_t, size_t, bus_size_t,
      80             :                                  int, int, int);
      81             : void    emuxki_dmamem_free(struct dmamem *, int);
      82             : void    emuxki_dmamem_delete(struct dmamem *mem, int type);
      83             : 
      84             : struct emuxki_mem *emuxki_mem_new(struct emuxki_softc *sc, int ptbidx,
      85             :         size_t size, int type, int flags);
      86             : void emuxki_mem_delete(struct emuxki_mem *mem, int type);
      87             : 
      88             : /* Emu10k1 init & shutdown */
      89             : int  emuxki_init(struct emuxki_softc *, int);
      90             : void emuxki_shutdown(struct emuxki_softc *);
      91             : 
      92             : /* Emu10k1 mem mgmt */
      93             : void   *emuxki_pmem_alloc(struct emuxki_softc *, size_t,int,int);
      94             : void   *emuxki_rmem_alloc(struct emuxki_softc *, size_t,int,int);
      95             : 
      96             : /*
      97             :  * Emu10k1 channels funcs : There is no direct access to channels, everything
      98             :  * is done through voices I will at least provide channel based fx params
      99             :  * modification, later...
     100             :  */
     101             : 
     102             : /* Emu10k1 voice mgmt */
     103             : struct emuxki_voice *emuxki_voice_new(struct emuxki_softc *, u_int8_t);
     104             : void   emuxki_voice_delete(struct emuxki_voice *);
     105             : int    emuxki_voice_set_audioparms(struct emuxki_voice *, u_int8_t, u_int8_t, u_int32_t);
     106             : /* emuxki_voice_set_fxparms will come later, it'll need channel distinction */
     107             : int emuxki_voice_set_bufparms(struct emuxki_voice *, void *, u_int32_t, u_int16_t);
     108             : int emuxki_voice_set_stereo(struct emuxki_voice *voice, u_int8_t stereo);
     109             : int emuxki_voice_dataloc_create(struct emuxki_voice *voice);
     110             : void emuxki_voice_dataloc_destroy(struct emuxki_voice *voice);
     111             : void emuxki_voice_commit_parms(struct emuxki_voice *);
     112             : void emuxki_voice_recsrc_release(struct emuxki_softc *sc, emuxki_recsrc_t source);
     113             : int emuxki_recsrc_reserve(struct emuxki_voice *voice, emuxki_recsrc_t source);
     114             : int emuxki_voice_adc_rate(struct emuxki_voice *);
     115             : u_int32_t emuxki_voice_curaddr(struct emuxki_voice *);
     116             : int emuxki_set_vparms(struct emuxki_voice *voice, struct audio_params *p);
     117             : int emuxki_voice_set_srate(struct emuxki_voice *voice, u_int32_t srate);
     118             : void emuxki_voice_start(struct emuxki_voice *, void (*) (void *), void *);
     119             : void emuxki_voice_halt(struct emuxki_voice *);
     120             : int emuxki_voice_channel_create(struct emuxki_voice *voice);
     121             : void emuxki_voice_channel_destroy(struct emuxki_voice *voice);
     122             : 
     123             : struct emuxki_channel *emuxki_channel_new(struct emuxki_voice *voice, u_int8_t num);
     124             : void emuxki_channel_delete(struct emuxki_channel *chan);
     125             : void emuxki_channel_start(struct emuxki_channel *chan);
     126             : void emuxki_channel_stop(struct emuxki_channel *chan);
     127             : void emuxki_channel_commit_fx(struct emuxki_channel *chan);
     128             : void emuxki_channel_commit_parms(struct emuxki_channel *chan);
     129             : void emuxki_channel_set_bufparms(struct emuxki_channel *chan, u_int32_t start, u_int32_t end);
     130             : void emuxki_channel_set_srate(struct emuxki_channel *chan, u_int32_t srate);
     131             : void emuxki_channel_set_fxsend(struct emuxki_channel *chan,
     132             :         struct emuxki_chanparms_fxsend *fxsend);
     133             : void emuxki_chanparms_set_defaults(struct emuxki_channel *chan);
     134             : 
     135             : void emuxki_resched_timer(struct emuxki_softc *sc);
     136             : 
     137             : /*
     138             :  * Emu10k1 stream mgmt : not done yet
     139             :  */
     140             : #if 0
     141             : struct emuxki_stream *emuxki_stream_new(struct emu10k1 *);
     142             : void   emuxki_stream_delete(struct emuxki_stream *);
     143             : int    emuxki_stream_set_audio_params(struct emuxki_stream *, u_int8_t,
     144             :                                             u_int8_t, u_int8_t, u_int16_t);
     145             : void   emuxki_stream_start(struct emuxki_stream *);
     146             : void   emuxki_stream_halt(struct emuxki_stream *);
     147             : #endif
     148             : 
     149             : /* fx interface */
     150             : void emuxki_initfx(struct emuxki_softc *sc);
     151             : void emuxki_dsp_addop(struct emuxki_softc *sc, u_int16_t *pc, u_int8_t op,
     152             :         u_int16_t r, u_int16_t a, u_int16_t x, u_int16_t y);
     153             : void emuxki_write_micro(struct emuxki_softc *sc, u_int32_t pc, u_int32_t data);
     154             : 
     155             : /* audio interface callbacks */
     156             : 
     157             : int     emuxki_open(void *, int);
     158             : void    emuxki_close(void *);
     159             : 
     160             : int     emuxki_set_params(void *, int, int,
     161             :                                       struct audio_params *,
     162             :                                       struct audio_params *);
     163             : 
     164             : int     emuxki_round_blocksize(void *, int);
     165             : size_t  emuxki_round_buffersize(void *, int, size_t);
     166             : 
     167             : int     emuxki_trigger_output(void *, void *, void *, int, void (*)(void *),
     168             :             void *, struct audio_params *);
     169             : int     emuxki_trigger_input(void *, void *, void *, int, void (*) (void *),
     170             :             void *, struct audio_params *);
     171             : int     emuxki_halt_output(void *);
     172             : int     emuxki_halt_input(void *);
     173             : 
     174             : int     emuxki_set_port(void *, mixer_ctrl_t *);
     175             : int     emuxki_get_port(void *, mixer_ctrl_t *);
     176             : int     emuxki_query_devinfo(void *, mixer_devinfo_t *);
     177             : 
     178             : void   *emuxki_allocm(void *, int, size_t, int, int);
     179             : void    emuxki_freem(void *, void *, int);
     180             : 
     181             : int     emuxki_get_props(void *);
     182             : 
     183             : /* Interrupt handler */
     184             : int  emuxki_intr(void *);
     185             : 
     186             : /* Emu10k1 AC97 interface callbacks */
     187             : int  emuxki_ac97_init(struct emuxki_softc *sc);
     188             : int  emuxki_ac97_attach(void *, struct ac97_codec_if *);
     189             : int  emuxki_ac97_read(void *, u_int8_t, u_int16_t *);
     190             : int  emuxki_ac97_write(void *, u_int8_t, u_int16_t);
     191             : void emuxki_ac97_reset(void *);
     192             : 
     193             : const struct pci_matchid emuxki_devices[] = {
     194             :         { PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_SBLIVE },
     195             :         { PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_AUDIGY },
     196             :         { PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_AUDIGY2 },
     197             : };
     198             : 
     199             : /*
     200             :  * Autoconfig goo.
     201             :  */
     202             : struct cfdriver emu_cd = {
     203             :         NULL, "emu", DV_DULL
     204             : };
     205             : 
     206             : struct cfattach emu_ca = {
     207             :         sizeof(struct emuxki_softc),
     208             :         emuxki_match,
     209             :         emuxki_attach,
     210             :         emuxki_detach,
     211             :         emuxki_activate
     212             : };
     213             : 
     214             : struct audio_hw_if emuxki_hw_if = {
     215             :         emuxki_open,
     216             :         emuxki_close,
     217             :         emuxki_set_params,
     218             :         emuxki_round_blocksize,
     219             :         NULL,                   /* commit settings */
     220             :         NULL,                   /* init_output */
     221             :         NULL,                   /* init_input */
     222             :         NULL,                   /* start_output */
     223             :         NULL,                   /* start_input */
     224             :         emuxki_halt_output,
     225             :         emuxki_halt_input,
     226             :         NULL,                   /* speaker_ctl */
     227             :         NULL,                   /* setfd */
     228             :         emuxki_set_port,
     229             :         emuxki_get_port,
     230             :         emuxki_query_devinfo,
     231             :         emuxki_allocm,
     232             :         emuxki_freem,
     233             :         emuxki_round_buffersize,
     234             :         emuxki_get_props,
     235             :         emuxki_trigger_output,
     236             :         emuxki_trigger_input
     237             : };
     238             : 
     239             : #if 0
     240             : static const int emuxki_recsrc_intrmasks[EMU_NUMRECSRCS] =
     241             :     { EMU_INTE_MICBUFENABLE, EMU_INTE_ADCBUFENABLE, EMU_INTE_EFXBUFENABLE };
     242             : #endif
     243             : static const u_int32_t emuxki_recsrc_bufaddrreg[EMU_NUMRECSRCS] =
     244             :     { EMU_MICBA, EMU_ADCBA, EMU_FXBA };
     245             : static const u_int32_t emuxki_recsrc_szreg[EMU_NUMRECSRCS] =
     246             :     { EMU_MICBS, EMU_ADCBS, EMU_FXBS };
     247             : static const int emuxki_recbuf_sz[] = {
     248             :         0, 384, 448, 512, 640, 768, 896, 1024, 1280, 1536, 1792,
     249             :         2048, 2560, 3072, 3584, 4096, 5120, 6144, 7168, 8192, 10240,
     250             :         12288, 14366, 16384, 20480, 24576, 28672, 32768, 40960, 49152,
     251             :         57344, 65536
     252             : };
     253             : 
     254             : /*
     255             :  * DMA memory mgmt
     256             :  */
     257             : 
     258             : void
     259           0 : emuxki_dmamem_delete(struct dmamem *mem, int type)
     260             : {
     261           0 :         free(mem->segs, type, 0);
     262           0 :         free(mem, type, 0);
     263           0 : }
     264             : 
     265             : struct dmamem *
     266           0 : emuxki_dmamem_alloc(bus_dma_tag_t dmat, size_t size, bus_size_t align,
     267             :              int nsegs, int type, int flags)
     268             : {
     269             :         struct dmamem   *mem;
     270             :         int             bus_dma_flags;
     271             : 
     272             :         /* Allocate memory for structure */
     273           0 :         if ((mem = malloc(sizeof(*mem), type, flags)) == NULL)
     274           0 :                 return (NULL);
     275           0 :         mem->dmat = dmat;
     276           0 :         mem->size = size;
     277           0 :         mem->align = align;
     278           0 :         mem->nsegs = nsegs;
     279           0 :         mem->bound = 0;
     280             : 
     281           0 :         mem->segs = mallocarray(mem->nsegs, sizeof(*(mem->segs)), type, flags);
     282           0 :         if (mem->segs == NULL) {
     283           0 :                 free(mem, type, 0);
     284           0 :                 return (NULL);
     285             :         }
     286             : 
     287           0 :         bus_dma_flags = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
     288           0 :         if (bus_dmamem_alloc(dmat, mem->size, mem->align, mem->bound,
     289             :                              mem->segs, mem->nsegs, &(mem->rsegs),
     290             :                              bus_dma_flags)) {
     291           0 :                 emuxki_dmamem_delete(mem, type);
     292           0 :                 return (NULL);
     293             :         }
     294             : 
     295           0 :         if (bus_dmamem_map(dmat, mem->segs, mem->nsegs, mem->size,
     296             :                            &(mem->kaddr), bus_dma_flags | BUS_DMA_COHERENT)) {
     297           0 :                 bus_dmamem_free(dmat, mem->segs, mem->nsegs);
     298           0 :                 emuxki_dmamem_delete(mem, type);
     299           0 :                 return (NULL);
     300             :         }
     301             : 
     302           0 :         if (bus_dmamap_create(dmat, mem->size, mem->nsegs, mem->size,
     303             :                               mem->bound, bus_dma_flags, &(mem->map))) {
     304           0 :                 bus_dmamem_unmap(dmat, mem->kaddr, mem->size);
     305           0 :                 bus_dmamem_free(dmat, mem->segs, mem->nsegs);
     306           0 :                 emuxki_dmamem_delete(mem, type);
     307           0 :                 return (NULL);
     308             :         }
     309             : 
     310           0 :         if (bus_dmamap_load(dmat, mem->map, mem->kaddr, 
     311             :                             mem->size, NULL, bus_dma_flags)) {
     312           0 :                 bus_dmamap_destroy(dmat, mem->map);
     313           0 :                 bus_dmamem_unmap(dmat, mem->kaddr, mem->size);
     314           0 :                 bus_dmamem_free(dmat, mem->segs, mem->nsegs);
     315           0 :                 emuxki_dmamem_delete(mem, type);
     316           0 :                 return (NULL);
     317             :         }
     318             : 
     319           0 :         return (mem);
     320           0 : }
     321             : 
     322             : void
     323           0 : emuxki_dmamem_free(struct dmamem *mem, int type)
     324             : {
     325           0 :         bus_dmamap_unload(mem->dmat, mem->map);
     326           0 :         bus_dmamap_destroy(mem->dmat, mem->map);
     327           0 :         bus_dmamem_unmap(mem->dmat, mem->kaddr, mem->size);
     328           0 :         bus_dmamem_free(mem->dmat, mem->segs, mem->nsegs);
     329           0 :         emuxki_dmamem_delete(mem, type);
     330           0 : }
     331             : 
     332             : 
     333             : /*
     334             :  * Autoconf device callbacks : attach and detach
     335             :  */
     336             : 
     337             : void
     338           0 : emuxki_pci_shutdown(struct emuxki_softc *sc)
     339             : {
     340           0 :         if (sc->sc_ih != NULL)
     341           0 :                 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
     342           0 :         if (sc->sc_ios)
     343           0 :                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
     344           0 : }
     345             : 
     346             : int
     347           0 : emuxki_scinit(struct emuxki_softc *sc, int resuming)
     348             : {
     349             :         int             err;
     350             : 
     351           0 :         bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG,
     352             :                 /* enable spdif(?) output on non-APS */
     353             :                 (sc->sc_flags & EMUXKI_APS? 0 : EMU_HCFG_GPOUTPUT0) |
     354             :                 EMU_HCFG_LOCKSOUNDCACHE | EMU_HCFG_LOCKTANKCACHE_MASK |
     355             :                 EMU_HCFG_MUTEBUTTONENABLE);
     356           0 :         bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_INTE,
     357             :                 EMU_INTE_SAMPLERATER | EMU_INTE_PCIERRENABLE);
     358             : 
     359           0 :         if ((err = emuxki_init(sc, resuming)))
     360           0 :                 return (err);
     361             : 
     362           0 :         if (sc->sc_flags & EMUXKI_AUDIGY2) {
     363           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG,
     364             :                         EMU_HCFG_AUDIOENABLE | EMU_HCFG_AC3ENABLE_CDSPDIF |
     365             :                         EMU_HCFG_AC3ENABLE_GPSPDIF | EMU_HCFG_AUTOMUTE);
     366           0 :         } else if (sc->sc_flags & EMUXKI_AUDIGY) {
     367           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG,
     368             :                         EMU_HCFG_AUDIOENABLE | EMU_HCFG_AUTOMUTE);
     369           0 :         } else {
     370           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG,
     371             :                         EMU_HCFG_AUDIOENABLE | EMU_HCFG_JOYENABLE |
     372             :                         EMU_HCFG_LOCKTANKCACHE_MASK | EMU_HCFG_AUTOMUTE);
     373             :         }
     374           0 :         bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_INTE,
     375             :                 bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_INTE) |
     376             :                 EMU_INTE_VOLINCRENABLE | EMU_INTE_VOLDECRENABLE |
     377             :                 EMU_INTE_MUTEENABLE);
     378             : 
     379           0 :         if (sc->sc_flags & EMUXKI_AUDIGY2) {
     380           0 :                 if (sc->sc_flags & EMUXKI_CA0108) {
     381           0 :                         bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A_IOCFG,
     382             :                             0x0060 | bus_space_read_4(sc->sc_iot, sc->sc_ioh,
     383             :                             EMU_A_IOCFG));
     384           0 :                 } else {
     385           0 :                         bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A_IOCFG,
     386             :                             EMU_A_IOCFG_GPOUT0 | bus_space_read_4(sc->sc_iot,
     387             :                             sc->sc_ioh, EMU_A_IOCFG));
     388             :                 }
     389             :         }
     390             : 
     391           0 :         if (!resuming) {
     392             :                 /* No multiple voice support for now */
     393           0 :                 sc->pvoice = sc->rvoice = NULL;
     394           0 :         }
     395             : 
     396           0 :         return (0);
     397           0 : }
     398             : 
     399             : int
     400           0 : emuxki_ac97_init(struct emuxki_softc *sc)
     401             : {
     402           0 :         sc->hostif.arg = sc;
     403           0 :         sc->hostif.attach = emuxki_ac97_attach;
     404           0 :         sc->hostif.read = emuxki_ac97_read;
     405           0 :         sc->hostif.write = emuxki_ac97_write;
     406           0 :         sc->hostif.reset = emuxki_ac97_reset;
     407           0 :         sc->hostif.flags = NULL;
     408           0 :         return (ac97_attach(&(sc->hostif)));
     409             : }
     410             : 
     411             : int
     412           0 : emuxki_match(struct device *parent, void *match, void *aux)
     413             : {
     414           0 :         return (pci_matchbyid((struct pci_attach_args *)aux, emuxki_devices,
     415             :             nitems(emuxki_devices)));
     416             : }
     417             : 
     418             : void
     419           0 : emuxki_attach(struct device *parent, struct device *self, void *aux)
     420             : {
     421           0 :         struct emuxki_softc *sc = (struct emuxki_softc *) self;
     422           0 :         struct pci_attach_args *pa = aux;
     423           0 :         pci_intr_handle_t ih;
     424             :         const char     *intrstr;
     425             : 
     426           0 :         if (pci_mapreg_map(pa, EMU_PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
     427           0 :             &(sc->sc_iot), &(sc->sc_ioh), &(sc->sc_iob), &(sc->sc_ios), 0)) {
     428           0 :                 printf(": can't map i/o space\n");
     429           0 :                 return;
     430             :         }
     431             : 
     432           0 :         sc->sc_pc   = pa->pa_pc;
     433           0 :         sc->sc_dmat = pa->pa_dmat;
     434             : 
     435           0 :         if (pci_intr_map(pa, &ih)) {
     436           0 :                 printf(": can't map interrupt\n");
     437           0 :                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
     438           0 :                 return;
     439             :         }
     440             : 
     441           0 :         intrstr = pci_intr_string(pa->pa_pc, ih);
     442           0 :         sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO | IPL_MPSAFE,
     443           0 :             emuxki_intr, sc, sc->sc_dev.dv_xname);
     444           0 :         if (sc->sc_ih == NULL) {
     445           0 :                 printf(": can't establish interrupt");
     446           0 :                 if (intrstr != NULL)
     447           0 :                         printf(" at %s", intrstr);
     448           0 :                 printf("\n");
     449           0 :                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
     450           0 :                 return;
     451             :         }
     452           0 :         printf(": %s\n", intrstr);
     453             : 
     454             :         /* XXX it's unknown whether APS is made from Audigy as well */
     455           0 :         if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CREATIVELABS_AUDIGY) {
     456           0 :                 sc->sc_flags |= EMUXKI_AUDIGY;
     457           0 :                 if (PCI_REVISION(pa->pa_class) == 0x04 ||
     458           0 :                     PCI_REVISION(pa->pa_class) == 0x08) {
     459           0 :                         sc->sc_flags |= EMUXKI_AUDIGY2;
     460           0 :                 }
     461           0 :         } else if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CREATIVELABS_AUDIGY2) {
     462           0 :                 sc->sc_flags |= EMUXKI_AUDIGY | EMUXKI_AUDIGY2;
     463           0 :                 if (pci_conf_read(pa->pa_pc, pa->pa_tag,
     464           0 :                     PCI_SUBSYS_ID_REG) == 0x10011102) {
     465           0 :                         sc->sc_flags |= EMUXKI_CA0108;
     466           0 :                 }
     467           0 :         } else if (pci_conf_read(pa->pa_pc, pa->pa_tag,
     468           0 :             PCI_SUBSYS_ID_REG) == EMU_SUBSYS_APS) {
     469           0 :                 sc->sc_flags |= EMUXKI_APS;
     470           0 :         } else {
     471           0 :                 sc->sc_flags |= EMUXKI_SBLIVE;
     472             :         }
     473             : 
     474           0 :         if (emuxki_scinit(sc, 0) ||
     475             :             /* APS has no ac97 XXX */
     476           0 :             (sc->sc_flags & EMUXKI_APS || emuxki_ac97_init(sc)) ||
     477           0 :             (sc->sc_audev = audio_attach_mi(&emuxki_hw_if, sc, self)) == NULL) {
     478           0 :                 emuxki_pci_shutdown(sc);
     479           0 :                 return;
     480             :         }
     481           0 : }
     482             : 
     483             : int
     484           0 : emuxki_detach(struct device *self, int flags)
     485             : {
     486           0 :         struct emuxki_softc *sc = (struct emuxki_softc *) self;
     487             : 
     488           0 :         if (sc->sc_audev != NULL) /* Test in case audio didn't attach */
     489           0 :                 config_detach(sc->sc_audev, 0);
     490             : 
     491             :         /* All voices should be stopped now but add some code here if not */
     492             : 
     493           0 :         bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG,
     494             :                 EMU_HCFG_LOCKSOUNDCACHE | EMU_HCFG_LOCKTANKCACHE_MASK |
     495             :                 EMU_HCFG_MUTEBUTTONENABLE);
     496           0 :         bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_INTE, 0);
     497             : 
     498           0 :         emuxki_shutdown(sc);
     499             : 
     500           0 :         emuxki_pci_shutdown(sc);
     501             : 
     502           0 :         return (0);
     503             : }
     504             : 
     505             : int
     506           0 : emuxki_activate(struct device *self, int act)
     507             : {
     508           0 :         struct emuxki_softc *sc = (struct emuxki_softc *)self;
     509             : 
     510           0 :         switch (act) {
     511             :         case DVACT_RESUME:
     512           0 :                 emuxki_scinit(sc, 1);
     513           0 :                 ac97_resume(&sc->hostif, sc->codecif);
     514           0 :                 break;
     515             :         default:
     516             :                 break;
     517             :         }
     518           0 :         return (config_activate_children(self, act));
     519             : }
     520             : 
     521             : /* Misc stuff relative to emu10k1 */
     522             : 
     523             : static u_int32_t
     524           0 : emuxki_rate_to_pitch(u_int32_t rate)
     525             : {
     526             :         static const u_int32_t logMagTable[128] = {
     527             :                 0x00000, 0x02dfc, 0x05b9e, 0x088e6, 0x0b5d6, 0x0e26f, 0x10eb3,
     528             :                 0x13aa2, 0x1663f, 0x1918a, 0x1bc84, 0x1e72e, 0x2118b, 0x23b9a,
     529             :                 0x2655d, 0x28ed5, 0x2b803, 0x2e0e8, 0x30985, 0x331db, 0x359eb,
     530             :                 0x381b6, 0x3a93d, 0x3d081, 0x3f782, 0x41e42, 0x444c1, 0x46b01,
     531             :                 0x49101, 0x4b6c4, 0x4dc49, 0x50191, 0x5269e, 0x54b6f, 0x57006,
     532             :                 0x59463, 0x5b888, 0x5dc74, 0x60029, 0x623a7, 0x646ee, 0x66a00,
     533             :                 0x68cdd, 0x6af86, 0x6d1fa, 0x6f43c, 0x7164b, 0x73829, 0x759d4,
     534             :                 0x77b4f, 0x79c9a, 0x7bdb5, 0x7dea1, 0x7ff5e, 0x81fed, 0x8404e,
     535             :                 0x86082, 0x88089, 0x8a064, 0x8c014, 0x8df98, 0x8fef1, 0x91e20,
     536             :                 0x93d26, 0x95c01, 0x97ab4, 0x9993e, 0x9b79f, 0x9d5d9, 0x9f3ec,
     537             :                 0xa11d8, 0xa2f9d, 0xa4d3c, 0xa6ab5, 0xa8808, 0xaa537, 0xac241,
     538             :                 0xadf26, 0xafbe7, 0xb1885, 0xb3500, 0xb5157, 0xb6d8c, 0xb899f,
     539             :                 0xba58f, 0xbc15e, 0xbdd0c, 0xbf899, 0xc1404, 0xc2f50, 0xc4a7b,
     540             :                 0xc6587, 0xc8073, 0xc9b3f, 0xcb5ed, 0xcd07c, 0xceaec, 0xd053f,
     541             :                 0xd1f73, 0xd398a, 0xd5384, 0xd6d60, 0xd8720, 0xda0c3, 0xdba4a,
     542             :                 0xdd3b4, 0xded03, 0xe0636, 0xe1f4e, 0xe384a, 0xe512c, 0xe69f3,
     543             :                 0xe829f, 0xe9b31, 0xeb3a9, 0xecc08, 0xee44c, 0xefc78, 0xf148a,
     544             :                 0xf2c83, 0xf4463, 0xf5c2a, 0xf73da, 0xf8b71, 0xfa2f0, 0xfba57,
     545             :                 0xfd1a7, 0xfe8df
     546             :         };
     547             :         static const u_int8_t logSlopeTable[128] = {
     548             :                 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58,
     549             :                 0x57, 0x56, 0x56, 0x55, 0x55, 0x54, 0x53, 0x53,
     550             :                 0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f,
     551             :                 0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b,
     552             :                 0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47,
     553             :                 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44,
     554             :                 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41,
     555             :                 0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e,
     556             :                 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
     557             :                 0x3b, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39,
     558             :                 0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37,
     559             :                 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x35,
     560             :                 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34,
     561             :                 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32,
     562             :                 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x30, 0x30,
     563             :                 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
     564             :         };
     565             :         int8_t          i;
     566             : 
     567           0 :         if (rate == 0)
     568           0 :                 return 0;       /* Bail out if no leading "1" */
     569           0 :         rate *= 11185;          /* Scale 48000 to 0x20002380 */
     570           0 :         for (i = 31; i > 0; i--) {
     571           0 :                 if (rate & 0x80000000) {    /* Detect leading "1" */
     572           0 :                         return (((u_int32_t) (i - 15) << 20) +
     573           0 :                                 logMagTable[0x7f & (rate >> 24)] +
     574           0 :                                 (0x7f & (rate >> 17)) *
     575           0 :                                 logSlopeTable[0x7f & (rate >> 24)]);
     576             :                 }
     577           0 :                 rate <<= 1;
     578             :         }
     579             : 
     580           0 :         return 0;               /* Should never reach this point */
     581           0 : }
     582             : 
     583             : /* Emu10k1 Low level */
     584             : 
     585             : static u_int32_t
     586           0 : emuxki_read(struct emuxki_softc *sc, u_int16_t chano, u_int32_t reg)
     587             : {
     588             :         u_int32_t       ptr, mask = 0xffffffff;
     589             :         u_int8_t        size, offset = 0;
     590             : 
     591           0 :         ptr = ((((u_int32_t) reg) << 16) &
     592           0 :                 (sc->sc_flags & EMUXKI_AUDIGY ?
     593           0 :                         EMU_A_PTR_ADDR_MASK : EMU_PTR_ADDR_MASK)) |
     594           0 :                 (chano & EMU_PTR_CHNO_MASK);
     595           0 :         if (reg & 0xff000000) {
     596           0 :                 size = (reg >> 24) & 0x3f;
     597           0 :                 offset = (reg >> 16) & 0x1f;
     598           0 :                 mask = ((1 << size) - 1) << offset;
     599           0 :         }
     600             : 
     601           0 :         bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_PTR, ptr);
     602           0 :         ptr = (bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_DATA) & mask)
     603           0 :                 >> offset;
     604           0 :         return (ptr);
     605             : }
     606             : 
     607             : static void
     608           0 : emuxki_write(struct emuxki_softc *sc, u_int16_t chano,
     609             :               u_int32_t reg, u_int32_t data)
     610             : {
     611             :         u_int32_t       ptr, mask;
     612             :         u_int8_t        size, offset;
     613             : 
     614           0 :         ptr = ((((u_int32_t) reg) << 16) &
     615           0 :                 (sc->sc_flags & EMUXKI_AUDIGY ?
     616           0 :                         EMU_A_PTR_ADDR_MASK : EMU_PTR_ADDR_MASK)) |
     617           0 :                 (chano & EMU_PTR_CHNO_MASK);
     618             : 
     619             :         /* BE CAREFUL WITH THAT AXE, EUGENE */
     620           0 :         if (ptr == 0x52 || ptr == 0x53)
     621           0 :                 return;
     622             : 
     623           0 :         if (reg & 0xff000000) {
     624           0 :                 size = (reg >> 24) & 0x3f;
     625           0 :                 offset = (reg >> 16) & 0x1f;
     626           0 :                 mask = ((1 << size) - 1) << offset;
     627           0 :                 data = ((data << offset) & mask) |
     628           0 :                         (emuxki_read(sc, chano, reg & 0xffff) & ~mask);
     629           0 :         }
     630             : 
     631           0 :         bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_PTR, ptr);
     632           0 :         bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_DATA, data);
     633           0 : }
     634             : 
     635             : /* Microcode should this go in /sys/dev/microcode ? */
     636             : 
     637             : void
     638           0 : emuxki_write_micro(struct emuxki_softc *sc, u_int32_t pc, u_int32_t data)
     639             : {
     640           0 :         emuxki_write(sc, 0,
     641           0 :                 (sc->sc_flags & EMUXKI_AUDIGY ?
     642           0 :                         EMU_A_MICROCODEBASE : EMU_MICROCODEBASE) + pc,
     643             :                  data);
     644           0 : }
     645             : 
     646             : void
     647           0 : emuxki_dsp_addop(struct emuxki_softc *sc, u_int16_t *pc, u_int8_t op,
     648             :                   u_int16_t r, u_int16_t a, u_int16_t x, u_int16_t y)
     649             : {
     650           0 :         if (sc->sc_flags & EMUXKI_AUDIGY) {
     651           0 :                 emuxki_write_micro(sc, *pc << 1,
     652           0 :                         ((x << 12) & EMU_A_DSP_LOWORD_OPX_MASK) |
     653           0 :                         (y & EMU_A_DSP_LOWORD_OPY_MASK));
     654           0 :                 emuxki_write_micro(sc, (*pc << 1) + 1,
     655           0 :                         ((op << 24) & EMU_A_DSP_HIWORD_OPCODE_MASK) |
     656           0 :                         ((r << 12) & EMU_A_DSP_HIWORD_RESULT_MASK) |
     657           0 :                         (a & EMU_A_DSP_HIWORD_OPA_MASK));
     658           0 :         } else {
     659           0 :                 emuxki_write_micro(sc, *pc << 1,
     660           0 :                         ((x << 10) & EMU_DSP_LOWORD_OPX_MASK) |
     661           0 :                         (y & EMU_DSP_LOWORD_OPY_MASK));
     662           0 :                 emuxki_write_micro(sc, (*pc << 1) + 1,
     663           0 :                         ((op << 20) & EMU_DSP_HIWORD_OPCODE_MASK) |
     664           0 :                         ((r << 10) & EMU_DSP_HIWORD_RESULT_MASK) |
     665           0 :                         (a & EMU_DSP_HIWORD_OPA_MASK));
     666             :         }
     667           0 :         (*pc)++;
     668           0 : }
     669             : 
     670             : /* init and shutdown */
     671             : 
     672             : void
     673           0 : emuxki_initfx(struct emuxki_softc *sc)
     674             : {
     675           0 :         u_int16_t       pc;
     676             : 
     677             :         /* Set all GPRs to 0 */
     678           0 :         for (pc = 0; pc < 256; pc++)
     679           0 :                 emuxki_write(sc, 0, EMU_DSP_GPR(pc), 0);
     680           0 :         for (pc = 0; pc < 160; pc++) {
     681           0 :                 emuxki_write(sc, 0, EMU_TANKMEMDATAREGBASE + pc, 0);
     682           0 :                 emuxki_write(sc, 0, EMU_TANKMEMADDRREGBASE + pc, 0);
     683             :         }
     684           0 :         pc = 0;
     685             : 
     686           0 :         if (sc->sc_flags & EMUXKI_AUDIGY) {
     687             :                 /* AC97 Out (l/r) = AC97 In (l/r) + FX[0/1] * 4 */
     688           0 :                 emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
     689             :                                   EMU_A_DSP_OUTL(EMU_A_DSP_OUT_A_FRONT),
     690             :                                   EMU_A_DSP_CST(0),
     691             :                                   EMU_DSP_FX(0), EMU_A_DSP_CST(4));
     692           0 :                 emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
     693             :                                   EMU_A_DSP_OUTR(EMU_A_DSP_OUT_A_FRONT),
     694             :                                   EMU_A_DSP_CST(0),
     695             :                                   EMU_DSP_FX(1), EMU_A_DSP_CST(4));
     696             : 
     697             :                 /* Rear channel OUT (l/r) = FX[2/3] * 4 */
     698             : #if 0
     699             :                 emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
     700             :                                   EMU_A_DSP_OUTL(EMU_A_DSP_OUT_A_REAR),
     701             :                                   EMU_A_DSP_OUTL(EMU_A_DSP_OUT_A_FRONT),
     702             :                                   EMU_DSP_FX(0), EMU_A_DSP_CST(4));
     703             :                 emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
     704             :                                   EMU_A_DSP_OUTR(EMU_A_DSP_OUT_A_REAR),
     705             :                                   EMU_A_DSP_OUTR(EMU_A_DSP_OUT_A_FRONT),
     706             :                                   EMU_DSP_FX(1), EMU_A_DSP_CST(4));
     707             : #endif
     708             :                 /* ADC recording (l/r) = AC97 In (l/r) */
     709           0 :                 emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3,
     710             :                                   EMU_A_DSP_OUTL(EMU_A_DSP_OUT_ADC),
     711             :                                   EMU_A_DSP_INL(EMU_DSP_IN_AC97),
     712             :                                   EMU_A_DSP_CST(0), EMU_A_DSP_CST(0));
     713           0 :                 emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3,
     714             :                                   EMU_A_DSP_OUTR(EMU_A_DSP_OUT_ADC),
     715             :                                   EMU_A_DSP_INR(EMU_DSP_IN_AC97),
     716             :                                   EMU_A_DSP_CST(0), EMU_A_DSP_CST(0));
     717             : 
     718             :                 /* zero out the rest of the microcode */
     719           0 :                 while (pc < 512)
     720           0 :                         emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3,
     721             :                                           EMU_A_DSP_CST(0), EMU_A_DSP_CST(0),
     722             :                                           EMU_A_DSP_CST(0), EMU_A_DSP_CST(0));
     723             : 
     724           0 :                 emuxki_write(sc, 0, EMU_A_DBG, 0);      /* Is it really necessary ? */
     725           0 :         } else {
     726             :                 /* AC97 Out (l/r) = AC97 In (l/r) + FX[0/1] * 4 */
     727           0 :                 emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
     728             :                                   EMU_DSP_OUTL(EMU_DSP_OUT_A_FRONT),
     729             :                                   EMU_DSP_CST(0),
     730             :                                   EMU_DSP_FX(0), EMU_DSP_CST(4));
     731           0 :                 emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
     732             :                                   EMU_DSP_OUTR(EMU_DSP_OUT_A_FRONT),
     733             :                                   EMU_DSP_CST(0),
     734             :                                   EMU_DSP_FX(1), EMU_DSP_CST(4));
     735             : 
     736             :                 /* Rear channel OUT (l/r) = FX[2/3] * 4 */
     737             : #if 0
     738             :                 emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
     739             :                                   EMU_DSP_OUTL(EMU_DSP_OUT_AD_REAR),
     740             :                                   EMU_DSP_OUTL(EMU_DSP_OUT_A_FRONT),
     741             :                                   EMU_DSP_FX(0), EMU_DSP_CST(4));
     742             :                 emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS,
     743             :                                   EMU_DSP_OUTR(EMU_DSP_OUT_AD_REAR),
     744             :                                   EMU_DSP_OUTR(EMU_DSP_OUT_A_FRONT),
     745             :                                   EMU_DSP_FX(1), EMU_DSP_CST(4));
     746             : #endif
     747             :                 /* ADC recording (l/r) = AC97 In (l/r) */
     748           0 :                 emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3,
     749             :                                   EMU_DSP_OUTL(EMU_DSP_OUT_ADC),
     750             :                                   EMU_DSP_INL(EMU_DSP_IN_AC97),
     751             :                                   EMU_DSP_CST(0), EMU_DSP_CST(0));
     752           0 :                 emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3,
     753             :                                   EMU_DSP_OUTR(EMU_DSP_OUT_ADC),
     754             :                                   EMU_DSP_INR(EMU_DSP_IN_AC97),
     755             :                                   EMU_DSP_CST(0), EMU_DSP_CST(0));
     756             : 
     757             :                 /* zero out the rest of the microcode */
     758           0 :                 while (pc < 512)
     759           0 :                         emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3,
     760             :                                           EMU_DSP_CST(0), EMU_DSP_CST(0),
     761             :                                           EMU_DSP_CST(0), EMU_DSP_CST(0));
     762             : 
     763           0 :                 emuxki_write(sc, 0, EMU_DBG, 0);        /* Is it really necessary ? */
     764             :         }
     765           0 : }
     766             : 
     767             : int
     768           0 : emuxki_init(struct emuxki_softc *sc, int resuming)
     769             : {
     770             :         u_int16_t       i;
     771             :         u_int32_t       spcs, *ptb;
     772             :         bus_addr_t      silentpage;
     773             : 
     774             :         /* disable any channel interrupt */
     775           0 :         emuxki_write(sc, 0, EMU_CLIEL, 0);
     776           0 :         emuxki_write(sc, 0, EMU_CLIEH, 0);
     777           0 :         emuxki_write(sc, 0, EMU_SOLEL, 0);
     778           0 :         emuxki_write(sc, 0, EMU_SOLEH, 0);
     779             : 
     780             :         /* Set recording buffers sizes to zero */
     781           0 :         emuxki_write(sc, 0, EMU_MICBS, EMU_RECBS_BUFSIZE_NONE);
     782           0 :         emuxki_write(sc, 0, EMU_MICBA, 0);
     783           0 :         emuxki_write(sc, 0, EMU_FXBS, EMU_RECBS_BUFSIZE_NONE);
     784           0 :         emuxki_write(sc, 0, EMU_FXBA, 0);
     785           0 :         emuxki_write(sc, 0, EMU_ADCBS, EMU_RECBS_BUFSIZE_NONE);
     786           0 :         emuxki_write(sc, 0, EMU_ADCBA, 0);
     787             : 
     788           0 :         if (sc->sc_flags & EMUXKI_AUDIGY) {
     789           0 :                 emuxki_write(sc, 0, EMU_SPBYPASS, EMU_SPBYPASS_24_BITS);
     790           0 :                 emuxki_write(sc, 0, EMU_AC97SLOT, EMU_AC97SLOT_CENTER | EMU_AC97SLOT_LFE);
     791           0 :         }
     792             : 
     793             :         /* Initialize all channels to stopped and no effects */
     794           0 :         for (i = 0; i < EMU_NUMCHAN; i++) {
     795           0 :                 emuxki_write(sc, i, EMU_CHAN_DCYSUSV, 0);
     796           0 :                 emuxki_write(sc, i, EMU_CHAN_IP, 0);
     797           0 :                 emuxki_write(sc, i, EMU_CHAN_VTFT, 0xffff);
     798           0 :                 emuxki_write(sc, i, EMU_CHAN_CVCF, 0xffff);
     799           0 :                 emuxki_write(sc, i, EMU_CHAN_PTRX, 0);
     800           0 :                 emuxki_write(sc, i, EMU_CHAN_CPF, 0);
     801           0 :                 emuxki_write(sc, i, EMU_CHAN_CCR, 0);
     802           0 :                 emuxki_write(sc, i, EMU_CHAN_PSST, 0);
     803           0 :                 emuxki_write(sc, i, EMU_CHAN_DSL, 0x10);        /* Why 16 ? */
     804           0 :                 emuxki_write(sc, i, EMU_CHAN_CCCA, 0);
     805           0 :                 emuxki_write(sc, i, EMU_CHAN_Z1, 0);
     806           0 :                 emuxki_write(sc, i, EMU_CHAN_Z2, 0);
     807           0 :                 emuxki_write(sc, i, EMU_CHAN_FXRT, 0x32100000);
     808           0 :                 emuxki_write(sc, i, EMU_CHAN_ATKHLDM, 0);
     809           0 :                 emuxki_write(sc, i, EMU_CHAN_DCYSUSM, 0);
     810           0 :                 emuxki_write(sc, i, EMU_CHAN_IFATN, 0xffff);
     811           0 :                 emuxki_write(sc, i, EMU_CHAN_PEFE, 0);
     812           0 :                 emuxki_write(sc, i, EMU_CHAN_FMMOD, 0);
     813           0 :                 emuxki_write(sc, i, EMU_CHAN_TREMFRQ, 24);
     814           0 :                 emuxki_write(sc, i, EMU_CHAN_FM2FRQ2, 24);
     815           0 :                 emuxki_write(sc, i, EMU_CHAN_TEMPENV, 0);
     816             : 
     817             :                 /* these are last so OFF prevents writing */
     818           0 :                 emuxki_write(sc, i, EMU_CHAN_LFOVAL2, 0);
     819           0 :                 emuxki_write(sc, i, EMU_CHAN_LFOVAL1, 0);
     820           0 :                 emuxki_write(sc, i, EMU_CHAN_ATKHLDV, 0);
     821           0 :                 emuxki_write(sc, i, EMU_CHAN_ENVVOL, 0);
     822           0 :                 emuxki_write(sc, i, EMU_CHAN_ENVVAL, 0);
     823             :         }
     824             : 
     825             :         /* set digital outputs format */
     826             :         spcs = (EMU_SPCS_CLKACCY_1000PPM | EMU_SPCS_SAMPLERATE_48 |
     827             :               EMU_SPCS_CHANNELNUM_LEFT | EMU_SPCS_SOURCENUM_UNSPEC |
     828             :                 EMU_SPCS_GENERATIONSTATUS | 0x00001200 /* Cat code. */ |
     829             :                 0x00000000 /* IEC-958 Mode */ | EMU_SPCS_EMPHASIS_NONE |
     830             :                 EMU_SPCS_COPYRIGHT);
     831           0 :         emuxki_write(sc, 0, EMU_SPCS0, spcs);
     832           0 :         emuxki_write(sc, 0, EMU_SPCS1, spcs);
     833           0 :         emuxki_write(sc, 0, EMU_SPCS2, spcs);
     834             : 
     835           0 :         if (sc->sc_flags & EMUXKI_CA0108) {
     836             :                 u_int32_t tmp;
     837             : 
     838             :                 /* Setup SRCMulti_I2S SamplingRate */
     839           0 :                 tmp = emuxki_read(sc, 0, EMU_A_SPDIF_SAMPLERATE) & 0xfffff1ff;
     840           0 :                 emuxki_write(sc, 0, EMU_A_SPDIF_SAMPLERATE, tmp | 0x400);
     841             : 
     842             :                 /* Setup SRCSel (Enable SPDIF, I2S SRCMulti) */
     843           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_PTR, EMU_A2_SRCSEL);
     844           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_DATA,
     845             :                 EMU_A2_SRCSEL_ENABLE_SPDIF | EMU_A2_SRCSEL_ENABLE_SRCMULTI);
     846             : 
     847             :                 /* Setup SRCMulti Input Audio Enable */
     848           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_PTR, 0x7b0000);
     849           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_DATA, 0xff000000);
     850             : 
     851             :                 /* Setup SPDIF Out Audio Enable
     852             :                  * The Audigy 2 Value has a separate SPDIF out,
     853             :                  * so no need for a mixer switch */
     854           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_PTR, 0x7a0000);
     855           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_DATA, 0xff000000);
     856           0 :                 tmp = bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_A_IOCFG) & ~0x8; /* Clear bit 3 */
     857           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A_IOCFG, tmp);
     858           0 :         } else if(sc->sc_flags & EMUXKI_AUDIGY2) {
     859           0 :                 emuxki_write(sc, 0, EMU_A2_SPDIF_SAMPLERATE, EMU_A2_SPDIF_UNKNOWN);
     860             : 
     861           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_PTR, EMU_A2_SRCSEL);
     862           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_DATA, 
     863             :                         EMU_A2_SRCSEL_ENABLE_SPDIF | EMU_A2_SRCSEL_ENABLE_SRCMULTI);
     864             : 
     865           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_PTR, EMU_A2_SRCMULTI);
     866           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_DATA, EMU_A2_SRCMULTI_ENABLE_INPUT);
     867           0 :         }
     868             : 
     869             : 
     870             :         /* Let's play with sound processor */
     871           0 :         emuxki_initfx(sc);
     872             : 
     873           0 :         if (!resuming) {
     874             :                 /* Here is our Page Table */
     875           0 :                 if ((sc->ptb = emuxki_dmamem_alloc(sc->sc_dmat,
     876             :                     EMU_MAXPTE * sizeof(u_int32_t),
     877             :                     EMU_DMA_ALIGN, EMU_DMAMEM_NSEG,
     878           0 :                     M_DEVBUF, M_WAITOK)) == NULL)
     879           0 :                         return (ENOMEM);
     880             : 
     881             :                 /* This is necessary unless you like Metallic noise... */
     882           0 :                 if ((sc->silentpage = emuxki_dmamem_alloc(sc->sc_dmat, EMU_PTESIZE,
     883           0 :                     EMU_DMA_ALIGN, EMU_DMAMEM_NSEG, M_DEVBUF, M_WAITOK))==NULL){
     884           0 :                         emuxki_dmamem_free(sc->ptb, M_DEVBUF);
     885           0 :                         return (ENOMEM);
     886             :                 }
     887             : 
     888             :                 /* Zero out the silent page */
     889             :                 /* This might not be always true, it might be 128 for 8bit channels */
     890           0 :                 memset(KERNADDR(sc->silentpage), 0, DMASIZE(sc->silentpage));
     891           0 :         }
     892             : 
     893             :         /*
     894             :          * Set all the PTB Entries to the silent page We shift the physical
     895             :          * address by one and OR it with the page number. I don't know what
     896             :          * the ORed index is for, might be a very useful unused feature...
     897             :          */
     898           0 :         silentpage = DMAADDR(sc->silentpage) << 1;
     899           0 :         ptb = KERNADDR(sc->ptb);
     900           0 :         for (i = 0; i < EMU_MAXPTE; i++)
     901           0 :                 ptb[i] = htole32(silentpage | i);
     902             : 
     903             :         /* Write PTB address and set TCB to none */
     904           0 :         emuxki_write(sc, 0, EMU_PTB, DMAADDR(sc->ptb));
     905           0 :         emuxki_write(sc, 0, EMU_TCBS, 0);       /* This means 16K TCB */
     906           0 :         emuxki_write(sc, 0, EMU_TCB, 0);        /* No TCB use for now */
     907             : 
     908             :         /*
     909             :          * Set channels MAPs to the silent page.
     910             :          * I don't know what MAPs are for.
     911             :          */
     912           0 :         silentpage |= EMU_CHAN_MAP_PTI_MASK;
     913           0 :         for (i = 0; i < EMU_NUMCHAN; i++) {
     914           0 :                 emuxki_write(sc, i, EMU_CHAN_MAPA, silentpage);
     915           0 :                 emuxki_write(sc, i, EMU_CHAN_MAPB, silentpage);
     916           0 :                 sc->channel[i] = NULL;
     917             :         }
     918             : 
     919           0 :         if (!resuming) {
     920             :                 /* Init voices list */
     921           0 :                 LIST_INIT(&(sc->voices));
     922           0 :         }
     923             : 
     924             :         /* Timer is stopped */
     925           0 :         sc->timerstate &= ~EMU_TIMER_STATE_ENABLED;
     926           0 :         return (0);
     927           0 : }
     928             : 
     929             : void
     930           0 : emuxki_shutdown(struct emuxki_softc *sc)
     931             : {
     932             :         u_int32_t       i;
     933             : 
     934             :         /* Disable any Channels interrupts */
     935           0 :         emuxki_write(sc, 0, EMU_CLIEL, 0);
     936           0 :         emuxki_write(sc, 0, EMU_CLIEH, 0);
     937           0 :         emuxki_write(sc, 0, EMU_SOLEL, 0);
     938           0 :         emuxki_write(sc, 0, EMU_SOLEH, 0);
     939             : 
     940             :         /*
     941             :          * Should do some voice(stream) stopping stuff here, that's what will
     942             :          * stop and deallocate all channels.
     943             :          */
     944             : 
     945             :         /* Stop all channels */
     946             :         /* XXX This shouldn't be necessary, I'll remove once everything works */
     947           0 :         for (i = 0; i < EMU_NUMCHAN; i++)
     948           0 :                 emuxki_write(sc, i, EMU_CHAN_DCYSUSV, 0);
     949           0 :         for (i = 0; i < EMU_NUMCHAN; i++) {
     950           0 :                 emuxki_write(sc, i, EMU_CHAN_VTFT, 0);
     951           0 :                 emuxki_write(sc, i, EMU_CHAN_CVCF, 0);
     952           0 :                 emuxki_write(sc, i, EMU_CHAN_PTRX, 0);
     953           0 :                 emuxki_write(sc, i, EMU_CHAN_CPF, 0);
     954             :         }
     955             : 
     956             :         /*
     957             :          * Deallocate Emu10k1 caches and recording buffers. Again it will be
     958             :          * removed because it will be done in voice shutdown.
     959             :          */
     960           0 :         emuxki_write(sc, 0, EMU_MICBS, EMU_RECBS_BUFSIZE_NONE);
     961           0 :         emuxki_write(sc, 0, EMU_MICBA, 0);
     962           0 :         emuxki_write(sc, 0, EMU_FXBS, EMU_RECBS_BUFSIZE_NONE);
     963           0 :         emuxki_write(sc, 0, EMU_FXBA, 0);
     964           0 :         if (sc->sc_flags & EMUXKI_AUDIGY) {
     965           0 :                 emuxki_write(sc, 0, EMU_A_FXWC1, 0);
     966           0 :                 emuxki_write(sc, 0, EMU_A_FXWC2, 0);
     967           0 :         } else
     968           0 :                 emuxki_write(sc, 0, EMU_FXWC, 0);
     969           0 :         emuxki_write(sc, 0, EMU_ADCBS, EMU_RECBS_BUFSIZE_NONE);
     970           0 :         emuxki_write(sc, 0, EMU_ADCBA, 0);
     971             : 
     972             :         /*
     973             :          * XXX I don't know yet how I will handle tank cache buffer,
     974             :          * I don't even clearly  know what it is for.
     975             :          */
     976           0 :         emuxki_write(sc, 0, EMU_TCB, 0);        /* 16K again */
     977           0 :         emuxki_write(sc, 0, EMU_TCBS, 0);
     978             : 
     979           0 :         emuxki_write(sc, 0, EMU_DBG, 0x8000);   /* necessary ? */
     980             : 
     981           0 :         emuxki_dmamem_free(sc->silentpage, M_DEVBUF);
     982           0 :         emuxki_dmamem_free(sc->ptb, M_DEVBUF);
     983           0 : }
     984             : 
     985             : /* Emu10k1 Memory management */
     986             : 
     987             : struct emuxki_mem *
     988           0 : emuxki_mem_new(struct emuxki_softc *sc, int ptbidx,
     989             :                 size_t size, int type, int flags)
     990             : {
     991             :         struct emuxki_mem *mem;
     992             : 
     993           0 :         if ((mem = malloc(sizeof(*mem), type, flags)) == NULL)
     994           0 :                 return (NULL);
     995             : 
     996           0 :         mem->ptbidx = ptbidx;
     997           0 :         if ((mem->dmamem = emuxki_dmamem_alloc(sc->sc_dmat, size,
     998           0 :             EMU_DMA_ALIGN, EMU_DMAMEM_NSEG, type, flags)) == NULL) {
     999           0 :                 free(mem, type, 0);
    1000           0 :                 return (NULL);
    1001             :         }
    1002           0 :         return (mem);
    1003           0 : }
    1004             : 
    1005             : void
    1006           0 : emuxki_mem_delete(struct emuxki_mem *mem, int type)
    1007             : {
    1008           0 :         emuxki_dmamem_free(mem->dmamem, type);
    1009           0 :         free(mem, type, 0);
    1010           0 : }
    1011             : 
    1012             : void *
    1013           0 : emuxki_pmem_alloc(struct emuxki_softc *sc, size_t size, int type, int flags)
    1014             : {
    1015             :         int             i, j;
    1016             :         size_t          numblocks;
    1017             :         struct emuxki_mem *mem;
    1018             :         u_int32_t      *ptb, silentpage;
    1019             : 
    1020           0 :         ptb = KERNADDR(sc->ptb);
    1021           0 :         silentpage = DMAADDR(sc->silentpage) << 1;
    1022           0 :         numblocks = size / EMU_PTESIZE;
    1023           0 :         if (size % EMU_PTESIZE)
    1024           0 :                 numblocks++;
    1025             : 
    1026           0 :         for (i = 0; i < EMU_MAXPTE; i++)
    1027           0 :                 if ((letoh32(ptb[i]) & EMU_CHAN_MAP_PTE_MASK) == silentpage) {
    1028             :                         /* We look for a free PTE */
    1029           0 :                         for (j = 0; j < numblocks; j++)
    1030           0 :                                 if ((letoh32(ptb[i + j])
    1031           0 :                                     & EMU_CHAN_MAP_PTE_MASK)
    1032           0 :                                     != silentpage)
    1033             :                                         break;
    1034           0 :                         if (j == numblocks) {
    1035           0 :                                 if ((mem = emuxki_mem_new(sc, i,
    1036           0 :                                                 size, type, flags)) == NULL) {
    1037           0 :                                         return (NULL);
    1038             :                                 }
    1039           0 :                                 for (j = 0; j < numblocks; j++)
    1040           0 :                                         ptb[i + j] =
    1041           0 :                                             htole32((((DMAADDR(mem->dmamem) +
    1042             :                                             j * EMU_PTESIZE)) << 1) | (i + j));
    1043           0 :                                 mtx_enter(&audio_lock);
    1044           0 :                                 LIST_INSERT_HEAD(&(sc->mem), mem, next);
    1045           0 :                                 mtx_leave(&audio_lock);
    1046           0 :                                 return (KERNADDR(mem->dmamem));
    1047             :                         } else
    1048           0 :                                 i += j;
    1049           0 :                 }
    1050           0 :         return (NULL);
    1051           0 : }
    1052             : 
    1053             : void *
    1054           0 : emuxki_rmem_alloc(struct emuxki_softc *sc, size_t size, int type, int flags)
    1055             : {
    1056             :         struct emuxki_mem *mem;
    1057             : 
    1058           0 :         mem = emuxki_mem_new(sc, EMU_RMEM, size, type, flags);
    1059           0 :         if (mem == NULL)
    1060           0 :                 return (NULL);
    1061             : 
    1062           0 :         mtx_enter(&audio_lock);
    1063           0 :         LIST_INSERT_HEAD(&(sc->mem), mem, next);
    1064           0 :         mtx_leave(&audio_lock);
    1065             : 
    1066           0 :         return (KERNADDR(mem->dmamem));
    1067           0 : }
    1068             : 
    1069             : /*
    1070             :  * emuxki_channel_* : Channel management functions
    1071             :  * emuxki_chanparms_* : Channel parameters modification functions
    1072             :  */
    1073             : 
    1074             : /*
    1075             :  * is splaudio necessary here, can the same voice be manipulated by two
    1076             :  * different threads at a time ?
    1077             :  */
    1078             : void
    1079           0 : emuxki_chanparms_set_defaults(struct emuxki_channel *chan)
    1080             : {
    1081           0 :         chan->fxsend.a.level = chan->fxsend.b.level =
    1082           0 :         chan->fxsend.c.level = chan->fxsend.d.level =
    1083             :         /* for audigy */
    1084           0 :         chan->fxsend.e.level = chan->fxsend.f.level =
    1085           0 :         chan->fxsend.g.level = chan->fxsend.h.level =
    1086           0 :                 chan->voice->sc->sc_flags & EMUXKI_AUDIGY ?
    1087             :                         0xc0 : 0xff;    /* not max */
    1088             : 
    1089           0 :         chan->fxsend.a.dest = 0x0;
    1090           0 :         chan->fxsend.b.dest = 0x1;
    1091           0 :         chan->fxsend.c.dest = 0x2;
    1092           0 :         chan->fxsend.d.dest = 0x3;
    1093             :         /* for audigy */
    1094           0 :         chan->fxsend.e.dest = 0x4;
    1095           0 :         chan->fxsend.f.dest = 0x5;
    1096           0 :         chan->fxsend.g.dest = 0x6;
    1097           0 :         chan->fxsend.h.dest = 0x7;
    1098             : 
    1099           0 :         chan->pitch.initial = 0x0000;        /* shouldn't it be 0xE000 ? */
    1100           0 :         chan->pitch.current = 0x0000;        /* should it be 0x0400 */
    1101           0 :         chan->pitch.target = 0x0000; /* the unity pitch shift ? */
    1102           0 :         chan->pitch.envelope_amount = 0x00;  /* none */
    1103             : 
    1104           0 :         chan->initial_attenuation = 0x00;    /* no attenuation */
    1105           0 :         chan->volume.current = 0x0000;       /* no volume */
    1106           0 :         chan->volume.target = 0xffff;
    1107           0 :         chan->volume.envelope.current_state = 0x8000;        /* 0 msec delay */
    1108           0 :         chan->volume.envelope.hold_time = 0x7f;      /* 0 msec */
    1109           0 :         chan->volume.envelope.attack_time = 0x7F;    /* 5.5msec */
    1110           0 :         chan->volume.envelope.sustain_level = 0x7F;  /* full  */
    1111           0 :         chan->volume.envelope.decay_time = 0x7F;     /* 22msec  */
    1112             : 
    1113           0 :         chan->filter.initial_cutoff_frequency = 0xff;        /* no filter */
    1114           0 :         chan->filter.current_cutoff_frequency = 0xffff;      /* no filtering */
    1115           0 :         chan->filter.target_cutoff_frequency = 0xffff;       /* no filtering */
    1116           0 :         chan->filter.lowpass_resonance_height = 0x0;
    1117           0 :         chan->filter.interpolation_ROM = 0x1;        /* full band */
    1118           0 :         chan->filter.envelope_amount = 0x7f; /* none */
    1119           0 :         chan->filter.LFO_modulation_depth = 0x00;    /* none */
    1120             : 
    1121           0 :         chan->loop.start = 0x000000;
    1122           0 :         chan->loop.end = 0x000010;   /* Why ? */
    1123             : 
    1124           0 :         chan->modulation.envelope.current_state = 0x8000;
    1125           0 :         chan->modulation.envelope.hold_time = 0x00;  /* 127 better ? */
    1126           0 :         chan->modulation.envelope.attack_time = 0x00;        /* infinite */
    1127           0 :         chan->modulation.envelope.sustain_level = 0x00;      /* off */
    1128           0 :         chan->modulation.envelope.decay_time = 0x7f; /* 22 msec */
    1129           0 :         chan->modulation.LFO_state = 0x8000;
    1130             : 
    1131           0 :         chan->vibrato_LFO.state = 0x8000;
    1132           0 :         chan->vibrato_LFO.modulation_depth = 0x00;   /* none */
    1133           0 :         chan->vibrato_LFO.vibrato_depth = 0x00;
    1134           0 :         chan->vibrato_LFO.frequency = 0x00;  /* Why set to 24 when
    1135             :                                                  * initialized ? */
    1136             : 
    1137           0 :         chan->tremolo_depth = 0x00;
    1138           0 : }
    1139             : 
    1140             : /* only call it at splaudio */
    1141             : struct emuxki_channel *
    1142           0 : emuxki_channel_new(struct emuxki_voice *voice, u_int8_t num)
    1143             : {
    1144             :         struct emuxki_channel *chan;
    1145             : 
    1146           0 :         chan = malloc(sizeof(struct emuxki_channel), M_DEVBUF,
    1147             :             M_WAITOK | M_CANFAIL);
    1148           0 :         if (chan == NULL)
    1149           0 :                 return (NULL);
    1150             : 
    1151           0 :         chan->voice = voice;
    1152           0 :         chan->num = num;
    1153           0 :         emuxki_chanparms_set_defaults(chan);
    1154           0 :         chan->voice->sc->channel[num] = chan;
    1155           0 :         return (chan);
    1156           0 : }
    1157             : 
    1158             : /* only call it at splaudio */
    1159             : void
    1160           0 : emuxki_channel_delete(struct emuxki_channel *chan)
    1161             : {
    1162           0 :         chan->voice->sc->channel[chan->num] = NULL;
    1163           0 :         free(chan, M_DEVBUF, 0);
    1164           0 : }
    1165             : 
    1166             : void
    1167           0 : emuxki_channel_set_fxsend(struct emuxki_channel *chan,
    1168             :                            struct emuxki_chanparms_fxsend *fxsend)
    1169             : {
    1170             :         /* Could do a memcpy ...*/
    1171           0 :         chan->fxsend.a.level = fxsend->a.level;
    1172           0 :         chan->fxsend.b.level = fxsend->b.level;
    1173           0 :         chan->fxsend.c.level = fxsend->c.level;
    1174           0 :         chan->fxsend.d.level = fxsend->d.level;
    1175           0 :         chan->fxsend.a.dest = fxsend->a.dest;
    1176           0 :         chan->fxsend.b.dest = fxsend->b.dest;
    1177           0 :         chan->fxsend.c.dest = fxsend->c.dest;
    1178           0 :         chan->fxsend.d.dest = fxsend->d.dest;
    1179             : 
    1180             :         /* for audigy */
    1181           0 :         chan->fxsend.e.level = fxsend->e.level;
    1182           0 :         chan->fxsend.f.level = fxsend->f.level;
    1183           0 :         chan->fxsend.g.level = fxsend->g.level;
    1184           0 :         chan->fxsend.h.level = fxsend->h.level;
    1185           0 :         chan->fxsend.e.dest = fxsend->e.dest;
    1186           0 :         chan->fxsend.f.dest = fxsend->f.dest;
    1187           0 :         chan->fxsend.g.dest = fxsend->g.dest;
    1188           0 :         chan->fxsend.h.dest = fxsend->h.dest;
    1189           0 : }
    1190             : 
    1191             : void
    1192           0 : emuxki_channel_set_srate(struct emuxki_channel *chan, u_int32_t srate)
    1193             : {
    1194           0 :         chan->pitch.target = (srate << 8) / 375;
    1195           0 :         chan->pitch.target = (chan->pitch.target >> 1) +
    1196           0 :                 (chan->pitch.target & 1);
    1197           0 :         chan->pitch.target &= 0xffff;
    1198           0 :         chan->pitch.current = chan->pitch.target;
    1199           0 :         chan->pitch.initial =
    1200           0 :                 (emuxki_rate_to_pitch(srate) >> 8) & EMU_CHAN_IP_MASK;
    1201           0 : }
    1202             : 
    1203             : /* voice params must be set before calling this */
    1204             : void
    1205           0 : emuxki_channel_set_bufparms(struct emuxki_channel *chan,
    1206             :                              u_int32_t start, u_int32_t end)
    1207             : {
    1208           0 :         chan->loop.start = start & EMU_CHAN_PSST_LOOPSTARTADDR_MASK;
    1209           0 :         chan->loop.end = end & EMU_CHAN_DSL_LOOPENDADDR_MASK;
    1210           0 : }
    1211             : 
    1212             : void
    1213           0 : emuxki_channel_commit_fx(struct emuxki_channel *chan)
    1214             : {
    1215           0 :         struct emuxki_softc *sc = chan->voice->sc;
    1216           0 :         u_int8_t        chano = chan->num;
    1217             :         
    1218           0 :         if (sc->sc_flags & EMUXKI_AUDIGY) {
    1219           0 :                 emuxki_write(sc, chano, EMU_A_CHAN_FXRT1,
    1220           0 :                               (chan->fxsend.d.dest << 24) |
    1221           0 :                               (chan->fxsend.c.dest << 16) |
    1222           0 :                               (chan->fxsend.b.dest << 8) |
    1223           0 :                               (chan->fxsend.a.dest));
    1224           0 :                 emuxki_write(sc, chano, EMU_A_CHAN_FXRT2,
    1225           0 :                               (chan->fxsend.h.dest << 24) |
    1226           0 :                               (chan->fxsend.g.dest << 16) |
    1227           0 :                               (chan->fxsend.f.dest << 8) |
    1228           0 :                               (chan->fxsend.e.dest));
    1229           0 :                 emuxki_write(sc, chano, EMU_A_CHAN_SENDAMOUNTS,
    1230           0 :                               (chan->fxsend.e.level << 24) |
    1231           0 :                               (chan->fxsend.f.level << 16) |
    1232           0 :                               (chan->fxsend.g.level << 8) |
    1233           0 :                               (chan->fxsend.h.level));
    1234           0 :         } else {
    1235           0 :                 emuxki_write(sc, chano, EMU_CHAN_FXRT,
    1236           0 :                               (chan->fxsend.d.dest << 28) |
    1237           0 :                               (chan->fxsend.c.dest << 24) |
    1238           0 :                               (chan->fxsend.b.dest << 20) |
    1239           0 :                               (chan->fxsend.a.dest << 16));
    1240             :         }
    1241             :         
    1242           0 :         emuxki_write(sc, chano, 0x10000000 | EMU_CHAN_PTRX,
    1243           0 :                       (chan->fxsend.a.level << 8) | chan->fxsend.b.level);
    1244           0 :         emuxki_write(sc, chano, EMU_CHAN_DSL,
    1245           0 :                       (chan->fxsend.d.level << 24) | chan->loop.end);
    1246           0 :         emuxki_write(sc, chano, EMU_CHAN_PSST,
    1247           0 :                       (chan->fxsend.c.level << 24) | chan->loop.start);
    1248           0 : }
    1249             : 
    1250             : void
    1251           0 : emuxki_channel_commit_parms(struct emuxki_channel *chan)
    1252             : {
    1253           0 :         struct emuxki_voice *voice = chan->voice;
    1254           0 :         struct emuxki_softc *sc = voice->sc;
    1255             :         u_int32_t start, mapval;
    1256           0 :         u_int8_t chano = chan->num;
    1257             : 
    1258           0 :         start = chan->loop.start +
    1259           0 :                 (voice->stereo ? 28 : 30) * (voice->b16 + 1);
    1260           0 :         mapval = DMAADDR(sc->silentpage) << 1 | EMU_CHAN_MAP_PTI_MASK;
    1261             : 
    1262           0 :         mtx_enter(&audio_lock);
    1263           0 :         emuxki_write(sc, chano, EMU_CHAN_CPF_STEREO, voice->stereo);
    1264             : 
    1265           0 :         emuxki_channel_commit_fx(chan);
    1266             : 
    1267           0 :         emuxki_write(sc, chano, EMU_CHAN_CCCA,
    1268           0 :                 (chan->filter.lowpass_resonance_height << 28) |
    1269           0 :                 (chan->filter.interpolation_ROM << 25) |
    1270           0 :                 (voice->b16 ? 0 : EMU_CHAN_CCCA_8BITSELECT) | start);
    1271           0 :         emuxki_write(sc, chano, EMU_CHAN_Z1, 0);
    1272           0 :         emuxki_write(sc, chano, EMU_CHAN_Z2, 0);
    1273           0 :         emuxki_write(sc, chano, EMU_CHAN_MAPA, mapval);
    1274           0 :         emuxki_write(sc, chano, EMU_CHAN_MAPB, mapval);
    1275           0 :         emuxki_write(sc, chano, EMU_CHAN_CVCF_CURRFILTER,
    1276           0 :                 chan->filter.current_cutoff_frequency);
    1277           0 :         emuxki_write(sc, chano, EMU_CHAN_VTFT_FILTERTARGET,
    1278           0 :                 chan->filter.target_cutoff_frequency);
    1279           0 :         emuxki_write(sc, chano, EMU_CHAN_ATKHLDM,
    1280           0 :                 (chan->modulation.envelope.hold_time << 8) |
    1281           0 :                 chan->modulation.envelope.attack_time);
    1282           0 :         emuxki_write(sc, chano, EMU_CHAN_DCYSUSM,
    1283           0 :                 (chan->modulation.envelope.sustain_level << 8) |
    1284           0 :                 chan->modulation.envelope.decay_time);
    1285           0 :         emuxki_write(sc, chano, EMU_CHAN_LFOVAL1,
    1286           0 :                 chan->modulation.LFO_state);
    1287           0 :         emuxki_write(sc, chano, EMU_CHAN_LFOVAL2,
    1288           0 :                 chan->vibrato_LFO.state);
    1289           0 :         emuxki_write(sc, chano, EMU_CHAN_FMMOD,
    1290           0 :                 (chan->vibrato_LFO.modulation_depth << 8) |
    1291           0 :                 chan->filter.LFO_modulation_depth);
    1292           0 :         emuxki_write(sc, chano, EMU_CHAN_TREMFRQ,
    1293           0 :                 (chan->tremolo_depth << 8));
    1294           0 :         emuxki_write(sc, chano, EMU_CHAN_FM2FRQ2,
    1295           0 :                 (chan->vibrato_LFO.vibrato_depth << 8) |
    1296           0 :                 chan->vibrato_LFO.frequency);
    1297           0 :         emuxki_write(sc, chano, EMU_CHAN_ENVVAL,
    1298           0 :                 chan->modulation.envelope.current_state);
    1299           0 :         emuxki_write(sc, chano, EMU_CHAN_ATKHLDV,
    1300           0 :                 (chan->volume.envelope.hold_time << 8) |
    1301           0 :                 chan->volume.envelope.attack_time);
    1302           0 :         emuxki_write(sc, chano, EMU_CHAN_ENVVOL,
    1303           0 :                 chan->volume.envelope.current_state);
    1304           0 :         emuxki_write(sc, chano, EMU_CHAN_PEFE,
    1305           0 :                 (chan->pitch.envelope_amount << 8) |
    1306           0 :                 chan->filter.envelope_amount);
    1307           0 :         mtx_leave(&audio_lock);
    1308           0 : }
    1309             : 
    1310             : void
    1311           0 : emuxki_channel_start(struct emuxki_channel *chan)
    1312             : {
    1313           0 :         struct emuxki_voice *voice = chan->voice;
    1314           0 :         struct emuxki_softc *sc = voice->sc;
    1315           0 :         u_int8_t        cache_sample, cache_invalid_size, chano = chan->num;
    1316             :         u_int32_t       sample;
    1317             : 
    1318           0 :         cache_sample = voice->stereo ? 4 : 2;
    1319           0 :         sample = voice->b16 ? 0x00000000 : 0x80808080;
    1320           0 :         cache_invalid_size = (voice->stereo ? 28 : 30) * (voice->b16 + 1);
    1321             : 
    1322           0 :         while (cache_sample--) {
    1323           0 :                 emuxki_write(sc, chano, EMU_CHAN_CD0 + cache_sample,
    1324             :                         sample);
    1325             :         }
    1326           0 :         emuxki_write(sc, chano, EMU_CHAN_CCR_CACHEINVALIDSIZE, 0);
    1327           0 :         emuxki_write(sc, chano, EMU_CHAN_CCR_READADDRESS, 64);
    1328           0 :         emuxki_write(sc, chano, EMU_CHAN_CCR_CACHEINVALIDSIZE,
    1329           0 :                 cache_invalid_size);
    1330           0 :         emuxki_write(sc, chano, EMU_CHAN_IFATN,
    1331           0 :                 (chan->filter.target_cutoff_frequency << 8) |
    1332           0 :                 chan->initial_attenuation);
    1333           0 :         emuxki_write(sc, chano, EMU_CHAN_VTFT_VOLUMETARGET,
    1334           0 :                 chan->volume.target);
    1335           0 :         emuxki_write(sc, chano, EMU_CHAN_CVCF_CURRVOL,
    1336           0 :                 chan->volume.current);
    1337           0 :         emuxki_write(sc, 0,
    1338           0 :                 EMU_MKSUBREG(1, chano, EMU_SOLEL + (chano >> 5)),
    1339             :                 0);     /* Clear stop on loop */
    1340           0 :         emuxki_write(sc, 0,
    1341           0 :                 EMU_MKSUBREG(1, chano, EMU_CLIEL + (chano >> 5)),
    1342             :                 0);     /* Clear loop interrupt */
    1343           0 :         emuxki_write(sc, chano, EMU_CHAN_DCYSUSV,
    1344           0 :                 (chan->volume.envelope.sustain_level << 8) |
    1345           0 :                 chan->volume.envelope.decay_time);
    1346           0 :         emuxki_write(sc, chano, EMU_CHAN_PTRX_PITCHTARGET,
    1347           0 :                 chan->pitch.target);
    1348           0 :         emuxki_write(sc, chano, EMU_CHAN_CPF_PITCH,
    1349           0 :                 chan->pitch.current);
    1350           0 :         emuxki_write(sc, chano, EMU_CHAN_IP, chan->pitch.initial);
    1351           0 : }
    1352             : 
    1353             : void
    1354           0 : emuxki_channel_stop(struct emuxki_channel *chan)
    1355             : {
    1356           0 :         u_int8_t chano = chan->num;
    1357           0 :         struct emuxki_softc *sc = chan->voice->sc;
    1358             : 
    1359           0 :         emuxki_write(sc, chano, EMU_CHAN_PTRX_PITCHTARGET, 0);
    1360           0 :         emuxki_write(sc, chano, EMU_CHAN_CPF_PITCH, 0);
    1361           0 :         emuxki_write(sc, chano, EMU_CHAN_IFATN_ATTENUATION, 0xff);
    1362           0 :         emuxki_write(sc, chano, EMU_CHAN_VTFT_VOLUMETARGET, 0);
    1363           0 :         emuxki_write(sc, chano, EMU_CHAN_CVCF_CURRVOL, 0);
    1364           0 :         emuxki_write(sc, chano, EMU_CHAN_IP, 0);
    1365           0 : }
    1366             : 
    1367             : /*
    1368             :  * Voices management
    1369             :  * emuxki_voice_dataloc : use(play or rec) independent dataloc union helpers
    1370             :  * emuxki_voice_channel_* : play part of dataloc union helpers
    1371             :  * emuxki_voice_recsrc_* : rec part of dataloc union helpers
    1372             :  */
    1373             : 
    1374             : /* Allocate channels for voice in case of play voice */
    1375             : int
    1376           0 : emuxki_voice_channel_create(struct emuxki_voice *voice)
    1377             : {
    1378           0 :         struct emuxki_channel **channel = voice->sc->channel;
    1379           0 :         u_int8_t i, stereo = voice->stereo;
    1380             : 
    1381           0 :         for (i = 0; i < EMU_NUMCHAN; i += stereo + 1) {
    1382           0 :                 if ((stereo && (channel[i + 1] != NULL)) ||
    1383           0 :                     (channel[i] != NULL))       /* Looking for free channels */
    1384             :                         continue;
    1385           0 :                 if (stereo) {
    1386           0 :                         voice->dataloc.chan[1] =
    1387           0 :                                 emuxki_channel_new(voice, i + 1);
    1388           0 :                         if (voice->dataloc.chan[1] == NULL) {
    1389           0 :                                 return (ENOMEM);
    1390             :                         }
    1391             :                 }
    1392           0 :                 voice->dataloc.chan[0] = emuxki_channel_new(voice, i);
    1393           0 :                 if (voice->dataloc.chan[0] == NULL) {
    1394           0 :                         if (stereo) {
    1395           0 :                                 emuxki_channel_delete(voice->dataloc.chan[1]);
    1396           0 :                                 voice->dataloc.chan[1] = NULL;
    1397           0 :                         }
    1398           0 :                         return (ENOMEM);
    1399             :                 }
    1400           0 :                 return (0);
    1401             :         }
    1402           0 :         return (EAGAIN);
    1403           0 : }
    1404             : 
    1405             : /* When calling this function we assume no one can access the voice */
    1406             : void
    1407           0 : emuxki_voice_channel_destroy(struct emuxki_voice *voice)
    1408             : {
    1409           0 :         emuxki_channel_delete(voice->dataloc.chan[0]);
    1410           0 :         voice->dataloc.chan[0] = NULL;
    1411           0 :         if (voice->stereo)
    1412           0 :                 emuxki_channel_delete(voice->dataloc.chan[1]);
    1413           0 :         voice->dataloc.chan[1] = NULL;
    1414           0 : }
    1415             : 
    1416             : /*
    1417             :  * Will come back when used in voice_dataloc_create
    1418             :  */
    1419             : int
    1420           0 : emuxki_recsrc_reserve(struct emuxki_voice *voice, emuxki_recsrc_t source)
    1421             : {
    1422           0 :         if (source >= EMU_NUMRECSRCS) {
    1423             : #ifdef EMUXKI_DEBUG
    1424             :                 printf("Tried to reserve invalid source: %d\n", source);
    1425             : #endif
    1426           0 :                 return (EINVAL);
    1427             :         }
    1428           0 :         if (voice->sc->recsrc[source] == voice)
    1429           0 :                 return (0);                     /* XXX */
    1430           0 :         if (voice->sc->recsrc[source] != NULL)
    1431           0 :                 return (EBUSY);
    1432           0 :         voice->sc->recsrc[source] = voice;
    1433           0 :         return (0);
    1434           0 : }
    1435             : 
    1436             : /* When calling this function we assume the voice is stopped */
    1437             : void
    1438           0 : emuxki_voice_recsrc_release(struct emuxki_softc *sc, emuxki_recsrc_t source)
    1439             : {
    1440           0 :         sc->recsrc[source] = NULL;
    1441           0 : }
    1442             : 
    1443             : int
    1444           0 : emuxki_voice_dataloc_create(struct emuxki_voice *voice)
    1445             : {
    1446             :         int             error;
    1447             : 
    1448           0 :         if (voice->use & EMU_VOICE_USE_PLAY) {
    1449           0 :                 if ((error = emuxki_voice_channel_create(voice)))
    1450           0 :                         return (error);
    1451             :         } else {
    1452           0 :                 if ((error =
    1453           0 :                     emuxki_recsrc_reserve(voice, voice->dataloc.source)))
    1454           0 :                         return (error);
    1455             :         }
    1456           0 :         return (0);
    1457           0 : }
    1458             : 
    1459             : void
    1460           0 : emuxki_voice_dataloc_destroy(struct emuxki_voice *voice)
    1461             : {
    1462           0 :         if (voice->use & EMU_VOICE_USE_PLAY) {
    1463           0 :                 if (voice->dataloc.chan[0] != NULL)
    1464           0 :                         emuxki_voice_channel_destroy(voice);
    1465             :         } else {
    1466           0 :                 if (voice->dataloc.source != EMU_RECSRC_NOTSET) {
    1467           0 :                         emuxki_voice_recsrc_release(voice->sc,
    1468             :                                                      voice->dataloc.source);
    1469           0 :                         voice->dataloc.source = EMU_RECSRC_NOTSET;
    1470           0 :                 }
    1471             :         }
    1472           0 : }
    1473             : 
    1474             : struct emuxki_voice *
    1475           0 : emuxki_voice_new(struct emuxki_softc *sc, u_int8_t use)
    1476             : {
    1477             :         struct emuxki_voice *voice;
    1478             : 
    1479           0 :         mtx_enter(&audio_lock);
    1480           0 :         voice = sc->lvoice;
    1481           0 :         sc->lvoice = NULL;
    1482           0 :         mtx_leave(&audio_lock);
    1483             : 
    1484           0 :         if (!voice) {
    1485           0 :                 if (!(voice = malloc(sizeof(*voice), M_DEVBUF, M_WAITOK)))
    1486           0 :                         return (NULL);
    1487           0 :         } else if (voice->use != use) 
    1488           0 :                 emuxki_voice_dataloc_destroy(voice);
    1489             :         else
    1490             :                 goto skip_initialize;
    1491             : 
    1492           0 :         voice->sc = sc;
    1493           0 :         voice->state = !EMU_VOICE_STATE_STARTED;
    1494           0 :         voice->stereo = EMU_VOICE_STEREO_NOTSET;
    1495           0 :         voice->b16 = 0;
    1496           0 :         voice->sample_rate = 0;
    1497           0 :         if (use & EMU_VOICE_USE_PLAY)
    1498           0 :                 voice->dataloc.chan[0] = voice->dataloc.chan[1] = NULL;
    1499             :         else
    1500           0 :                 voice->dataloc.source = EMU_RECSRC_NOTSET;
    1501           0 :         voice->buffer = NULL;
    1502           0 :         voice->blksize = 0;
    1503           0 :         voice->trigblk = 0;
    1504           0 :         voice->blkmod = 0;
    1505           0 :         voice->inth = NULL;
    1506           0 :         voice->inthparam = NULL;
    1507           0 :         voice->use = use;
    1508             : 
    1509             : skip_initialize:
    1510           0 :         mtx_enter(&audio_lock);
    1511           0 :         LIST_INSERT_HEAD((&sc->voices), voice, next);
    1512           0 :         mtx_leave(&audio_lock);
    1513             : 
    1514           0 :         return (voice);
    1515           0 : }
    1516             : 
    1517             : void
    1518           0 : emuxki_voice_delete(struct emuxki_voice *voice)
    1519             : {
    1520           0 :         struct emuxki_softc *sc = voice->sc;
    1521             :         struct emuxki_voice *lvoice;
    1522             : 
    1523           0 :         if (voice->state & EMU_VOICE_STATE_STARTED)
    1524           0 :                 emuxki_voice_halt(voice);
    1525             : 
    1526           0 :         mtx_enter(&audio_lock);
    1527           0 :         LIST_REMOVE(voice, next);
    1528           0 :         lvoice = sc->lvoice;
    1529           0 :         sc->lvoice = voice;
    1530           0 :         mtx_leave(&audio_lock);
    1531             : 
    1532           0 :         if (lvoice) {
    1533           0 :                 emuxki_voice_dataloc_destroy(lvoice);
    1534           0 :                 free(lvoice, M_DEVBUF, 0);
    1535           0 :         }
    1536           0 : }
    1537             : 
    1538             : int
    1539           0 : emuxki_voice_set_stereo(struct emuxki_voice *voice, u_int8_t stereo)
    1540             : {
    1541             :         int     error;
    1542             :         emuxki_recsrc_t source = 0; /* XXX: gcc */
    1543           0 :         struct emuxki_chanparms_fxsend fxsend;
    1544             : 
    1545           0 :         if (! (voice->use & EMU_VOICE_USE_PLAY))
    1546           0 :                 source = voice->dataloc.source;
    1547           0 :         emuxki_voice_dataloc_destroy(voice);
    1548           0 :         if (! (voice->use & EMU_VOICE_USE_PLAY))
    1549           0 :                 voice->dataloc.source = source;
    1550           0 :         voice->stereo = stereo;
    1551           0 :         if ((error = emuxki_voice_dataloc_create(voice)))
    1552           0 :           return (error);
    1553           0 :         if (voice->use & EMU_VOICE_USE_PLAY) {
    1554           0 :                 fxsend.a.dest = 0x0;
    1555           0 :                 fxsend.b.dest = 0x1;
    1556           0 :                 fxsend.c.dest = 0x2;
    1557           0 :                 fxsend.d.dest = 0x3;
    1558             :                 /* for audigy */
    1559           0 :                 fxsend.e.dest = 0x4;
    1560           0 :                 fxsend.f.dest = 0x5;
    1561           0 :                 fxsend.g.dest = 0x6;
    1562           0 :                 fxsend.h.dest = 0x7;
    1563           0 :                 if (voice->stereo) {
    1564           0 :                         fxsend.a.level = fxsend.c.level = 0xc0;
    1565           0 :                         fxsend.b.level = fxsend.d.level = 0x00;
    1566           0 :                         fxsend.e.level = fxsend.g.level = 0xc0;
    1567           0 :                         fxsend.f.level = fxsend.h.level = 0x00;
    1568           0 :                         emuxki_channel_set_fxsend(voice->dataloc.chan[0],
    1569             :                                                    &fxsend);
    1570           0 :                         fxsend.a.level = fxsend.c.level = 0x00;
    1571           0 :                         fxsend.b.level = fxsend.d.level = 0xc0;
    1572           0 :                         fxsend.e.level = fxsend.g.level = 0x00;
    1573           0 :                         fxsend.f.level = fxsend.h.level = 0xc0;
    1574           0 :                         emuxki_channel_set_fxsend(voice->dataloc.chan[1],
    1575             :                                                    &fxsend);
    1576           0 :                 } /* No else : default is good for mono */      
    1577             :         }
    1578           0 :         return (0);
    1579           0 : }
    1580             : 
    1581             : int
    1582           0 : emuxki_voice_set_srate(struct emuxki_voice *voice, u_int32_t srate)
    1583             : {
    1584           0 :         if (voice->use & EMU_VOICE_USE_PLAY) {
    1585           0 :                 if (srate < 4000)
    1586           0 :                         srate = 4000;
    1587           0 :                 if (srate > 48000)
    1588           0 :                         srate = 48000;
    1589           0 :                 voice->sample_rate = srate;
    1590           0 :                 emuxki_channel_set_srate(voice->dataloc.chan[0], srate);
    1591           0 :                 if (voice->stereo)
    1592           0 :                         emuxki_channel_set_srate(voice->dataloc.chan[1],
    1593             :                                                   srate);
    1594             :         } else {
    1595           0 :                 if (srate < 8000)
    1596           0 :                         srate = 8000;
    1597           0 :                 if (srate > 48000)
    1598           0 :                         srate = 48000;
    1599           0 :                 voice->sample_rate = srate;
    1600           0 :                 if (emuxki_voice_adc_rate(voice) < 0) {
    1601           0 :                         voice->sample_rate = 0;
    1602           0 :                         return (EINVAL);
    1603             :                 }
    1604             :         }
    1605           0 :         return (0);
    1606           0 : }
    1607             : 
    1608             : int
    1609           0 : emuxki_voice_set_audioparms(struct emuxki_voice *voice, u_int8_t stereo,
    1610             :                              u_int8_t b16, u_int32_t srate)
    1611             : {
    1612             :         int             error = 0;
    1613             : 
    1614             :         /*
    1615             :          * Audio driver tried to set recording AND playing params even if
    1616             :          * device opened in play or record only mode ==>
    1617             :          * modified emuxki_set_params.
    1618             :          * Stays here for now just in case ...
    1619             :          */
    1620           0 :         if (voice == NULL) {
    1621             : #ifdef EMUXKI_DEBUG
    1622             :                 printf("warning: tried to set unallocated voice params !!\n");
    1623             : #endif
    1624           0 :                 return (0);
    1625             :         }
    1626             : 
    1627           0 :         if (voice->stereo == stereo && voice->b16 == b16 &&
    1628           0 :             voice->sample_rate == srate)
    1629           0 :                 return (0);
    1630             : 
    1631             : #ifdef EMUXKI_DEBUG
    1632             :         printf("Setting %s voice params : %s, %u bits, %u hz\n",
    1633             :                (voice->use & EMU_VOICE_USE_PLAY) ? "play" : "record",
    1634             :                stereo ? "stereo" : "mono", (b16 + 1) * 8, srate);
    1635             : #endif
    1636             :         
    1637           0 :         voice->b16 = b16;
    1638             : 
    1639             :         /* sample rate must be set after any channel number changes */ 
    1640           0 :         if ((voice->stereo != stereo) || (voice->sample_rate != srate)) {
    1641           0 :                 if (voice->stereo != stereo) {
    1642           0 :                         if ((error = emuxki_voice_set_stereo(voice, stereo)))
    1643           0 :                                 return (error);
    1644             :                 }
    1645           0 :                 error = emuxki_voice_set_srate(voice, srate);
    1646           0 :         }
    1647           0 :         return error;
    1648           0 : }
    1649             : 
    1650             : /* voice audio parms (see just before) must be set prior to this */
    1651             : int
    1652           0 : emuxki_voice_set_bufparms(struct emuxki_voice *voice, void *ptr,
    1653             :                            u_int32_t bufsize, u_int16_t blksize)
    1654             : {
    1655             :         struct emuxki_mem *mem;
    1656             :         struct emuxki_channel **chan;
    1657             :         u_int32_t start, end;
    1658             :         u_int8_t sample_size;
    1659             :         int idx;
    1660             :         int error = EFAULT;
    1661             : 
    1662           0 :         LIST_FOREACH(mem, &voice->sc->mem, next) {
    1663           0 :                 if (KERNADDR(mem->dmamem) != ptr)
    1664             :                         continue;
    1665             : 
    1666           0 :                 voice->buffer = mem;
    1667           0 :                 sample_size = (voice->b16 + 1) * (voice->stereo + 1);
    1668           0 :                 voice->trigblk = 0;  /* This shouldn't be needed */
    1669           0 :                 voice->blkmod = bufsize / blksize;
    1670           0 :                 if (bufsize % blksize)    /* This should not happen */
    1671           0 :                         voice->blkmod++;
    1672             :                 error = 0;
    1673             : 
    1674           0 :                 if (voice->use & EMU_VOICE_USE_PLAY) {
    1675           0 :                         voice->blksize = blksize / sample_size;
    1676           0 :                         chan = voice->dataloc.chan;
    1677           0 :                         start = (mem->ptbidx << 12) / sample_size;
    1678           0 :                         end = start + bufsize / sample_size;
    1679           0 :                         emuxki_channel_set_bufparms(chan[0],
    1680             :                                                      start, end);
    1681           0 :                         if (voice->stereo)
    1682           0 :                                 emuxki_channel_set_bufparms(chan[1],
    1683             :                                      start, end);
    1684           0 :                         voice->timerate = (u_int32_t) 48000 *
    1685           0 :                                         voice->blksize / voice->sample_rate;
    1686           0 :                         if (voice->timerate < 5)
    1687           0 :                                 error = EINVAL;
    1688             :                 } else {
    1689           0 :                         voice->blksize = blksize;
    1690           0 :                         for(idx = sizeof(emuxki_recbuf_sz) /
    1691           0 :                             sizeof(emuxki_recbuf_sz[0]); --idx >= 0;)
    1692           0 :                                 if (emuxki_recbuf_sz[idx] == bufsize)
    1693             :                                         break;
    1694           0 :                         if (idx < 0) {
    1695             : #ifdef EMUXKI_DEBUG
    1696             :                                 printf("Invalid bufsize: %d\n", bufsize);
    1697             : #endif
    1698           0 :                                 return (EINVAL);
    1699             :                         }
    1700           0 :                         mtx_enter(&audio_lock);
    1701           0 :                         emuxki_write(voice->sc, 0,
    1702           0 :                             emuxki_recsrc_szreg[voice->dataloc.source], idx);
    1703           0 :                         emuxki_write(voice->sc, 0,
    1704           0 :                             emuxki_recsrc_bufaddrreg[voice->dataloc.source],
    1705           0 :                             DMAADDR(mem->dmamem));
    1706           0 :                         mtx_leave(&audio_lock);
    1707             :                         /* Use timer to emulate DMA completion interrupt */
    1708           0 :                         voice->timerate = (u_int32_t) 48000 * blksize /
    1709           0 :                             (voice->sample_rate * sample_size);
    1710           0 :                         if (voice->timerate < 5) {
    1711             : #ifdef EMUXKI_DEBUG
    1712             :                                 printf("Invalid timerate: %d, blksize %d\n",
    1713             :                                     voice->timerate, blksize);
    1714             : #endif
    1715             :                                 error = EINVAL;
    1716           0 :                         }
    1717             :                 }
    1718             : 
    1719             :                 break;
    1720             :         }
    1721             : 
    1722           0 :         return (error);
    1723           0 : }
    1724             : 
    1725             : void
    1726           0 : emuxki_voice_commit_parms(struct emuxki_voice *voice)
    1727             : {
    1728           0 :         if (voice->use & EMU_VOICE_USE_PLAY) {
    1729           0 :                 emuxki_channel_commit_parms(voice->dataloc.chan[0]);
    1730           0 :                 if (voice->stereo)
    1731           0 :                         emuxki_channel_commit_parms(voice->dataloc.chan[1]);
    1732             :         }
    1733           0 : }
    1734             : 
    1735             : u_int32_t
    1736           0 : emuxki_voice_curaddr(struct emuxki_voice *voice)
    1737             : {
    1738             :         int idxreg = 0;
    1739             : 
    1740             :         /* XXX different semantics in these cases */
    1741           0 :         if (voice->use & EMU_VOICE_USE_PLAY) {
    1742             :                 /* returns number of samples (an l/r pair counts 1) */
    1743           0 :                 return (emuxki_read(voice->sc,
    1744           0 :                                      voice->dataloc.chan[0]->num,
    1745           0 :                                      EMU_CHAN_CCCA_CURRADDR) -
    1746           0 :                         voice->dataloc.chan[0]->loop.start);
    1747             :         } else {
    1748             :                 /* returns number of bytes */
    1749           0 :                 switch (voice->dataloc.source) {
    1750             :                         case EMU_RECSRC_MIC:
    1751           0 :                                 idxreg = (voice->sc->sc_flags & EMUXKI_AUDIGY) ?
    1752             :                                         EMU_A_MICIDX : EMU_MICIDX;
    1753           0 :                                 break;
    1754             :                         case EMU_RECSRC_ADC:
    1755           0 :                                 idxreg = (voice->sc->sc_flags & EMUXKI_AUDIGY) ?
    1756             :                                         EMU_A_ADCIDX : EMU_ADCIDX;
    1757           0 :                                 break;
    1758             :                         case EMU_RECSRC_FX:
    1759             :                                 idxreg = EMU_FXIDX;
    1760           0 :                                 break;
    1761             :                         default:
    1762             : #ifdef EMUXKI_DEBUG
    1763             :                                 printf("emu: bad recording source!\n");
    1764             : #endif
    1765             :                                 break;
    1766             :                 }
    1767           0 :                 return (emuxki_read(voice->sc, 0, EMU_RECIDX(idxreg))
    1768           0 :                                 & EMU_RECIDX_MASK);
    1769             :         }
    1770             :         return (0);
    1771           0 : }
    1772             : 
    1773             : void
    1774           0 : emuxki_resched_timer(struct emuxki_softc *sc)
    1775             : {
    1776             :         struct emuxki_voice *voice;
    1777             :         u_int16_t       timerate = 1024;
    1778             :         u_int8_t        active = 0;
    1779             : 
    1780           0 :         LIST_FOREACH(voice, &sc->voices, next) {
    1781           0 :                 if ((voice->state & EMU_VOICE_STATE_STARTED) == 0)
    1782             :                         continue;
    1783             :                 active = 1;
    1784           0 :                 if (voice->timerate < timerate)
    1785           0 :                         timerate = voice->timerate;
    1786             :         }
    1787             : 
    1788           0 :         if (timerate & ~EMU_TIMER_RATE_MASK)
    1789           0 :                 timerate = 0;
    1790           0 :         bus_space_write_2(sc->sc_iot, sc->sc_ioh, EMU_TIMER, timerate);
    1791           0 :         if (!active && (sc->timerstate & EMU_TIMER_STATE_ENABLED)) {
    1792           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_INTE,
    1793             :                         bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_INTE) &
    1794             :                         ~EMU_INTE_INTERTIMERENB);
    1795           0 :                 sc->timerstate &= ~EMU_TIMER_STATE_ENABLED;
    1796           0 :         } else if (active && !(sc->timerstate & EMU_TIMER_STATE_ENABLED)) {
    1797           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_INTE,
    1798             :                         bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_INTE) |
    1799             :                         EMU_INTE_INTERTIMERENB);
    1800           0 :                 sc->timerstate |= EMU_TIMER_STATE_ENABLED;
    1801           0 :         }
    1802           0 : }
    1803             : 
    1804             : int
    1805           0 : emuxki_voice_adc_rate(struct emuxki_voice *voice)
    1806             : {
    1807           0 :         switch(voice->sample_rate) {
    1808             :                 case 48000:
    1809           0 :                         return EMU_ADCCR_SAMPLERATE_48;
    1810             :                         break;
    1811             :                 case 44100:
    1812           0 :                         return EMU_ADCCR_SAMPLERATE_44;
    1813             :                         break;
    1814             :                 case 32000:
    1815           0 :                         return EMU_ADCCR_SAMPLERATE_32;
    1816             :                         break;
    1817             :                 case 24000:
    1818           0 :                         return EMU_ADCCR_SAMPLERATE_24;
    1819             :                         break;
    1820             :                 case 22050:
    1821           0 :                         return EMU_ADCCR_SAMPLERATE_22;
    1822             :                         break;
    1823             :                 case 16000:
    1824           0 :                         return EMU_ADCCR_SAMPLERATE_16;
    1825             :                         break;
    1826             :                 case 12000:
    1827           0 :                         if (voice->sc->sc_flags & EMUXKI_AUDIGY)
    1828           0 :                                 return EMU_A_ADCCR_SAMPLERATE_12;
    1829             :                         else {
    1830             : #ifdef EMUXKI_DEBUG
    1831             :                                 printf("recording sample_rate not supported : %u\n", voice->sample_rate);
    1832             : #endif
    1833           0 :                                 return (-1);
    1834             :                         }
    1835             :                         break;
    1836             :                 case 11000:
    1837           0 :                         if (voice->sc->sc_flags & EMUXKI_AUDIGY)
    1838           0 :                                 return EMU_A_ADCCR_SAMPLERATE_11;
    1839             :                         else
    1840           0 :                                 return EMU_ADCCR_SAMPLERATE_11;
    1841             :                         break;
    1842             :                 case 8000:
    1843           0 :                         if (voice->sc->sc_flags & EMUXKI_AUDIGY)
    1844           0 :                                 return EMU_A_ADCCR_SAMPLERATE_8;
    1845             :                         else
    1846           0 :                                 return EMU_ADCCR_SAMPLERATE_8;
    1847             :                         break;
    1848             :                 default:
    1849             : #ifdef EMUXKI_DEBUG
    1850             :                                 printf("recording sample_rate not supported : %u\n", voice->sample_rate);
    1851             : #endif
    1852           0 :                                 return (-1);
    1853             :         }
    1854             :         return (-1);  /* shouldn't get here */
    1855           0 : }
    1856             : 
    1857             : void
    1858           0 : emuxki_voice_start(struct emuxki_voice *voice,
    1859             :                     void (*inth) (void *), void *inthparam)
    1860             : {
    1861             :         u_int32_t val;
    1862             : 
    1863           0 :         mtx_enter(&audio_lock);
    1864           0 :         voice->inth = inth;
    1865           0 :         voice->inthparam = inthparam;
    1866           0 :         if (voice->use & EMU_VOICE_USE_PLAY) {
    1867             :                 voice->trigblk = 1;
    1868           0 :                 emuxki_channel_start(voice->dataloc.chan[0]);
    1869           0 :                 if (voice->stereo)
    1870           0 :                         emuxki_channel_start(voice->dataloc.chan[1]);
    1871             :         } else {
    1872             :                 voice->trigblk = 1;
    1873           0 :                 switch (voice->dataloc.source) {
    1874             :                 case EMU_RECSRC_ADC:
    1875             :                         /* XXX need to program DSP to output L+R
    1876             :                          * XXX in monaural case? */
    1877           0 :                         if (voice->sc->sc_flags & EMUXKI_AUDIGY) {
    1878             :                                 val = EMU_A_ADCCR_LCHANENABLE;
    1879           0 :                                 if (voice->stereo)
    1880           0 :                                         val |= EMU_A_ADCCR_RCHANENABLE;
    1881             :                         } else {
    1882             :                                 val = EMU_ADCCR_LCHANENABLE;
    1883           0 :                                 if (voice->stereo)
    1884           0 :                                         val |= EMU_ADCCR_RCHANENABLE;
    1885             :                         }
    1886           0 :                         val |= emuxki_voice_adc_rate(voice);
    1887           0 :                         emuxki_write(voice->sc, 0, EMU_ADCCR, 0);
    1888           0 :                         emuxki_write(voice->sc, 0, EMU_ADCCR, val);
    1889           0 :                         break;
    1890             :                 case EMU_RECSRC_MIC:
    1891             :                 case EMU_RECSRC_FX:
    1892           0 :                         printf("unimplemented\n");
    1893           0 :                         break;
    1894             :                 case EMU_RECSRC_NOTSET:
    1895             :                 default:
    1896             :                         break;
    1897             :                 }
    1898             : #if 0
    1899             :                 /* DMA completion interrupt is useless; use timer */
    1900             :                 val = emu_rd(sc, INTE, 4);
    1901             :                 val |= emuxki_recsrc_intrmasks[voice->dataloc.source];
    1902             :                 emu_wr(sc, INTE, val, 4);
    1903             : #endif
    1904             :         }
    1905           0 :         voice->state |= EMU_VOICE_STATE_STARTED;
    1906           0 :         emuxki_resched_timer(voice->sc);
    1907           0 :         mtx_leave(&audio_lock);
    1908           0 : }
    1909             : 
    1910             : void
    1911           0 : emuxki_voice_halt(struct emuxki_voice *voice)
    1912             : {
    1913           0 :         mtx_enter(&audio_lock);
    1914           0 :         if (voice->use & EMU_VOICE_USE_PLAY) {
    1915           0 :                 emuxki_channel_stop(voice->dataloc.chan[0]);
    1916           0 :                 if (voice->stereo)
    1917           0 :                         emuxki_channel_stop(voice->dataloc.chan[1]);
    1918             :         } else {
    1919           0 :                 switch (voice->dataloc.source) {
    1920             :                 case EMU_RECSRC_ADC:
    1921           0 :                         emuxki_write(voice->sc, 0, EMU_ADCCR, 0);
    1922           0 :                         break;
    1923             :                 case EMU_RECSRC_FX:
    1924             :                 case EMU_RECSRC_MIC:
    1925           0 :                         printf("unimplemented\n");
    1926           0 :                         break;
    1927             :                 case EMU_RECSRC_NOTSET:
    1928           0 :                         printf("Bad dataloc.source\n");
    1929           0 :                 }
    1930             :                 /* This should reset buffer pointer */
    1931           0 :                 emuxki_write(voice->sc, 0,
    1932           0 :                     emuxki_recsrc_szreg[voice->dataloc.source],
    1933             :                     EMU_RECBS_BUFSIZE_NONE);
    1934             : #if 0
    1935             :                 val = emu_rd(sc, INTE, 4);
    1936             :                 val &= ~emuxki_recsrc_intrmasks[voice->dataloc.source];
    1937             :                 emu_wr(sc, INTE, val, 4);
    1938             : #endif
    1939             :         }
    1940           0 :         voice->state &= ~EMU_VOICE_STATE_STARTED;
    1941           0 :         emuxki_resched_timer(voice->sc);
    1942           0 :         mtx_leave(&audio_lock);
    1943           0 : }
    1944             : 
    1945             : /*
    1946             :  * The interrupt handler
    1947             :  */
    1948             : int
    1949           0 : emuxki_intr(void *arg)
    1950             : {
    1951           0 :         struct emuxki_softc *sc = arg;
    1952             :         u_int32_t       ipr, curblk, us = 0;
    1953             :         struct emuxki_voice *voice;
    1954             : 
    1955           0 :         mtx_enter(&audio_lock);
    1956           0 :         while ((ipr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_IPR))) {
    1957           0 :                 if (ipr & EMU_IPR_INTERVALTIMER) {
    1958           0 :                         LIST_FOREACH(voice, &sc->voices, next) {
    1959           0 :                                 if ((voice->state &
    1960           0 :                                       EMU_VOICE_STATE_STARTED) == 0)
    1961             :                                         continue;
    1962             : 
    1963           0 :                                 curblk = emuxki_voice_curaddr(voice) /
    1964           0 :                                        voice->blksize;
    1965             : #if 0
    1966             :                                 if (curblk == voice->trigblk) {
    1967             :                                         voice->inth(voice->inthparam);
    1968             :                                         voice->trigblk++;
    1969             :                                         voice->trigblk %= voice->blkmod;
    1970             :                                 }
    1971             : #else
    1972           0 :                                 while ((curblk >= voice->trigblk &&
    1973           0 :                                     curblk < (voice->trigblk + voice->blkmod / 2)) ||
    1974           0 :                                     ((int)voice->trigblk - (int)curblk) >
    1975           0 :                                     (voice->blkmod / 2 + 1)) {
    1976           0 :                                         voice->inth(voice->inthparam);
    1977           0 :                                         voice->trigblk++;
    1978           0 :                                         voice->trigblk %= voice->blkmod;
    1979             :                                 }
    1980             : #endif
    1981             :                         }
    1982             :                         us = 1;
    1983           0 :                 }
    1984             : 
    1985             :                 /* Got interrupt */
    1986           0 :                 bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_IPR, ipr);
    1987             :         }
    1988           0 :         mtx_leave(&audio_lock);
    1989           0 :         return (us);
    1990             : }
    1991             : 
    1992             : 
    1993             : /*
    1994             :  * Audio Architecture callbacks
    1995             :  */
    1996             : 
    1997             : int
    1998           0 : emuxki_open(void *addr, int flags)
    1999             : {
    2000           0 :         struct emuxki_softc *sc = addr;
    2001             : 
    2002             : #ifdef EMUXKI_DEBUG
    2003             :         printf("%s: emuxki_open called\n", sc->sc_dev.dv_xname);
    2004             : #endif
    2005             : 
    2006             :         /*
    2007             :          * Multiple voice support would be added as soon as I find a way to
    2008             :          * trick the audio arch into supporting multiple voices.
    2009             :          * Or I might integrate a modified audio arch supporting
    2010             :          * multiple voices.
    2011             :          */
    2012             : 
    2013             :         /*
    2014             :          * I did this because i have problems identifying the selected
    2015             :          * recording source(s) which is necessary when setting recording
    2016             :          * params. This will be addressed very soon.
    2017             :          */
    2018           0 :         if (flags & FREAD) {
    2019           0 :                 sc->rvoice = emuxki_voice_new(sc, 0 /* EMU_VOICE_USE_RECORD */);
    2020           0 :                 if (sc->rvoice == NULL)
    2021           0 :                         return (EBUSY);
    2022             : 
    2023             :                 /* XXX Hardcode RECSRC_ADC for now */
    2024           0 :                 sc->rvoice->dataloc.source = EMU_RECSRC_ADC;
    2025           0 :         }
    2026             : 
    2027           0 :         if (flags & FWRITE) {
    2028           0 :                 sc->pvoice = emuxki_voice_new(sc, EMU_VOICE_USE_PLAY);
    2029           0 :                 if (sc->pvoice == NULL) {
    2030           0 :                         if (flags & FREAD)
    2031           0 :                                 emuxki_voice_delete(sc->rvoice);
    2032           0 :                         return (EBUSY);
    2033             :                 }
    2034             :         }
    2035             : 
    2036           0 :         return (0);
    2037           0 : }
    2038             : 
    2039             : void
    2040           0 : emuxki_close(void *addr)
    2041             : {
    2042           0 :         struct emuxki_softc *sc = addr;
    2043             : 
    2044             : #ifdef EMUXKI_DEBUG
    2045             :         printf("%s: emu10K1_close called\n", sc->sc_dev.dv_xname);
    2046             : #endif
    2047             : 
    2048             :         /* No multiple voice support for now */
    2049           0 :         if (sc->rvoice != NULL)
    2050           0 :                 emuxki_voice_delete(sc->rvoice);
    2051           0 :         sc->rvoice = NULL;
    2052           0 :         if (sc->pvoice != NULL)
    2053           0 :                 emuxki_voice_delete(sc->pvoice);
    2054           0 :         sc->pvoice = NULL;
    2055           0 : }
    2056             : 
    2057             : int
    2058           0 : emuxki_set_vparms(struct emuxki_voice *voice, struct audio_params *p)
    2059             : {
    2060             :         u_int8_t        b16, mode;
    2061             : 
    2062           0 :         mode = (voice->use & EMU_VOICE_USE_PLAY) ?
    2063             :                 AUMODE_PLAY : AUMODE_RECORD;
    2064           0 :         if (p->channels > 2)
    2065           0 :                 p->channels = 2;
    2066           0 :         if (p->precision > 16)
    2067           0 :                 p->precision = 16;
    2068             :         /* Will change when streams come in use */
    2069             : 
    2070             :         /*
    2071             :          * Always use slinear_le for recording, as how to set otherwise
    2072             :          * isn't known.
    2073             :          */
    2074           0 :         if (mode == AUMODE_PLAY)
    2075           0 :                 b16 = (p->precision == 16);
    2076             :         else {
    2077             :                 b16 = 1;
    2078           0 :                 p->precision = 16;
    2079             :         }
    2080             : 
    2081           0 :         switch (p->encoding) {
    2082             :         case AUDIO_ENCODING_SLINEAR_LE:
    2083           0 :                 if (p->precision != 16)
    2084           0 :                         return EINVAL;
    2085             :                 break;
    2086             : 
    2087             :         case AUDIO_ENCODING_ULINEAR_LE:
    2088             :         case AUDIO_ENCODING_ULINEAR_BE:
    2089           0 :                 if (p->precision != 8)
    2090           0 :                         return EINVAL;
    2091             :                 break;
    2092             : 
    2093             :         default:
    2094           0 :                 return (EINVAL);
    2095             :         }
    2096           0 :         p->bps = AUDIO_BPS(p->precision);
    2097           0 :         p->msb = 1;
    2098             : 
    2099           0 :         return (emuxki_voice_set_audioparms(voice, p->channels == 2,
    2100           0 :                                      b16, p->sample_rate));
    2101           0 : }
    2102             : 
    2103             : int
    2104           0 : emuxki_set_params(void *addr, int setmode, int usemode,
    2105             :                    struct audio_params *play, struct audio_params *rec)
    2106             : {
    2107           0 :         struct emuxki_softc *sc = addr;
    2108             :         int          mode, error;
    2109             :         struct audio_params *p;
    2110             : 
    2111           0 :         for (mode = AUMODE_RECORD; mode != -1;
    2112           0 :              mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
    2113           0 :                 if ((usemode & setmode & mode) == 0)
    2114             :                         continue;
    2115             : 
    2116           0 :                 p = (mode == AUMODE_PLAY) ? play : rec;
    2117             : 
    2118             :                 /* No multiple voice support for now */
    2119           0 :                 if ((error = emuxki_set_vparms((mode == AUMODE_PLAY) ?
    2120           0 :                                                 sc->pvoice : sc->rvoice, p)))
    2121           0 :                         return (error);
    2122             :         }
    2123             : 
    2124           0 :         return (0);
    2125           0 : }
    2126             : 
    2127             : int
    2128           0 : emuxki_halt_output(void *addr)
    2129             : {
    2130           0 :         struct emuxki_softc *sc = addr;
    2131             : 
    2132             :         /* No multiple voice support for now */
    2133           0 :         if (sc->pvoice == NULL)
    2134           0 :                 return (ENXIO);
    2135             : 
    2136           0 :         emuxki_voice_halt(sc->pvoice);
    2137           0 :         return (0);
    2138           0 : }
    2139             : 
    2140             : int
    2141           0 : emuxki_halt_input(void *addr)
    2142             : {
    2143           0 :         struct emuxki_softc *sc = addr;
    2144             : 
    2145             : #ifdef EMUXKI_DEBUG
    2146             :         printf("%s: emuxki_halt_input called\n", sc->sc_dev.dv_xname);
    2147             : #endif
    2148             : 
    2149             :         /* No multiple voice support for now */
    2150           0 :         if (sc->rvoice == NULL)
    2151           0 :                 return (ENXIO);
    2152           0 :         emuxki_voice_halt(sc->rvoice);
    2153           0 :         return (0);
    2154           0 : }
    2155             : 
    2156             : int
    2157           0 : emuxki_set_port(void *addr, mixer_ctrl_t *mctl)
    2158             : {
    2159           0 :         struct emuxki_softc *sc = addr;
    2160             : 
    2161           0 :         return sc->codecif->vtbl->mixer_set_port(sc->codecif, mctl);
    2162             : }
    2163             : 
    2164             : int
    2165           0 : emuxki_get_port(void *addr, mixer_ctrl_t *mctl)
    2166             : {
    2167           0 :         struct emuxki_softc *sc = addr;
    2168             : 
    2169           0 :         return sc->codecif->vtbl->mixer_get_port(sc->codecif, mctl);
    2170             : }
    2171             : 
    2172             : int
    2173           0 : emuxki_query_devinfo(void *addr, mixer_devinfo_t *minfo)
    2174             : {
    2175           0 :         struct emuxki_softc *sc = addr;
    2176             : 
    2177           0 :         return sc->codecif->vtbl->query_devinfo(sc->codecif, minfo);
    2178             : }
    2179             : 
    2180             : void *
    2181           0 : emuxki_allocm(void *addr, int direction, size_t size, int type, int flags)
    2182             : {
    2183           0 :         struct emuxki_softc *sc = addr;
    2184             : 
    2185           0 :         if (direction == AUMODE_PLAY)
    2186           0 :                 return emuxki_pmem_alloc(sc, size, type, flags);
    2187             :         else
    2188           0 :                 return emuxki_rmem_alloc(sc, size, type, flags);
    2189           0 : }
    2190             : 
    2191             : void
    2192           0 : emuxki_freem(void *addr, void *ptr, int type)
    2193             : {
    2194           0 :         struct emuxki_softc *sc = addr;
    2195             :         int          i;
    2196             :         struct emuxki_mem *mem;
    2197             :         size_t    numblocks;
    2198             :         u_int32_t      *ptb, silentpage;
    2199             : 
    2200           0 :         ptb = KERNADDR(sc->ptb);
    2201           0 :         silentpage = DMAADDR(sc->silentpage) << 1;
    2202           0 :         LIST_FOREACH(mem, &sc->mem, next) {
    2203           0 :                 if (KERNADDR(mem->dmamem) != ptr)
    2204             :                         continue;
    2205             : 
    2206           0 :                 mtx_enter(&audio_lock);
    2207           0 :                 if (mem->ptbidx != EMU_RMEM) {
    2208           0 :                         numblocks = DMASIZE(mem->dmamem) / EMU_PTESIZE;
    2209           0 :                         if (DMASIZE(mem->dmamem) % EMU_PTESIZE)
    2210           0 :                                 numblocks++;
    2211           0 :                         for (i = 0; i < numblocks; i++)
    2212           0 :                                 ptb[mem->ptbidx + i] =
    2213           0 :                                     htole32(silentpage | (mem->ptbidx + i));
    2214             :                 }
    2215           0 :                 LIST_REMOVE(mem, next);
    2216           0 :                 mtx_leave(&audio_lock);
    2217             : 
    2218           0 :                 emuxki_mem_delete(mem, type);
    2219           0 :                 break;
    2220             :         }
    2221           0 : }
    2222             : 
    2223             : /* blocksize should be a divisor of allowable buffersize */
    2224             : /* XXX probably this could be done better */
    2225             : int
    2226           0 : emuxki_round_blocksize(void *addr, int blksize)
    2227             : {
    2228             :         int bufsize = 65536;
    2229             : 
    2230           0 :         while (bufsize > blksize)
    2231           0 :                 bufsize /= 2;
    2232             : 
    2233           0 :         return bufsize;
    2234             : }
    2235             :         
    2236             : size_t
    2237           0 : emuxki_round_buffersize(void *addr, int direction, size_t bsize)
    2238             : {
    2239             : 
    2240           0 :         if (direction == AUMODE_PLAY) {
    2241           0 :                 if (bsize < EMU_PTESIZE)
    2242           0 :                         bsize = EMU_PTESIZE;
    2243           0 :                 else if (bsize > (EMU_PTESIZE * EMU_MAXPTE))
    2244           0 :                         bsize = EMU_PTESIZE * EMU_MAXPTE;
    2245             :                 /* Would be better if set to max available */
    2246           0 :                 else if (bsize % EMU_PTESIZE)
    2247           0 :                         bsize = bsize -
    2248           0 :                                 (bsize % EMU_PTESIZE) +
    2249             :                                 EMU_PTESIZE;
    2250             :         } else {
    2251             :                 int idx;
    2252             : 
    2253             :                 /* find nearest lower recbuf size */
    2254           0 :                 for(idx = sizeof(emuxki_recbuf_sz) /
    2255           0 :                     sizeof(emuxki_recbuf_sz[0]); --idx >= 0; ) {
    2256           0 :                         if (bsize >= emuxki_recbuf_sz[idx]) {
    2257             :                                 bsize = emuxki_recbuf_sz[idx];
    2258           0 :                                 break;
    2259             :                         }
    2260             :                 }
    2261             : 
    2262           0 :                 if (bsize == 0)
    2263           0 :                         bsize = 384;
    2264             :         }
    2265             : 
    2266           0 :         return (bsize);
    2267             : }
    2268             : 
    2269             : int
    2270           0 : emuxki_get_props(void *addr)
    2271             : {
    2272           0 :         return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT |
    2273             :                 AUDIO_PROP_FULLDUPLEX);
    2274             : }
    2275             : 
    2276             : int
    2277           0 : emuxki_trigger_output(void *addr, void *start, void *end, int blksize,
    2278             :                        void (*inth) (void *), void *inthparam,
    2279             :                        struct audio_params *params)
    2280             : {
    2281           0 :         struct emuxki_softc *sc = addr;
    2282             :         /* No multiple voice support for now */
    2283           0 :         struct emuxki_voice *voice = sc->pvoice;
    2284             :         int          error;
    2285             : 
    2286           0 :         if (voice == NULL)
    2287           0 :                 return (ENXIO);
    2288           0 :         if ((error = emuxki_set_vparms(voice, params)))
    2289           0 :                 return (error);
    2290           0 :         if ((error = emuxki_voice_set_bufparms(voice, start,
    2291           0 :                                 (caddr_t)end - (caddr_t)start, blksize)))
    2292           0 :                 return (error);
    2293           0 :         emuxki_voice_commit_parms(voice);
    2294           0 :         emuxki_voice_start(voice, inth, inthparam);
    2295           0 :         return (0);
    2296           0 : }
    2297             : 
    2298             : int
    2299           0 : emuxki_trigger_input(void *addr, void *start, void *end, int blksize,
    2300             :                       void (*inth) (void *), void *inthparam,
    2301             :                       struct audio_params *params)
    2302             : {
    2303           0 :         struct emuxki_softc *sc = addr;
    2304             :         /* No multiple voice support for now */
    2305           0 :         struct emuxki_voice *voice = sc->rvoice;
    2306             :         int     error;
    2307             : 
    2308           0 :         if (voice == NULL)
    2309           0 :                 return (ENXIO);
    2310           0 :         if ((error = emuxki_set_vparms(voice, params)))
    2311           0 :                 return (error);
    2312           0 :         if ((error = emuxki_voice_set_bufparms(voice, start,
    2313           0 :                                                 (caddr_t)end - (caddr_t)start,
    2314           0 :                                                 blksize)))
    2315           0 :                 return (error);
    2316           0 :         emuxki_voice_start(voice, inth, inthparam);
    2317           0 :         return (0);
    2318           0 : }
    2319             : 
    2320             : 
    2321             : /*
    2322             :  * AC97 callbacks
    2323             :  */
    2324             : 
    2325             : int
    2326           0 : emuxki_ac97_attach(void *arg, struct ac97_codec_if *codecif)
    2327             : {
    2328           0 :         struct emuxki_softc *sc = arg;
    2329             : 
    2330           0 :         sc->codecif = codecif;
    2331           0 :         return (0);
    2332             : }
    2333             : 
    2334             : int
    2335           0 : emuxki_ac97_read(void *arg, u_int8_t reg, u_int16_t *val)
    2336             : {
    2337           0 :         struct emuxki_softc *sc = arg;
    2338             : 
    2339           0 :         mtx_enter(&audio_lock);
    2340           0 :         bus_space_write_1(sc->sc_iot, sc->sc_ioh, EMU_AC97ADDR, reg);
    2341           0 :         *val = bus_space_read_2(sc->sc_iot, sc->sc_ioh, EMU_AC97DATA);
    2342           0 :         mtx_leave(&audio_lock);
    2343             : 
    2344           0 :         return (0);
    2345             : }
    2346             : 
    2347             : int
    2348           0 : emuxki_ac97_write(void *arg, u_int8_t reg, u_int16_t val)
    2349             : {
    2350           0 :         struct emuxki_softc *sc = arg;
    2351             : 
    2352           0 :         mtx_enter(&audio_lock);
    2353           0 :         bus_space_write_1(sc->sc_iot, sc->sc_ioh, EMU_AC97ADDR, reg);
    2354           0 :         bus_space_write_2(sc->sc_iot, sc->sc_ioh, EMU_AC97DATA, val);
    2355           0 :         mtx_leave(&audio_lock);
    2356             : 
    2357           0 :         return (0);
    2358             : }
    2359             : 
    2360             : void
    2361           0 : emuxki_ac97_reset(void *arg)
    2362             : {
    2363           0 : }

Generated by: LCOV version 1.13