The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/pci/eap.c

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

    1 /*      $NetBSD: eap.c,v 1.67.2.1 2004/09/22 20:58:27 jmc Exp $ */
    2 /*      $OpenBSD: eap.c,v 1.6 1999/10/05 19:24:42 csapuntz Exp $ */
    3 
    4 /*
    5  * Copyright (c) 1998, 1999, 2002 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Lennart Augustsson <augustss@NetBSD.org>, Charles M. Hannum, and
   10  * Antti Kantee <pooka@NetBSD.org>.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. All advertising materials mentioning features or use of this software
   21  *    must display the following acknowledgement:
   22  *        This product includes software developed by the NetBSD
   23  *        Foundation, Inc. and its contributors.
   24  * 4. Neither the name of The NetBSD Foundation nor the names of its
   25  *    contributors may be used to endorse or promote products derived
   26  *    from this software without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   38  * POSSIBILITY OF SUCH DAMAGE.
   39  */
   40 
   41 /*
   42  * Debugging:   Andreas Gustafsson <gson@araneus.fi>
   43  * Testing:     Chuck Cranor       <chuck@maria.wustl.edu>
   44  *              Phil Nelson        <phil@cs.wwu.edu>
   45  *
   46  * ES1371/AC97: Ezra Story         <ezy@panix.com>
   47  */
   48 
   49 /* 
   50  * Ensoniq ES1370 + AK4531 and ES1371/ES1373 + AC97
   51  *
   52  * Documentation links:
   53  * 
   54  * ftp://ftp.alsa-project.org/pub/manuals/ensoniq/
   55  * ftp://ftp.alsa-project.org/pub/manuals/asahi_kasei/4531.pdf
   56  * ftp://download.intel.com/ial/scalableplatforms/audio/ac97r21.pdf
   57  */
   58 
   59 #include <sys/cdefs.h>
   60 __KERNEL_RCSID(0, "$NetBSD: eap.c,v 1.67.2.1 2004/09/22 20:58:27 jmc Exp $");
   61 
   62 #include "midi.h"
   63 
   64 #include <sys/param.h>
   65 #include <sys/systm.h>
   66 #include <sys/kernel.h>
   67 #include <sys/fcntl.h>
   68 #include <sys/malloc.h>
   69 #include <sys/device.h>
   70 #include <sys/proc.h>
   71 #include <sys/select.h>
   72 
   73 #include <dev/pci/pcidevs.h>
   74 #include <dev/pci/pcivar.h>
   75 
   76 #include <sys/audioio.h>
   77 #include <dev/audio_if.h>
   78 #include <dev/midi_if.h>
   79 #include <dev/audiovar.h>
   80 #include <dev/mulaw.h>
   81 #include <dev/auconv.h>
   82 #include <dev/ic/ac97var.h>
   83 
   84 #include <machine/bus.h>
   85 
   86 #include <dev/pci/eapreg.h>
   87 
   88 #define PCI_CBIO                0x10
   89 
   90 /* Debug */
   91 #ifdef AUDIO_DEBUG
   92 #define DPRINTF(x)      if (eapdebug) printf x
   93 #define DPRINTFN(n,x)   if (eapdebug>(n)) printf x
   94 int     eapdebug = 0;
   95 #else
   96 #define DPRINTF(x)
   97 #define DPRINTFN(n,x)
   98 #endif
   99 
  100 int     eap_match(struct device *, struct cfdata *, void *);
  101 void    eap_attach(struct device *, struct device *, void *);
  102 int     eap_detach(struct device *, int);
  103 int     eap_intr(void *);
  104 
  105 struct eap_dma {
  106         bus_dmamap_t map;
  107         caddr_t addr;
  108         bus_dma_segment_t segs[1];
  109         int nsegs;
  110         size_t size;
  111         struct eap_dma *next;
  112 };
  113 
  114 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
  115 #define KERNADDR(p) ((void *)((p)->addr))
  116 
  117 /*
  118  * The card has two DACs. Using them is a bit twisted: we use DAC2
  119  * as default and DAC1 as the optional secondary DAC.
  120  */
  121 #define EAP_DAC1 1
  122 #define EAP_DAC2 0
  123 #define EAP_I1 EAP_DAC2
  124 #define EAP_I2 EAP_DAC1
  125 struct eap_instance {
  126         struct device *parent;
  127         int index;
  128 
  129         void    (*ei_pintr)(void *);    /* DMA completion intr handler */
  130         void    *ei_parg;               /* arg for ei_intr() */
  131         struct device *ei_audiodev;             /* audio device, for detach */
  132 #ifdef DIAGNOSTIC
  133         char    ei_prun;
  134 #endif
  135 };
  136 
  137 struct eap_softc {
  138         struct device sc_dev;           /* base device */
  139         void *sc_ih;                    /* interrupt vectoring */
  140         bus_space_tag_t iot;
  141         bus_space_handle_t ioh;
  142         bus_size_t iosz;
  143         bus_dma_tag_t sc_dmatag;        /* DMA tag */
  144 
  145         struct eap_dma *sc_dmas;
  146 
  147         void    (*sc_rintr)(void *);    /* DMA completion intr handler */
  148         void    *sc_rarg;               /* arg for sc_intr() */
  149 #ifdef DIAGNOSTIC
  150         char    sc_rrun;
  151 #endif
  152 
  153 #if NMIDI > 0
  154         void    (*sc_iintr)(void *, int); /* midi input ready handler */
  155         void    (*sc_ointr)(void *);    /* midi output ready handler */
  156         void    *sc_arg;
  157         struct device *sc_mididev;
  158 #endif
  159 
  160         u_short sc_port[AK_NPORTS];     /* mirror of the hardware setting */
  161         u_int   sc_record_source;       /* recording source mask */
  162         u_int   sc_output_source;       /* output source mask */
  163         u_int   sc_mic_preamp;
  164         char    sc_1371;                /* Using ES1371/AC97 codec */
  165 
  166         struct ac97_codec_if *codec_if;
  167         struct ac97_host_if host_if;    
  168 
  169         struct eap_instance sc_ei[2];
  170 
  171         pci_chipset_tag_t sc_pc;        /* For detach */
  172 };
  173 
  174 int     eap_allocmem(struct eap_softc *, size_t, size_t, struct eap_dma *);
  175 int     eap_freemem(struct eap_softc *, struct eap_dma *);
  176 
  177 #define EWRITE1(sc, r, x) bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x))
  178 #define EWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x))
  179 #define EWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x))
  180 #define EREAD1(sc, r) bus_space_read_1((sc)->iot, (sc)->ioh, (r))
  181 #define EREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r))
  182 #define EREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r))
  183 
  184 CFATTACH_DECL(eap, sizeof(struct eap_softc),
  185     eap_match, eap_attach, eap_detach, NULL);
  186 
  187 int     eap_open(void *, int);
  188 void    eap_close(void *);
  189 int     eap_query_encoding(void *, struct audio_encoding *);
  190 int     eap_set_params(void *, int, int, struct audio_params *, struct audio_params *);
  191 int     eap_round_blocksize(void *, int);
  192 int     eap_trigger_output(void *, void *, void *, int, void (*)(void *),
  193             void *, struct audio_params *);
  194 int     eap_trigger_input(void *, void *, void *, int, void (*)(void *),
  195             void *, struct audio_params *);
  196 int     eap_halt_output(void *);
  197 int     eap_halt_input(void *);
  198 void    eap1370_write_codec(struct eap_softc *, int, int);
  199 int     eap_getdev(void *, struct audio_device *);
  200 int     eap1370_mixer_set_port(void *, mixer_ctrl_t *);
  201 int     eap1370_mixer_get_port(void *, mixer_ctrl_t *);
  202 int     eap1371_mixer_set_port(void *, mixer_ctrl_t *);
  203 int     eap1371_mixer_get_port(void *, mixer_ctrl_t *);
  204 int     eap1370_query_devinfo(void *, mixer_devinfo_t *);
  205 void   *eap_malloc(void *, int, size_t, struct malloc_type *, int);
  206 void    eap_free(void *, void *, struct malloc_type *);
  207 size_t  eap_round_buffersize(void *, int, size_t);
  208 paddr_t eap_mappage(void *, void *, off_t, int);
  209 int     eap_get_props(void *);
  210 void    eap1370_set_mixer(struct eap_softc *sc, int a, int d);
  211 u_int32_t eap1371_src_wait(struct eap_softc *sc);
  212 void    eap1371_set_adc_rate(struct eap_softc *sc, int rate);
  213 void    eap1371_set_dac_rate(struct eap_instance *ei, int rate);
  214 int     eap1371_src_read(struct eap_softc *sc, int a);
  215 void    eap1371_src_write(struct eap_softc *sc, int a, int d);
  216 int     eap1371_query_devinfo(void *addr, mixer_devinfo_t *dip);
  217 
  218 int     eap1371_attach_codec(void *sc, struct ac97_codec_if *);
  219 int     eap1371_read_codec(void *sc, u_int8_t a, u_int16_t *d);
  220 int     eap1371_write_codec(void *sc, u_int8_t a, u_int16_t d);
  221 int     eap1371_reset_codec(void *sc);
  222 int     eap1371_get_portnum_by_name(struct eap_softc *, char *, char *,
  223                                          char *);
  224 #if NMIDI > 0
  225 void    eap_midi_close(void *);
  226 void    eap_midi_getinfo(void *, struct midi_info *);
  227 int     eap_midi_open(void *, int, void (*)(void *, int),
  228                            void (*)(void *), void *);
  229 int     eap_midi_output(void *, int);
  230 #endif
  231 
  232 struct audio_hw_if eap1370_hw_if = {
  233         eap_open,
  234         eap_close,
  235         NULL,
  236         eap_query_encoding,
  237         eap_set_params,
  238         eap_round_blocksize,
  239         NULL,
  240         NULL,
  241         NULL,
  242         NULL,
  243         NULL,
  244         eap_halt_output,
  245         eap_halt_input,
  246         NULL,
  247         eap_getdev,
  248         NULL,
  249         eap1370_mixer_set_port,
  250         eap1370_mixer_get_port,
  251         eap1370_query_devinfo,
  252         eap_malloc,
  253         eap_free,
  254         eap_round_buffersize,
  255         eap_mappage,
  256         eap_get_props,
  257         eap_trigger_output,
  258         eap_trigger_input,
  259         NULL,
  260 };
  261 
  262 struct audio_hw_if eap1371_hw_if = {
  263         eap_open,
  264         eap_close,
  265         NULL,
  266         eap_query_encoding,
  267         eap_set_params,
  268         eap_round_blocksize,
  269         NULL,
  270         NULL,
  271         NULL,
  272         NULL,
  273         NULL,
  274         eap_halt_output,
  275         eap_halt_input,
  276         NULL,
  277         eap_getdev,
  278         NULL,
  279         eap1371_mixer_set_port,
  280         eap1371_mixer_get_port,
  281         eap1371_query_devinfo,
  282         eap_malloc,
  283         eap_free,
  284         eap_round_buffersize,
  285         eap_mappage,
  286         eap_get_props,
  287         eap_trigger_output,
  288         eap_trigger_input,
  289         NULL,
  290 };
  291 
  292 #if NMIDI > 0
  293 struct midi_hw_if eap_midi_hw_if = {
  294         eap_midi_open,
  295         eap_midi_close,
  296         eap_midi_output,
  297         eap_midi_getinfo,
  298         0,                              /* ioctl */
  299 };
  300 #endif
  301 
  302 struct audio_device eap_device = {
  303         "Ensoniq AudioPCI",
  304         "",
  305         "eap"
  306 };
  307 
  308 int
  309 eap_match(struct device *parent, struct cfdata *match, void *aux)
  310 {
  311         struct pci_attach_args *pa = (struct pci_attach_args *) aux;
  312 
  313         switch (PCI_VENDOR(pa->pa_id)) {
  314         case PCI_VENDOR_CREATIVELABS:
  315                 switch (PCI_PRODUCT(pa->pa_id)) {
  316                 case PCI_PRODUCT_CREATIVELABS_EV1938:
  317                         return (1);
  318                 }
  319                 break;
  320         case PCI_VENDOR_ENSONIQ:
  321                 switch (PCI_PRODUCT(pa->pa_id)) {
  322                 case PCI_PRODUCT_ENSONIQ_AUDIOPCI:
  323                 case PCI_PRODUCT_ENSONIQ_AUDIOPCI97:
  324                 case PCI_PRODUCT_ENSONIQ_CT5880:
  325                         return (1);
  326                 }
  327                 break;
  328         }
  329 
  330         return (0);
  331 }
  332 
  333 void
  334 eap1370_write_codec(struct eap_softc *sc, int a, int d)
  335 {
  336         int icss, to;
  337 
  338         to = EAP_WRITE_TIMEOUT;
  339         do {
  340                 icss = EREAD4(sc, EAP_ICSS);
  341                 DPRINTFN(5,("eap: codec %d prog: icss=0x%08x\n", a, icss));
  342                 if (!to--) {
  343                         printf("eap: timeout writing to codec\n");
  344                         return;
  345                 }
  346         } while(icss & EAP_CWRIP);  /* XXX could use CSTAT here */
  347         EWRITE4(sc, EAP_CODEC, EAP_SET_CODEC(a, d));
  348 }
  349 
  350 /*
  351  * Reading and writing the CODEC is very convoluted.  This mimics the
  352  * FreeBSD and Linux drivers.
  353  */
  354 
  355 static __inline void
  356 eap1371_ready_codec(struct eap_softc *sc, u_int8_t a, u_int32_t wd)
  357 {
  358         int to, s;
  359         u_int32_t src, t;
  360 
  361         for (to = 0; to < EAP_WRITE_TIMEOUT; to++) {
  362                 if (!(EREAD4(sc, E1371_CODEC) & E1371_CODEC_WIP))
  363                         break;
  364                 delay(1);
  365         }
  366         if (to >= EAP_WRITE_TIMEOUT)
  367                 printf("%s: eap1371_ready_codec timeout 1\n", 
  368                        sc->sc_dev.dv_xname);
  369 
  370         s = splaudio();
  371         src = eap1371_src_wait(sc) & E1371_SRC_CTLMASK;
  372         EWRITE4(sc, E1371_SRC, src | E1371_SRC_STATE_OK);
  373 
  374         for (to = 0; to < EAP_READ_TIMEOUT; to++) {
  375                 t = EREAD4(sc, E1371_SRC);
  376                 if ((t & E1371_SRC_STATE_MASK) == 0)
  377                         break;
  378                 delay(1);
  379         }
  380         if (to >= EAP_READ_TIMEOUT)
  381                 printf("%s: eap1371_ready_codec timeout 2\n", 
  382                        sc->sc_dev.dv_xname);
  383 
  384         for (to = 0; to < EAP_READ_TIMEOUT; to++) {
  385                 t = EREAD4(sc, E1371_SRC);
  386                 if ((t & E1371_SRC_STATE_MASK) == E1371_SRC_STATE_OK)
  387                         break;
  388                 delay(1);
  389         }
  390         if (to >= EAP_READ_TIMEOUT)
  391                 printf("%s: eap1371_ready_codec timeout 3\n", 
  392                        sc->sc_dev.dv_xname);
  393 
  394         EWRITE4(sc, E1371_CODEC, wd);
  395 
  396         eap1371_src_wait(sc);
  397         EWRITE4(sc, E1371_SRC, src);
  398 
  399         splx(s);
  400 }
  401 
  402 int
  403 eap1371_read_codec(void *sc_, u_int8_t a, u_int16_t *d)
  404 {
  405         struct eap_softc *sc = sc_;
  406         int to;
  407         u_int32_t t;
  408 
  409         eap1371_ready_codec(sc, a, E1371_SET_CODEC(a, 0) | E1371_CODEC_READ);
  410 
  411         for (to = 0; to < EAP_WRITE_TIMEOUT; to++) {
  412                 if (!(EREAD4(sc, E1371_CODEC) & E1371_CODEC_WIP))
  413                         break;
  414         }
  415         if (to > EAP_WRITE_TIMEOUT)
  416                 printf("%s: eap1371_read_codec timeout 1\n", 
  417                        sc->sc_dev.dv_xname);
  418 
  419         for (to = 0; to < EAP_WRITE_TIMEOUT; to++) {
  420                 t = EREAD4(sc, E1371_CODEC);
  421                 if (t & E1371_CODEC_VALID)
  422                         break;
  423         }
  424         if (to > EAP_WRITE_TIMEOUT)
  425                 printf("%s: eap1371_read_codec timeout 2\n", 
  426                        sc->sc_dev.dv_xname);
  427 
  428         *d = (u_int16_t)t;
  429 
  430         DPRINTFN(10, ("eap1371: reading codec (%x) = %x\n", a, *d));
  431 
  432         return (0);
  433 }
  434 
  435 int
  436 eap1371_write_codec(void *sc_, u_int8_t a, u_int16_t d)
  437 {
  438         struct eap_softc *sc = sc_;
  439 
  440         eap1371_ready_codec(sc, a, E1371_SET_CODEC(a, d));
  441 
  442         DPRINTFN(10, ("eap1371: writing codec %x --> %x\n", d, a));
  443 
  444         return (0);
  445 }
  446 
  447 u_int32_t
  448 eap1371_src_wait(struct eap_softc *sc)
  449 {
  450         int to;
  451         u_int32_t src;
  452         
  453         for (to = 0; to < EAP_READ_TIMEOUT; to++) {
  454                 src = EREAD4(sc, E1371_SRC);
  455                 if (!(src & E1371_SRC_RBUSY))
  456                         return (src);
  457                 delay(1);
  458         }
  459         printf("%s: eap1371_src_wait timeout\n", sc->sc_dev.dv_xname);
  460         return (src);
  461 }
  462 
  463 int
  464 eap1371_src_read(struct eap_softc *sc, int a)
  465 {
  466         int to;
  467         u_int32_t src, t;
  468 
  469         src = eap1371_src_wait(sc) & E1371_SRC_CTLMASK;
  470         src |= E1371_SRC_ADDR(a);
  471         EWRITE4(sc, E1371_SRC, src | E1371_SRC_STATE_OK);
  472 
  473         t = eap1371_src_wait(sc);
  474         if ((t & E1371_SRC_STATE_MASK) != E1371_SRC_STATE_OK) {
  475                 for (to = 0; to < EAP_READ_TIMEOUT; to++) {
  476                         t = EREAD4(sc, E1371_SRC);
  477                         if ((t & E1371_SRC_STATE_MASK) == E1371_SRC_STATE_OK)
  478                                 break;
  479                         delay(1);
  480                 }
  481         }
  482 
  483         EWRITE4(sc, E1371_SRC, src);
  484 
  485         return t & E1371_SRC_DATAMASK;
  486 }
  487 
  488 void
  489 eap1371_src_write(struct eap_softc *sc, int a, int d)
  490 {
  491         u_int32_t r;
  492 
  493         r = eap1371_src_wait(sc) & E1371_SRC_CTLMASK;
  494         r |= E1371_SRC_RAMWE | E1371_SRC_ADDR(a) | E1371_SRC_DATA(d);
  495         EWRITE4(sc, E1371_SRC, r);
  496 }
  497         
  498 void
  499 eap1371_set_adc_rate(struct eap_softc *sc, int rate)
  500 {
  501         int freq, n, truncm;
  502         int out;
  503         int s;
  504 
  505         /* Whatever, it works, so I'll leave it :) */
  506 
  507         if (rate > 48000)
  508                 rate = 48000;
  509         if (rate < 4000)
  510                 rate = 4000;
  511         n = rate / 3000;
  512         if ((1 << n) & SRC_MAGIC)
  513                 n--;
  514         truncm = ((21 * n) - 1) | 1;
  515         freq = ((48000 << 15) / rate) * n;
  516         if (rate >= 24000) {
  517                 if (truncm > 239)
  518                         truncm = 239;
  519                 out = ESRC_SET_TRUNC((239 - truncm) / 2);
  520         } else {
  521                 if (truncm > 119)
  522                         truncm = 119;
  523                 out = ESRC_SMF | ESRC_SET_TRUNC((119 - truncm) / 2);
  524         }
  525         out |= ESRC_SET_N(n);
  526         s = splaudio();
  527         eap1371_src_write(sc, ESRC_ADC+ESRC_TRUNC_N, out);
  528 
  529       
  530         out = eap1371_src_read(sc, ESRC_ADC+ESRC_IREGS) & 0xff;
  531         eap1371_src_write(sc, ESRC_ADC+ESRC_IREGS, out | 
  532                           ESRC_SET_VFI(freq >> 15));
  533         eap1371_src_write(sc, ESRC_ADC+ESRC_VFF, freq & 0x7fff);
  534         eap1371_src_write(sc, ESRC_ADC_VOLL, ESRC_SET_ADC_VOL(n));
  535         eap1371_src_write(sc, ESRC_ADC_VOLR, ESRC_SET_ADC_VOL(n));
  536         splx(s);
  537 }
  538 
  539 void
  540 eap1371_set_dac_rate(struct eap_instance *ei, int rate)
  541 {
  542         struct eap_softc *sc = (struct eap_softc *)ei->parent;
  543         int dac = ei->index == EAP_DAC1 ? ESRC_DAC1 : ESRC_DAC2;
  544         int freq, r;
  545         int s;
  546  
  547         DPRINTFN(2, ("eap1371_set_dac_date: set rate for %d\n", ei->index));
  548 
  549         /* Whatever, it works, so I'll leave it :) */
  550 
  551         if (rate > 48000)
  552             rate = 48000;
  553         if (rate < 4000)
  554             rate = 4000;
  555         freq = ((rate << 15) + 1500) / 3000;
  556         
  557         s = splaudio();
  558         eap1371_src_wait(sc);
  559         r = EREAD4(sc, E1371_SRC) & (E1371_SRC_DISABLE | 
  560             E1371_SRC_DISP2 | E1371_SRC_DISP1 | E1371_SRC_DISREC);
  561         r |= ei->index == EAP_DAC1 ? E1371_SRC_DISP1 : E1371_SRC_DISP2;
  562         EWRITE4(sc, E1371_SRC, r);
  563         r = eap1371_src_read(sc, dac + ESRC_IREGS) & 0x00ff;
  564         eap1371_src_write(sc, dac + ESRC_IREGS, r | ((freq >> 5) & 0xfc00));
  565         eap1371_src_write(sc, dac + ESRC_VFF, freq & 0x7fff);
  566         r = EREAD4(sc, E1371_SRC) & (E1371_SRC_DISABLE | 
  567             E1371_SRC_DISP2 | E1371_SRC_DISP1 | E1371_SRC_DISREC);
  568         r &= ~(ei->index == EAP_DAC1 ? E1371_SRC_DISP1 : E1371_SRC_DISP2);
  569         EWRITE4(sc, E1371_SRC, r);
  570         splx(s);
  571 }
  572 
  573 void
  574 eap_attach(struct device *parent, struct device *self, void *aux)
  575 {
  576         struct eap_softc *sc = (struct eap_softc *)self;
  577         struct pci_attach_args *pa = (struct pci_attach_args *)aux;
  578         pci_chipset_tag_t pc = pa->pa_pc;
  579         struct audio_hw_if *eap_hw_if;
  580         char const *intrstr;
  581         pci_intr_handle_t ih;
  582         pcireg_t csr;
  583         char devinfo[256];
  584         mixer_ctrl_t ctl;
  585         int i;
  586         int revision, ct5880;
  587         const char *revstr = "";
  588 
  589         aprint_naive(": Audio controller\n");
  590 
  591         /* Stash this away for detach */
  592         sc->sc_pc = pc;
  593 
  594         /* Flag if we're "creative" */
  595         sc->sc_1371 = !(PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ENSONIQ &&
  596                         PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_AUDIOPCI);
  597 
  598         /*
  599          * The vendor and product ID's are quite "interesting". Just
  600          * trust the following and be happy.
  601          */
  602         pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo);
  603         revision = PCI_REVISION(pa->pa_class);
  604         ct5880 = 0;
  605         if (sc->sc_1371) {
  606                 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ENSONIQ &&
  607                     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ENSONIQ_CT5880) {
  608                         ct5880 = 1;
  609                         switch (revision) {
  610                         case EAP_CT5880_C: revstr = "CT5880-C "; break;
  611                         case EAP_CT5880_D: revstr = "CT5880-D "; break;
  612                         case EAP_CT5880_E: revstr = "CT5880-E "; break;
  613                         }
  614                 } else {
  615                         switch (revision) {
  616                         case EAP_EV1938_A: revstr = "EV1938-A "; break;
  617                         case EAP_ES1373_A: revstr = "ES1373-A "; break;
  618                         case EAP_ES1373_B: revstr = "ES1373-B "; break;
  619                         case EAP_CT5880_A: revstr = "CT5880-A "; ct5880=1;break;
  620                         case EAP_ES1373_8: revstr = "ES1373-8" ; ct5880=1;break;
  621                         case EAP_ES1371_B: revstr = "ES1371-B "; break;
  622                         }
  623                 }
  624         }
  625         aprint_normal(": %s %s(rev. 0x%02x)\n", devinfo, revstr, revision);
  626 
  627         /* Map I/O register */
  628         if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
  629               &sc->iot, &sc->ioh, NULL, &sc->iosz)) {
  630                 aprint_error("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
  631                 return;
  632         }
  633 
  634         sc->sc_dmatag = pa->pa_dmat;
  635 
  636         /* Enable the device. */
  637         csr = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
  638         pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
  639                        csr | PCI_COMMAND_MASTER_ENABLE);
  640 
  641         /* Map and establish the interrupt. */
  642         if (pci_intr_map(pa, &ih)) {
  643                 aprint_error("%s: couldn't map interrupt\n",
  644                     sc->sc_dev.dv_xname);
  645                 return;
  646         }
  647         intrstr = pci_intr_string(pc, ih);
  648         sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, eap_intr, sc);
  649         if (sc->sc_ih == NULL) {
  650                 aprint_error("%s: couldn't establish interrupt",
  651                     sc->sc_dev.dv_xname);
  652                 if (intrstr != NULL)
  653                         aprint_normal(" at %s", intrstr);
  654                 aprint_normal("\n");
  655                 return;
  656         }
  657         aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
  658 
  659         sc->sc_ei[EAP_I1].parent = (struct device *)sc;
  660         sc->sc_ei[EAP_I1].index = EAP_DAC2;
  661         sc->sc_ei[EAP_I2].parent = (struct device *)sc;
  662         sc->sc_ei[EAP_I2].index = EAP_DAC1;
  663 
  664         if (!sc->sc_1371) {
  665                 /* Enable interrupts and looping mode. */
  666                 /* enable the parts we need */
  667                 EWRITE4(sc, EAP_SIC, EAP_P2_INTR_EN | EAP_R1_INTR_EN);
  668                 EWRITE4(sc, EAP_ICSC, EAP_CDC_EN); 
  669 
  670                 /* reset codec */       
  671                 /* normal operation */ 
  672                 /* select codec clocks */
  673                 eap1370_write_codec(sc, AK_RESET, AK_PD); 
  674                 eap1370_write_codec(sc, AK_RESET, AK_PD | AK_NRST);
  675                 eap1370_write_codec(sc, AK_CS, 0x0);
  676 
  677                 eap_hw_if = &eap1370_hw_if;
  678 
  679                 /* Enable all relevant mixer switches. */
  680                 ctl.dev = EAP_OUTPUT_SELECT;
  681                 ctl.type = AUDIO_MIXER_SET;
  682                 ctl.un.mask = 1 << EAP_VOICE_VOL | 1 << EAP_FM_VOL | 
  683                         1 << EAP_CD_VOL | 1 << EAP_LINE_VOL | 1 << EAP_AUX_VOL |
  684                         1 << EAP_MIC_VOL;
  685                 eap_hw_if->set_port(&sc->sc_ei[EAP_I1], &ctl);
  686 
  687                 ctl.type = AUDIO_MIXER_VALUE;
  688                 ctl.un.value.num_channels = 1;
  689                 for (ctl.dev = EAP_MASTER_VOL; ctl.dev < EAP_MIC_VOL; 
  690                      ctl.dev++) {
  691                         ctl.un.value.level[AUDIO_MIXER_LEVEL_MONO] = VOL_0DB;
  692                         eap_hw_if->set_port(&sc->sc_ei[EAP_I1], &ctl);
  693                 }
  694                 ctl.un.value.level[AUDIO_MIXER_LEVEL_MONO] = 0;
  695                 eap_hw_if->set_port(&sc->sc_ei[EAP_I1], &ctl);
  696                 ctl.dev = EAP_MIC_PREAMP;
  697                 ctl.type = AUDIO_MIXER_ENUM;
  698                 ctl.un.ord = 0;
  699                 eap_hw_if->set_port(&sc->sc_ei[EAP_I1], &ctl);
  700                 ctl.dev = EAP_RECORD_SOURCE;
  701                 ctl.type = AUDIO_MIXER_SET;
  702                 ctl.un.mask = 1 << EAP_MIC_VOL;
  703                 eap_hw_if->set_port(&sc->sc_ei[EAP_I1], &ctl);
  704         } else {
  705                 /* clean slate */
  706 
  707                 EWRITE4(sc, EAP_SIC, 0);
  708                 EWRITE4(sc, EAP_ICSC, 0);
  709                 EWRITE4(sc, E1371_LEGACY, 0);
  710 
  711                 if (ct5880) {
  712                         EWRITE4(sc, EAP_ICSS, EAP_CT5880_AC97_RESET);
  713                         /* Let codec wake up */
  714                         delay(20000);
  715                 }
  716 
  717                 /* Reset from es1371's perspective */
  718                 EWRITE4(sc, EAP_ICSC, E1371_SYNC_RES);
  719                 delay(20);
  720                 EWRITE4(sc, EAP_ICSC, 0);
  721 
  722                 /*
  723                  * Must properly reprogram sample rate converter,
  724                  * or it locks up.  Set some defaults for the life of the
  725                  * machine, and set up a sb default sample rate.
  726                  */
  727                 EWRITE4(sc, E1371_SRC, E1371_SRC_DISABLE);
  728                 for (i = 0; i < 0x80; i++)
  729                         eap1371_src_write(sc, i, 0);
  730                 eap1371_src_write(sc, ESRC_DAC1+ESRC_TRUNC_N, ESRC_SET_N(16));
  731                 eap1371_src_write(sc, ESRC_DAC2+ESRC_TRUNC_N, ESRC_SET_N(16));
  732                 eap1371_src_write(sc, ESRC_DAC1+ESRC_IREGS, ESRC_SET_VFI(16));
  733                 eap1371_src_write(sc, ESRC_DAC2+ESRC_IREGS, ESRC_SET_VFI(16));
  734                 eap1371_src_write(sc, ESRC_ADC_VOLL, ESRC_SET_ADC_VOL(16));
  735                 eap1371_src_write(sc, ESRC_ADC_VOLR, ESRC_SET_ADC_VOL(16));
  736                 eap1371_src_write(sc, ESRC_DAC1_VOLL, ESRC_SET_DAC_VOLI(1));
  737                 eap1371_src_write(sc, ESRC_DAC1_VOLR, ESRC_SET_DAC_VOLI(1));
  738                 eap1371_src_write(sc, ESRC_DAC2_VOLL, ESRC_SET_DAC_VOLI(1));
  739                 eap1371_src_write(sc, ESRC_DAC2_VOLR, ESRC_SET_DAC_VOLI(1));
  740                 eap1371_set_adc_rate(sc, 22050);
  741                 eap1371_set_dac_rate(&sc->sc_ei[0], 22050);
  742                 eap1371_set_dac_rate(&sc->sc_ei[1], 22050);
  743              
  744                 EWRITE4(sc, E1371_SRC, 0);
  745 
  746                 /* Reset codec */
  747 
  748                 /* Interrupt enable */
  749                 sc->host_if.arg = sc;
  750                 sc->host_if.attach = eap1371_attach_codec;
  751                 sc->host_if.read = eap1371_read_codec;
  752                 sc->host_if.write = eap1371_write_codec;
  753                 sc->host_if.reset = eap1371_reset_codec;
  754                 
  755                 if (ac97_attach(&sc->host_if) == 0) {
  756                         /* Interrupt enable */
  757                         EWRITE4(sc, EAP_SIC, EAP_P2_INTR_EN | EAP_R1_INTR_EN);
  758                 } else
  759                         return;
  760 
  761                 eap_hw_if = &eap1371_hw_if;
  762 
  763                 /* Just enable the DAC and master volumes by default */
  764                 ctl.type = AUDIO_MIXER_ENUM;
  765                 ctl.un.ord = 0;  /* off */
  766                 ctl.dev = eap1371_get_portnum_by_name(sc, AudioCoutputs,
  767                        AudioNmaster, AudioNmute);
  768                 eap1371_mixer_set_port(&sc->sc_ei[EAP_I1], &ctl);
  769                 ctl.dev = eap1371_get_portnum_by_name(sc, AudioCinputs,
  770                        AudioNdac, AudioNmute);
  771                 eap1371_mixer_set_port(&sc->sc_ei[EAP_I1], &ctl);
  772                 ctl.dev = eap1371_get_portnum_by_name(sc, AudioCrecord,
  773                        AudioNvolume, AudioNmute);
  774                 eap1371_mixer_set_port(&sc->sc_ei[EAP_I1], &ctl);
  775                 
  776                 ctl.dev = eap1371_get_portnum_by_name(sc, AudioCrecord,
  777                        AudioNsource, NULL);
  778                 ctl.type = AUDIO_MIXER_ENUM;
  779                 ctl.un.ord = 0;
  780                 eap1371_mixer_set_port(&sc->sc_ei[EAP_I1], &ctl);
  781 
  782         }
  783 
  784         sc->sc_ei[EAP_I1].ei_audiodev =
  785             audio_attach_mi(eap_hw_if, &sc->sc_ei[EAP_I1], &sc->sc_dev);
  786 
  787 #ifdef EAP_USE_BOTH_DACS
  788         aprint_normal("%s: attaching secondary DAC\n", sc->sc_dev.dv_xname);
  789         sc->sc_ei[EAP_I2].ei_audiodev =
  790             audio_attach_mi(eap_hw_if, &sc->sc_ei[EAP_I2], &sc->sc_dev);
  791 #endif
  792 
  793 #if NMIDI > 0
  794         sc->sc_mididev = midi_attach_mi(&eap_midi_hw_if, sc, &sc->sc_dev);
  795 #endif
  796 }
  797 
  798 int
  799 eap_detach(struct device *self, int flags)
  800 {
  801         struct eap_softc *sc = (struct eap_softc *) self;
  802 
  803 #if NMIDI > 0
  804         if (sc->sc_mididev != NULL)
  805                 config_detach(sc->sc_mididev, 0);
  806 #endif
  807 #ifdef EAP_USE_BOTH_DACS
  808         if (sc->sc_ei[EAP_I2].ei_audiodev != NULL)
  809                 config_detach(sc->sc_ei[EAP_I2].ei_audiodev, 0);
  810 #endif
  811         if (sc->sc_ei[EAP_I1].ei_audiodev != NULL)
  812                 config_detach(sc->sc_ei[EAP_I1].ei_audiodev, 0);
  813 
  814         bus_space_unmap(sc->iot, sc->ioh, sc->iosz);
  815         pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
  816 
  817         return (0);
  818 }
  819 
  820 int
  821 eap1371_attach_codec(void *sc_, struct ac97_codec_if *codec_if)
  822 {
  823         struct eap_softc *sc = sc_;
  824         
  825         sc->codec_if = codec_if;
  826         return (0);
  827 }
  828 
  829 int
  830 eap1371_reset_codec(void *sc_)
  831 {
  832         struct eap_softc *sc = sc_;
  833         u_int32_t icsc;
  834         int s;
  835 
  836         s = splaudio();
  837         icsc = EREAD4(sc, EAP_ICSC);
  838         EWRITE4(sc, EAP_ICSC, icsc | E1371_SYNC_RES);
  839         delay(20);
  840         EWRITE4(sc, EAP_ICSC, icsc & ~E1371_SYNC_RES);
  841         delay(1);
  842         splx(s);
  843 
  844         return 0;
  845 }
  846 
  847 int
  848 eap_intr(void *p)
  849 {
  850         struct eap_softc *sc = p;
  851         u_int32_t intr, sic;
  852 
  853         intr = EREAD4(sc, EAP_ICSS);
  854         if (!(intr & EAP_INTR))
  855                 return (0);
  856         sic = EREAD4(sc, EAP_SIC);
  857         DPRINTFN(5, ("eap_intr: ICSS=0x%08x, SIC=0x%08x\n", intr, sic));
  858         if (intr & EAP_I_ADC) {
  859 #if 0
  860                 /*
  861                  * XXX This is a hack!
  862                  * The EAP chip sometimes generates the recording interrupt
  863                  * while it is still transferring the data.  To make sure
  864                  * it has all arrived we busy wait until the count is right.
  865                  * The transfer we are waiting for is 8 longwords.
  866                  */
  867                 int s, nw, n;
  868                 EWRITE4(sc, EAP_MEMPAGE, EAP_ADC_PAGE);
  869                 s = EREAD4(sc, EAP_ADC_CSR);
  870                 nw = ((s & 0xffff) + 1) >> 2; /* # of words in DMA */
  871                 n = 0;
  872                 while (((EREAD4(sc, EAP_ADC_SIZE) >> 16) + 8) % nw == 0) {
  873                         delay(10);
  874                         if (++n > 100) {
  875                                 printf("eapintr: DMA fix timeout");
  876                                 break;
  877                         }
  878                 }
  879                 /* Continue with normal interrupt handling. */
  880 #endif
  881                 EWRITE4(sc, EAP_SIC, sic & ~EAP_R1_INTR_EN);
  882                 EWRITE4(sc, EAP_SIC, sic | EAP_R1_INTR_EN);
  883                 if (sc->sc_rintr)
  884                         sc->sc_rintr(sc->sc_rarg);
  885         }
  886 
  887         if (intr & EAP_I_DAC2) {
  888                 EWRITE4(sc, EAP_SIC, sic & ~EAP_P2_INTR_EN);
  889                 EWRITE4(sc, EAP_SIC, sic | EAP_P2_INTR_EN);
  890                 if (sc->sc_ei[EAP_DAC2].ei_pintr)
  891                         sc->sc_ei[EAP_DAC2].ei_pintr(sc->sc_ei[EAP_DAC2].ei_parg);
  892         }
  893 
  894         if (intr & EAP_I_DAC1) {
  895                 EWRITE4(sc, EAP_SIC, sic & ~EAP_P1_INTR_EN);
  896                 EWRITE4(sc, EAP_SIC, sic | EAP_P1_INTR_EN);
  897                 if (sc->sc_ei[EAP_DAC1].ei_pintr)
  898                         sc->sc_ei[EAP_DAC1].ei_pintr(sc->sc_ei[EAP_DAC1].ei_parg);
  899         }
  900 
  901         if (intr & EAP_I_MCCB)
  902                 panic("eap_intr: unexpected MCCB interrupt");
  903 #if NMIDI > 0
  904         if ((intr & EAP_I_UART) && sc->sc_iintr != NULL) {
  905                 u_int32_t data;
  906 
  907                 if (EREAD1(sc, EAP_UART_STATUS) & EAP_US_RXINT) {
  908                         while (EREAD1(sc, EAP_UART_STATUS) & EAP_US_RXRDY) {
  909                                 data = EREAD1(sc, EAP_UART_DATA);
  910                                 sc->sc_iintr(sc->sc_arg, data);
  911                         }
  912                 }
  913         }
  914 #endif
  915         return (1);
  916 }
  917 
  918 int
  919 eap_allocmem(struct eap_softc *sc, size_t size, size_t align, struct eap_dma *p)
  920 {
  921         int error;
  922 
  923         p->size = size;
  924         error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0,
  925                                  p->segs, sizeof(p->segs)/sizeof(p->segs[0]),
  926                                  &p->nsegs, BUS_DMA_NOWAIT);
  927         if (error)
  928                 return (error);
  929 
  930         error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size, 
  931                                &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
  932         if (error)
  933                 goto free;
  934 
  935         error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size,
  936                                   0, BUS_DMA_NOWAIT, &p->map);
  937         if (error)
  938                 goto unmap;
  939 
  940         error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL, 
  941                                 BUS_DMA_NOWAIT);
  942         if (error)
  943                 goto destroy;
  944         return (0);
  945 
  946 destroy:
  947         bus_dmamap_destroy(sc->sc_dmatag, p->map);
  948 unmap:
  949         bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
  950 free:
  951         bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
  952         return (error);
  953 }
  954 
  955 int
  956 eap_freemem(struct eap_softc *sc, struct eap_dma *p)
  957 {
  958         bus_dmamap_unload(sc->sc_dmatag, p->map);
  959         bus_dmamap_destroy(sc->sc_dmatag, p->map);
  960         bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
  961         bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
  962         return (0);
  963 }
  964 
  965 int
  966 eap_open(void *addr, int flags)
  967 {
  968         struct eap_instance *ei = addr;
  969 
  970         /* there is only one ADC */
  971         if (ei->index == EAP_I2 && flags & AUOPEN_READ)
  972                 return (EOPNOTSUPP);
  973 
  974         return (0);
  975 }
  976 
  977 /*
  978  * Close function is called at splaudio().
  979  */
  980 void
  981 eap_close(void *addr)
  982 {
  983         struct eap_instance *ei = addr;
  984         struct eap_softc *sc = (struct eap_softc *)ei->parent;
  985     
  986         eap_halt_output(ei);
  987         if (ei->index == EAP_I1) {
  988                 eap_halt_input(ei);
  989                 sc->sc_rintr = 0;
  990         }
  991 
  992         ei->ei_pintr = 0;
  993 }
  994 
  995 int
  996 eap_query_encoding(void *addr, struct audio_encoding *fp)
  997 {
  998         switch (fp->index) {
  999         case 0:
 1000                 strcpy(fp->name, AudioEulinear);
 1001                 fp->encoding = AUDIO_ENCODING_ULINEAR;
 1002                 fp->precision = 8;
 1003                 fp->flags = 0;
 1004                 return (0);
 1005         case 1:
 1006                 strcpy(fp->name, AudioEmulaw);
 1007                 fp->encoding = AUDIO_ENCODING_ULAW;
 1008                 fp->precision = 8;
 1009                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1010                 return (0);
 1011         case 2:
 1012                 strcpy(fp->name, AudioEalaw);
 1013                 fp->encoding = AUDIO_ENCODING_ALAW;
 1014                 fp->precision = 8;
 1015                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1016                 return (0);
 1017         case 3:
 1018                 strcpy(fp->name, AudioEslinear);
 1019                 fp->encoding = AUDIO_ENCODING_SLINEAR;
 1020                 fp->precision = 8;
 1021                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1022                 return (0);
 1023         case 4:
 1024                 strcpy(fp->name, AudioEslinear_le);
 1025                 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
 1026                 fp->precision = 16;
 1027                 fp->flags = 0;
 1028                 return (0);
 1029         case 5:
 1030                 strcpy(fp->name, AudioEulinear_le);
 1031                 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
 1032                 fp->precision = 16;
 1033                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1034                 return (0);
 1035         case 6:
 1036                 strcpy(fp->name, AudioEslinear_be);
 1037                 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
 1038                 fp->precision = 16;
 1039                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1040                 return (0);
 1041         case 7:
 1042                 strcpy(fp->name, AudioEulinear_be);
 1043                 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
 1044                 fp->precision = 16;
 1045                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1046                 return (0);
 1047         default:
 1048                 return (EINVAL);
 1049         }
 1050 }
 1051 
 1052 int
 1053 eap_set_params(void *addr, int setmode, int usemode,
 1054                struct audio_params *play, struct audio_params *rec)
 1055 {
 1056         struct eap_instance *ei = addr;
 1057         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1058         struct audio_params *p;
 1059         int mode;
 1060         u_int32_t div;
 1061 
 1062         /*
 1063          * The es1370 only has one clock, so make the sample rates match.
 1064          * This only applies for ADC/DAC2. The FM DAC is handled below.
 1065          */
 1066         if (!sc->sc_1371 && ei->index == EAP_DAC2) {
 1067             if (play->sample_rate != rec->sample_rate &&
 1068                 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
 1069                 if (setmode == AUMODE_PLAY) {
 1070                     rec->sample_rate = play->sample_rate;
 1071                     setmode |= AUMODE_RECORD;
 1072                 } else if (setmode == AUMODE_RECORD) {
 1073                     play->sample_rate = rec->sample_rate;
 1074                     setmode |= AUMODE_PLAY;
 1075                 } else
 1076                     return (EINVAL);
 1077             }
 1078         }
 1079 
 1080         for (mode = AUMODE_RECORD; mode != -1; 
 1081              mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
 1082                 if ((setmode & mode) == 0)
 1083                         continue;
 1084 
 1085                 p = mode == AUMODE_PLAY ? play : rec;
 1086 
 1087                 if (p->sample_rate < 4000 || p->sample_rate > 48000 ||
 1088                     (p->precision != 8 && p->precision != 16) ||
 1089                     (p->channels != 1 && p->channels != 2))
 1090                         return (EINVAL);
 1091 
 1092                 p->factor = 1;
 1093                 p->sw_code = 0;
 1094                 switch (p->encoding) {
 1095                 case AUDIO_ENCODING_SLINEAR_BE:
 1096                         if (p->precision == 16)
 1097                                 p->sw_code = swap_bytes;
 1098                         else
 1099                                 p->sw_code = change_sign8;
 1100                         break;
 1101                 case AUDIO_ENCODING_SLINEAR_LE:
 1102                         if (p->precision != 16)
 1103                                 p->sw_code = change_sign8;
 1104                         break;
 1105                 case AUDIO_ENCODING_ULINEAR_BE:
 1106                         if (p->precision == 16) {
 1107                                 if (mode == AUMODE_PLAY)
 1108                                         p->sw_code = swap_bytes_change_sign16_le;
 1109                                 else
 1110                                         p->sw_code = change_sign16_swap_bytes_le;
 1111                         }
 1112                         break;
 1113                 case AUDIO_ENCODING_ULINEAR_LE:
 1114                         if (p->precision == 16)
 1115                                 p->sw_code = change_sign16_le;
 1116                         break;
 1117                 case AUDIO_ENCODING_ULAW:
 1118                         if (mode == AUMODE_PLAY) {
 1119                                 p->factor = 2;
 1120                                 p->sw_code = mulaw_to_slinear16_le;
 1121                         } else
 1122                                 p->sw_code = ulinear8_to_mulaw;
 1123                         break;
 1124                 case AUDIO_ENCODING_ALAW:
 1125                         if (mode == AUMODE_PLAY) {
 1126                                 p->factor = 2;
 1127                                 p->sw_code = alaw_to_slinear16_le;
 1128                         } else
 1129                                 p->sw_code = ulinear8_to_alaw;
 1130                         break;
 1131                 default:
 1132                         return (EINVAL);
 1133                 }
 1134         }
 1135 
 1136         if (sc->sc_1371) {
 1137                 eap1371_set_dac_rate(ei, play->sample_rate);
 1138                 eap1371_set_adc_rate(sc, rec->sample_rate);
 1139         } else if (ei->index == EAP_DAC2) {
 1140                 /* Set the speed */
 1141                 DPRINTFN(2, ("eap_set_params: old ICSC = 0x%08x\n", 
 1142                              EREAD4(sc, EAP_ICSC)));
 1143                 div = EREAD4(sc, EAP_ICSC) & ~EAP_PCLKBITS;
 1144                 /*
 1145                  * XXX
 1146                  * The -2 isn't documented, but seemed to make the wall 
 1147                  * time match
 1148                  * what I expect.  - mycroft
 1149                  */
 1150                 if (usemode == AUMODE_RECORD)
 1151                         div |= EAP_SET_PCLKDIV(EAP_XTAL_FREQ / 
 1152                                 rec->sample_rate - 2);
 1153                 else
 1154                         div |= EAP_SET_PCLKDIV(EAP_XTAL_FREQ / 
 1155                                 play->sample_rate - 2);
 1156 #if 0
 1157                 div |= EAP_CCB_INTRM;
 1158 #else
 1159                 /*
 1160                  * It is not obvious how to acknowledge MCCB interrupts, so
 1161                  * we had better not enable them.
 1162                  */
 1163 #endif
 1164                 EWRITE4(sc, EAP_ICSC, div);
 1165                 DPRINTFN(2, ("eap_set_params: set ICSC = 0x%08x\n", div));
 1166         } else {
 1167                 /*
 1168                  * The FM DAC has only a few fixed-frequency choises, so
 1169                  * pick out the best candidate.
 1170                  */
 1171                 div = EREAD4(sc, EAP_ICSC);
 1172                 DPRINTFN(2, ("eap_set_params: old ICSC = 0x%08x\n", div));
 1173 
 1174                 div &= ~EAP_WTSRSEL;
 1175                 if (play->sample_rate < 8268)
 1176                         div |= EAP_WTSRSEL_5;
 1177                 else if (play->sample_rate < 16537)
 1178                         div |= EAP_WTSRSEL_11;
 1179                 else if (play->sample_rate < 33075)
 1180                         div |= EAP_WTSRSEL_22;
 1181                 else
 1182                         div |= EAP_WTSRSEL_44;
 1183 
 1184                 EWRITE4(sc, EAP_ICSC, div);
 1185                 DPRINTFN(2, ("eap_set_params: set ICSC = 0x%08x\n", div));
 1186         }
 1187 
 1188         return (0);
 1189 }
 1190 
 1191 int
 1192 eap_round_blocksize(void *addr, int blk)
 1193 {
 1194         return (blk & -32);     /* keep good alignment */
 1195 }
 1196 
 1197 int
 1198 eap_trigger_output(
 1199         void *addr,
 1200         void *start,
 1201         void *end,
 1202         int blksize,
 1203         void (*intr)(void *),
 1204         void *arg,
 1205         struct audio_params *param)
 1206 {
 1207         struct eap_instance *ei = addr;
 1208         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1209         struct eap_dma *p;
 1210         u_int32_t icsc, sic;
 1211         int sampshift;
 1212 
 1213 #ifdef DIAGNOSTIC
 1214         if (ei->ei_prun)
 1215                 panic("eap_trigger_output: already running");
 1216         ei->ei_prun = 1;
 1217 #endif
 1218 
 1219         DPRINTFN(1, ("eap_trigger_output: sc=%p start=%p end=%p "
 1220             "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
 1221         ei->ei_pintr = intr;
 1222         ei->ei_parg = arg;
 1223 
 1224         sic = EREAD4(sc, EAP_SIC);
 1225         sic &= ~(EAP_S_EB(ei->index) | EAP_S_MB(ei->index) | EAP_INC_BITS);
 1226 
 1227         if (ei->index == EAP_DAC2)
 1228                 sic |= EAP_SET_P2_ST_INC(0)
 1229                     | EAP_SET_P2_END_INC(param->precision * param->factor / 8);
 1230 
 1231         sampshift = 0;
 1232         if (param->precision * param->factor == 16) {
 1233                 sic |= EAP_S_EB(ei->index);
 1234                 sampshift++;
 1235         }
 1236         if (param->channels == 2) {
 1237                 sic |= EAP_S_MB(ei->index);
 1238                 sampshift++;
 1239         }
 1240         EWRITE4(sc, EAP_SIC, sic & ~EAP_P_INTR_EN(ei->index));
 1241         EWRITE4(sc, EAP_SIC, sic | EAP_P_INTR_EN(ei->index));
 1242 
 1243         for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
 1244                 ;
 1245         if (!p) {
 1246                 printf("eap_trigger_output: bad addr %p\n", start);
 1247                 return (EINVAL);
 1248         }
 1249 
 1250         if (ei->index == EAP_DAC2) {
 1251                 DPRINTF(("eap_trigger_output: DAC2_ADDR=0x%x, DAC2_SIZE=0x%x\n",
 1252                          (int)DMAADDR(p), 
 1253                          (int)EAP_SET_SIZE(0,
 1254                          (((char *)end - (char *)start) >> 2) - 1)));
 1255                 EWRITE4(sc, EAP_MEMPAGE, EAP_DAC_PAGE);
 1256                 EWRITE4(sc, EAP_DAC2_ADDR, DMAADDR(p));
 1257                 EWRITE4(sc, EAP_DAC2_SIZE, 
 1258                         EAP_SET_SIZE(0, 
 1259                         ((char *)end - (char *)start) >> 2) - 1);
 1260                 EWRITE4(sc, EAP_DAC2_CSR, (blksize >> sampshift) - 1);
 1261         } else if (ei->index == EAP_DAC1) {
 1262                 DPRINTF(("eap_trigger_output: DAC1_ADDR=0x%x, DAC1_SIZE=0x%x\n",
 1263                          (int)DMAADDR(p), 
 1264                          (int)EAP_SET_SIZE(0,
 1265                          (((char *)end - (char *)start) >> 2) - 1)));
 1266                 EWRITE4(sc, EAP_MEMPAGE, EAP_DAC_PAGE);
 1267                 EWRITE4(sc, EAP_DAC1_ADDR, DMAADDR(p));
 1268                 EWRITE4(sc, EAP_DAC1_SIZE, 
 1269                         EAP_SET_SIZE(0, 
 1270                         ((char *)end - (char *)start) >> 2) - 1);
 1271                 EWRITE4(sc, EAP_DAC1_CSR, (blksize >> sampshift) - 1);
 1272         }
 1273 #ifdef DIAGNOSTIC
 1274         else
 1275                 panic("eap_trigger_output: impossible instance %d", ei->index);
 1276 #endif
 1277 
 1278         if (sc->sc_1371)
 1279                 EWRITE4(sc, E1371_SRC, 0);
 1280 
 1281         icsc = EREAD4(sc, EAP_ICSC);
 1282         icsc |= EAP_DAC_EN(ei->index);
 1283         EWRITE4(sc, EAP_ICSC, icsc);
 1284 
 1285         DPRINTFN(1, ("eap_trigger_output: set ICSC = 0x%08x\n", icsc));
 1286 
 1287         return (0);
 1288 }
 1289 
 1290 int
 1291 eap_trigger_input(
 1292         void *addr,
 1293         void *start,
 1294         void *end,
 1295         int blksize,
 1296         void (*intr)(void *),
 1297         void *arg,
 1298         struct audio_params *param)
 1299 {
 1300         struct eap_instance *ei = addr;
 1301         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1302         struct eap_dma *p;
 1303         u_int32_t icsc, sic;
 1304         int sampshift;
 1305 
 1306 #ifdef DIAGNOSTIC
 1307         if (sc->sc_rrun)
 1308                 panic("eap_trigger_input: already running");
 1309         sc->sc_rrun = 1;
 1310 #endif
 1311 
 1312         DPRINTFN(1, ("eap_trigger_input: ei=%p start=%p end=%p blksize=%d intr=%p(%p)\n", 
 1313             addr, start, end, blksize, intr, arg));
 1314         sc->sc_rintr = intr;
 1315         sc->sc_rarg = arg;
 1316 
 1317         sic = EREAD4(sc, EAP_SIC);
 1318         sic &= ~(EAP_R1_S_EB | EAP_R1_S_MB);
 1319         sampshift = 0;
 1320         if (param->precision * param->factor == 16) {
 1321                 sic |= EAP_R1_S_EB;
 1322                 sampshift++;
 1323         }
 1324         if (param->channels == 2) {
 1325                 sic |= EAP_R1_S_MB;
 1326                 sampshift++;
 1327         }
 1328         EWRITE4(sc, EAP_SIC, sic & ~EAP_R1_INTR_EN);
 1329         EWRITE4(sc, EAP_SIC, sic | EAP_R1_INTR_EN);
 1330 
 1331         for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
 1332                 ;
 1333         if (!p) {
 1334                 printf("eap_trigger_input: bad addr %p\n", start);
 1335                 return (EINVAL);
 1336         }
 1337 
 1338         DPRINTF(("eap_trigger_input: ADC_ADDR=0x%x, ADC_SIZE=0x%x\n",
 1339                  (int)DMAADDR(p), 
 1340                  (int)EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1)));
 1341         EWRITE4(sc, EAP_MEMPAGE, EAP_ADC_PAGE);
 1342         EWRITE4(sc, EAP_ADC_ADDR, DMAADDR(p));
 1343         EWRITE4(sc, EAP_ADC_SIZE, 
 1344                 EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1));
 1345 
 1346         EWRITE4(sc, EAP_ADC_CSR, (blksize >> sampshift) - 1);
 1347 
 1348         if (sc->sc_1371)
 1349                 EWRITE4(sc, E1371_SRC, 0);
 1350 
 1351         icsc = EREAD4(sc, EAP_ICSC);
 1352         icsc |= EAP_ADC_EN;
 1353         EWRITE4(sc, EAP_ICSC, icsc);
 1354 
 1355         DPRINTFN(1, ("eap_trigger_input: set ICSC = 0x%08x\n", icsc));
 1356 
 1357         return (0);
 1358 }
 1359 
 1360 int
 1361 eap_halt_output(void *addr)
 1362 {
 1363         struct eap_instance *ei = addr;
 1364         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1365         u_int32_t icsc;
 1366 
 1367         DPRINTF(("eap: eap_halt_output\n"));
 1368         icsc = EREAD4(sc, EAP_ICSC);
 1369         EWRITE4(sc, EAP_ICSC, icsc & ~(EAP_DAC_EN(ei->index)));
 1370 #ifdef DIAGNOSTIC
 1371         ei->ei_prun = 0;
 1372 #endif
 1373 
 1374         return (0);
 1375 }
 1376 
 1377 int
 1378 eap_halt_input(void *addr)
 1379 {
 1380         struct eap_instance *ei = addr;
 1381         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1382         u_int32_t icsc;
 1383     
 1384 #define EAP_USE_FMDAC_ALSO
 1385         DPRINTF(("eap: eap_halt_input\n"));
 1386         icsc = EREAD4(sc, EAP_ICSC);
 1387         EWRITE4(sc, EAP_ICSC, icsc & ~EAP_ADC_EN);
 1388 #ifdef DIAGNOSTIC
 1389         sc->sc_rrun = 0;
 1390 #endif
 1391         return (0);
 1392 }
 1393 
 1394 int
 1395 eap_getdev(void *addr, struct audio_device *retp)
 1396 {
 1397         *retp = eap_device;
 1398         return (0);
 1399 }
 1400 
 1401 int
 1402 eap1371_mixer_set_port(void *addr, mixer_ctrl_t *cp)
 1403 {
 1404         struct eap_instance *ei = addr;
 1405         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1406 
 1407         return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp));
 1408 }
 1409 
 1410 int
 1411 eap1371_mixer_get_port(void *addr, mixer_ctrl_t *cp)
 1412 {
 1413         struct eap_instance *ei = addr;
 1414         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1415 
 1416         return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp));
 1417 }
 1418 
 1419 int
 1420 eap1371_query_devinfo(void *addr, mixer_devinfo_t *dip)
 1421 {
 1422         struct eap_instance *ei = addr;
 1423         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1424 
 1425         return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dip));
 1426 }
 1427 
 1428 int
 1429 eap1371_get_portnum_by_name(struct eap_softc *sc,
 1430                             char *class, char *device, char *qualifier)
 1431 {
 1432         return (sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if, class,
 1433              device, qualifier));
 1434 }
 1435 
 1436 void
 1437 eap1370_set_mixer(struct eap_softc *sc, int a, int d)
 1438 {
 1439         eap1370_write_codec(sc, a, d);
 1440 
 1441         sc->sc_port[a] = d;
 1442         DPRINTFN(1, ("eap1370_mixer_set_port port 0x%02x = 0x%02x\n", a, d));
 1443 }
 1444 
 1445 int
 1446 eap1370_mixer_set_port(void *addr, mixer_ctrl_t *cp)
 1447 {
 1448         struct eap_instance *ei = addr;
 1449         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1450         int lval, rval, l, r, la, ra;
 1451         int l1, r1, l2, r2, m, o1, o2;
 1452 
 1453         if (cp->dev == EAP_RECORD_SOURCE) {
 1454                 if (cp->type != AUDIO_MIXER_SET)
 1455                         return (EINVAL);
 1456                 m = sc->sc_record_source = cp->un.mask;
 1457                 l1 = l2 = r1 = r2 = 0;
 1458                 if (m & (1 << EAP_VOICE_VOL)) 
 1459                         l2 |= AK_M_VOICE, r2 |= AK_M_VOICE;
 1460                 if (m & (1 << EAP_FM_VOL)) 
 1461                         l1 |= AK_M_FM_L, r1 |= AK_M_FM_R;
 1462                 if (m & (1 << EAP_CD_VOL)) 
 1463                         l1 |= AK_M_CD_L, r1 |= AK_M_CD_R;
 1464                 if (m & (1 << EAP_LINE_VOL)) 
 1465                         l1 |= AK_M_LINE_L, r1 |= AK_M_LINE_R;
 1466                 if (m & (1 << EAP_AUX_VOL)) 
 1467                         l2 |= AK_M2_AUX_L, r2 |= AK_M2_AUX_R;
 1468                 if (m & (1 << EAP_MIC_VOL)) 
 1469                         l2 |= AK_M_TMIC, r2 |= AK_M_TMIC;
 1470                 eap1370_set_mixer(sc, AK_IN_MIXER1_L, l1);              
 1471                 eap1370_set_mixer(sc, AK_IN_MIXER1_R, r1);
 1472                 eap1370_set_mixer(sc, AK_IN_MIXER2_L, l2);
 1473                 eap1370_set_mixer(sc, AK_IN_MIXER2_R, r2);
 1474                 return (0);
 1475         }
 1476         if (cp->dev == EAP_OUTPUT_SELECT) {
 1477                 if (cp->type != AUDIO_MIXER_SET)
 1478                         return (EINVAL);
 1479                 m = sc->sc_output_source = cp->un.mask;
 1480                 o1 = o2 = 0;
 1481                 if (m & (1 << EAP_VOICE_VOL)) 
 1482                         o2 |= AK_M_VOICE_L | AK_M_VOICE_R;
 1483                 if (m & (1 << EAP_FM_VOL)) 
 1484                         o1 |= AK_M_FM_L | AK_M_FM_R;
 1485                 if (m & (1 << EAP_CD_VOL)) 
 1486                         o1 |= AK_M_CD_L | AK_M_CD_R;
 1487                 if (m & (1 << EAP_LINE_VOL)) 
 1488                         o1 |= AK_M_LINE_L | AK_M_LINE_R;
 1489                 if (m & (1 << EAP_AUX_VOL)) 
 1490                         o2 |= AK_M_AUX_L | AK_M_AUX_R;
 1491                 if (m & (1 << EAP_MIC_VOL)) 
 1492                         o1 |= AK_M_MIC;
 1493                 eap1370_set_mixer(sc, AK_OUT_MIXER1, o1);
 1494                 eap1370_set_mixer(sc, AK_OUT_MIXER2, o2);
 1495                 return (0);
 1496         }
 1497         if (cp->dev == EAP_MIC_PREAMP) {
 1498                 if (cp->type != AUDIO_MIXER_ENUM)
 1499                         return (EINVAL);
 1500                 if (cp->un.ord != 0 && cp->un.ord != 1)
 1501                         return (EINVAL);
 1502                 sc->sc_mic_preamp = cp->un.ord;
 1503                 eap1370_set_mixer(sc, AK_MGAIN, cp->un.ord);
 1504                 return (0);
 1505         }
 1506         if (cp->type != AUDIO_MIXER_VALUE)
 1507                 return (EINVAL);
 1508         if (cp->un.value.num_channels == 1)
 1509                 lval = rval = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
 1510         else if (cp->un.value.num_channels == 2) {
 1511                 lval = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
 1512                 rval = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
 1513         } else
 1514                 return (EINVAL);
 1515         ra = -1;
 1516         switch (cp->dev) {
 1517         case EAP_MASTER_VOL:
 1518                 l = VOL_TO_ATT5(lval);
 1519                 r = VOL_TO_ATT5(rval);
 1520                 la = AK_MASTER_L;
 1521                 ra = AK_MASTER_R;
 1522                 break;
 1523         case EAP_MIC_VOL:
 1524                 if (cp->un.value.num_channels != 1)
 1525                         return (EINVAL);
 1526                 la = AK_MIC;
 1527                 goto lr;
 1528         case EAP_VOICE_VOL:
 1529                 la = AK_VOICE_L;
 1530                 ra = AK_VOICE_R;
 1531                 goto lr;
 1532         case EAP_FM_VOL:
 1533                 la = AK_FM_L;
 1534                 ra = AK_FM_R;
 1535                 goto lr;
 1536         case EAP_CD_VOL:
 1537                 la = AK_CD_L;
 1538                 ra = AK_CD_R;
 1539                 goto lr;
 1540         case EAP_LINE_VOL:
 1541                 la = AK_LINE_L;
 1542                 ra = AK_LINE_R;
 1543                 goto lr;
 1544         case EAP_AUX_VOL:
 1545                 la = AK_AUX_L;
 1546                 ra = AK_AUX_R;
 1547         lr:
 1548                 l = VOL_TO_GAIN5(lval);
 1549                 r = VOL_TO_GAIN5(rval);
 1550                 break;
 1551         default:
 1552                 return (EINVAL);
 1553         }
 1554         eap1370_set_mixer(sc, la, l);
 1555         if (ra >= 0) {
 1556                 eap1370_set_mixer(sc, ra, r);
 1557         }
 1558         return (0);
 1559 }
 1560 
 1561 int
 1562 eap1370_mixer_get_port(void *addr, mixer_ctrl_t *cp)
 1563 {
 1564         struct eap_instance *ei = addr;
 1565         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1566         int la, ra, l, r;
 1567 
 1568         switch (cp->dev) {
 1569         case EAP_RECORD_SOURCE:
 1570                 if (cp->type != AUDIO_MIXER_SET)
 1571                         return (EINVAL);
 1572                 cp->un.mask = sc->sc_record_source;
 1573                 return (0);
 1574         case EAP_OUTPUT_SELECT:
 1575                 if (cp->type != AUDIO_MIXER_SET)
 1576                         return (EINVAL);
 1577                 cp->un.mask = sc->sc_output_source;
 1578                 return (0);
 1579         case EAP_MIC_PREAMP:
 1580                 if (cp->type != AUDIO_MIXER_ENUM)
 1581                         return (EINVAL);
 1582                 cp->un.ord = sc->sc_mic_preamp;
 1583                 return (0);
 1584         case EAP_MASTER_VOL:
 1585                 l = ATT5_TO_VOL(sc->sc_port[AK_MASTER_L]);
 1586                 r = ATT5_TO_VOL(sc->sc_port[AK_MASTER_R]);
 1587                 break;
 1588         case EAP_MIC_VOL:
 1589                 if (cp->un.value.num_channels != 1)
 1590                         return (EINVAL);
 1591                 la = ra = AK_MIC;
 1592                 goto lr;
 1593         case EAP_VOICE_VOL:
 1594                 la = AK_VOICE_L;
 1595                 ra = AK_VOICE_R;
 1596                 goto lr;
 1597         case EAP_FM_VOL:
 1598                 la = AK_FM_L;
 1599                 ra = AK_FM_R;
 1600                 goto lr;
 1601         case EAP_CD_VOL:
 1602                 la = AK_CD_L;
 1603                 ra = AK_CD_R;
 1604                 goto lr;
 1605         case EAP_LINE_VOL:
 1606                 la = AK_LINE_L;
 1607                 ra = AK_LINE_R;
 1608                 goto lr;
 1609         case EAP_AUX_VOL:
 1610                 la = AK_AUX_L;
 1611                 ra = AK_AUX_R;
 1612         lr:
 1613                 l = GAIN5_TO_VOL(sc->sc_port[la]);
 1614                 r = GAIN5_TO_VOL(sc->sc_port[ra]);
 1615                 break;
 1616         default:
 1617                 return (EINVAL);
 1618         }
 1619         if (cp->un.value.num_channels == 1)
 1620                 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = (l+r) / 2;
 1621         else if (cp->un.value.num_channels == 2) {
 1622                 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]  = l;
 1623                 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r;
 1624         } else
 1625                 return (EINVAL);
 1626         return (0);
 1627 }
 1628 
 1629 int
 1630 eap1370_query_devinfo(void *addr, mixer_devinfo_t *dip)
 1631 {
 1632 
 1633         switch (dip->index) {
 1634         case EAP_MASTER_VOL:
 1635                 dip->type = AUDIO_MIXER_VALUE;
 1636                 dip->mixer_class = EAP_OUTPUT_CLASS;
 1637                 dip->prev = dip->next = AUDIO_MIXER_LAST;
 1638                 strcpy(dip->label.name, AudioNmaster);
 1639                 dip->un.v.num_channels = 2;
 1640                 strcpy(dip->un.v.units.name, AudioNvolume);
 1641                 return (0);
 1642         case EAP_VOICE_VOL:
 1643                 dip->type = AUDIO_MIXER_VALUE;
 1644                 dip->mixer_class = EAP_INPUT_CLASS;
 1645                 dip->prev = AUDIO_MIXER_LAST;
 1646                 dip->next = AUDIO_MIXER_LAST;
 1647                 strcpy(dip->label.name, AudioNdac);
 1648                 dip->un.v.num_channels = 2;
 1649                 strcpy(dip->un.v.units.name, AudioNvolume);
 1650                 return (0);
 1651         case EAP_FM_VOL:
 1652                 dip->type = AUDIO_MIXER_VALUE;
 1653                 dip->mixer_class = EAP_INPUT_CLASS;
 1654                 dip->prev = AUDIO_MIXER_LAST;
 1655                 dip->next = AUDIO_MIXER_LAST;
 1656                 strcpy(dip->label.name, AudioNfmsynth);
 1657                 dip->un.v.num_channels = 2;
 1658                 strcpy(dip->un.v.units.name, AudioNvolume);
 1659                 return (0);
 1660         case EAP_CD_VOL:
 1661                 dip->type = AUDIO_MIXER_VALUE;
 1662                 dip->mixer_class = EAP_INPUT_CLASS;
 1663                 dip->prev = AUDIO_MIXER_LAST;
 1664                 dip->next = AUDIO_MIXER_LAST;
 1665                 strcpy(dip->label.name, AudioNcd);
 1666                 dip->un.v.num_channels = 2;
 1667                 strcpy(dip->un.v.units.name, AudioNvolume);
 1668                 return (0);
 1669         case EAP_LINE_VOL:
 1670                 dip->type = AUDIO_MIXER_VALUE;
 1671                 dip->mixer_class = EAP_INPUT_CLASS;
 1672                 dip->prev = AUDIO_MIXER_LAST;
 1673                 dip->next = AUDIO_MIXER_LAST;
 1674                 strcpy(dip->label.name, AudioNline);
 1675                 dip->un.v.num_channels = 2;
 1676                 strcpy(dip->un.v.units.name, AudioNvolume);
 1677                 return (0);
 1678         case EAP_AUX_VOL:
 1679                 dip->type = AUDIO_MIXER_VALUE;
 1680                 dip->mixer_class = EAP_INPUT_CLASS;
 1681                 dip->prev = AUDIO_MIXER_LAST;
 1682                 dip->next = AUDIO_MIXER_LAST;
 1683                 strcpy(dip->label.name, AudioNaux);
 1684                 dip->un.v.num_channels = 2;
 1685                 strcpy(dip->un.v.units.name, AudioNvolume);
 1686                 return (0);
 1687         case EAP_MIC_VOL:
 1688                 dip->type = AUDIO_MIXER_VALUE;
 1689                 dip->mixer_class = EAP_INPUT_CLASS;
 1690                 dip->prev = AUDIO_MIXER_LAST;
 1691                 dip->next = EAP_MIC_PREAMP;
 1692                 strcpy(dip->label.name, AudioNmicrophone);
 1693                 dip->un.v.num_channels = 1;
 1694                 strcpy(dip->un.v.units.name, AudioNvolume);
 1695                 return (0);
 1696         case EAP_RECORD_SOURCE:
 1697                 dip->mixer_class = EAP_RECORD_CLASS;
 1698                 dip->prev = dip->next = AUDIO_MIXER_LAST;
 1699                 strcpy(dip->label.name, AudioNsource);
 1700                 dip->type = AUDIO_MIXER_SET;
 1701                 dip->un.s.num_mem = 6;
 1702                 strcpy(dip->un.s.member[0].label.name, AudioNmicrophone);
 1703                 dip->un.s.member[0].mask = 1 << EAP_MIC_VOL;
 1704                 strcpy(dip->un.s.member[1].label.name, AudioNcd);
 1705                 dip->un.s.member[1].mask = 1 << EAP_CD_VOL;
 1706                 strcpy(dip->un.s.member[2].label.name, AudioNline);
 1707                 dip->un.s.member[2].mask = 1 << EAP_LINE_VOL;
 1708                 strcpy(dip->un.s.member[3].label.name, AudioNfmsynth);
 1709                 dip->un.s.member[3].mask = 1 << EAP_FM_VOL;
 1710                 strcpy(dip->un.s.member[4].label.name, AudioNaux);
 1711                 dip->un.s.member[4].mask = 1 << EAP_AUX_VOL;
 1712                 strcpy(dip->un.s.member[5].label.name, AudioNdac);
 1713                 dip->un.s.member[5].mask = 1 << EAP_VOICE_VOL;
 1714                 return (0);
 1715         case EAP_OUTPUT_SELECT:
 1716                 dip->mixer_class = EAP_OUTPUT_CLASS;
 1717                 dip->prev = dip->next = AUDIO_MIXER_LAST;
 1718                 strcpy(dip->label.name, AudioNselect);
 1719                 dip->type = AUDIO_MIXER_SET;
 1720                 dip->un.s.num_mem = 6;
 1721                 strcpy(dip->un.s.member[0].label.name, AudioNmicrophone);
 1722                 dip->un.s.member[0].mask = 1 << EAP_MIC_VOL;
 1723                 strcpy(dip->un.s.member[1].label.name, AudioNcd);
 1724                 dip->un.s.member[1].mask = 1 << EAP_CD_VOL;
 1725                 strcpy(dip->un.s.member[2].label.name, AudioNline);
 1726                 dip->un.s.member[2].mask = 1 << EAP_LINE_VOL;
 1727                 strcpy(dip->un.s.member[3].label.name, AudioNfmsynth);
 1728                 dip->un.s.member[3].mask = 1 << EAP_FM_VOL;
 1729                 strcpy(dip->un.s.member[4].label.name, AudioNaux);
 1730                 dip->un.s.member[4].mask = 1 << EAP_AUX_VOL;
 1731                 strcpy(dip->un.s.member[5].label.name, AudioNdac);
 1732                 dip->un.s.member[5].mask = 1 << EAP_VOICE_VOL;
 1733                 return (0);
 1734         case EAP_MIC_PREAMP:
 1735                 dip->type = AUDIO_MIXER_ENUM;
 1736                 dip->mixer_class = EAP_INPUT_CLASS;
 1737                 dip->prev = EAP_MIC_VOL;
 1738                 dip->next = AUDIO_MIXER_LAST;
 1739                 strcpy(dip->label.name, AudioNpreamp);
 1740                 dip->un.e.num_mem = 2;
 1741                 strcpy(dip->un.e.member[0].label.name, AudioNoff);
 1742                 dip->un.e.member[0].ord = 0;
 1743                 strcpy(dip->un.e.member[1].label.name, AudioNon);
 1744                 dip->un.e.member[1].ord = 1;
 1745                 return (0);
 1746         case EAP_OUTPUT_CLASS:
 1747                 dip->type = AUDIO_MIXER_CLASS;
 1748                 dip->mixer_class = EAP_OUTPUT_CLASS;
 1749                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1750                 strcpy(dip->label.name, AudioCoutputs);
 1751                 return (0);
 1752         case EAP_RECORD_CLASS:
 1753                 dip->type = AUDIO_MIXER_CLASS;
 1754                 dip->mixer_class = EAP_RECORD_CLASS;
 1755                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1756                 strcpy(dip->label.name, AudioCrecord);
 1757                 return (0);
 1758         case EAP_INPUT_CLASS:
 1759                 dip->type = AUDIO_MIXER_CLASS;
 1760                 dip->mixer_class = EAP_INPUT_CLASS;
 1761                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1762                 strcpy(dip->label.name, AudioCinputs);
 1763                 return (0);
 1764         }
 1765         return (ENXIO);
 1766 }
 1767 
 1768 void *
 1769 eap_malloc(void *addr, int direction, size_t size,
 1770     struct malloc_type *pool, int flags)
 1771 {
 1772         struct eap_instance *ei = addr;
 1773         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1774         struct eap_dma *p;
 1775         int error;
 1776 
 1777         p = malloc(sizeof(*p), pool, flags);
 1778         if (!p)
 1779                 return (0);
 1780         error = eap_allocmem(sc, size, 16, p);
 1781         if (error) {
 1782                 free(p, pool);
 1783                 return (0);
 1784         }
 1785         p->next = sc->sc_dmas;
 1786         sc->sc_dmas = p;
 1787         return (KERNADDR(p));
 1788 }
 1789 
 1790 void
 1791 eap_free(void *addr, void *ptr, struct malloc_type *pool)
 1792 {
 1793         struct eap_instance *ei = addr;
 1794         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1795         struct eap_dma **pp, *p;
 1796 
 1797         for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) {
 1798                 if (KERNADDR(p) == ptr) {
 1799                         eap_freemem(sc, p);
 1800                         *pp = p->next;
 1801                         free(p, pool);
 1802                         return;
 1803                 }
 1804         }
 1805 }
 1806 
 1807 size_t
 1808 eap_round_buffersize(void *addr, int direction, size_t size)
 1809 {
 1810 
 1811         return (size);
 1812 }
 1813 
 1814 paddr_t
 1815 eap_mappage(void *addr, void *mem, off_t off, int prot)
 1816 {
 1817         struct eap_instance *ei = addr;
 1818         struct eap_softc *sc = (struct eap_softc *)ei->parent;
 1819         struct eap_dma *p;
 1820 
 1821         if (off < 0)
 1822                 return (-1);
 1823         for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next)
 1824                 ;
 1825         if (!p)
 1826                 return (-1);
 1827         return (bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs, 
 1828                                 off, prot, BUS_DMA_WAITOK));
 1829 }
 1830 
 1831 int
 1832 eap_get_props(void *addr)
 1833 {
 1834 
 1835         return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | 
 1836                 AUDIO_PROP_FULLDUPLEX);
 1837 }
 1838 
 1839 #if NMIDI > 0
 1840 int
 1841 eap_midi_open(void *addr, int flags,
 1842               void (*iintr)(void *, int),
 1843               void (*ointr)(void *),
 1844               void *arg)
 1845 {
 1846         struct eap_softc *sc = addr;
 1847         u_int32_t uctrl;
 1848 
 1849         sc->sc_iintr = iintr;
 1850         sc->sc_ointr = ointr;
 1851         sc->sc_arg = arg;
 1852 
 1853         EWRITE4(sc, EAP_ICSC, EREAD4(sc, EAP_ICSC) | EAP_UART_EN);
 1854         uctrl = 0;
 1855         if (flags & FREAD)
 1856                 uctrl |= EAP_UC_RXINTEN;
 1857 #if 0
 1858         /* I don't understand ../midi.c well enough to use output interrupts */
 1859         if (flags & FWRITE)
 1860                 uctrl |= EAP_UC_TXINTEN; */
 1861 #endif
 1862         EWRITE1(sc, EAP_UART_CONTROL, uctrl);
 1863 
 1864         return (0);
 1865 }
 1866 
 1867 void
 1868 eap_midi_close(void *addr)
 1869 {
 1870         struct eap_softc *sc = addr;
 1871 
 1872         tsleep(sc, PWAIT, "eapclm", hz/10); /* give uart a chance to drain */
 1873         EWRITE1(sc, EAP_UART_CONTROL, 0);
 1874         EWRITE4(sc, EAP_ICSC, EREAD4(sc, EAP_ICSC) & ~EAP_UART_EN);
 1875 
 1876         sc->sc_iintr = 0;
 1877         sc->sc_ointr = 0;
 1878 }
 1879 
 1880 int
 1881 eap_midi_output(void *addr, int d)
 1882 {
 1883         struct eap_softc *sc = addr;
 1884         int x;
 1885 
 1886         for (x = 0; x != MIDI_BUSY_WAIT; x++) {
 1887                 if (EREAD1(sc, EAP_UART_STATUS) & EAP_US_TXRDY) {
 1888                         EWRITE1(sc, EAP_UART_DATA, d);
 1889                         return (0);
 1890                 }
 1891                 delay(MIDI_BUSY_DELAY);
 1892         }
 1893         return (EIO);
 1894 }
 1895 
 1896 void
 1897 eap_midi_getinfo(void *addr, struct midi_info *mi)
 1898 {
 1899         mi->name = "AudioPCI MIDI UART";
 1900         mi->props = MIDI_PROP_CAN_INPUT;
 1901 }
 1902 
 1903 #endif

Cache object: 2cb1ff4d25429325861c47a0e0479478


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.