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

Cache object: bd765819c28b4237922e5b92df22b53c


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