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

Cache object: 5f27b6b5209a6c698c0ba940b68e7393


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