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/ic/interwave.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: interwave.c,v 1.43 2020/02/29 05:51:11 isaki Exp $     */
    2 
    3 /*
    4  * Copyright (c) 1997, 1999, 2008 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * Author: Kari Mettinen
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   20  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   21  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   28  * POSSIBILITY OF SUCH DAMAGE.
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __KERNEL_RCSID(0, "$NetBSD: interwave.c,v 1.43 2020/02/29 05:51:11 isaki Exp $");
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/errno.h>
   37 #include <sys/ioctl.h>
   38 #include <sys/syslog.h>
   39 #include <sys/device.h>
   40 #include <sys/proc.h>
   41 #include <sys/buf.h>
   42 #include <sys/fcntl.h>
   43 #include <sys/malloc.h>
   44 #include <sys/kernel.h>
   45 #include <sys/cpu.h>
   46 #include <sys/intr.h>
   47 #include <sys/audioio.h>
   48 
   49 #include <machine/pio.h>
   50 
   51 #include <dev/audio/audio_if.h>
   52 
   53 #include <dev/isa/isavar.h>
   54 #include <dev/isa/isadmavar.h>
   55 
   56 #include <dev/ic/interwavereg.h>
   57 #include <dev/ic/interwavevar.h>
   58 
   59 
   60 static void iwreset(struct iw_softc *, int);
   61 
   62 static int iw_set_speed(struct iw_softc *, u_long, char);
   63 static u_long iw_set_format(struct iw_softc *, u_long, int);
   64 static void iw_mixer_line_level(struct iw_softc *, int, int, int);
   65 static void iw_trigger_dma(struct iw_softc *, u_char);
   66 static void iw_stop_dma(struct iw_softc *, u_char, u_char);
   67 static void iw_dma_count(struct iw_softc *, u_short, int);
   68 static int iwintr(void *);
   69 static void iw_meminit(struct iw_softc *);
   70 static void iw_mempoke(struct iw_softc *, u_long, u_char);
   71 static u_char iw_mempeek(struct iw_softc *, u_long);
   72 
   73 #ifdef USE_WAVETABLE
   74 static void iw_set_voice_place(struct iw_softc *, u_char, u_long);
   75 static void iw_voice_pan(struct iw_softc *, u_char, u_short, u_short);
   76 static void iw_voice_freq(struct iw_softc *, u_char, u_long);
   77 static void iw_set_loopmode(struct iw_softc *, u_char, u_char, u_char);
   78 static void iw_set_voice_pos(struct iw_softc *, u_short, u_long, u_long);
   79 static void iw_start_voice(struct iw_softc *, u_char);
   80 static void iw_play_voice(struct iw_softc *, u_long, u_long, u_short);
   81 static void iw_stop_voice(struct iw_softc *, u_char);
   82 static void iw_move_voice_end(struct iw_softc *, u_short, u_long);
   83 static void iw_initvoices(struct iw_softc *);
   84 #endif
   85 
   86 struct audio_device iw_device = {
   87         "Am78C201",
   88         "0.1",
   89         "guspnp"
   90 };
   91 
   92 /* The HW supports more formats but only SLINEAR_NE/16/2ch is enough. */
   93 static const struct audio_format iw_formats[] = {
   94         {
   95                 .mode           = AUMODE_PLAY | AUMODE_RECORD,
   96                 .encoding       = AUDIO_ENCODING_SLINEAR_NE,
   97                 .validbits      = 16,
   98                 .precision      = 16,
   99                 .channels       = 2,
  100                 .channel_mask   = AUFMT_STEREO,
  101                 .frequency_type = 16,
  102                 .frequency      = {
  103                          5510,  6620,  8000,  9600, 11025,
  104                         16000, 18900, 22050, 27420, 32000,
  105                         33075, 37800, 38400, 44100, 44800, 48000,
  106                 },
  107         },
  108 };
  109 #define IW_NFORMATS __arraycount(iw_formats)
  110 
  111 #ifdef AUDIO_DEBUG
  112 int iw_debug;
  113 #define DPRINTF(p)       if (iw_debug) printf p
  114 #else
  115 #define DPRINTF(p)
  116 #endif
  117 
  118 static int      iw_cc = 1;
  119 #ifdef DIAGNOSTIC
  120 static int      outputs = 0;
  121 static int      iw_ints = 0;
  122 static int      inputs = 0;
  123 static int      iw_inints = 0;
  124 #endif
  125 
  126 int
  127 iwintr(void *arg)
  128 {
  129         struct  iw_softc *sc;
  130         int     val;
  131         u_char  intrs;
  132 
  133         sc = arg;
  134         val = 0;
  135         intrs = 0;
  136 
  137         mutex_spin_enter(&sc->sc_intr_lock);
  138 
  139         IW_READ_DIRECT_1(6, sc->p2xr_h, intrs); /* UISR */
  140 
  141         /* codec ints */
  142 
  143         /*
  144          * The proper order to do this seems to be to read CSR3 to get the
  145          * int cause and fifo over underrrun status, then deal with the ints
  146          * (new DMA set up), and to clear ints by writing the respective bit
  147          * to 0.
  148          */
  149 
  150         /* read what ints happened */
  151 
  152         IW_READ_CODEC_1(CSR3I, intrs);
  153 
  154         /* clear them */
  155 
  156         IW_WRITE_DIRECT_1(2, sc->codec_index_h, 0x00);
  157 
  158         /* and process them */
  159 
  160         if (intrs & 0x20) {
  161 #ifdef DIAGNOSTIC
  162                 iw_inints++;
  163 #endif
  164                 if (sc->sc_recintr != 0)
  165                         sc->sc_recintr(sc->sc_recarg);
  166                 val = 1;
  167         }
  168         if (intrs & 0x10) {
  169 #ifdef DIAGNOSTIC
  170                 iw_ints++;
  171 #endif
  172                 if (sc->sc_playintr != 0)
  173                         sc->sc_playintr(sc->sc_playarg);
  174                 val = 1;
  175         }
  176 
  177         mutex_spin_exit(&sc->sc_intr_lock);
  178 
  179         return val;
  180 }
  181 
  182 void
  183 iwattach(struct iw_softc *sc)
  184 {
  185         int     got_irq;
  186 
  187         DPRINTF(("iwattach sc %p\n", sc));
  188         got_irq = 0;
  189 
  190         sc->cdatap = 1;         /* relative offsets in region */
  191         sc->csr1r = 2;
  192         sc->cxdr = 3;           /* CPDR or CRDR */
  193 
  194         sc->gmxr = 0;           /* sc->p3xr */
  195         sc->gmxdr = 1;          /* GMTDR or GMRDR */
  196         sc->svsr = 2;
  197         sc->igidxr = 3;
  198         sc->i16dp = 4;
  199         sc->i8dp = 5;
  200         sc->lmbdr = 7;
  201 
  202         sc->rec_precision = sc->play_precision = 8;
  203         sc->rec_channels = sc->play_channels = 1;
  204         sc->rec_encoding = sc->play_encoding = AUDIO_ENCODING_ULAW;
  205         sc->sc_irate = 8000;
  206         sc->sc_orate = 8000;
  207 
  208         sc->sc_fullduplex = 1;
  209 
  210         sc->sc_dma_flags = 0;
  211 
  212         mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
  213         mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);
  214 
  215         aprint_naive("\n");
  216         /*
  217          * We can only use a few selected irqs, see if we got one from pnp
  218          * code that suits us.
  219          */
  220 
  221         if (sc->sc_irq > 0) {
  222                 sc->sc_ih = isa_intr_establish(sc->sc_p2xr_ic,
  223                     sc->sc_irq, IST_EDGE, IPL_AUDIO, iwintr, sc);
  224                 got_irq = 1;
  225         }
  226         if (!got_irq) {
  227                 aprint_error("\niwattach: couldn't get a suitable irq\n");
  228                 mutex_destroy(&sc->sc_lock);
  229                 mutex_destroy(&sc->sc_intr_lock);
  230                 return;
  231         }
  232         aprint_normal("\n");
  233         iwreset(sc, 0);
  234         iw_set_format(sc, AUDIO_ENCODING_ULAW, 0);
  235         iw_set_format(sc, AUDIO_ENCODING_ULAW, 1);
  236         aprint_normal("%s: interwave version %s\n",
  237             device_xname(sc->sc_dev), iw_device.version);
  238         audio_attach_mi(sc->iw_hw_if, sc, sc->sc_dev);
  239 }
  240 
  241 int
  242 iwopen(struct iw_softc *sc, int flags)
  243 {
  244 
  245         DPRINTF(("iwopen: sc %p\n", sc));
  246 
  247 #ifdef DIAGNOSTIC
  248         outputs = 0;
  249         iw_ints = 0;
  250         inputs = 0;
  251         iw_inints = 0;
  252 #endif
  253 
  254         iwreset(sc, 1);
  255 
  256         return 0;
  257 }
  258 
  259 void
  260 iwclose(void *addr)
  261 {
  262 
  263         DPRINTF(("iwclose sc %p\n", addr));
  264 #ifdef DIAGNOSTIC
  265         DPRINTF(("iwclose: outputs %d ints %d inputs %d in_ints %d\n",
  266                 outputs, iw_ints, inputs, iw_inints));
  267 #endif
  268 }
  269 
  270 #define RAM_STEP        64*1024
  271 
  272 static void
  273 iw_mempoke(struct iw_softc *sc, u_long addy, u_char val)
  274 {
  275 
  276         IW_WRITE_GENERAL_2(LMALI, (u_short) addy);
  277         IW_WRITE_GENERAL_1(LMAHI, (u_char) (addy >> 16));
  278 
  279         /* Write byte to LMBDR */
  280         IW_WRITE_DIRECT_1(sc->p3xr + 7, sc->p3xr_h, val);
  281 }
  282 
  283 static u_char
  284 iw_mempeek(struct iw_softc *sc, u_long addy)
  285 {
  286         u_char  ret;
  287 
  288         IW_WRITE_GENERAL_2(LMALI, (u_short) addy);
  289         IW_WRITE_GENERAL_1(LMAHI, (u_char) (addy >> 16));
  290 
  291         IW_READ_DIRECT_1(sc->p3xr + 7, sc->p3xr_h, ret);
  292         return ret;             /* return byte from LMBDR */
  293 }
  294 
  295 static void
  296 iw_meminit(struct iw_softc *sc)
  297 {
  298         u_long  bank[4] = {0L, 0L, 0L, 0L};
  299         u_long  addr, base, cnt;
  300         u_char  i, ram /* ,memval=0 */ ;
  301         u_short lmcfi;
  302         u_long  temppi;
  303         u_long  *lpbanks;
  304 
  305         addr = 0L;
  306         base = 0L;
  307         cnt = 0L;
  308         ram = 0;
  309         lpbanks = &temppi;
  310 
  311         IW_WRITE_GENERAL_1(LDMACI, 0x00);
  312 
  313         IW_READ_GENERAL_2(LMCFI, lmcfi);        /* 0x52 */
  314         lmcfi |= 0x0A0C;
  315         IW_WRITE_GENERAL_2(LMCFI, lmcfi);       /* max addr span */
  316         IW_WRITE_GENERAL_1(LMCI, 0x00);
  317 
  318         /* fifo addresses */
  319 
  320         IW_WRITE_GENERAL_2(LMRFAI, ((4 * 1024 * 1024) >> 8));
  321         IW_WRITE_GENERAL_2(LMPFAI, ((4 * 1024 * 1024 + 16 * 1024) >> 8));
  322 
  323         IW_WRITE_GENERAL_2(LMFSI, 0x000);
  324 
  325         IW_WRITE_GENERAL_2(LDICI, 0x0000);
  326 
  327         while (addr < (16 * 1024 * 1024)) {
  328                 iw_mempoke(sc, addr, 0x00);
  329                 addr += RAM_STEP;
  330         }
  331 
  332         printf("%s:", device_xname(sc->sc_dev));
  333 
  334         for (i = 0; i < 4; i++) {
  335                 iw_mempoke(sc, base, 0xAA);     /* mark start of bank */
  336                 iw_mempoke(sc, base + 1L, 0x55);
  337                 if (iw_mempeek(sc, base) == 0xAA  &&
  338                     iw_mempeek(sc, base + 1L) == 0x55)
  339                         ram = 1;
  340                 if (ram) {
  341                         while (cnt < (4 * 1024 * 1024)) {
  342                                 bank[i] += RAM_STEP;
  343                                 cnt += RAM_STEP;
  344                                 addr = base + cnt;
  345                                 if (iw_mempeek(sc, addr) == 0xAA)
  346                                         break;
  347                         }
  348                 }
  349                 if (lpbanks != NULL) {
  350                         *lpbanks = bank[i];
  351                         lpbanks++;
  352                 }
  353                 bank[i] = bank[i] >> 10;
  354                 printf("%s bank[%d]: %ldK", i ? "," : "", i, bank[i]);
  355                 base += 4 * 1024 * 1024;
  356                 cnt = 0L;
  357                 ram = 0;
  358         }
  359 
  360         printf("\n");
  361 
  362         /*
  363          * this is not really useful since GUS PnP supports memory
  364          * configurations that aren't really supported by Interwave...beware
  365          * of holes! Also, we don't use the memory for anything in this
  366          * version of the driver.
  367          *
  368          * we've configured for 4M-4M-4M-4M
  369          */
  370 }
  371 
  372 static void
  373 iwreset(struct iw_softc *sc, int warm)
  374 {
  375         u_char  reg, cmode, val, mixer_image;
  376 
  377         val = 0;
  378         mixer_image = 0;
  379         reg = 0;                /* XXX gcc -Wall */
  380 
  381         cmode = 0x6c;           /* enhanced codec mode (full duplex) */
  382 
  383         /* reset */
  384 
  385         IW_WRITE_GENERAL_1(URSTI, 0x00);
  386         delay(10);
  387         IW_WRITE_GENERAL_1(URSTI, 0x07);
  388         IW_WRITE_GENERAL_1(ICMPTI, 0x1f);       /* disable DSP and uici and
  389                                                  * udci writes */
  390         IW_WRITE_GENERAL_1(IDECI, 0x7f);        /* enable ints to ISA and
  391                                                  * codec access */
  392         IW_READ_GENERAL_1(IVERI, reg);
  393         IW_WRITE_GENERAL_1(IVERI, reg | 0x01);  /* hidden reg lock disable */
  394         IW_WRITE_GENERAL_1(UASBCI, 0x00);
  395 
  396         /* synth enhanced mode (default), 0 active voices, disable ints */
  397 
  398         IW_WRITE_GENERAL_1(SGMI_WR, 0x01);      /* enhanced mode, LFOs
  399                                                  * disabled */
  400         for (val = 0; val < 32; val++) {
  401                 /* set each synth sound volume to 0 */
  402                 IW_WRITE_DIRECT_1(sc->p3xr + 2, sc->p3xr_h, val);
  403                 IW_WRITE_GENERAL_1(SVSI_WR, 0x00);
  404                 IW_WRITE_GENERAL_2(SASLI_WR, 0x0000);
  405                 IW_WRITE_GENERAL_2(SASHI_WR, 0x0000);
  406                 IW_WRITE_GENERAL_2(SAELI_WR, 0x0000);
  407                 IW_WRITE_GENERAL_2(SAEHI_WR, 0x0000);
  408                 IW_WRITE_GENERAL_2(SFCI_WR, 0x0000);
  409                 IW_WRITE_GENERAL_1(SACI_WR, 0x02);
  410                 IW_WRITE_GENERAL_1(SVSI_WR, 0x00);
  411                 IW_WRITE_GENERAL_1(SVEI_WR, 0x00);
  412                 IW_WRITE_GENERAL_2(SVLI_WR, 0x0000);
  413                 IW_WRITE_GENERAL_1(SVCI_WR, 0x02);
  414                 IW_WRITE_GENERAL_1(SMSI_WR, 0x02);
  415         }
  416 
  417         IW_WRITE_GENERAL_1(SAVI_WR, 0x00);
  418 
  419         /* codec mode/init */
  420 
  421         /* first change mode to 1 */
  422 
  423         IW_WRITE_CODEC_1(CMODEI, 0x00);
  424 
  425         /* and mode 3 */
  426 
  427         IW_WRITE_CODEC_1(CMODEI, cmode);
  428 
  429         IW_READ_CODEC_1(CMODEI, reg);
  430 
  431         DPRINTF(("cmode %x\n", reg));
  432 
  433         sc->revision = ((reg & 0x80) >> 3) | (reg & 0x0f);
  434 
  435         IW_WRITE_DIRECT_1(sc->codec_index + 2, sc->p2xr_h, 0x00);
  436 
  437         IW_WRITE_CODEC_1(CFIG1I | IW_MCE, 0x00);        /* DMA 2 chan access */
  438         IW_WRITE_CODEC_1(CEXTI, 0x00);  /* disable ints for now */
  439 
  440 
  441         IW_WRITE_CODEC_1(CLPCTI, 0x00); /* reset playback sample counters */
  442         IW_WRITE_CODEC_1(CUPCTI, 0x00); /* always upper byte last */
  443         IW_WRITE_CODEC_1(CFIG2I, 0x80); /* full voltage range, enable record
  444                                          * and playback sample counters, and
  445                                          * don't center output in case or
  446                                          * FIFO underrun */
  447         IW_WRITE_CODEC_1(CFIG3I, 0xc0); /* enable record/playback irq (still
  448                                          * turned off from CEXTI), max DMA
  449                                          * rate */
  450         IW_WRITE_CODEC_1(CSR3I, 0x00);  /* clear status 3 reg */
  451 
  452 
  453         IW_WRITE_CODEC_1(CLRCTI, 0x00); /* reset record sample counters */
  454         IW_WRITE_CODEC_1(CURCTI, 0x00); /* always upper byte last */
  455 
  456 
  457         IW_READ_GENERAL_1(IVERI, reg);
  458 
  459         sc->vers = reg >> 4;
  460         if (!warm)
  461                 snprintf(iw_device.version, sizeof(iw_device.version), "%d.%d",
  462                     sc->vers, sc->revision);
  463 
  464         IW_WRITE_GENERAL_1(IDECI, 0x7f);        /* irqs and codec decode
  465                                                  * enable */
  466 
  467 
  468         /* ports */
  469 
  470         if (!warm) {
  471                 iw_mixer_line_level(sc, IW_LINE_OUT, 255, 255);
  472                 iw_mixer_line_level(sc, IW_LINE_IN, 0, 0);
  473                 iw_mixer_line_level(sc, IW_AUX1, 0, 0);
  474                 iw_mixer_line_level(sc, IW_AUX2, 200, 200); /* CD */
  475                 sc->sc_dac.off = 0;
  476                 iw_mixer_line_level(sc, IW_DAC, 200, 200);
  477 
  478                 iw_mixer_line_level(sc, IW_MIC_IN, 0, 0);
  479                 iw_mixer_line_level(sc, IW_REC, 0, 0);
  480                 iw_mixer_line_level(sc, IW_LOOPBACK, 0, 0);
  481                 iw_mixer_line_level(sc, IW_MONO_IN, 0, 0);
  482 
  483                 /* mem stuff */
  484                 iw_meminit(sc);
  485 
  486         }
  487         IW_WRITE_CODEC_1(CEXTI, 0x02);  /* codec int enable */
  488 
  489         /* clear _LDMACI */
  490 
  491         IW_WRITE_GENERAL_1(LDMACI, 0x00);
  492 
  493         /* enable mixer paths */
  494         mixer_image = 0x0c;
  495         IW_WRITE_DIRECT_1(sc->p2xr, sc->p2xr_h, mixer_image);
  496         /*
  497          * enable output, line in. disable mic in bit 0 = 0 -> line in on
  498          * (from codec?) bit 1 = 0 -> output on bit 2 = 1 -> mic in on bit 3
  499          * = 1 -> irq&drq pin enable bit 4 = 1 -> channel interrupts to chan
  500          * 1 bit 5 = 1 -> enable midi loop back bit 6 = 0 -> irq latches
  501          * URCR[2:0] bit 6 = 1 -> DMA latches URCR[2:0]
  502          */
  503 
  504 
  505         IW_READ_DIRECT_1(sc->p2xr, sc->p2xr_h, mixer_image);
  506 #ifdef AUDIO_DEBUG
  507         if (!warm)
  508                 DPRINTF(("mix image %x \n", mixer_image));
  509 #endif
  510 }
  511 
  512 struct iw_codec_freq {
  513         u_long  freq;
  514         u_char  bits;
  515 };
  516 
  517 int
  518 iw_set_speed(struct iw_softc *sc, u_long freq, char in)
  519 {
  520         u_char  var, cfig3, reg;
  521 
  522         static struct iw_codec_freq iw_cf[17] = {
  523 #define FREQ_1 24576000
  524 #define FREQ_2 16934400
  525 #define XTAL1 0
  526 #define XTAL2 1
  527                 {5510, 0x00 | XTAL2}, {6620, 0x0E | XTAL2},
  528                 {8000, 0x00 | XTAL1}, {9600, 0x0E | XTAL1},
  529                 {11025, 0x02 | XTAL2}, {16000, 0x02 | XTAL1},
  530                 {18900, 0x04 | XTAL2}, {22050, 0x06 | XTAL2},
  531                 {27420, 0x04 | XTAL1}, {32000, 0x06 | XTAL1},
  532                 {33075, 0x0C | XTAL2}, {37800, 0x08 | XTAL2},
  533                 {38400, 0x0A | XTAL1}, {44100, 0x0A | XTAL2},
  534                 {44800, 0x08 | XTAL1}, {48000, 0x0C | XTAL1},
  535                 {48000, 0x0C | XTAL1}   /* really a dummy for indexing later */
  536 #undef XTAL1
  537 #undef XTAL2
  538         };
  539 
  540         cfig3 = 0;              /* XXX gcc -Wall */
  541 
  542         /*
  543          * if the frequency is between 3493 Hz and 32 kHz we can use a more
  544          * accurate frequency than the ones listed above base on the formula
  545          * FREQ/((16*(48+x))) where FREQ is either FREQ_1 (24576000Hz) or
  546          * FREQ_2 (16934400Hz) and x is the value to be written to either
  547          * CPVFI or CRVFI. To enable this option, bit 2 in CFIG3 needs to be
  548          * set high
  549          *
  550          * NOT IMPLEMENTED!
  551          *
  552          * Note that if you have a 'bad' XTAL_1 (higher than 18.5 MHz), 44.8 kHz
  553          * and 38.4 kHz modes will provide wrong frequencies to output.
  554          */
  555 
  556 
  557         if (freq > 48000)
  558                 freq = 48000;
  559         if (freq < 5510)
  560                 freq = 5510;
  561 
  562         /* reset CFIG3[2] */
  563 
  564         IW_READ_CODEC_1(CFIG3I, cfig3);
  565 
  566         cfig3 |= 0xc0;          /* not full fifo treshhold */
  567 
  568         DPRINTF(("cfig3i = %x -> ", cfig3));
  569 
  570         cfig3 &= ~0x04;
  571         IW_WRITE_CODEC_1(CFIG3I, cfig3);
  572         IW_READ_CODEC_1(CFIG3I, cfig3);
  573 
  574         DPRINTF(("%x\n", cfig3));
  575 
  576         for (var = 0; var < 16; var++)  /* select closest frequency */
  577                 if (freq <= iw_cf[var].freq)
  578                         break;
  579         if (var != 16)
  580                 if (abs(freq - iw_cf[var].freq) > abs(iw_cf[var + 1].freq - freq))
  581                         var++;
  582 
  583         if (in)
  584                 IW_WRITE_CODEC_1(CRDFI | IW_MCE, sc->recfmtbits | iw_cf[var].bits);
  585         else
  586                 IW_WRITE_CODEC_1(CPDFI | IW_MCE, sc->playfmtbits | iw_cf[var].bits);
  587         freq = iw_cf[var].freq;
  588         DPRINTF(("setting %s frequency to %d bits %x \n",
  589                in ? "in" : "out", (int) freq, iw_cf[var].bits));
  590 
  591         IW_READ_CODEC_1(CPDFI, reg);
  592 
  593         DPRINTF((" CPDFI %x ", reg));
  594 
  595         IW_READ_CODEC_1(CRDFI, reg);
  596 
  597         DPRINTF((" CRDFI %x ", reg));
  598         __USE(reg);
  599 
  600         return freq;
  601 }
  602 
  603 int
  604 iw_query_format(void *addr, audio_format_query_t *afp)
  605 {
  606 
  607         return audio_query_format(iw_formats, IW_NFORMATS, afp);
  608 }
  609 
  610 static u_long
  611 iw_set_format(struct iw_softc *sc, u_long precision, int in)
  612 {
  613         u_char  data;
  614         int     encoding, channels;
  615 
  616         encoding = in ? sc->rec_encoding : sc->play_encoding;
  617         channels = in ? sc->rec_channels : sc->play_channels;
  618 
  619         DPRINTF(("iw_set_format\n"));
  620 
  621         switch (encoding) {
  622         case AUDIO_ENCODING_ULAW:
  623                 data = 0x00;
  624                 break;
  625 
  626         case AUDIO_ENCODING_ALAW:
  627                 data = 0x00;
  628                 break;
  629 
  630         case AUDIO_ENCODING_SLINEAR_LE:
  631                 if (precision == 16)
  632                         data = 0x40;    /* little endian. 0xc0 is big endian */
  633                 else
  634                         data = 0x00;
  635                 break;
  636 
  637         case AUDIO_ENCODING_SLINEAR_BE:
  638                 if (precision == 16)
  639                         data = 0xc0;
  640                 else
  641                         data = 0x00;
  642                 break;
  643 
  644         case AUDIO_ENCODING_ADPCM:
  645                 data = 0xa0;
  646                 break;
  647 
  648         default:
  649                 return -1;
  650         }
  651 
  652         if (channels == 2)
  653                 data |= 0x10;   /* stereo */
  654 
  655         if (in) {
  656                 /* in */
  657                 sc->recfmtbits = data;
  658                 /* This will zero the normal codec frequency,
  659                  * iw_set_speed should always be called afterwards.
  660                  */
  661                 IW_WRITE_CODEC_1(CRDFI | IW_MCE, data);
  662         } else {
  663                 /* out */
  664                 sc->playfmtbits = data;
  665                 IW_WRITE_CODEC_1(CPDFI | IW_MCE, data);
  666         }
  667 
  668         DPRINTF(("formatbits %s %x", in ? "in" : "out", data));
  669 
  670         return encoding;
  671 }
  672 
  673 int
  674 iw_audio_set_format(void *addr, int setmode,
  675         const audio_params_t *p, const audio_params_t *q,
  676         audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
  677 {
  678         struct iw_softc *sc;
  679 
  680         DPRINTF(("%s: code %u, prec %u, rate %u, chan %u\n", __func__,
  681             p->encoding, p->precision, p->sample_rate, p->channels));
  682         sc = addr;
  683 
  684         if (setmode & AUMODE_PLAY) {
  685                 sc->play_channels = p->channels;
  686                 sc->play_encoding = p->encoding;
  687                 sc->play_precision = p->precision;
  688                 iw_set_format(sc, p->precision, 0);
  689                 sc->sc_orate = iw_set_speed(sc, p->sample_rate, 0);
  690         } else {
  691                 sc->rec_channels = q->channels;
  692                 sc->rec_encoding = q->encoding;
  693                 sc->rec_precision = q->precision;
  694                 /* XXX Is this 'p' a typo of 'q' ? */
  695                 iw_set_format(sc, p->precision, 1);
  696                 sc->sc_irate = iw_set_speed(sc, q->sample_rate, 1);
  697         }
  698         return 0;
  699 }
  700 
  701 void
  702 iw_mixer_line_level(struct iw_softc *sc, int line, int levl, int levr)
  703 {
  704         u_char  gainl, gainr, attenl, attenr;
  705 
  706         switch (line) {
  707         case IW_REC:
  708                 gainl = sc->sc_recsrcbits | (levl >> 4);
  709                 gainr = sc->sc_recsrcbits | (levr >> 4);
  710                 DPRINTF(("recording with %x", gainl));
  711                 IW_WRITE_CODEC_1(CLICI, gainl);
  712                 IW_WRITE_CODEC_1(CRICI, gainr);
  713                 sc->sc_rec.voll = levl & 0xf0;
  714                 sc->sc_rec.volr = levr & 0xf0;
  715                 break;
  716 
  717         case IW_AUX1:
  718 
  719                 gainl = (255 - levl) >> 3;
  720                 gainr = (255 - levr) >> 3;
  721 
  722                 /* mute if 0 level */
  723                 if (levl == 0)
  724                         gainl |= 0x80;
  725                 if (levr == 0)
  726                         gainr |= 0x80;
  727 
  728                 IW_WRITE_CODEC_1(IW_LEFT_AUX1_PORT, gainl);
  729                 IW_WRITE_CODEC_1(IW_RIGHT_AUX1_PORT, gainr);
  730                 sc->sc_aux1.voll = levl & 0xf8;
  731                 sc->sc_aux1.volr = levr & 0xf8;
  732 
  733                 break;
  734 
  735         case IW_AUX2:
  736 
  737                 gainl = (255 - levl) >> 3;
  738                 gainr = (255 - levr) >> 3;
  739 
  740                 /* mute if 0 level */
  741                 if (levl == 0)
  742                         gainl |= 0x80;
  743                 if (levr == 0)
  744                         gainr |= 0x80;
  745 
  746                 IW_WRITE_CODEC_1(IW_LEFT_AUX2_PORT, gainl);
  747                 IW_WRITE_CODEC_1(IW_RIGHT_AUX2_PORT, gainr);
  748                 sc->sc_aux2.voll = levl & 0xf8;
  749                 sc->sc_aux2.volr = levr & 0xf8;
  750                 break;
  751         case IW_DAC:
  752                 attenl = ((255 - levl) >> 2) | ((levl && !sc->sc_dac.off) ? 0 : 0x80);
  753                 attenr = ((255 - levr) >> 2) | ((levr && !sc->sc_dac.off) ? 0 : 0x80);
  754                 IW_WRITE_CODEC_1(CLDACI, attenl);
  755                 IW_WRITE_CODEC_1(CRDACI, attenr);
  756                 sc->sc_dac.voll = levl & 0xfc;
  757                 sc->sc_dac.volr = levr & 0xfc;
  758                 break;
  759         case IW_LOOPBACK:
  760                 attenl = ((255 - levl) & 0xfc) | (levl ? 0x01 : 0);
  761                 IW_WRITE_CODEC_1(CLCI, attenl);
  762                 sc->sc_loopback.voll = levl & 0xfc;
  763                 break;
  764         case IW_LINE_IN:
  765                 gainl = (levl >> 3) | (levl ? 0 : 0x80);
  766                 gainr = (levr >> 3) | (levr ? 0 : 0x80);
  767                 IW_WRITE_CODEC_1(CLLICI, gainl);
  768                 IW_WRITE_CODEC_1(CRLICI, gainr);
  769                 sc->sc_linein.voll = levl & 0xf8;
  770                 sc->sc_linein.volr = levr & 0xf8;
  771                 break;
  772         case IW_MIC_IN:
  773                 gainl = ((255 - levl) >> 3) | (levl ? 0 : 0x80);
  774                 gainr = ((255 - levr) >> 3) | (levr ? 0 : 0x80);
  775                 IW_WRITE_CODEC_1(CLMICI, gainl);
  776                 IW_WRITE_CODEC_1(CRMICI, gainr);
  777                 sc->sc_mic.voll = levl & 0xf8;
  778                 sc->sc_mic.volr = levr & 0xf8;
  779                 break;
  780         case IW_LINE_OUT:
  781                 attenl = ((255 - levl) >> 3) | (levl ? 0 : 0x80);
  782                 attenr = ((255 - levr) >> 3) | (levr ? 0 : 0x80);
  783                 IW_WRITE_CODEC_1(CLOAI, attenl);
  784                 IW_WRITE_CODEC_1(CROAI, attenr);
  785                 sc->sc_lineout.voll = levl & 0xf8;
  786                 sc->sc_lineout.volr = levr & 0xf8;
  787                 break;
  788         case IW_MONO_IN:
  789                 attenl = ((255 - levl) >> 4) | (levl ? 0 : 0xc0);       /* in/out mute */
  790                 IW_WRITE_CODEC_1(CMONOI, attenl);
  791                 sc->sc_monoin.voll = levl & 0xf0;
  792                 break;
  793         }
  794 }
  795 
  796 int
  797 iw_commit_settings(void *addr)
  798 {
  799 
  800         return 0;
  801 }
  802 
  803 void
  804 iw_trigger_dma(struct iw_softc *sc, u_char io)
  805 {
  806         u_char  reg;
  807 
  808         IW_READ_CODEC_1(CSR3I, reg);
  809         IW_WRITE_CODEC_1(CSR3I, reg & ~(io == IW_DMA_PLAYBACK ? 0x10 : 0x20));
  810 
  811         IW_READ_CODEC_1(CFIG1I, reg);
  812 
  813         IW_WRITE_CODEC_1(CFIG1I, reg | io);
  814 
  815         /* let the counter run */
  816         IW_READ_CODEC_1(CFIG2I, reg);
  817         IW_WRITE_CODEC_1(CFIG2I, reg & ~(io << 4));
  818 }
  819 
  820 void
  821 iw_stop_dma(struct iw_softc *sc, u_char io, u_char hard)
  822 {
  823         u_char  reg;
  824 
  825         /* just stop the counter, no need to flush the fifo */
  826         IW_READ_CODEC_1(CFIG2I, reg);
  827         IW_WRITE_CODEC_1(CFIG2I, (reg | (io << 4)));
  828 
  829         if (hard) {
  830                 /* unless we're closing the device */
  831                 IW_READ_CODEC_1(CFIG1I, reg);
  832                 IW_WRITE_CODEC_1(CFIG1I, reg & ~io);
  833         }
  834 }
  835 
  836 void
  837 iw_dma_count(struct iw_softc *sc, u_short count, int io)
  838 {
  839 
  840         if (io == IW_DMA_PLAYBACK) {
  841                 IW_WRITE_CODEC_1(CLPCTI, (u_char) (count & 0x00ff));
  842                 IW_WRITE_CODEC_1(CUPCTI, (u_char) ((count >> 8) & 0x00ff));
  843         } else {
  844                 IW_WRITE_CODEC_1(CLRCTI, (u_char) (count & 0x00ff));
  845                 IW_WRITE_CODEC_1(CURCTI, (u_char) ((count >> 8) & 0x00ff));
  846         }
  847 }
  848 
  849 int
  850 iw_init_output(void *addr, void *sbuf, int cc)
  851 {
  852         struct iw_softc *sc = (struct iw_softc *) addr;
  853 
  854         DPRINTF(("iw_init_output\n"));
  855 
  856         isa_dmastart(sc->sc_ic, sc->sc_playdrq, sbuf,
  857                      cc, NULL, DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT);
  858         return 0;
  859 }
  860 
  861 int
  862 iw_init_input(void *addr, void *sbuf, int cc)
  863 {
  864         struct  iw_softc *sc;
  865 
  866         DPRINTF(("iw_init_input\n"));
  867         sc = (struct iw_softc *) addr;
  868         isa_dmastart(sc->sc_ic, sc->sc_recdrq, sbuf,
  869                      cc, NULL, DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT);
  870         return 0;
  871 }
  872 
  873 
  874 int
  875 iw_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
  876 {
  877         struct  iw_softc *sc;
  878 
  879 #ifdef DIAGNOSTIC
  880         if (!intr) {
  881                 printf("iw_start_output: no callback!\n");
  882                 return 1;
  883         }
  884 #endif
  885         sc = addr;
  886         sc->sc_playintr = intr;
  887         sc->sc_playarg = arg;
  888         sc->sc_dma_flags |= DMAMODE_WRITE;
  889         sc->sc_playdma_bp = p;
  890 
  891         isa_dmastart(sc->sc_ic, sc->sc_playdrq, sc->sc_playdma_bp,
  892             cc, NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
  893 
  894 
  895         if (sc->play_encoding == AUDIO_ENCODING_ADPCM)
  896                 cc >>= 2;
  897         if (sc->play_precision == 16)
  898                 cc >>= 1;
  899 
  900         if (sc->play_channels == 2 && sc->play_encoding != AUDIO_ENCODING_ADPCM)
  901                 cc >>= 1;
  902 
  903         cc -= iw_cc;
  904 
  905         /* iw_dma_access(sc,1); */
  906         if (cc != sc->sc_playdma_cnt) {
  907                 iw_dma_count(sc, (u_short) cc, IW_DMA_PLAYBACK);
  908                 sc->sc_playdma_cnt = cc;
  909 
  910                 iw_trigger_dma(sc, IW_DMA_PLAYBACK);
  911         }
  912 
  913 #ifdef DIAGNOSTIC
  914         if (outputs != iw_ints)
  915                 printf("iw_start_output: out %d, int %d\n", outputs, iw_ints);
  916         outputs++;
  917 #endif
  918 
  919         return 0;
  920 }
  921 
  922 
  923 int
  924 iw_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
  925 {
  926         struct  iw_softc *sc;
  927 
  928 #ifdef DIAGNOSTIC
  929         if (!intr) {
  930                 printf("iw_start_input: no callback!\n");
  931                 return 1;
  932         }
  933 #endif
  934         sc = addr;
  935         sc->sc_recintr = intr;
  936         sc->sc_recarg = arg;
  937         sc->sc_dma_flags |= DMAMODE_READ;
  938         sc->sc_recdma_bp = p;
  939 
  940         isa_dmastart(sc->sc_ic, sc->sc_recdrq, sc->sc_recdma_bp,
  941             cc, NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
  942 
  943 
  944         if (sc->rec_encoding == AUDIO_ENCODING_ADPCM)
  945                 cc >>= 2;
  946         if (sc->rec_precision == 16)
  947                 cc >>= 1;
  948 
  949         if (sc->rec_channels == 2 && sc->rec_encoding != AUDIO_ENCODING_ADPCM)
  950                 cc >>= 1;
  951 
  952         cc -= iw_cc;
  953 
  954         /* iw_dma_access(sc,0); */
  955         if (sc->sc_recdma_cnt != cc) {
  956                 iw_dma_count(sc, (u_short) cc, IW_DMA_RECORD);
  957                 sc->sc_recdma_cnt = cc;
  958                 /* iw_dma_ctrl(sc, IW_DMA_RECORD); */
  959                 iw_trigger_dma(sc, IW_DMA_RECORD);
  960         }
  961 
  962 #ifdef DIAGNOSTIC
  963         if ((inputs != iw_inints))
  964                 printf("iw_start_input: in %d, inints %d\n", inputs, iw_inints);
  965         inputs++;
  966 #endif
  967 
  968         return 0;
  969 }
  970 
  971 
  972 int
  973 iw_halt_output(void *addr)
  974 {
  975         struct  iw_softc *sc;
  976 
  977         sc = addr;
  978         iw_stop_dma(sc, IW_DMA_PLAYBACK, 0);
  979         return 0;
  980 }
  981 
  982 
  983 int
  984 iw_halt_input(void *addr)
  985 {
  986         struct  iw_softc *sc;
  987 
  988         sc = addr;
  989         iw_stop_dma(sc, IW_DMA_RECORD, 0);
  990         return 0;
  991 }
  992 
  993 int
  994 iw_speaker_ctl(void *addr, int newstate)
  995 {
  996         struct iw_softc *sc;
  997         u_char reg;
  998 
  999         sc = addr;
 1000         if (newstate == SPKR_ON) {
 1001                 sc->sc_dac.off = 0;
 1002                 IW_READ_CODEC_1(CLDACI, reg);
 1003                 IW_WRITE_CODEC_1(CLDACI, reg & 0x7f);
 1004                 IW_READ_CODEC_1(CRDACI, reg);
 1005                 IW_WRITE_CODEC_1(CRDACI, reg & 0x7f);
 1006         } else {
 1007                 /* SPKR_OFF */
 1008                 sc->sc_dac.off = 1;
 1009                 IW_READ_CODEC_1(CLDACI, reg);
 1010                 IW_WRITE_CODEC_1(CLDACI, reg | 0x80);
 1011                 IW_READ_CODEC_1(CRDACI, reg);
 1012                 IW_WRITE_CODEC_1(CRDACI, reg | 0x80);
 1013         }
 1014         return 0;
 1015 }
 1016 
 1017 int
 1018 iw_getdev(void *addr, struct audio_device *retp)
 1019 {
 1020 
 1021         *retp = iw_device;
 1022         return 0;
 1023 }
 1024 
 1025 /* Mixer (in/out ports) */
 1026 int
 1027 iw_set_port(void *addr, mixer_ctrl_t *cp)
 1028 {
 1029         struct iw_softc *sc;
 1030         u_char vall, valr;
 1031         int error;
 1032 
 1033         sc = addr;
 1034         vall = 0;
 1035         valr = 0;
 1036         error = EINVAL;
 1037         switch (cp->dev) {
 1038         case IW_MIC_IN_LVL:
 1039                 if (cp->type == AUDIO_MIXER_VALUE) {
 1040                         error = 0;
 1041                         if (cp->un.value.num_channels == 1) {
 1042                                 vall = valr = cp->un.value.level[0];
 1043                         } else {
 1044                                 vall = cp->un.value.level[0];
 1045                                 valr = cp->un.value.level[1];
 1046                         }
 1047                         sc->sc_mic.voll = vall;
 1048                         sc->sc_mic.volr = valr;
 1049                         iw_mixer_line_level(sc, IW_MIC_IN, vall, valr);
 1050                 }
 1051                 break;
 1052         case IW_AUX1_LVL:
 1053                 if (cp->type == AUDIO_MIXER_VALUE) {
 1054                         error = 0;
 1055                         if (cp->un.value.num_channels == 1) {
 1056                                 vall = valr = cp->un.value.level[0];
 1057                         } else {
 1058                                 vall = cp->un.value.level[0];
 1059                                 valr = cp->un.value.level[1];
 1060                         }
 1061                         sc->sc_aux1.voll = vall;
 1062                         sc->sc_aux1.volr = valr;
 1063                         iw_mixer_line_level(sc, IW_AUX1, vall, valr);
 1064                 }
 1065                 break;
 1066         case IW_AUX2_LVL:
 1067                 if (cp->type == AUDIO_MIXER_VALUE) {
 1068                         error = 0;
 1069                         if (cp->un.value.num_channels == 1) {
 1070                                 vall = valr = cp->un.value.level[0];
 1071                         } else {
 1072                                 vall = cp->un.value.level[0];
 1073                                 valr = cp->un.value.level[1];
 1074                         }
 1075                         sc->sc_aux2.voll = vall;
 1076                         sc->sc_aux2.volr = valr;
 1077                         iw_mixer_line_level(sc, IW_AUX2, vall, valr);
 1078                 }
 1079                 break;
 1080         case IW_LINE_IN_LVL:
 1081                 if (cp->type == AUDIO_MIXER_VALUE) {
 1082                         error = 0;
 1083                         if (cp->un.value.num_channels == 1) {
 1084                                 vall = valr = cp->un.value.level[0];
 1085                         } else {
 1086                                 vall = cp->un.value.level[0];
 1087                                 valr = cp->un.value.level[1];
 1088                         }
 1089                         sc->sc_linein.voll = vall;
 1090                         sc->sc_linein.volr = valr;
 1091                         iw_mixer_line_level(sc, IW_LINE_IN, vall, valr);
 1092                 }
 1093                 break;
 1094         case IW_LINE_OUT_LVL:
 1095                 if (cp->type == AUDIO_MIXER_VALUE) {
 1096                         error = 0;
 1097                         if (cp->un.value.num_channels == 1) {
 1098                                 vall = valr = cp->un.value.level[0];
 1099                         } else {
 1100                                 vall = cp->un.value.level[0];
 1101                                 valr = cp->un.value.level[1];
 1102                         }
 1103                         sc->sc_lineout.voll = vall;
 1104                         sc->sc_lineout.volr = valr;
 1105                         iw_mixer_line_level(sc, IW_LINE_OUT, vall, valr);
 1106                 }
 1107                 break;
 1108         case IW_REC_LVL:
 1109                 if (cp->type == AUDIO_MIXER_VALUE) {
 1110                         error = 0;
 1111                         if (cp->un.value.num_channels == 1) {
 1112                                 vall = valr = cp->un.value.level[0];
 1113                         } else {
 1114                                 vall = cp->un.value.level[0];
 1115                                 valr = cp->un.value.level[1];
 1116                         }
 1117                         sc->sc_rec.voll = vall;
 1118                         sc->sc_rec.volr = valr;
 1119                         iw_mixer_line_level(sc, IW_REC, vall, valr);
 1120                 }
 1121                 break;
 1122 
 1123         case IW_DAC_LVL:
 1124                 if (cp->type == AUDIO_MIXER_VALUE) {
 1125                         error = 0;
 1126                         if (cp->un.value.num_channels == 1) {
 1127                                 vall = valr = cp->un.value.level[0];
 1128                         } else {
 1129                                 vall = cp->un.value.level[0];
 1130                                 valr = cp->un.value.level[1];
 1131                         }
 1132                         sc->sc_dac.voll = vall;
 1133                         sc->sc_dac.volr = valr;
 1134                         iw_mixer_line_level(sc, IW_DAC, vall, valr);
 1135                 }
 1136                 break;
 1137 
 1138         case IW_LOOPBACK_LVL:
 1139                 if (cp->type == AUDIO_MIXER_VALUE) {
 1140                         error = 0;
 1141                         if (cp->un.value.num_channels != 1) {
 1142                                 return EINVAL;
 1143                         } else {
 1144                                 valr = vall = cp->un.value.level[0];
 1145                         }
 1146                         sc->sc_loopback.voll = vall;
 1147                         sc->sc_loopback.volr = valr;
 1148                         iw_mixer_line_level(sc, IW_LOOPBACK, vall, valr);
 1149                 }
 1150                 break;
 1151 
 1152         case IW_MONO_IN_LVL:
 1153                 if (cp->type == AUDIO_MIXER_VALUE) {
 1154                         error = 0;
 1155                         if (cp->un.value.num_channels != 1) {
 1156                                 return EINVAL;
 1157                         } else {
 1158                                 valr = vall = cp->un.value.level[0];
 1159                         }
 1160                         sc->sc_monoin.voll = vall;
 1161                         sc->sc_monoin.volr = valr;
 1162                         iw_mixer_line_level(sc, IW_MONO_IN, vall, valr);
 1163                 }
 1164                 break;
 1165         case IW_RECORD_SOURCE:
 1166                 error = 0;
 1167                 sc->sc_recsrcbits = cp->un.ord << 6;
 1168                 DPRINTF(("record source %d bits %x\n", cp->un.ord,
 1169                     sc->sc_recsrcbits));
 1170                 iw_mixer_line_level(sc, IW_REC, sc->sc_rec.voll,
 1171                     sc->sc_rec.volr);
 1172                 break;
 1173         }
 1174 
 1175         return error;
 1176 }
 1177 
 1178 
 1179 int
 1180 iw_get_port(void *addr, mixer_ctrl_t *cp)
 1181 {
 1182         struct iw_softc *sc;
 1183         int error;
 1184 
 1185         sc = addr;
 1186         error = EINVAL;
 1187         switch (cp->dev) {
 1188         case IW_MIC_IN_LVL:
 1189                 if (cp->type == AUDIO_MIXER_VALUE) {
 1190                         cp->un.value.num_channels = 2;
 1191                         cp->un.value.level[0] = sc->sc_mic.voll;
 1192                         cp->un.value.level[1] = sc->sc_mic.volr;
 1193                         error = 0;
 1194                 }
 1195                 break;
 1196         case IW_AUX1_LVL:
 1197                 if (cp->type == AUDIO_MIXER_VALUE) {
 1198                         cp->un.value.num_channels = 2;
 1199                         cp->un.value.level[0] = sc->sc_aux1.voll;
 1200                         cp->un.value.level[1] = sc->sc_aux1.volr;
 1201                         error = 0;
 1202                 }
 1203                 break;
 1204         case IW_AUX2_LVL:
 1205                 if (cp->type == AUDIO_MIXER_VALUE) {
 1206                         cp->un.value.num_channels = 2;
 1207                         cp->un.value.level[0] = sc->sc_aux2.voll;
 1208                         cp->un.value.level[1] = sc->sc_aux2.volr;
 1209                         error = 0;
 1210                 }
 1211                 break;
 1212         case IW_LINE_OUT_LVL:
 1213                 if (cp->type == AUDIO_MIXER_VALUE) {
 1214                         cp->un.value.num_channels = 2;
 1215                         cp->un.value.level[0] = sc->sc_lineout.voll;
 1216                         cp->un.value.level[1] = sc->sc_lineout.volr;
 1217                         error = 0;
 1218                 }
 1219                 break;
 1220         case IW_LINE_IN_LVL:
 1221                 if (cp->type == AUDIO_MIXER_VALUE) {
 1222                         cp->un.value.num_channels = 2;
 1223                         cp->un.value.level[0] = sc->sc_linein.voll;
 1224                         cp->un.value.level[1] = sc->sc_linein.volr;
 1225                         error = 0;
 1226                 }
 1227                 break;
 1228         case IW_REC_LVL:
 1229                 if (cp->type == AUDIO_MIXER_VALUE) {
 1230                         cp->un.value.num_channels = 2;
 1231                         cp->un.value.level[0] = sc->sc_rec.voll;
 1232                         cp->un.value.level[1] = sc->sc_rec.volr;
 1233                         error = 0;
 1234                 }
 1235                 break;
 1236 
 1237         case IW_DAC_LVL:
 1238                 if (cp->type == AUDIO_MIXER_VALUE) {
 1239                         cp->un.value.num_channels = 2;
 1240                         cp->un.value.level[0] = sc->sc_dac.voll;
 1241                         cp->un.value.level[1] = sc->sc_dac.volr;
 1242                         error = 0;
 1243                 }
 1244                 break;
 1245 
 1246         case IW_LOOPBACK_LVL:
 1247                 if (cp->type == AUDIO_MIXER_VALUE) {
 1248                         cp->un.value.num_channels = 1;
 1249                         cp->un.value.level[0] = sc->sc_loopback.voll;
 1250                         error = 0;
 1251                 }
 1252                 break;
 1253 
 1254         case IW_MONO_IN_LVL:
 1255                 if (cp->type == AUDIO_MIXER_VALUE) {
 1256                         cp->un.value.num_channels = 1;
 1257                         cp->un.value.level[0] = sc->sc_monoin.voll;
 1258                         error = 0;
 1259                 }
 1260                 break;
 1261         case IW_RECORD_SOURCE:
 1262                 cp->un.ord = sc->sc_recsrcbits >> 6;
 1263                 error = 0;
 1264                 break;
 1265         }
 1266 
 1267         return error;
 1268 }
 1269 
 1270 
 1271 
 1272 int
 1273 iw_query_devinfo(void *addr, mixer_devinfo_t *dip)
 1274 {
 1275 
 1276         switch (dip->index) {
 1277         case IW_MIC_IN_LVL:     /* Microphone */
 1278                 dip->type = AUDIO_MIXER_VALUE;
 1279                 dip->mixer_class = IW_INPUT_CLASS;
 1280                 dip->prev = AUDIO_MIXER_LAST;
 1281                 dip->next = AUDIO_MIXER_LAST;
 1282                 strcpy(dip->label.name, AudioNmicrophone);
 1283                 dip->un.v.num_channels = 2;
 1284                 strcpy(dip->un.v.units.name, AudioNvolume);
 1285                 break;
 1286         case IW_AUX1_LVL:
 1287                 dip->type = AUDIO_MIXER_VALUE;
 1288                 dip->mixer_class = IW_INPUT_CLASS;
 1289                 dip->prev = AUDIO_MIXER_LAST;
 1290                 dip->next = AUDIO_MIXER_LAST;
 1291                 strcpy(dip->label.name, AudioNline);
 1292                 dip->un.v.num_channels = 2;
 1293                 strcpy(dip->un.v.units.name, AudioNvolume);
 1294                 break;
 1295         case IW_AUX2_LVL:
 1296                 dip->type = AUDIO_MIXER_VALUE;
 1297                 dip->mixer_class = IW_INPUT_CLASS;
 1298                 dip->prev = AUDIO_MIXER_LAST;
 1299                 dip->next = AUDIO_MIXER_LAST;
 1300                 strcpy(dip->label.name, AudioNcd);
 1301                 dip->un.v.num_channels = 2;
 1302                 strcpy(dip->un.v.units.name, AudioNvolume);
 1303                 break;
 1304         case IW_LINE_OUT_LVL:
 1305                 dip->type = AUDIO_MIXER_VALUE;
 1306                 dip->mixer_class = IW_OUTPUT_CLASS;
 1307                 dip->prev = AUDIO_MIXER_LAST;
 1308                 dip->next = AUDIO_MIXER_LAST;
 1309                 strcpy(dip->label.name, AudioNline);
 1310                 dip->un.v.num_channels = 2;
 1311                 strcpy(dip->un.v.units.name, AudioNvolume);
 1312                 break;
 1313         case IW_DAC_LVL:
 1314                 dip->type = AUDIO_MIXER_VALUE;
 1315                 dip->mixer_class = IW_OUTPUT_CLASS;
 1316                 dip->prev = AUDIO_MIXER_LAST;
 1317                 dip->next = AUDIO_MIXER_LAST;
 1318                 strcpy(dip->label.name, AudioNdac);
 1319                 dip->un.v.num_channels = 2;
 1320                 strcpy(dip->un.v.units.name, AudioNvolume);
 1321                 break;
 1322         case IW_LINE_IN_LVL:
 1323                 dip->type = AUDIO_MIXER_VALUE;
 1324                 dip->mixer_class = IW_INPUT_CLASS;
 1325                 dip->prev = AUDIO_MIXER_LAST;
 1326                 dip->next = AUDIO_MIXER_LAST;
 1327                 strcpy(dip->label.name, AudioNinput);
 1328                 dip->un.v.num_channels = 2;
 1329                 strcpy(dip->un.v.units.name, AudioNvolume);
 1330                 break;
 1331         case IW_MONO_IN_LVL:
 1332                 dip->type = AUDIO_MIXER_VALUE;
 1333                 dip->mixer_class = IW_INPUT_CLASS;
 1334                 dip->prev = AUDIO_MIXER_LAST;
 1335                 dip->next = AUDIO_MIXER_LAST;
 1336                 strcpy(dip->label.name, AudioNmono);
 1337                 dip->un.v.num_channels = 1;
 1338                 strcpy(dip->un.v.units.name, AudioNvolume);
 1339                 break;
 1340 
 1341         case IW_REC_LVL:        /* record level */
 1342                 dip->type = AUDIO_MIXER_VALUE;
 1343                 dip->mixer_class = IW_RECORD_CLASS;
 1344                 dip->prev = AUDIO_MIXER_LAST;
 1345                 dip->next = AUDIO_MIXER_LAST;
 1346                 strcpy(dip->label.name, AudioNrecord);
 1347                 dip->un.v.num_channels = 2;
 1348                 strcpy(dip->un.v.units.name, AudioNvolume);
 1349                 break;
 1350 
 1351         case IW_LOOPBACK_LVL:
 1352                 dip->type = AUDIO_MIXER_VALUE;
 1353                 dip->mixer_class = IW_RECORD_CLASS;
 1354                 dip->prev = AUDIO_MIXER_LAST;
 1355                 dip->next = AUDIO_MIXER_LAST;
 1356                 strcpy(dip->label.name, "filter");
 1357                 dip->un.v.num_channels = 1;
 1358                 strcpy(dip->un.v.units.name, AudioNvolume);
 1359                 break;
 1360 
 1361         case IW_RECORD_SOURCE:
 1362                 dip->mixer_class = IW_RECORD_CLASS;
 1363                 dip->type = AUDIO_MIXER_ENUM;
 1364                 dip->prev = AUDIO_MIXER_LAST;
 1365                 dip->next = AUDIO_MIXER_LAST;
 1366                 strcpy(dip->label.name, AudioNsource);
 1367                 dip->un.e.num_mem = 4;
 1368                 strcpy(dip->un.e.member[0].label.name, AudioNline);
 1369                 dip->un.e.member[0].ord = IW_LINE_IN_SRC;
 1370                 strcpy(dip->un.e.member[1].label.name, "aux1");
 1371                 dip->un.e.member[1].ord = IW_AUX1_SRC;
 1372                 strcpy(dip->un.e.member[2].label.name, AudioNmicrophone);
 1373                 dip->un.e.member[2].ord = IW_MIC_IN_SRC;
 1374                 strcpy(dip->un.e.member[3].label.name, AudioNmixerout);
 1375                 dip->un.e.member[3].ord = IW_MIX_OUT_SRC;
 1376                 break;
 1377         case IW_INPUT_CLASS:
 1378                 dip->type = AUDIO_MIXER_CLASS;
 1379                 dip->mixer_class = IW_INPUT_CLASS;
 1380                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1381                 strcpy(dip->label.name, AudioCinputs);
 1382                 break;
 1383         case IW_OUTPUT_CLASS:
 1384                 dip->type = AUDIO_MIXER_CLASS;
 1385                 dip->mixer_class = IW_OUTPUT_CLASS;
 1386                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1387                 strcpy(dip->label.name, AudioCoutputs);
 1388                 break;
 1389         case IW_RECORD_CLASS:   /* record source class */
 1390                 dip->type = AUDIO_MIXER_CLASS;
 1391                 dip->mixer_class = IW_RECORD_CLASS;
 1392                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1393                 strcpy(dip->label.name, AudioCrecord);
 1394                 return 0;
 1395         default:
 1396                 return ENXIO;
 1397         }
 1398         return 0;
 1399 }
 1400 
 1401 
 1402 void *
 1403 iw_malloc(void *addr, int direction, size_t size)
 1404 {
 1405         struct iw_softc *sc;
 1406         int drq;
 1407 
 1408         sc = addr;
 1409         if (direction == AUMODE_PLAY)
 1410                 drq = sc->sc_playdrq;
 1411         else
 1412                 drq = sc->sc_recdrq;
 1413         return isa_malloc(sc->sc_ic, drq, size, M_DEVBUF, M_WAITOK);
 1414 }
 1415 
 1416 void
 1417 iw_free(void *addr, void *ptr, size_t size)
 1418 {
 1419 
 1420         isa_free(ptr, M_DEVBUF);
 1421 }
 1422 
 1423 size_t
 1424 iw_round_buffersize(void *addr, int direction, size_t size)
 1425 {
 1426         struct iw_softc *sc;
 1427         bus_size_t maxsize;
 1428 
 1429         sc = addr;
 1430         if (direction == AUMODE_PLAY)
 1431                 maxsize = sc->sc_play_maxsize;
 1432         else
 1433                 maxsize = sc->sc_rec_maxsize;
 1434 
 1435         if (size > maxsize)
 1436                 size = maxsize;
 1437         return size;
 1438 }
 1439 
 1440 int
 1441 iw_get_props(void *addr)
 1442 {
 1443         struct iw_softc *sc;
 1444 
 1445         sc = addr;
 1446         return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE |
 1447                 (sc->sc_fullduplex ? AUDIO_PROP_FULLDUPLEX : 0);
 1448 }
 1449 
 1450 void
 1451 iw_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread)
 1452 {
 1453         struct iw_softc *sc;
 1454 
 1455         sc = addr;
 1456         *intr = &sc->sc_intr_lock;
 1457         *thread = &sc->sc_lock;
 1458 }

Cache object: cbf9994a1a42bbe6118ed1d0f9fdc076


[ 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.