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/isa/ad1848.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 /*      $OpenBSD: ad1848.c,v 1.48 2022/10/28 14:55:46 kn Exp $  */
    2 /*      $NetBSD: ad1848.c,v 1.45 1998/01/30 02:02:38 augustss Exp $     */
    3 
    4 /*
    5  * Copyright (c) 1994 John Brezak
    6  * Copyright (c) 1991-1993 Regents of the University of California.
    7  * All rights reserved.
    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 Computer Systems
   20  *      Engineering Group at Lawrence Berkeley Laboratory.
   21  * 4. Neither the name of the University nor of the Laboratory may be used
   22  *    to endorse or promote products derived from this software without
   23  *    specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  */
   38 
   39 /*
   40  * Copyright by Hannu Savolainen 1994
   41  *
   42  * Redistribution and use in source and binary forms, with or without
   43  * modification, are permitted provided that the following conditions are
   44  * met: 1. Redistributions of source code must retain the above copyright
   45  * notice, this list of conditions and the following disclaimer. 2.
   46  * Redistributions in binary form must reproduce the above copyright notice,
   47  * this list of conditions and the following disclaimer in the documentation
   48  * and/or other materials provided with the distribution.
   49  *
   50  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
   51  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   53  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   54  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   56  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   57  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   58  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   59  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   60  * SUCH DAMAGE.
   61  *
   62  */
   63 /*
   64  * Portions of this code are from the VOXware support for the ad1848
   65  * by Hannu Savolainen <hannu@voxware.pp.fi>
   66  * 
   67  * Portions also supplied from the SoundBlaster driver for NetBSD.
   68  */
   69 
   70 #include <sys/param.h>
   71 #include <sys/systm.h>
   72 #include <sys/errno.h>
   73 #include <sys/ioctl.h>
   74 #include <sys/syslog.h>
   75 #include <sys/device.h>
   76 #include <sys/buf.h>
   77 #include <sys/fcntl.h>
   78 
   79 #include <machine/cpu.h>
   80 #include <machine/bus.h>
   81 
   82 #include <sys/audioio.h>
   83 
   84 #include <dev/audio_if.h>
   85 
   86 #include <dev/isa/isavar.h>
   87 #include <dev/isa/isadmavar.h>
   88 
   89 #include <dev/ic/ad1848reg.h>
   90 #include <dev/ic/cs4231reg.h>
   91 #include <dev/isa/ad1848var.h>
   92 #include <dev/isa/cs4231var.h>
   93 
   94 #ifdef AUDIO_DEBUG
   95 #define DPRINTF(x)      do { if (ad1848debug) printf x; } while (0);
   96 int     ad1848debug = 0;
   97 #else
   98 #define DPRINTF(x)
   99 #endif
  100 
  101 /*
  102  * Initial values for the indirect registers of CS4248/AD1848.
  103  */
  104 static int ad1848_init_values[] = {
  105         GAIN_12 | INPUT_MIC_GAIN_ENABLE,        /* Left Input Control */
  106         GAIN_12 | INPUT_MIC_GAIN_ENABLE,        /* Right Input Control */
  107         ATTEN_12,                       /* Left Aux #1 Input Control */
  108         ATTEN_12,                       /* Right Aux #1 Input Control */
  109         ATTEN_12,                       /* Left Aux #2 Input Control */
  110         ATTEN_12,                       /* Right Aux #2 Input Control */
  111         /* bits 5-0 are attenuation select */
  112         ATTEN_12,                       /* Left DAC output Control */
  113         ATTEN_12,                       /* Right DAC output Control */
  114         CLOCK_XTAL1 | FMT_PCM8,         /* Clock and Data Format */
  115         SINGLE_DMA | AUTO_CAL_ENABLE,   /* Interface Config */
  116         INTERRUPT_ENABLE,               /* Pin control */
  117         0x00,                           /* Test and Init */
  118         MODE2,                          /* Misc control */
  119         ATTEN_0 << 2,                   /* Digital Mix Control */
  120         0,                              /* Upper base Count */
  121         0,                              /* Lower base Count */
  122 
  123         /* These are for CS4231 &c. only (additional registers): */
  124         0,                              /* Alt feature 1 */
  125         0,                              /* Alt feature 2 */
  126         ATTEN_12,                       /* Left line in */
  127         ATTEN_12,                       /* Right line in */
  128         0,                              /* Timer low */
  129         0,                              /* Timer high */
  130         0,                              /* unused */
  131         0,                              /* unused */
  132         0,                              /* IRQ status */
  133         0,                              /* unused */
  134 
  135         /* Mono input (a.k.a speaker) (mic) Control */
  136         MONO_INPUT_MUTE|ATTEN_6,        /* mute speaker by default */
  137         0,                              /* unused */
  138         0,                              /* record format */
  139         0,                              /* Crystal Clock Select */
  140         0,                              /* upper record count */
  141         0                               /* lower record count */
  142 };
  143 
  144 static struct audio_params ad1848_audio_default =
  145         {48000, AUDIO_ENCODING_SLINEAR_LE, 16, 2, 1, 2};
  146 
  147 void    ad1848_reset(struct ad1848_softc *);
  148 int     ad1848_set_speed(struct ad1848_softc *, u_long *);
  149 void    ad1848_mute_monitor(void *, int);
  150 
  151 /* indirect register access */
  152 static int ad_read(struct ad1848_softc *, int);
  153 static void ad_write(struct ad1848_softc *, int, int);
  154 static void ad_set_MCE(struct ad1848_softc *, int);
  155 static void wait_for_calibration(struct ad1848_softc *);
  156 
  157 /* direct register (AD1848_{IADDR,IDATA,STATUS} only) access */
  158 #define ADREAD(sc, addr) bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_iooffs+(addr))
  159 #define ADWRITE(sc, addr, data) bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_iooffs+(addr), (data))
  160 
  161 static int
  162 ad_read(struct ad1848_softc *sc, int reg)
  163 {
  164         int x;
  165 
  166         ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit);
  167         x = ADREAD(sc, AD1848_IDATA);
  168         /*  printf("(%02x<-%02x) ", reg|sc->MCE_bit, x); */
  169 
  170         return x;
  171 }
  172 
  173 static void
  174 ad_write(struct ad1848_softc *sc, int reg, int data)
  175 {
  176         ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit);
  177         ADWRITE(sc, AD1848_IDATA, data & 0xff);
  178         /* printf("(%02x->%02x) ", reg|sc->MCE_bit, data); */
  179 }
  180 
  181 static void
  182 ad_set_MCE(struct ad1848_softc *sc, int state)
  183 {
  184         if (state)
  185                 sc->MCE_bit = MODE_CHANGE_ENABLE;
  186         else
  187                 sc->MCE_bit = 0;
  188 
  189         ADWRITE(sc, AD1848_IADDR, sc->MCE_bit);
  190 }
  191 
  192 static void
  193 wait_for_calibration(struct ad1848_softc *sc)
  194 {
  195         int timeout;
  196 
  197         DPRINTF(("ad1848: Auto calibration started.\n"));
  198         /*
  199          * Wait until the auto calibration process has finished.
  200          *
  201          * 1) Wait until the chip becomes ready (reads don't return SP_IN_INIT).
  202          * 2) Wait until the ACI bit of I11 goes hi and then lo.
  203          *   a) With AD1848 alike, ACI goes hi within 5 sample cycles
  204          *        and remains hi for ~384 sample periods.
  205          *   b) With CS4231 alike, ACI goes hi immediately and remains
  206          *        hi for at least 168 sample periods.
  207          */
  208         timeout = AD1848_TIMO;
  209         while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
  210                 timeout--;
  211 
  212         if (ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
  213                 DPRINTF(("ad1848: Auto calibration timed out(1).\n"));
  214 
  215         if (!(sc->sc_flags & AD1848_FLAG_32REGS)) {
  216                 timeout = AD1848_TIMO;
  217                 while (timeout > 0 &&
  218                     !(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG))
  219                         timeout--;
  220 
  221                 if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) {
  222                         DPRINTF(("ad1848: Auto calibration timed out(2).\n"));
  223                 }
  224         }
  225 
  226         timeout = AD1848_TIMO;
  227         while (timeout > 0 && ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)
  228                 timeout--;
  229         if (ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)
  230                 DPRINTF(("ad1848: Auto calibration timed out(3).\n"));
  231 }
  232 
  233 #ifdef AUDIO_DEBUG
  234 void ad1848_dump_regs(struct ad1848_softc *);
  235 
  236 void
  237 ad1848_dump_regs(struct ad1848_softc *sc)
  238 {
  239         int i;
  240         u_char r;
  241         
  242         printf("ad1848 status=%02x", ADREAD(sc, AD1848_STATUS));
  243         printf(" regs: ");
  244         for (i = 0; i < 16; i++) {
  245                 r = ad_read(sc, i);
  246                 printf("%02x ", r);
  247         }
  248         if (sc->mode == 2) {
  249                 for (i = 16; i < 32; i++) {
  250                         r = ad_read(sc, i);
  251                         printf("%02x ", r);
  252                 }
  253         }
  254         printf("\n");
  255 }
  256 #endif
  257 
  258 /*
  259  * Map and probe for the ad1848 chip
  260  */
  261 int
  262 ad1848_mapprobe(struct ad1848_softc *sc, int iobase)
  263 {
  264         if (!AD1848_BASE_VALID(iobase)) {
  265 #ifdef AUDIO_DEBUG
  266                 printf("ad1848: configured iobase %04x invalid\n", iobase);
  267 #endif
  268                 return 0;
  269         }
  270 
  271         sc->sc_iooffs = 0;
  272         /* Map the AD1848 ports */
  273         if (bus_space_map(sc->sc_iot, iobase, AD1848_NPORT, 0, &sc->sc_ioh))
  274                 return 0;
  275 
  276         if (!ad1848_probe(sc)) {
  277                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, AD1848_NPORT);
  278                 return 0;
  279         } else
  280                 return 1;
  281 }
  282 
  283 /*
  284  * Probe for the ad1848 chip
  285  */
  286 int
  287 ad1848_probe(struct ad1848_softc *sc)
  288 {
  289         u_char tmp, tmp1 = 0xff, tmp2 = 0xff;
  290 #if 0
  291         int i;
  292 #endif
  293 
  294         /* Is there an ad1848 chip ? */
  295         sc->MCE_bit = MODE_CHANGE_ENABLE;
  296         sc->mode = 1;   /* MODE 1 = original ad1848/ad1846/cs4248 */
  297         sc->sc_flags = 0;
  298 
  299         /*
  300          * Check that the I/O address is in use.
  301          *
  302          * The SP_IN_INIT bit of the base I/O port is known to be 0 after the
  303          * chip has performed its power-on initialization. Just assume
  304          * this has happened before the OS is starting.
  305          *
  306          * If the I/O address is unused, inb() typically returns 0xff.
  307          */
  308         tmp = ADREAD(sc, AD1848_IADDR);
  309         if (tmp & SP_IN_INIT) { /* Not a AD1848 */
  310 #if 0
  311                 DPRINTF(("ad_detect_A %x\n", tmp));
  312 #endif
  313                 goto bad;
  314         }
  315 
  316         /*
  317          * Test if it's possible to change contents of the indirect registers.
  318          * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read
  319          * only so try to avoid using it.
  320          */
  321         ad_write(sc, 0, 0xaa);
  322         ad_write(sc, 1, 0x45);  /* 0x55 with bit 0x10 clear */
  323 
  324         if ((tmp1 = ad_read(sc, 0)) != 0xaa ||
  325             (tmp2 = ad_read(sc, 1)) != 0x45) {
  326                 DPRINTF(("ad_detect_B (%x/%x)\n", tmp1, tmp2));
  327                 goto bad;
  328         }
  329 
  330         ad_write(sc, 0, 0x45);
  331         ad_write(sc, 1, 0xaa);
  332 
  333         if ((tmp1 = ad_read(sc, 0)) != 0x45 ||
  334             (tmp2 = ad_read(sc, 1)) != 0xaa) {
  335                 DPRINTF(("ad_detect_C (%x/%x)\n", tmp1, tmp2));
  336                 goto bad;
  337         }
  338 
  339         /*
  340          * The indirect register I12 has some read only bits. Lets
  341          * try to change them.
  342          */
  343         tmp = ad_read(sc, SP_MISC_INFO);
  344         ad_write(sc, SP_MISC_INFO, (~tmp) & 0x0f);
  345 
  346         if ((tmp & 0x0f) != ((tmp1 = ad_read(sc, SP_MISC_INFO)) & 0x0f)) {
  347                 DPRINTF(("ad_detect_D (%x)\n", tmp1));
  348                 goto bad;
  349         }
  350 
  351         /*
  352          * MSB and 4 LSBs of the reg I12 tell the chip revision.
  353          *
  354          * A preliminary version of the AD1846 data sheet stated that it
  355          * used an ID field of 0x0B.  The current version, however,
  356          * states that the AD1846 uses ID 0x0A, just like the AD1848K.
  357          *
  358          * this switch statement will need updating as newer clones arrive....
  359          */
  360         switch (tmp1 & 0x8f) {
  361         case 0x09:
  362                 sc->chip_name = "AD1848J";
  363                 break;
  364         case 0x0A:
  365                 sc->chip_name = "AD1848K";
  366                 break;
  367 #if 0   /* See above */
  368         case 0x0B:
  369                 sc->chip_name = "AD1846";
  370                 break;
  371 #endif
  372         case 0x81:
  373                 sc->chip_name = "CS4248revB"; /* or CS4231 rev B; see below */
  374                 break;
  375         case 0x89:
  376                 sc->chip_name = "CS4248";
  377                 break;
  378         case 0x8A:
  379                 sc->chip_name = "broken"; /* CS4231/AD1845; see below */
  380                 break;
  381         default:
  382                 sc->chip_name = "unknown";
  383                 DPRINTF(("ad1848: unknown codec version %#02X\n", (tmp1 & 0x8f)));
  384         }       
  385 
  386 #if 0
  387         /*
  388          * XXX I don't know why, but this probe fails on an otherwise
  389          * well-working AW35/pro card, so I'll just take it out for now.
  390          * [niklas@openbsd.org]
  391          */
  392 
  393         /*
  394          * The original AD1848/CS4248 has just 16 indirect registers. This
  395          * means that I0 and I16 should return the same value (etc.).
  396          * Ensure that the Mode2 enable bit of I12 is 0. Otherwise this test
  397          * fails with CS4231, AD1845, etc.
  398          */
  399         ad_write(sc, SP_MISC_INFO, 0);  /* Mode2 = disabled */
  400 
  401         for (i = 0; i < 16; i++) {
  402                 if ((tmp1 = ad_read(sc, i)) != (tmp2 = ad_read(sc, i + 16))) {
  403                         if (i != SP_TEST_AND_INIT) {
  404                                 DPRINTF(("ad_detect_F(%d/%x/%x)\n", i, tmp1, tmp2));
  405                                 goto bad;
  406                         }
  407                 }
  408         }
  409 #endif
  410 
  411         /*
  412          * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit
  413          * The bit 0x80 is always 1 in CS4248, CS4231, and AD1845.
  414          */
  415         ad_write(sc, SP_MISC_INFO, MODE2);      /* Set mode2, clear 0x80 */
  416 
  417         tmp1 = ad_read(sc, SP_MISC_INFO);
  418         if ((tmp1 & 0xc0) == (0x80 | MODE2)) {
  419                 /*
  420                  *      CS4231 or AD1845 detected - is it?
  421                  *
  422                  *      Verify that setting I2 doesn't change I18.
  423                  */
  424                 ad_write(sc, 18, 0x88); /* Set I18 to known value */
  425 
  426                 ad_write(sc, 2, 0x45);
  427                 if ((tmp2 = ad_read(sc, 18)) != 0x45) {
  428                         /* No change -> CS4231? */
  429                         ad_write(sc, 2, 0xaa);
  430                         if ((tmp2 = ad_read(sc, 18)) == 0xaa) {
  431                                 /* Rotten bits? */
  432                                 DPRINTF(("ad_detect_H(%x)\n", tmp2));
  433                                 goto bad;
  434                         }
  435 
  436                         /*
  437                          *  It's a CS4231, or another clone with 32 registers.
  438                          *  Let's find out which by checking I25.
  439                          */
  440                         if ((tmp1 & 0x8f) == 0x8a) {
  441                                 tmp1 = ad_read(sc, CS_VERSION_ID);
  442                                 switch (tmp1 & 0xe7) {
  443                                 case 0xA0:
  444                                         sc->chip_name = "CS4231A";
  445                                         break;
  446                                 case 0x80:
  447                                         /* I25 no good, AD1845 same as CS4231 */
  448                                         sc->chip_name = "CS4231 or AD1845";
  449                                         break;
  450                                 case 0x82:
  451                                         sc->chip_name = "CS4232";
  452                                         break;
  453                                 case 0xa2:
  454                                         sc->chip_name = "CS4232C";
  455                                         break;
  456                                 case 0x03:
  457                                         sc->chip_name = "CS4236/CS4236B";
  458                                         break;
  459                                 }
  460                         }
  461                         sc->mode = 2;
  462                         sc->sc_flags |= AD1848_FLAG_32REGS;
  463                 }
  464         }
  465 
  466         /* Wait for 1848 to init */
  467         while(ADREAD(sc, AD1848_IADDR) & SP_IN_INIT)
  468                 ;
  469 
  470         /* Wait for 1848 to autocal */
  471         ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT);
  472         while(ADREAD(sc, AD1848_IDATA) & AUTO_CAL_IN_PROG)
  473                 ;
  474 
  475         return 1;
  476 bad:
  477         return 0;
  478 }
  479 
  480 /* Unmap the I/O ports */
  481 void
  482 ad1848_unmap(struct ad1848_softc *sc)
  483 {
  484         bus_space_unmap(sc->sc_iot, sc->sc_ioh, AD1848_NPORT);
  485 }
  486 
  487 /*
  488  * Attach hardware to driver, attach hardware driver to audio
  489  * pseudo-device driver .
  490  */
  491 void
  492 ad1848_attach(struct ad1848_softc *sc)
  493 {
  494         int i;
  495         struct ad1848_volume vol_mid = {220, 220};
  496         struct ad1848_volume vol_0   = {0, 0};
  497         struct audio_params pparams, rparams;
  498         int timeout;
  499 
  500         sc->sc_playrun = 0;
  501         sc->sc_recrun = 0;
  502 
  503         if (sc->sc_drq != -1) {
  504                 if (isa_dmamap_create(sc->sc_isa, sc->sc_drq, MAX_ISADMA,
  505                     BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
  506                         printf("ad1848_attach: can't create map for drq %d\n",
  507                             sc->sc_drq);
  508                         return;
  509                 }
  510         }
  511         if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) {
  512                 if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq, MAX_ISADMA,
  513                     BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
  514                         printf("ad1848_attach: can't create map for second drq %d\n",
  515                             sc->sc_recdrq);
  516                         return;
  517                 }
  518         }
  519 
  520         /* Initialize the ad1848... */
  521         for (i = 0; i < 0x10; i++) {
  522                 ad_write(sc, i, ad1848_init_values[i]);
  523                 timeout = AD1848_TIMO;
  524                 while (timeout > 0 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT)
  525                         timeout--;
  526         }
  527         /* need 2 separate drqs for mode 2 */
  528         if ((sc->mode == 2) &&
  529             ((sc->sc_recdrq == -1) || (sc->sc_recdrq == sc->sc_drq))) {
  530                 ad_write(sc, SP_MISC_INFO, ad_read(sc, SP_MISC_INFO) & ~MODE2);
  531                 if (!(ad_read(sc, SP_MISC_INFO) & MODE2))
  532                         sc->mode = 1;
  533         }
  534         /* ...and additional CS4231 stuff too */
  535         if (sc->mode == 2) {
  536                 ad_write(sc, SP_INTERFACE_CONFIG, 0); /* disable SINGLE_DMA */
  537                 for (i = 0x10; i < 0x20; i++) {
  538                         if (ad1848_init_values[i] != 0) {
  539                                 ad_write(sc, i, ad1848_init_values[i]);
  540                                 timeout = AD1848_TIMO;
  541                                 while (timeout > 0 && 
  542                                     ADREAD(sc, AD1848_IADDR) & SP_IN_INIT)
  543                                         timeout--;
  544                         }
  545                 }
  546         }
  547         ad1848_reset(sc);
  548 
  549         pparams = ad1848_audio_default;
  550         rparams = ad1848_audio_default;
  551         (void) ad1848_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0,
  552             &pparams, &rparams);
  553 
  554         /* Set default gains */
  555         (void) ad1848_set_rec_gain(sc, &vol_mid);
  556         (void) ad1848_set_channel_gain(sc, AD1848_DAC_CHANNEL, &vol_mid);
  557         (void) ad1848_set_channel_gain(sc, AD1848_MONITOR_CHANNEL, &vol_0);
  558         /* CD volume */
  559         (void) ad1848_set_channel_gain(sc, AD1848_AUX1_CHANNEL, &vol_mid);
  560         if (sc->mode == 2) {
  561                  /* CD volume */
  562                 (void) ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_mid);
  563                 (void) ad1848_set_channel_gain(sc, AD1848_LINE_CHANNEL, &vol_mid);
  564                 (void) ad1848_set_channel_gain(sc, AD1848_MONO_CHANNEL, &vol_0);
  565                 sc->mute[AD1848_MONO_CHANNEL] = MUTE_ALL;
  566         } else
  567                 (void) ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_0);
  568 
  569         /* Set default port */
  570         (void) ad1848_set_rec_port(sc, MIC_IN_PORT);
  571 
  572         if (sc->chip_name)
  573                 printf(": %s", sc->chip_name);
  574 }
  575 
  576 /*
  577  * Various routines to interface to higher level audio driver
  578  */
  579 struct ad1848_mixerinfo {
  580         int left_reg;
  581         int right_reg;
  582         int atten_bits;
  583         int atten_mask;
  584 } mixer_channel_info[] = {
  585         { SP_LEFT_AUX2_CONTROL, SP_RIGHT_AUX2_CONTROL, AUX_INPUT_ATTEN_BITS,
  586                 AUX_INPUT_ATTEN_MASK },
  587         { SP_LEFT_AUX1_CONTROL, SP_RIGHT_AUX1_CONTROL, AUX_INPUT_ATTEN_BITS,
  588                 AUX_INPUT_ATTEN_MASK },
  589         { SP_LEFT_OUTPUT_CONTROL, SP_RIGHT_OUTPUT_CONTROL, OUTPUT_ATTEN_BITS,
  590                 OUTPUT_ATTEN_MASK }, 
  591         { CS_LEFT_LINE_CONTROL, CS_RIGHT_LINE_CONTROL, LINE_INPUT_ATTEN_BITS,
  592                 LINE_INPUT_ATTEN_MASK },
  593         { CS_MONO_IO_CONTROL, 0, MONO_INPUT_ATTEN_BITS, MONO_INPUT_ATTEN_MASK },
  594         { SP_DIGITAL_MIX, 0, OUTPUT_ATTEN_BITS, MIX_ATTEN_MASK }
  595 };
  596 
  597 /*
  598  *  This function doesn't set the mute flags but does use them.
  599  *  The mute flags reflect the mutes that have been applied by the user.
  600  *  However, the driver occasionally wants to mute devices (e.g. when changing
  601  *  sampling rate). These operations should not affect the mute flags.
  602  */
  603 void 
  604 ad1848_mute_channel(struct ad1848_softc *sc, int device, int mute)
  605 {
  606         u_char reg;
  607 
  608         reg = ad_read(sc, mixer_channel_info[device].left_reg);
  609 
  610         if (mute & MUTE_LEFT) {
  611                 if (device == AD1848_MONITOR_CHANNEL) {
  612                         ad_write(sc, mixer_channel_info[device].left_reg,
  613                             reg & 0xFE);
  614                 } else {
  615                         ad_write(sc, mixer_channel_info[device].left_reg,
  616                             reg | 0x80);
  617                 }
  618         } else if (!(sc->mute[device] & MUTE_LEFT)) {
  619                 if (device == AD1848_MONITOR_CHANNEL) {
  620                         ad_write(sc, mixer_channel_info[device].left_reg,
  621                             reg | 0x01);
  622                 } else {
  623                         ad_write(sc, mixer_channel_info[device].left_reg,
  624                             reg & ~0x80);
  625                 }
  626         }
  627 
  628         if (!mixer_channel_info[device].right_reg) {
  629                 return;
  630         }
  631 
  632         reg = ad_read(sc, mixer_channel_info[device].right_reg);
  633 
  634         if (mute & MUTE_RIGHT) {
  635                 ad_write(sc, mixer_channel_info[device].right_reg, reg | 0x80);
  636         } else if (!(sc->mute[device] & MUTE_RIGHT)) {
  637                 ad_write(sc, mixer_channel_info[device].right_reg, reg & ~0x80);
  638         }
  639 }
  640 
  641 int
  642 ad1848_set_channel_gain(struct ad1848_softc *sc, int device,
  643     struct ad1848_volume *gp)
  644 {
  645         struct ad1848_mixerinfo *info = &mixer_channel_info[device];
  646         u_char reg;
  647         u_int atten;
  648 
  649         sc->gains[device] = *gp;
  650 
  651         atten = ((AUDIO_MAX_GAIN - gp->left) * info->atten_bits) /
  652             AUDIO_MAX_GAIN;
  653 
  654         reg = ad_read(sc, info->left_reg) & (info->atten_mask);
  655         if (device == AD1848_MONITOR_CHANNEL)
  656                 reg |= ((atten & info->atten_bits) << 2);
  657         else
  658                 reg |= ((atten & info->atten_bits));
  659 
  660         ad_write(sc, info->left_reg, reg);
  661 
  662         if (!info->right_reg)
  663                 return 0;
  664 
  665         atten = ((AUDIO_MAX_GAIN - gp->right) * info->atten_bits) /
  666             AUDIO_MAX_GAIN;
  667         reg = ad_read(sc, info->right_reg);
  668         reg &= (info->atten_mask);
  669         ad_write(sc, info->right_reg, (atten & info->atten_bits) | reg);
  670 
  671         return 0;
  672 }
  673 
  674 int
  675 ad1848_get_device_gain(struct ad1848_softc *sc, int device,
  676     struct ad1848_volume *gp)
  677 {
  678         *gp = sc->gains[device];
  679         return 0;
  680 }
  681 
  682 int
  683 ad1848_get_rec_gain(struct ad1848_softc *sc, struct ad1848_volume *gp)
  684 {
  685         *gp = sc->rec_gain;
  686         return 0;
  687 }
  688 
  689 int
  690 ad1848_set_rec_gain(struct ad1848_softc *sc, struct ad1848_volume *gp)
  691 {
  692         u_char reg, gain;
  693         
  694         DPRINTF(("ad1848_set_rec_gain: %d:%d\n", gp->left, gp->right));
  695 
  696         sc->rec_gain = *gp;
  697 
  698         gain = (gp->left * GAIN_22_5) / AUDIO_MAX_GAIN;
  699         reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
  700         reg &= INPUT_GAIN_MASK;
  701         ad_write(sc, SP_LEFT_INPUT_CONTROL, (gain & 0x0f) | reg);
  702 
  703         gain = (gp->right * GAIN_22_5) / AUDIO_MAX_GAIN;
  704         reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL);
  705         reg &= INPUT_GAIN_MASK;
  706         ad_write(sc, SP_RIGHT_INPUT_CONTROL, (gain & 0x0f) | reg);
  707 
  708         return 0;
  709 }
  710 
  711 void
  712 ad1848_mute_monitor(void *addr, int mute)
  713 {
  714         struct ad1848_softc *sc = addr;
  715 
  716         DPRINTF(("ad1848_mute_monitor: %smuting\n", mute ? "" : "un"));
  717         if (sc->mode == 2) {
  718                 ad1848_mute_channel(sc, AD1848_DAC_CHANNEL,
  719                     mute ? MUTE_ALL : 0);
  720                 ad1848_mute_channel(sc, AD1848_MONO_CHANNEL,
  721                     mute ? MUTE_MONO : 0);
  722                 ad1848_mute_channel(sc, AD1848_LINE_CHANNEL,
  723                     mute ? MUTE_ALL : 0);
  724         }
  725 
  726         ad1848_mute_channel(sc, AD1848_AUX2_CHANNEL, mute ? MUTE_ALL : 0);
  727         ad1848_mute_channel(sc, AD1848_AUX1_CHANNEL, mute ? MUTE_ALL : 0);
  728 }
  729 
  730 int
  731 ad1848_set_mic_gain(struct ad1848_softc *sc, struct ad1848_volume *gp)
  732 {
  733         u_char reg;
  734 
  735         DPRINTF(("cs4231_set_mic_gain: %d\n", gp->left));
  736 
  737         if (gp->left > AUDIO_MAX_GAIN / 2) {
  738                 sc->mic_gain_on = 1;
  739                 reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
  740                 ad_write(sc, SP_LEFT_INPUT_CONTROL,
  741                     reg | INPUT_MIC_GAIN_ENABLE);
  742         } else {
  743                 sc->mic_gain_on = 0;
  744                 reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
  745                 ad_write(sc, SP_LEFT_INPUT_CONTROL,
  746                     reg & ~INPUT_MIC_GAIN_ENABLE);
  747         }
  748 
  749         return 0;
  750 }
  751 
  752 int
  753 ad1848_get_mic_gain(struct ad1848_softc *sc, struct ad1848_volume *gp)
  754 {
  755         if (sc->mic_gain_on)
  756                 gp->left = gp->right = AUDIO_MAX_GAIN;
  757         else
  758                 gp->left = gp->right = AUDIO_MIN_GAIN;
  759 
  760         return 0;
  761 }
  762 
  763 
  764 static ad1848_devmap_t *ad1848_mixer_find_dev(ad1848_devmap_t *, int, mixer_ctrl_t *);
  765 
  766 static ad1848_devmap_t *
  767 ad1848_mixer_find_dev(ad1848_devmap_t *map, int cnt, mixer_ctrl_t *cp)
  768 {
  769         int idx;
  770 
  771         for (idx = 0; idx < cnt; idx++) {
  772                 if (map[idx].id == cp->dev) {
  773                         return &map[idx];
  774                 }
  775         }
  776         return NULL;
  777 }
  778 
  779 int
  780 ad1848_mixer_get_port(struct ad1848_softc *ac, struct ad1848_devmap *map,
  781     int cnt, mixer_ctrl_t *cp)
  782 {
  783         ad1848_devmap_t *entry;
  784         struct ad1848_volume vol;
  785         int error = EINVAL;
  786         int dev;
  787 
  788         if (!(entry = ad1848_mixer_find_dev(map, cnt, cp)))
  789                 return (ENXIO);
  790 
  791         dev = entry->dev;
  792         mtx_enter(&audio_lock);
  793         switch (entry->kind) {
  794         case AD1848_KIND_LVL:
  795                 if (cp->type != AUDIO_MIXER_VALUE)
  796                         break;
  797                 if (dev < AD1848_AUX2_CHANNEL ||
  798                     dev > AD1848_MONITOR_CHANNEL)
  799                         break;
  800                 if (cp->un.value.num_channels != 1 &&
  801                     mixer_channel_info[dev].right_reg == 0) 
  802                         break;
  803                 error = ad1848_get_device_gain(ac, dev, &vol);
  804                 if (!error)
  805                         ad1848_from_vol(cp, &vol);
  806                 break;
  807 
  808         case AD1848_KIND_MUTE:
  809                 if (cp->type != AUDIO_MIXER_ENUM)
  810                         break;
  811                 cp->un.ord = ac->mute[dev] ? 1 : 0;
  812                 error = 0;
  813                 break;
  814 
  815         case AD1848_KIND_RECORDGAIN:
  816                 if (cp->type != AUDIO_MIXER_VALUE)
  817                         break;
  818                 error = ad1848_get_rec_gain(ac, &vol);
  819                 if (!error)
  820                         ad1848_from_vol(cp, &vol);
  821                 break;
  822 
  823         case AD1848_KIND_MICGAIN:
  824                 if (cp->type != AUDIO_MIXER_VALUE)
  825                         break;
  826                 error = ad1848_get_mic_gain(ac, &vol);
  827                 if (!error)
  828                         ad1848_from_vol(cp, &vol);
  829                 break;
  830 
  831         case AD1848_KIND_RECORDSOURCE:
  832                 if (cp->type != AUDIO_MIXER_ENUM)
  833                         break;
  834                 cp->un.ord = ad1848_get_rec_port(ac);
  835                 error = 0;
  836                 break;
  837 
  838         default:
  839                 printf("Invalid kind\n");
  840                 break;
  841         }
  842         mtx_leave(&audio_lock);
  843         return error;
  844 }
  845 
  846 int      
  847 ad1848_mixer_set_port(struct ad1848_softc *ac, struct ad1848_devmap *map,
  848     int cnt, mixer_ctrl_t *cp)
  849 {
  850         ad1848_devmap_t *entry;
  851         struct ad1848_volume vol;
  852         int error = EINVAL;
  853         int dev;
  854 
  855         if (!(entry = ad1848_mixer_find_dev(map, cnt, cp)))
  856                 return (ENXIO);
  857 
  858         dev = entry->dev;
  859         mtx_enter(&audio_lock);
  860         switch (entry->kind) {
  861         case AD1848_KIND_LVL:
  862                 if (cp->type != AUDIO_MIXER_VALUE)
  863                         break;
  864                 if (dev < AD1848_AUX2_CHANNEL ||
  865                     dev > AD1848_MONITOR_CHANNEL)
  866                         break;
  867                 if (cp->un.value.num_channels != 1 &&
  868                     mixer_channel_info[dev].right_reg == 0) 
  869                         break;
  870                 ad1848_to_vol(cp, &vol);
  871                 error = ad1848_set_channel_gain(ac, dev, &vol);
  872                 break;
  873 
  874         case AD1848_KIND_MUTE:
  875                 if (cp->type != AUDIO_MIXER_ENUM)
  876                         break;
  877                 ac->mute[dev] = (cp->un.ord ? MUTE_ALL : 0);
  878                 ad1848_mute_channel(ac, dev, ac->mute[dev]);
  879                 error = 0;
  880                 break;
  881 
  882         case AD1848_KIND_RECORDGAIN:
  883                 if (cp->type != AUDIO_MIXER_VALUE)
  884                         break;
  885                 ad1848_to_vol(cp, &vol);
  886                 error = ad1848_set_rec_gain(ac, &vol);
  887                 break;
  888 
  889         case AD1848_KIND_MICGAIN:
  890                 if (cp->type != AUDIO_MIXER_VALUE)
  891                         break;
  892                 ad1848_to_vol(cp, &vol);
  893                 error = ad1848_set_mic_gain(ac, &vol);
  894                 break;
  895 
  896         case AD1848_KIND_RECORDSOURCE:
  897                 if (cp->type != AUDIO_MIXER_ENUM)
  898                         break;
  899                 error = ad1848_set_rec_port(ac,  cp->un.ord);
  900                 break;
  901 
  902         default:
  903                 printf("Invalid kind\n");
  904                 break;
  905         }
  906         mtx_leave(&audio_lock);
  907         return (error);
  908 }
  909 
  910 int
  911 ad1848_set_params(void *addr, int setmode, int usemode, struct audio_params *p,
  912     struct audio_params *r)
  913 {
  914         struct ad1848_softc *sc = addr;
  915         int error, bits, enc;
  916 
  917         DPRINTF(("ad1848_set_params: %d %d %d %ld\n", 
  918              p->encoding, p->precision, p->channels, p->sample_rate));
  919 
  920         enc = p->encoding;
  921         switch (enc) {
  922         case AUDIO_ENCODING_SLINEAR_LE:
  923                 if (p->precision == 8)
  924                         return EINVAL;
  925                 break;
  926         case AUDIO_ENCODING_SLINEAR_BE:
  927                 if (p->precision == 16)
  928                         return EINVAL;
  929                 break;
  930         case AUDIO_ENCODING_ULINEAR_LE:
  931                 if (p->precision == 16)
  932                         return EINVAL;
  933                 break;
  934         case AUDIO_ENCODING_ULINEAR_BE:
  935                 if (p->precision == 16)
  936                         return EINVAL;
  937                 break;
  938         }
  939         switch (enc) {
  940         case AUDIO_ENCODING_ULAW:
  941                 p->precision = 8;
  942                 bits = FMT_ULAW;
  943                 break;
  944         case AUDIO_ENCODING_ALAW:
  945                 p->precision = 8;
  946                 bits = FMT_ALAW;
  947                 break;
  948         case AUDIO_ENCODING_SLINEAR_LE:
  949                 if (p->precision == 16)
  950                         bits = FMT_TWOS_COMP;
  951                 else
  952                         return EINVAL;
  953                 break;
  954         case AUDIO_ENCODING_SLINEAR_BE:
  955                 if (p->precision == 16)
  956                         bits = FMT_TWOS_COMP_BE;
  957                 else
  958                         return EINVAL;
  959                 break;
  960         case AUDIO_ENCODING_ULINEAR_LE:
  961                 if (p->precision == 8)
  962                         bits = FMT_PCM8;
  963                 else
  964                         return EINVAL;
  965                 break;
  966         default:
  967                 return EINVAL;
  968         }
  969 
  970         if (p->channels < 1 || p->channels > 2)
  971                 return EINVAL;
  972 
  973         error = ad1848_set_speed(sc, &p->sample_rate);
  974         if (error)
  975                 return error;
  976 
  977         p->bps = AUDIO_BPS(p->precision);
  978         r->bps = AUDIO_BPS(r->precision);
  979         p->msb = 1;
  980         r->msb = 1;
  981 
  982         sc->format_bits = bits;
  983         sc->channels = p->channels;
  984         sc->precision = p->precision;
  985         sc->need_commit = 1;
  986 
  987         DPRINTF(("ad1848_set_params succeeded, bits=%x\n", bits));
  988         return (0);
  989 }
  990 
  991 int
  992 ad1848_set_rec_port(struct ad1848_softc *sc, int port)
  993 {
  994         u_char inp, reg;
  995 
  996         DPRINTF(("ad1848_set_rec_port: 0x%x\n", port));
  997 
  998         if (port == MIC_IN_PORT) {
  999                 inp = MIC_INPUT;
 1000         } else if (port == LINE_IN_PORT) {
 1001                 inp = LINE_INPUT;
 1002         } else if (port == DAC_IN_PORT) {
 1003                 inp = MIXED_DAC_INPUT;
 1004         } else if (sc->mode == 2 && port == AUX1_IN_PORT) {
 1005                 inp = AUX_INPUT;
 1006         } else
 1007                 return EINVAL;
 1008 
 1009         reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
 1010         reg &= INPUT_SOURCE_MASK;
 1011         ad_write(sc, SP_LEFT_INPUT_CONTROL, (inp | reg));
 1012 
 1013         reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL);
 1014         reg &= INPUT_SOURCE_MASK;
 1015         ad_write(sc, SP_RIGHT_INPUT_CONTROL, (inp | reg));
 1016 
 1017         sc->rec_port = port;
 1018 
 1019         return 0;
 1020 }
 1021 
 1022 int
 1023 ad1848_get_rec_port(struct ad1848_softc *sc)
 1024 {
 1025         return sc->rec_port;
 1026 }
 1027 
 1028 int
 1029 ad1848_round_blocksize(void *addr, int blk)
 1030 {
 1031         /* Round to a multiple of the biggest sample size. */
 1032         blk = (blk + 3) & -4;
 1033 
 1034         return blk;
 1035 }
 1036 
 1037 int
 1038 ad1848_open(void *addr, int flags)
 1039 {
 1040         struct ad1848_softc *sc = addr;
 1041 
 1042         DPRINTF(("ad1848_open: sc=%p\n", sc));
 1043 
 1044         if ((flags & (FWRITE | FREAD)) == (FWRITE | FREAD) && sc->mode != 2)
 1045                 return ENXIO;
 1046 
 1047         sc->sc_pintr = sc->sc_parg = NULL;
 1048         sc->sc_rintr = sc->sc_rarg = NULL;
 1049 
 1050         /* Enable interrupts */
 1051         DPRINTF(("ad1848_open: enable intrs\n"));
 1052         ad_write(sc, SP_PIN_CONTROL,
 1053             INTERRUPT_ENABLE | ad_read(sc, SP_PIN_CONTROL));
 1054 
 1055 #ifdef AUDIO_DEBUG
 1056         if (ad1848debug > 2)
 1057                 ad1848_dump_regs(sc);
 1058 #endif
 1059 
 1060         return 0;
 1061 }
 1062 
 1063 /*
 1064  * Close function is called at splaudio().
 1065  */
 1066 void
 1067 ad1848_close(void *addr)
 1068 {
 1069         struct ad1848_softc *sc = addr;
 1070         u_char r;
 1071 
 1072         ad1848_halt_output(sc);
 1073         ad1848_halt_input(sc);
 1074 
 1075         sc->sc_pintr = NULL;
 1076         sc->sc_rintr = NULL;
 1077 
 1078         DPRINTF(("ad1848_close: stop DMA\n"));
 1079 
 1080         ad_write(sc, SP_LOWER_BASE_COUNT, (u_char)0);
 1081         ad_write(sc, SP_UPPER_BASE_COUNT, (u_char)0);
 1082 
 1083         /* Disable interrupts */
 1084         DPRINTF(("ad1848_close: disable intrs\n"));
 1085         ad_write(sc, SP_PIN_CONTROL, 
 1086             ad_read(sc, SP_PIN_CONTROL) & ~INTERRUPT_ENABLE);
 1087 
 1088         DPRINTF(("ad1848_close: disable capture and playback\n"));
 1089         r = ad_read(sc, SP_INTERFACE_CONFIG);
 1090         r &= ~(CAPTURE_ENABLE | PLAYBACK_ENABLE);
 1091         ad_write(sc, SP_INTERFACE_CONFIG, r);
 1092 
 1093 #ifdef AUDIO_DEBUG
 1094         if (ad1848debug > 2)
 1095                 ad1848_dump_regs(sc);
 1096 #endif
 1097 }
 1098 
 1099 /*
 1100  * Lower-level routines
 1101  */
 1102 int
 1103 ad1848_commit_settings(void *addr)
 1104 {
 1105         struct ad1848_softc *sc = addr;
 1106         int timeout;
 1107         u_char fs;
 1108 
 1109         if (!sc->need_commit)
 1110                 return 0;
 1111 
 1112         mtx_enter(&audio_lock);
 1113 
 1114         ad1848_mute_monitor(sc, 1);
 1115 
 1116         /* Enables changes to the format select reg */
 1117         ad_set_MCE(sc, 1);
 1118 
 1119         fs = sc->speed_bits | sc->format_bits;
 1120 
 1121         if (sc->channels == 2)
 1122                 fs |= FMT_STEREO;
 1123 
 1124         ad_write(sc, SP_CLOCK_DATA_FORMAT, fs);
 1125 
 1126         /*
 1127          * If mode == 2 (CS4231), set I28 also. It's the capture format
 1128          * register.
 1129          */
 1130         if (sc->mode == 2) {
 1131                 /* Gravis Ultrasound MAX SDK sources says something about
 1132                  * errata sheets, with the implication that these inb()s
 1133                  * are necessary.
 1134                  */
 1135                 (void)ADREAD(sc, AD1848_IDATA);
 1136                 (void)ADREAD(sc, AD1848_IDATA);
 1137 
 1138                 /*
 1139                  * Write to I8 starts resynchronization. Wait until it
 1140                  * completes.
 1141                  */
 1142                 timeout = AD1848_TIMO;
 1143                 while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
 1144                         timeout--;
 1145 
 1146                 ad_write(sc, CS_REC_FORMAT, fs);
 1147                 /* Gravis Ultrasound MAX SDK sources says something about
 1148                  * errata sheets, with the implication that these inb()s
 1149                  * are necessary.
 1150                  */
 1151                 (void)ADREAD(sc, AD1848_IDATA);
 1152                 (void)ADREAD(sc, AD1848_IDATA);
 1153                 /* Now wait for resync for capture side of the house */
 1154         }
 1155         /*
 1156          * Write to I8 starts resynchronization. Wait until it completes.
 1157          */
 1158         timeout = AD1848_TIMO;
 1159         while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
 1160                 timeout--;
 1161 
 1162         if (ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
 1163                 printf("ad1848_commit: Auto calibration timed out\n");
 1164 
 1165         /*
 1166          * Starts the calibration process and enters playback mode after it.
 1167          */
 1168         ad_set_MCE(sc, 0);
 1169         wait_for_calibration(sc);
 1170 
 1171         ad1848_mute_monitor(sc, 0);
 1172 
 1173         mtx_leave(&audio_lock);
 1174         
 1175         sc->need_commit = 0;
 1176 
 1177         return 0;
 1178 }
 1179 
 1180 void
 1181 ad1848_reset(struct ad1848_softc *sc)
 1182 {
 1183         u_char r;
 1184 
 1185         DPRINTF(("ad1848_reset\n"));
 1186 
 1187         /* Clear the PEN and CEN bits */
 1188         r = ad_read(sc, SP_INTERFACE_CONFIG);
 1189         r &= ~(CAPTURE_ENABLE | PLAYBACK_ENABLE);
 1190         ad_write(sc, SP_INTERFACE_CONFIG, r);
 1191 
 1192         /* Clear interrupt status */
 1193         if (sc->mode == 2)
 1194                 ad_write(sc, CS_IRQ_STATUS, 0);
 1195         ADWRITE(sc, AD1848_STATUS, 0);
 1196 
 1197 #ifdef AUDIO_DEBUG
 1198         if (ad1848debug > 2)
 1199                 ad1848_dump_regs(sc);
 1200 #endif
 1201 }
 1202 
 1203 int
 1204 ad1848_set_speed(struct ad1848_softc *sc, u_long *argp)
 1205 {
 1206         /*
 1207          * The sampling speed is encoded in the least significant nible of I8.
 1208          * The LSB selects the clock source (0=24.576 MHz, 1=16.9344 MHz) and
 1209          * other three bits select the divisor (indirectly):
 1210          *
 1211          * The available speeds are in the following table. Keep the speeds in
 1212          * the increasing order.
 1213          */
 1214         typedef struct {
 1215                 int     speed;
 1216                 u_char  bits;
 1217         } speed_struct;
 1218         u_long arg = *argp;
 1219 
 1220         static speed_struct speed_table[] =  {
 1221                 {5510, (0 << 1) | 1},
 1222                 {5510, (0 << 1) | 1},
 1223                 {6620, (7 << 1) | 1},
 1224                 {8000, (0 << 1) | 0},
 1225                 {9600, (7 << 1) | 0},
 1226                 {11025, (1 << 1) | 1},
 1227                 {16000, (1 << 1) | 0},
 1228                 {18900, (2 << 1) | 1},
 1229                 {22050, (3 << 1) | 1},
 1230                 {27420, (2 << 1) | 0},
 1231                 {32000, (3 << 1) | 0},
 1232                 {33075, (6 << 1) | 1},
 1233                 {37800, (4 << 1) | 1},
 1234                 {44100, (5 << 1) | 1},
 1235                 {48000, (6 << 1) | 0}
 1236         };
 1237 
 1238         int i, n, selected = -1;
 1239 
 1240         n = sizeof(speed_table) / sizeof(speed_struct);
 1241 
 1242         if (arg < speed_table[0].speed)
 1243                 selected = 0;
 1244         if (arg > speed_table[n - 1].speed)
 1245                 selected = n - 1;
 1246 
 1247         for (i = 1 /*really*/ ; selected == -1 && i < n; i++)
 1248                 if (speed_table[i].speed == arg)
 1249                         selected = i;
 1250                 else if (speed_table[i].speed > arg) {
 1251                         int diff1, diff2;
 1252 
 1253                 diff1 = arg - speed_table[i - 1].speed;
 1254                 diff2 = speed_table[i].speed - arg;
 1255 
 1256                 if (diff1 < diff2)
 1257                         selected = i - 1;
 1258                 else
 1259                         selected = i;
 1260         }
 1261 
 1262         if (selected == -1) {
 1263                 printf("ad1848: Can't find speed???\n");
 1264                 selected = 3;
 1265         }
 1266 
 1267         sc->speed_bits = speed_table[selected].bits;
 1268         sc->need_commit = 1;
 1269         *argp = speed_table[selected].speed;
 1270 
 1271         return 0;
 1272 }
 1273 
 1274 /*
 1275  * Halt a DMA in progress.
 1276  */
 1277 int
 1278 ad1848_halt_output(void *addr)
 1279 {
 1280         struct ad1848_softc *sc = addr;
 1281         u_char reg;
 1282 
 1283         DPRINTF(("ad1848: ad1848_halt_output\n"));
 1284         mtx_enter(&audio_lock);
 1285         reg = ad_read(sc, SP_INTERFACE_CONFIG);
 1286         ad_write(sc, SP_INTERFACE_CONFIG, (reg & ~PLAYBACK_ENABLE));
 1287 
 1288         if (sc->sc_playrun == 1) {
 1289                 isa_dmaabort(sc->sc_isa, sc->sc_drq);
 1290                 sc->sc_playrun = 0;
 1291         }
 1292         mtx_leave(&audio_lock);
 1293         return 0;
 1294 }
 1295 
 1296 int
 1297 ad1848_halt_input(void *addr)
 1298 {
 1299         struct ad1848_softc *sc = addr;
 1300         u_char reg;
 1301 
 1302         DPRINTF(("ad1848: ad1848_halt_input\n"));
 1303         mtx_enter(&audio_lock);
 1304         reg = ad_read(sc, SP_INTERFACE_CONFIG);
 1305         ad_write(sc, SP_INTERFACE_CONFIG, (reg & ~CAPTURE_ENABLE));
 1306 
 1307         if (sc->sc_recrun == 1) {
 1308                 isa_dmaabort(sc->sc_isa, sc->sc_recdrq);
 1309                 sc->sc_recrun = 0;
 1310         }
 1311         mtx_leave(&audio_lock);
 1312         return 0;
 1313 }
 1314 
 1315 int
 1316 ad1848_trigger_input(void *addr, void *start, void *end, int blksize,
 1317     void (*intr)(void *), void *arg, struct audio_params *param)
 1318 {
 1319         struct ad1848_softc *sc = addr;
 1320         u_char reg;
 1321 
 1322         if (sc->sc_recdrq == -1) {
 1323                 DPRINTF(("ad1848_trigger_input: invalid recording drq\n"));
 1324                 return ENXIO;
 1325         }
 1326         mtx_enter(&audio_lock);
 1327         isa_dmastart(sc->sc_isa, sc->sc_recdrq, start,
 1328             (char *)end - (char *)start, NULL, DMAMODE_READ | DMAMODE_LOOP,
 1329             BUS_DMA_NOWAIT);
 1330 
 1331         sc->sc_recrun = 1;
 1332         sc->sc_rintr = intr;
 1333         sc->sc_rarg = arg;
 1334 
 1335         blksize = (blksize * NBBY) / (param->precision * param->channels) - 1;
 1336 
 1337         if (sc->mode == 2) {
 1338                 ad_write(sc, CS_LOWER_REC_CNT, (blksize & 0xff));
 1339                 ad_write(sc, CS_UPPER_REC_CNT, ((blksize >> 8) & 0xff));
 1340         } else {
 1341                 ad_write(sc, SP_LOWER_BASE_COUNT, blksize & 0xff);
 1342                 ad_write(sc, SP_UPPER_BASE_COUNT, (blksize >> 8) & 0xff);
 1343         }
 1344 
 1345         reg = ad_read(sc, SP_INTERFACE_CONFIG);
 1346         ad_write(sc, SP_INTERFACE_CONFIG, (CAPTURE_ENABLE | reg));
 1347 
 1348 #ifdef AUDIO_DEBUG
 1349         if (ad1848debug > 1)
 1350                 printf("ad1848_trigger_input: started capture\n");
 1351 #endif
 1352         mtx_leave(&audio_lock);
 1353         return 0;
 1354 }
 1355 
 1356 int
 1357 ad1848_trigger_output(void *addr, void *start, void *end, int blksize,
 1358     void (*intr)(void *), void *arg, struct audio_params *param)
 1359 {
 1360         struct ad1848_softc *sc = addr;
 1361         u_char reg;
 1362 
 1363         mtx_enter(&audio_lock);
 1364         isa_dmastart(sc->sc_isa, sc->sc_drq, start,
 1365             (char *)end - (char *)start, NULL,
 1366             DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT);
 1367 
 1368         sc->sc_playrun = 1;
 1369         sc->sc_pintr = intr;
 1370         sc->sc_parg = arg;
 1371 
 1372         blksize = (blksize * NBBY) / (param->precision * param->channels) - 1;
 1373 
 1374         ad_write(sc, SP_LOWER_BASE_COUNT, blksize & 0xff);
 1375         ad_write(sc, SP_UPPER_BASE_COUNT, (blksize >> 8) & 0xff);
 1376 
 1377         reg = ad_read(sc, SP_INTERFACE_CONFIG);
 1378         ad_write(sc, SP_INTERFACE_CONFIG, (PLAYBACK_ENABLE | reg));
 1379 
 1380 #ifdef AUDIO_DEBUG
 1381         if (ad1848debug > 1)
 1382                 printf("ad1848_trigger_output: started playback\n");
 1383 #endif
 1384         mtx_leave(&audio_lock);
 1385         return 0;
 1386 }
 1387 
 1388 int
 1389 ad1848_intr(void *arg)
 1390 {
 1391         struct ad1848_softc *sc = arg;
 1392         int retval = 0;
 1393         u_char status;
 1394 
 1395         mtx_enter(&audio_lock);
 1396         /* Get intr status */
 1397         status = ADREAD(sc, AD1848_STATUS);
 1398         
 1399 #ifdef AUDIO_DEBUG
 1400         if (ad1848debug > 1)
 1401                 printf("ad1848_intr: mode=%d pintr=%p prun=%d rintr=%p rrun=%d status=0x%x\n",
 1402                     sc->mode, sc->sc_pintr, sc->sc_playrun, sc->sc_rintr, sc->sc_recrun, status);
 1403 #endif
 1404 
 1405         /* Handle interrupt */
 1406         if ((status & INTERRUPT_STATUS) != 0) {
 1407                 if (sc->mode == 2) {
 1408                         status = ad_read(sc, CS_IRQ_STATUS);
 1409 #ifdef AUDIO_DEBUG
 1410                         if (ad1848debug > 2)
 1411                                 printf("ad1848_intr: cs_irq_status=0x%x (play=0x%x rec0x%x)\n",
 1412                                     status, CS_IRQ_PI, CS_IRQ_CI);
 1413 #endif
 1414                         if ((status & CS_IRQ_PI) && sc->sc_playrun) {
 1415                                 (*sc->sc_pintr)(sc->sc_parg);
 1416                                 retval = 1;
 1417                         }
 1418                         if ((status & CS_IRQ_CI) && sc->sc_recrun) {
 1419                                 (*sc->sc_rintr)(sc->sc_rarg);
 1420                                 retval = 1;
 1421                         }
 1422                 } else {
 1423                         if (sc->sc_playrun) {
 1424                                 (*sc->sc_pintr)(sc->sc_parg);
 1425                                 retval = 1;
 1426                         } else if (sc->sc_recrun) {
 1427                                 (*sc->sc_rintr)(sc->sc_rarg);
 1428                                 retval = 1;
 1429                         }
 1430                 }
 1431                 /* clear interrupt */
 1432                 ADWRITE(sc, AD1848_STATUS, 0);
 1433         }
 1434         mtx_leave(&audio_lock);
 1435         return(retval);
 1436 }
 1437 
 1438 void *
 1439 ad1848_malloc(void *addr, int direction, size_t size, int pool, int flags)
 1440 {
 1441         struct ad1848_softc *sc = addr;
 1442         int drq;
 1443 
 1444         if (direction == AUMODE_PLAY)
 1445                 drq = sc->sc_drq;
 1446         else
 1447                 drq = sc->sc_recdrq;
 1448 
 1449         return isa_malloc(sc->sc_isa, drq, size, pool, flags);
 1450 }
 1451 
 1452 void
 1453 ad1848_free(void *addr, void *ptr, int pool)
 1454 {
 1455         isa_free(ptr, pool);
 1456 }
 1457 
 1458 size_t
 1459 ad1848_round(void *addr, int direction, size_t size)
 1460 {
 1461         if (size > MAX_ISADMA)
 1462                 size = MAX_ISADMA;
 1463         return size;
 1464 }

Cache object: dfcc031b14c70b0f87ea2b69966e3737


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