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/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 /*      $NetBSD: ad1848.c,v 1.20 2005/01/15 15:19:52 kent Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Ken Hornstein and John Kohl.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 /*
   39  * Copyright (c) 1994 John Brezak
   40  * Copyright (c) 1991-1993 Regents of the University of California.
   41  * All rights reserved.
   42  *
   43  * Redistribution and use in source and binary forms, with or without
   44  * modification, are permitted provided that the following conditions
   45  * are met:
   46  * 1. Redistributions of source code must retain the above copyright
   47  *    notice, this list of conditions and the following disclaimer.
   48  * 2. Redistributions in binary form must reproduce the above copyright
   49  *    notice, this list of conditions and the following disclaimer in the
   50  *    documentation and/or other materials provided with the distribution.
   51  * 3. All advertising materials mentioning features or use of this software
   52  *    must display the following acknowledgement:
   53  *      This product includes software developed by the Computer Systems
   54  *      Engineering Group at Lawrence Berkeley Laboratory.
   55  * 4. Neither the name of the University nor of the Laboratory may be used
   56  *    to endorse or promote products derived from this software without
   57  *    specific prior written permission.
   58  *
   59  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   60  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   61  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   62  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   63  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   64  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   65  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   69  * SUCH DAMAGE.
   70  *
   71  */
   72 
   73 /*
   74  * Copyright by Hannu Savolainen 1994
   75  *
   76  * Redistribution and use in source and binary forms, with or without
   77  * modification, are permitted provided that the following conditions are
   78  * met: 1. Redistributions of source code must retain the above copyright
   79  * notice, this list of conditions and the following disclaimer. 2.
   80  * Redistributions in binary form must reproduce the above copyright notice,
   81  * this list of conditions and the following disclaimer in the documentation
   82  * and/or other materials provided with the distribution.
   83  *
   84  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
   85  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   86  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   87  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   88  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   89  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   90  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   91  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   92  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   93  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   94  * SUCH DAMAGE.
   95  *
   96  */
   97 /*
   98  * Portions of this code are from the VOXware support for the ad1848
   99  * by Hannu Savolainen <hannu@voxware.pp.fi>
  100  *
  101  * Portions also supplied from the SoundBlaster driver for NetBSD.
  102  */
  103 
  104 #include <sys/cdefs.h>
  105 __KERNEL_RCSID(0, "$NetBSD: ad1848.c,v 1.20 2005/01/15 15:19:52 kent Exp $");
  106 
  107 #include <sys/param.h>
  108 #include <sys/systm.h>
  109 #include <sys/errno.h>
  110 #include <sys/ioctl.h>
  111 #include <sys/device.h>
  112 #include <sys/fcntl.h>
  113 /*#include <sys/syslog.h>*/
  114 /*#include <sys/proc.h>*/
  115 
  116 #include <machine/cpu.h>
  117 #include <machine/bus.h>
  118 
  119 #include <sys/audioio.h>
  120 
  121 #include <dev/audio_if.h>
  122 #include <dev/auconv.h>
  123 
  124 #include <dev/ic/ad1848reg.h>
  125 #include <dev/ic/cs4231reg.h>
  126 #include <dev/ic/cs4237reg.h>
  127 #include <dev/ic/ad1848var.h>
  128 #if 0
  129 #include <dev/isa/cs4231var.h>
  130 #endif
  131 
  132 /*
  133  * AD1845 on some machines don't match the AD1845 doc
  134  * and defining AD1845_HACK to 1 works around the problems.
  135  * options AD1845_HACK=0  should work if you have ``correct'' one.
  136  */
  137 #ifndef AD1845_HACK
  138 #define AD1845_HACK     1       /* weird mixer, can't play slinear_be */
  139 #endif
  140 
  141 #ifdef AUDIO_DEBUG
  142 #define DPRINTF(x)      if (ad1848debug) printf x
  143 int     ad1848debug = 0;
  144 #else
  145 #define DPRINTF(x)
  146 #endif
  147 
  148 /*
  149  * Initial values for the indirect registers of CS4248/AD1848.
  150  */
  151 static const int ad1848_init_values[] = {
  152     GAIN_12|INPUT_MIC_GAIN_ENABLE,      /* Left Input Control */
  153     GAIN_12|INPUT_MIC_GAIN_ENABLE,      /* Right Input Control */
  154     ATTEN_12,                           /* Left Aux #1 Input Control */
  155     ATTEN_12,                           /* Right Aux #1 Input Control */
  156     ATTEN_12,                           /* Left Aux #2 Input Control */
  157     ATTEN_12,                           /* Right Aux #2 Input Control */
  158     /* bits 5-0 are attenuation select */
  159     ATTEN_12,                           /* Left DAC output Control */
  160     ATTEN_12,                           /* Right DAC output Control */
  161     CLOCK_XTAL1|FMT_PCM8,               /* Clock and Data Format */
  162     SINGLE_DMA|AUTO_CAL_ENABLE,         /* Interface Config */
  163     INTERRUPT_ENABLE,                   /* Pin control */
  164     0x00,                               /* Test and Init */
  165     MODE2,                              /* Misc control */
  166     ATTEN_0<<2,                         /* Digital Mix Control */
  167     0,                                  /* Upper base Count */
  168     0,                                  /* Lower base Count */
  169 
  170     /* These are for CS4231 &c. only (additional registers): */
  171     0,                                  /* Alt feature 1 */
  172     0,                                  /* Alt feature 2 */
  173     ATTEN_12,                           /* Left line in */
  174     ATTEN_12,                           /* Right line in */
  175     0,                                  /* Timer low */
  176     0,                                  /* Timer high */
  177     0,                                  /* unused */
  178     0,                                  /* unused */
  179     0,                                  /* IRQ status */
  180     0,                                  /* unused */
  181                         /* Mono input (a.k.a speaker) (mic) Control */
  182     MONO_INPUT_MUTE|ATTEN_6,            /* mute speaker by default */
  183     0,                                  /* unused */
  184     0,                                  /* record format */
  185     0,                                  /* Crystal Clock Select */
  186     0,                                  /* upper record count */
  187     0                                   /* lower record count */
  188 };
  189 
  190 
  191 int
  192 ad1848_to_vol(mixer_ctrl_t *cp, struct ad1848_volume *vol)
  193 {
  194 
  195         if (cp->un.value.num_channels == 1) {
  196                 vol->left =
  197                 vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
  198                 return 1;
  199         }
  200         else if (cp->un.value.num_channels == 2) {
  201                 vol->left  = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
  202                 vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
  203                 return 1;
  204         }
  205         return 0;
  206 }
  207 
  208 int
  209 ad1848_from_vol(mixer_ctrl_t *cp, struct ad1848_volume *vol)
  210 {
  211 
  212         if (cp->un.value.num_channels == 1) {
  213                 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left;
  214                 return 1;
  215         }
  216         else if (cp->un.value.num_channels == 2) {
  217                 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left;
  218                 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right;
  219                 return 1;
  220         }
  221         return 0;
  222 }
  223 
  224 
  225 __inline int
  226 ad_read(struct ad1848_softc *sc, int reg)
  227 {
  228         int x;
  229 
  230         ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit);
  231         x = ADREAD(sc, AD1848_IDATA);
  232         /*  printf("(%02x<-%02x) ", reg|sc->MCE_bit, x); */
  233         return x;
  234 }
  235 
  236 __inline void
  237 ad_write(struct ad1848_softc *sc, int reg, int data)
  238 {
  239 
  240         ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit);
  241         ADWRITE(sc, AD1848_IDATA, data & 0xff);
  242         /* printf("(%02x->%02x) ", reg|sc->MCE_bit, data); */
  243 }
  244 
  245 /*
  246  * extended registers (mode 3) require an additional level of
  247  * indirection through CS_XREG (I23).
  248  */
  249 
  250 __inline int
  251 ad_xread(struct ad1848_softc *sc, int reg)
  252 {
  253         int x;
  254 
  255         ADWRITE(sc, AD1848_IADDR, CS_XREG | sc->MCE_bit);
  256         ADWRITE(sc, AD1848_IDATA, (reg | ALT_F3_XRAE) & 0xff);
  257         x = ADREAD(sc, AD1848_IDATA);
  258 
  259         return x;
  260 }
  261 
  262 __inline void
  263 ad_xwrite(struct ad1848_softc *sc, int reg, int val)
  264 {
  265 
  266         ADWRITE(sc, AD1848_IADDR, CS_XREG | sc->MCE_bit);
  267         ADWRITE(sc, AD1848_IDATA, (reg | ALT_F3_XRAE) & 0xff);
  268         ADWRITE(sc, AD1848_IDATA, val & 0xff);
  269 }
  270 
  271 static void
  272 ad_set_MCE(struct ad1848_softc *sc, int state)
  273 {
  274 
  275         if (state)
  276                 sc->MCE_bit = MODE_CHANGE_ENABLE;
  277         else
  278                 sc->MCE_bit = 0;
  279         ADWRITE(sc, AD1848_IADDR, sc->MCE_bit);
  280 }
  281 
  282 static void
  283 wait_for_calibration(struct ad1848_softc *sc)
  284 {
  285         int timeout;
  286 
  287         DPRINTF(("ad1848: Auto calibration started.\n"));
  288         /*
  289          * Wait until the auto calibration process has finished.
  290          *
  291          * 1) Wait until the chip becomes ready (reads don't return 0x80).
  292          * 2) Wait until the ACI bit of I11 gets on and then off.
  293          *    Because newer chips are fast we may never see the ACI
  294          *    bit go on.  Just delay a little instead.
  295          */
  296         timeout = 10000;
  297         while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) {
  298                 delay(10);
  299                 timeout--;
  300         }
  301         if (timeout <= 0)
  302                 DPRINTF(("ad1848: Auto calibration timed out(1).\n"));
  303 
  304         /* Set register addr */
  305         ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT);
  306         /* Wait for address to appear when read back. */
  307         timeout = 100000;
  308         while (timeout > 0 &&
  309                (ADREAD(sc, AD1848_IADDR)&SP_IADDR_MASK) != SP_TEST_AND_INIT) {
  310                 delay(10);
  311                 timeout--;
  312         }
  313         if (timeout <= 0)
  314                 DPRINTF(("ad1848: Auto calibration timed out(1.5).\n"));
  315 
  316         if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) {
  317                 if (sc->mode > 1) {
  318                         /* A new chip, just delay a little. */
  319                         delay(100);     /* XXX what should it be? */
  320                 } else {
  321                         timeout = 10000;
  322                         while (timeout > 0 &&
  323                                !(ad_read(sc, SP_TEST_AND_INIT) &
  324                                  AUTO_CAL_IN_PROG)) {
  325                                 delay(10);
  326                                 timeout--;
  327                         }
  328                         if (timeout <= 0)
  329                                 DPRINTF(("ad1848: Auto calibration timed out(2).\n"));
  330                 }
  331         }
  332 
  333         timeout = 10000;
  334         while (timeout > 0 &&
  335                ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG) {
  336                 delay(10);
  337                 timeout--;
  338         }
  339         if (timeout <= 0)
  340                 DPRINTF(("ad1848: Auto calibration timed out(3).\n"));
  341 }
  342 
  343 #ifdef AUDIO_DEBUG
  344 void
  345 ad1848_dump_regs(struct ad1848_softc *sc)
  346 {
  347         int i;
  348         u_char r;
  349 
  350         printf("ad1848 status=%02x", ADREAD(sc, AD1848_STATUS));
  351         printf(" regs: ");
  352         for (i = 0; i < 16; i++) {
  353                 r = ad_read(sc, i);
  354                 printf("%02x ", r);
  355         }
  356         if (sc->mode >= 2) {
  357                 for (i = 16; i < 32; i++) {
  358                         r = ad_read(sc, i);
  359                         printf("%02x ", r);
  360                 }
  361         }
  362         printf("\n");
  363 }
  364 #endif /* AUDIO_DEBUG */
  365 
  366 
  367 /*
  368  * Attach hardware to driver, attach hardware driver to audio
  369  * pseudo-device driver .
  370  */
  371 void
  372 ad1848_attach(struct ad1848_softc *sc)
  373 {
  374         static struct ad1848_volume vol_mid = {220, 220};
  375         static struct ad1848_volume vol_0   = {0, 0};
  376         int i;
  377         int timeout;
  378 
  379         /* Initialize the ad1848... */
  380         for (i = 0; i < 0x10; i++) {
  381                 ad_write(sc, i, ad1848_init_values[i]);
  382                 timeout = 100000;
  383                 while (timeout > 0 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT)
  384                         timeout--;
  385         }
  386         /* ...and additional CS4231 stuff too */
  387         if (sc->mode >= 2) {
  388                 ad_write(sc, SP_INTERFACE_CONFIG, 0); /* disable SINGLE_DMA */
  389                 for (i = 0x10; i < 0x20; i++)
  390                         if (ad1848_init_values[i] != 0) {
  391                                 ad_write(sc, i, ad1848_init_values[i]);
  392                                 timeout = 100000;
  393                                 while (timeout > 0 &&
  394                                        ADREAD(sc, AD1848_IADDR) & SP_IN_INIT)
  395                                         timeout--;
  396                         }
  397         }
  398         ad1848_reset(sc);
  399 
  400         /* Set default gains */
  401         ad1848_set_rec_gain(sc, &vol_mid);
  402         ad1848_set_channel_gain(sc, AD1848_DAC_CHANNEL, &vol_mid);
  403         ad1848_set_channel_gain(sc, AD1848_MONITOR_CHANNEL, &vol_0);
  404         ad1848_set_channel_gain(sc, AD1848_AUX1_CHANNEL, &vol_mid);     /* CD volume */
  405         sc->mute[AD1848_MONITOR_CHANNEL] = MUTE_ALL;
  406         if (sc->mode >= 2
  407 #if AD1845_HACK
  408             && sc->is_ad1845 == 0
  409 #endif
  410                 ) {
  411                 ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_mid); /* CD volume */
  412                 ad1848_set_channel_gain(sc, AD1848_LINE_CHANNEL, &vol_mid);
  413                 ad1848_set_channel_gain(sc, AD1848_MONO_CHANNEL, &vol_0);
  414                 sc->mute[AD1848_MONO_CHANNEL] = MUTE_ALL;
  415         } else
  416                 ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_0);
  417 
  418         /* Set default port */
  419         ad1848_set_rec_port(sc, MIC_IN_PORT);
  420 
  421         printf(": %s", sc->chip_name);
  422 }
  423 
  424 /*
  425  * Various routines to interface to higher level audio driver
  426  */
  427 static const struct ad1848_mixerinfo {
  428         int  left_reg;
  429         int  right_reg;
  430         int  atten_bits;
  431         int  atten_mask;
  432 } mixer_channel_info[] =
  433 {
  434   { SP_LEFT_AUX2_CONTROL, SP_RIGHT_AUX2_CONTROL, AUX_INPUT_ATTEN_BITS,
  435     AUX_INPUT_ATTEN_MASK },
  436   { SP_LEFT_AUX1_CONTROL, SP_RIGHT_AUX1_CONTROL, AUX_INPUT_ATTEN_BITS,
  437     AUX_INPUT_ATTEN_MASK },
  438   { SP_LEFT_OUTPUT_CONTROL, SP_RIGHT_OUTPUT_CONTROL,
  439     OUTPUT_ATTEN_BITS, OUTPUT_ATTEN_MASK },
  440   { CS_LEFT_LINE_CONTROL, CS_RIGHT_LINE_CONTROL, LINE_INPUT_ATTEN_BITS,
  441     LINE_INPUT_ATTEN_MASK },
  442   { CS_MONO_IO_CONTROL, 0, MONO_INPUT_ATTEN_BITS, MONO_INPUT_ATTEN_MASK },
  443   { CS_MONO_IO_CONTROL, 0, 0, 0 },
  444   { SP_DIGITAL_MIX, 0, OUTPUT_ATTEN_BITS, MIX_ATTEN_MASK }
  445 };
  446 
  447 /*
  448  *  This function doesn't set the mute flags but does use them.
  449  *  The mute flags reflect the mutes that have been applied by the user.
  450  *  However, the driver occasionally wants to mute devices (e.g. when chaing
  451  *  sampling rate). These operations should not affect the mute flags.
  452  */
  453 
  454 void
  455 ad1848_mute_channel(struct ad1848_softc *sc, int device, int mute)
  456 {
  457         u_char reg;
  458 
  459         reg = ad_read(sc, mixer_channel_info[device].left_reg);
  460 
  461         if (mute & MUTE_LEFT) {
  462                 if (device == AD1848_MONITOR_CHANNEL) {
  463                         if (sc->open_mode & FREAD)
  464                                 ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 0);
  465                         ad_write(sc, mixer_channel_info[device].left_reg,
  466                                  reg & ~DIGITAL_MIX1_ENABLE);
  467                 } else if (device == AD1848_OUT_CHANNEL)
  468                         ad_write(sc, mixer_channel_info[device].left_reg,
  469                                  reg | MONO_OUTPUT_MUTE);
  470                 else
  471                         ad_write(sc, mixer_channel_info[device].left_reg,
  472                                  reg | 0x80);
  473         } else if (!(sc->mute[device] & MUTE_LEFT)) {
  474                 if (device == AD1848_MONITOR_CHANNEL) {
  475                         ad_write(sc, mixer_channel_info[device].left_reg,
  476                                  reg | DIGITAL_MIX1_ENABLE);
  477                         if (sc->open_mode & FREAD)
  478                                 ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 1);
  479                 } else if (device == AD1848_OUT_CHANNEL)
  480                         ad_write(sc, mixer_channel_info[device].left_reg,
  481                                  reg & ~MONO_OUTPUT_MUTE);
  482                 else
  483                         ad_write(sc, mixer_channel_info[device].left_reg,
  484                                  reg & ~0x80);
  485         }
  486 
  487         if (!mixer_channel_info[device].right_reg)
  488                 return;
  489 
  490         reg = ad_read(sc, mixer_channel_info[device].right_reg);
  491 
  492         if (mute & MUTE_RIGHT) {
  493                 ad_write(sc, mixer_channel_info[device].right_reg, reg | 0x80);
  494         } else if (!(sc->mute[device] & MUTE_RIGHT)) {
  495                 ad_write(sc, mixer_channel_info[device].right_reg, reg &~0x80);
  496         }
  497 }
  498 
  499 int
  500 ad1848_set_channel_gain(struct ad1848_softc *sc, int device,
  501     struct ad1848_volume *gp)
  502 {
  503         const struct ad1848_mixerinfo *info;
  504         u_char reg;
  505         u_int atten;
  506 
  507         info = &mixer_channel_info[device];
  508         sc->gains[device] = *gp;
  509 
  510         atten = (AUDIO_MAX_GAIN - gp->left) * (info->atten_bits + 1) /
  511                 (AUDIO_MAX_GAIN + 1);
  512 
  513         reg = ad_read(sc, info->left_reg) & (info->atten_mask);
  514         if (device == AD1848_MONITOR_CHANNEL)
  515                 reg |= ((atten & info->atten_bits) << 2);
  516         else
  517                 reg |= ((atten & info->atten_bits));
  518 
  519         ad_write(sc, info->left_reg, reg);
  520 
  521         if (!info->right_reg)
  522                 return 0;
  523 
  524         atten = (AUDIO_MAX_GAIN - gp->right) * (info->atten_bits + 1) /
  525                 (AUDIO_MAX_GAIN + 1);
  526         reg = ad_read(sc, info->right_reg);
  527         reg &= info->atten_mask;
  528         ad_write(sc, info->right_reg, (atten & info->atten_bits) | reg);
  529 
  530         return 0;
  531 }
  532 
  533 int
  534 ad1848_get_device_gain(struct ad1848_softc *sc, int device,
  535     struct ad1848_volume *gp)
  536 {
  537 
  538         *gp = sc->gains[device];
  539         return 0;
  540 }
  541 
  542 int
  543 ad1848_get_rec_gain(struct ad1848_softc *sc, struct ad1848_volume *gp)
  544 {
  545 
  546         *gp = sc->rec_gain;
  547         return 0;
  548 }
  549 
  550 int
  551 ad1848_set_rec_gain(struct ad1848_softc *sc, struct ad1848_volume *gp)
  552 {
  553         u_char reg, gain;
  554 
  555         DPRINTF(("ad1848_set_rec_gain: %d:%d\n", gp->left, gp->right));
  556 
  557         sc->rec_gain = *gp;
  558 
  559         gain = (gp->left * (GAIN_22_5 + 1)) / (AUDIO_MAX_GAIN + 1);
  560         reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
  561         reg &= INPUT_GAIN_MASK;
  562         ad_write(sc, SP_LEFT_INPUT_CONTROL, (gain & 0x0f) | reg);
  563 
  564         gain = (gp->right * (GAIN_22_5 + 1)) / (AUDIO_MAX_GAIN + 1);
  565         reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL);
  566         reg &= INPUT_GAIN_MASK;
  567         ad_write(sc, SP_RIGHT_INPUT_CONTROL, (gain & 0x0f) | reg);
  568 
  569         return 0;
  570 }
  571 
  572 void
  573 ad1848_mute_wave_output(struct ad1848_softc *sc, int mute, int set)
  574 {
  575         int m;
  576 
  577         DPRINTF(("ad1848_mute_wave_output: %d, %d\n", mute, set));
  578 
  579         if (mute == WAVE_MUTE2_INIT) {
  580                 sc->wave_mute_status = 0;
  581                 mute = WAVE_MUTE2;
  582         }
  583         if (set)
  584                 m = sc->wave_mute_status |= mute;
  585         else
  586                 m = sc->wave_mute_status &= ~mute;
  587 
  588         if (m & WAVE_MUTE0 || ((m & WAVE_UNMUTE1) == 0 && m & WAVE_MUTE2))
  589                 ad1848_mute_channel(sc, AD1848_DAC_CHANNEL, MUTE_ALL);
  590         else
  591                 ad1848_mute_channel(sc, AD1848_DAC_CHANNEL,
  592                                             sc->mute[AD1848_DAC_CHANNEL]);
  593 }
  594 
  595 int
  596 ad1848_set_mic_gain(struct ad1848_softc *sc, struct ad1848_volume *gp)
  597 {
  598         u_char reg;
  599 
  600         DPRINTF(("cs4231_set_mic_gain: %d\n", gp->left));
  601 
  602         if (gp->left > AUDIO_MAX_GAIN/2) {
  603                 sc->mic_gain_on = 1;
  604                 reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
  605                 ad_write(sc, SP_LEFT_INPUT_CONTROL,
  606                          reg | INPUT_MIC_GAIN_ENABLE);
  607         } else {
  608                 sc->mic_gain_on = 0;
  609                 reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
  610                 ad_write(sc, SP_LEFT_INPUT_CONTROL,
  611                          reg & ~INPUT_MIC_GAIN_ENABLE);
  612         }
  613 
  614         return 0;
  615 }
  616 
  617 int
  618 ad1848_get_mic_gain(struct ad1848_softc *sc, struct ad1848_volume *gp)
  619 {
  620         if (sc->mic_gain_on)
  621                 gp->left = gp->right = AUDIO_MAX_GAIN;
  622         else
  623                 gp->left = gp->right = AUDIO_MIN_GAIN;
  624         return 0;
  625 }
  626 
  627 static ad1848_devmap_t *
  628 ad1848_mixer_find_dev(ad1848_devmap_t *map, int cnt, mixer_ctrl_t *cp)
  629 {
  630         int i;
  631 
  632         for (i = 0; i < cnt; i++) {
  633                 if (map[i].id == cp->dev) {
  634                         return (&map[i]);
  635                 }
  636         }
  637         return 0;
  638 }
  639 
  640 int
  641 ad1848_mixer_get_port(struct ad1848_softc *ac, struct ad1848_devmap *map,
  642     int cnt, mixer_ctrl_t *cp)
  643 {
  644         ad1848_devmap_t *entry;
  645         struct ad1848_volume vol;
  646         int error;
  647         int dev;
  648 
  649         error = EINVAL;
  650         if (!(entry = ad1848_mixer_find_dev(map, cnt, cp)))
  651                 return ENXIO;
  652 
  653         dev = entry->dev;
  654 
  655         switch (entry->kind) {
  656         case AD1848_KIND_LVL:
  657                 if (cp->type != AUDIO_MIXER_VALUE)
  658                         break;
  659 
  660                 if (dev < AD1848_AUX2_CHANNEL ||
  661                     dev > AD1848_MONITOR_CHANNEL)
  662                         break;
  663 
  664                 if (cp->un.value.num_channels != 1 &&
  665                     mixer_channel_info[dev].right_reg == 0)
  666                         break;
  667 
  668                 error = ad1848_get_device_gain(ac, dev, &vol);
  669                 if (!error)
  670                         ad1848_from_vol(cp, &vol);
  671 
  672                 break;
  673 
  674         case AD1848_KIND_MUTE:
  675                 if (cp->type != AUDIO_MIXER_ENUM) break;
  676 
  677                 cp->un.ord = ac->mute[dev] ? 1 : 0;
  678                 error = 0;
  679                 break;
  680 
  681         case AD1848_KIND_RECORDGAIN:
  682                 if (cp->type != AUDIO_MIXER_VALUE) break;
  683 
  684                 error = ad1848_get_rec_gain(ac, &vol);
  685                 if (!error)
  686                         ad1848_from_vol(cp, &vol);
  687 
  688                 break;
  689 
  690         case AD1848_KIND_MICGAIN:
  691                 if (cp->type != AUDIO_MIXER_VALUE) break;
  692 
  693                 error = ad1848_get_mic_gain(ac, &vol);
  694                 if (!error)
  695                         ad1848_from_vol(cp, &vol);
  696 
  697                 break;
  698 
  699         case AD1848_KIND_RECORDSOURCE:
  700                 if (cp->type != AUDIO_MIXER_ENUM) break;
  701                 cp->un.ord = ad1848_get_rec_port(ac);
  702                 error = 0;
  703                 break;
  704 
  705         default:
  706                 printf ("Invalid kind\n");
  707                 break;
  708         }
  709 
  710         return error;
  711 }
  712 
  713 int
  714 ad1848_mixer_set_port(struct ad1848_softc *ac, struct ad1848_devmap *map,
  715     int cnt, mixer_ctrl_t *cp)
  716 {
  717         ad1848_devmap_t *entry;
  718         struct ad1848_volume vol;
  719         int error;
  720         int dev;
  721 
  722         error = EINVAL;
  723         if (!(entry = ad1848_mixer_find_dev(map, cnt, cp)))
  724                 return ENXIO;
  725 
  726         dev = entry->dev;
  727 
  728         switch (entry->kind) {
  729         case AD1848_KIND_LVL:
  730                 if (cp->type != AUDIO_MIXER_VALUE)
  731                         break;
  732 
  733                 if (dev < AD1848_AUX2_CHANNEL ||
  734                     dev > AD1848_MONITOR_CHANNEL)
  735                         break;
  736 
  737                 if (cp->un.value.num_channels != 1 &&
  738                     mixer_channel_info[dev].right_reg == 0)
  739                         break;
  740 
  741                 ad1848_to_vol(cp, &vol);
  742                 error = ad1848_set_channel_gain(ac, dev, &vol);
  743                 break;
  744 
  745         case AD1848_KIND_MUTE:
  746                 if (cp->type != AUDIO_MIXER_ENUM) break;
  747 
  748                 ac->mute[dev] = (cp->un.ord ? MUTE_ALL : 0);
  749                 ad1848_mute_channel(ac, dev, ac->mute[dev]);
  750                 error = 0;
  751                 break;
  752 
  753         case AD1848_KIND_RECORDGAIN:
  754                 if (cp->type != AUDIO_MIXER_VALUE) break;
  755 
  756                 ad1848_to_vol(cp, &vol);
  757                 error = ad1848_set_rec_gain(ac, &vol);
  758                 break;
  759 
  760         case AD1848_KIND_MICGAIN:
  761                 if (cp->type != AUDIO_MIXER_VALUE) break;
  762 
  763                 ad1848_to_vol(cp, &vol);
  764                 error = ad1848_set_mic_gain(ac, &vol);
  765                 break;
  766 
  767         case AD1848_KIND_RECORDSOURCE:
  768                 if (cp->type != AUDIO_MIXER_ENUM) break;
  769 
  770                 error = ad1848_set_rec_port(ac,  cp->un.ord);
  771                 break;
  772 
  773         default:
  774                 printf ("Invalid kind\n");
  775                 break;
  776         }
  777 
  778         return error;
  779 }
  780 
  781 int
  782 ad1848_query_encoding(void *addr, struct audio_encoding *fp)
  783 {
  784         struct ad1848_softc *sc;
  785 
  786         sc = addr;
  787         switch (fp->index) {
  788         case 0:
  789                 strcpy(fp->name, AudioEmulaw);
  790                 fp->encoding = AUDIO_ENCODING_ULAW;
  791                 fp->precision = 8;
  792                 fp->flags = 0;
  793                 break;
  794         case 1:
  795                 strcpy(fp->name, AudioEalaw);
  796                 fp->encoding = AUDIO_ENCODING_ALAW;
  797                 fp->precision = 8;
  798                 fp->flags = 0;
  799                 break;
  800         case 2:
  801                 strcpy(fp->name, AudioEslinear_le);
  802                 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
  803                 fp->precision = 16;
  804                 fp->flags = 0;
  805                 break;
  806         case 3:
  807                 strcpy(fp->name, AudioEulinear);
  808                 fp->encoding = AUDIO_ENCODING_ULINEAR;
  809                 fp->precision = 8;
  810                 fp->flags = 0;
  811                 break;
  812 
  813         case 4: /* only on CS4231 */
  814                 strcpy(fp->name, AudioEslinear_be);
  815                 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
  816                 fp->precision = 16;
  817                 fp->flags = sc->mode == 1
  818 #if AD1845_HACK
  819                     || sc->is_ad1845
  820 #endif
  821                         ? AUDIO_ENCODINGFLAG_EMULATED : 0;
  822                 break;
  823 
  824                 /* emulate some modes */
  825         case 5:
  826                 strcpy(fp->name, AudioEslinear);
  827                 fp->encoding = AUDIO_ENCODING_SLINEAR;
  828                 fp->precision = 8;
  829                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  830                 break;
  831         case 6:
  832                 strcpy(fp->name, AudioEulinear_le);
  833                 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
  834                 fp->precision = 16;
  835                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  836                 break;
  837         case 7:
  838                 strcpy(fp->name, AudioEulinear_be);
  839                 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
  840                 fp->precision = 16;
  841                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  842                 break;
  843 
  844         case 8: /* only on CS4231 */
  845                 if (sc->mode == 1 || sc->is_ad1845)
  846                         return EINVAL;
  847                 strcpy(fp->name, AudioEadpcm);
  848                 fp->encoding = AUDIO_ENCODING_ADPCM;
  849                 fp->precision = 4;
  850                 fp->flags = 0;
  851                 break;
  852         default:
  853                 return EINVAL;
  854                 /*NOTREACHED*/
  855         }
  856         return 0;
  857 }
  858 
  859 int
  860 ad1848_set_params(void *addr, int setmode, int usemode, audio_params_t *p,
  861     audio_params_t *r, stream_filter_list_t *pfil, stream_filter_list_t *rfil)
  862 {
  863         audio_params_t phw, rhw;
  864         struct ad1848_softc *sc;
  865         int error, bits, enc;
  866         stream_filter_factory_t *pswcode;
  867         stream_filter_factory_t *rswcode;
  868 
  869         DPRINTF(("ad1848_set_params: %u %u %u %u\n",
  870                  p->encoding, p->precision, p->channels, p->sample_rate));
  871 
  872         sc = addr;
  873         enc = p->encoding;
  874         pswcode = rswcode = 0;
  875         phw = *p;
  876         rhw = *r;
  877         switch (enc) {
  878         case AUDIO_ENCODING_SLINEAR_LE:
  879                 if (p->precision == 8) {
  880                         enc = AUDIO_ENCODING_ULINEAR_LE;
  881                         phw.encoding = AUDIO_ENCODING_ULINEAR_LE;
  882                         rhw.encoding = AUDIO_ENCODING_ULINEAR_LE;
  883                         pswcode = rswcode = change_sign8;
  884                 }
  885                 break;
  886         case AUDIO_ENCODING_SLINEAR_BE:
  887                 if (p->precision == 16 && (sc->mode == 1
  888 #if AD1845_HACK
  889                     || sc->is_ad1845
  890 #endif
  891                         )) {
  892                         enc = AUDIO_ENCODING_SLINEAR_LE;
  893                         phw.encoding = AUDIO_ENCODING_SLINEAR_LE;
  894                         rhw.encoding = AUDIO_ENCODING_SLINEAR_LE;
  895                         pswcode = rswcode = swap_bytes;
  896                 }
  897                 break;
  898         case AUDIO_ENCODING_ULINEAR_LE:
  899                 if (p->precision == 16) {
  900                         enc = AUDIO_ENCODING_SLINEAR_LE;
  901                         phw.encoding = AUDIO_ENCODING_SLINEAR_LE;
  902                         rhw.encoding = AUDIO_ENCODING_SLINEAR_LE;
  903                         pswcode = rswcode = change_sign16;
  904                 }
  905                 break;
  906         case AUDIO_ENCODING_ULINEAR_BE:
  907                 if (p->precision == 16) {
  908                         if (sc->mode == 1
  909 #if AD1845_HACK
  910                             || sc->is_ad1845
  911 #endif
  912                                 ) {
  913                                 enc = AUDIO_ENCODING_SLINEAR_LE;
  914                                 phw.encoding = AUDIO_ENCODING_SLINEAR_LE;
  915                                 rhw.encoding = AUDIO_ENCODING_SLINEAR_LE;
  916                                 pswcode = swap_bytes_change_sign16;
  917                                 rswcode = swap_bytes_change_sign16;
  918                         } else {
  919                                 enc = AUDIO_ENCODING_SLINEAR_BE;
  920                                 phw.encoding = AUDIO_ENCODING_SLINEAR_BE;
  921                                 rhw.encoding = AUDIO_ENCODING_SLINEAR_BE;
  922                                 pswcode = rswcode = change_sign16;
  923                         }
  924                 }
  925                 break;
  926         }
  927         switch (enc) {
  928         case AUDIO_ENCODING_ULAW:
  929                 bits = FMT_ULAW >> 5;
  930                 break;
  931         case AUDIO_ENCODING_ALAW:
  932                 bits = FMT_ALAW >> 5;
  933                 break;
  934         case AUDIO_ENCODING_ADPCM:
  935                 bits = FMT_ADPCM >> 5;
  936                 break;
  937         case AUDIO_ENCODING_SLINEAR_LE:
  938                 if (p->precision == 16)
  939                         bits = FMT_TWOS_COMP >> 5;
  940                 else
  941                         return EINVAL;
  942                 break;
  943         case AUDIO_ENCODING_SLINEAR_BE:
  944                 if (p->precision == 16)
  945                         bits = FMT_TWOS_COMP_BE >> 5;
  946                 else
  947                         return EINVAL;
  948                 break;
  949         case AUDIO_ENCODING_ULINEAR_LE:
  950                 if (p->precision == 8)
  951                         bits = FMT_PCM8 >> 5;
  952                 else
  953                         return EINVAL;
  954                 break;
  955         default:
  956                 return EINVAL;
  957         }
  958 
  959         if (p->channels < 1 || p->channels > 2)
  960                 return EINVAL;
  961 
  962         error = ad1848_set_speed(sc, &p->sample_rate);
  963         if (error)
  964                 return error;
  965         phw.sample_rate = p->sample_rate;
  966 
  967         if (pswcode != NULL)
  968                 pfil->append(pfil, pswcode, &phw);
  969         if (rswcode != NULL)
  970                 rfil->append(rfil, rswcode, &rhw);
  971 
  972         sc->format_bits = bits;
  973         sc->channels = p->channels;
  974         sc->precision = p->precision;
  975         sc->need_commit = 1;
  976 
  977         DPRINTF(("ad1848_set_params succeeded, bits=%x\n", bits));
  978         return 0;
  979 }
  980 
  981 int
  982 ad1848_set_rec_port(struct ad1848_softc *sc, int port)
  983 {
  984         u_char inp, reg;
  985 
  986         DPRINTF(("ad1848_set_rec_port: 0x%x\n", port));
  987 
  988         if (port == MIC_IN_PORT)
  989                 inp = MIC_INPUT;
  990         else if (port == LINE_IN_PORT)
  991                 inp = LINE_INPUT;
  992         else if (port == DAC_IN_PORT)
  993                 inp = MIXED_DAC_INPUT;
  994         else if (sc->mode >= 2 && port == AUX1_IN_PORT)
  995                 inp = AUX_INPUT;
  996         else
  997                 return EINVAL;
  998 
  999         reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
 1000         reg &= INPUT_SOURCE_MASK;
 1001         ad_write(sc, SP_LEFT_INPUT_CONTROL, (inp|reg));
 1002 
 1003         reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL);
 1004         reg &= INPUT_SOURCE_MASK;
 1005         ad_write(sc, SP_RIGHT_INPUT_CONTROL, (inp|reg));
 1006 
 1007         sc->rec_port = port;
 1008 
 1009         return 0;
 1010 }
 1011 
 1012 int
 1013 ad1848_get_rec_port(struct ad1848_softc *sc)
 1014 {
 1015         return sc->rec_port;
 1016 }
 1017 
 1018 int
 1019 ad1848_round_blocksize(void *addr, int blk,
 1020     int mode, const audio_params_t *param)
 1021 {
 1022 
 1023         /* Round to a multiple of the biggest sample size. */
 1024         return blk &= -4;
 1025 }
 1026 
 1027 int
 1028 ad1848_open(void *addr, int flags)
 1029 {
 1030         struct ad1848_softc *sc;
 1031         u_char reg;
 1032 
 1033         sc = addr;
 1034         DPRINTF(("ad1848_open: sc=%p\n", sc));
 1035 
 1036         sc->open_mode = flags;
 1037 
 1038         /* Enable interrupts */
 1039         DPRINTF(("ad1848_open: enable intrs\n"));
 1040         reg = ad_read(sc, SP_PIN_CONTROL);
 1041         ad_write(sc, SP_PIN_CONTROL, reg | INTERRUPT_ENABLE);
 1042 
 1043         /* If recording && monitoring, the playback part is also used. */
 1044         if (flags & FREAD && sc->mute[AD1848_MONITOR_CHANNEL] == 0)
 1045                 ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 1);
 1046 
 1047 #ifdef AUDIO_DEBUG
 1048         if (ad1848debug)
 1049                 ad1848_dump_regs(sc);
 1050 #endif
 1051 
 1052         return 0;
 1053 }
 1054 
 1055 /*
 1056  * Close function is called at splaudio().
 1057  */
 1058 void
 1059 ad1848_close(void *addr)
 1060 {
 1061         struct ad1848_softc *sc;
 1062         u_char reg;
 1063 
 1064         sc = addr;
 1065         sc->open_mode = 0;
 1066 
 1067         ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 0);
 1068 
 1069         /* Disable interrupts */
 1070         DPRINTF(("ad1848_close: disable intrs\n"));
 1071         reg = ad_read(sc, SP_PIN_CONTROL);
 1072         ad_write(sc, SP_PIN_CONTROL, reg & ~INTERRUPT_ENABLE);
 1073 
 1074 #ifdef AUDIO_DEBUG
 1075         if (ad1848debug)
 1076                 ad1848_dump_regs(sc);
 1077 #endif
 1078 }
 1079 
 1080 /*
 1081  * Lower-level routines
 1082  */
 1083 int
 1084 ad1848_commit_settings(void *addr)
 1085 {
 1086         struct ad1848_softc *sc;
 1087         int timeout;
 1088         u_char fs;
 1089         int s;
 1090 
 1091         sc = addr;
 1092         if (!sc->need_commit)
 1093                 return 0;
 1094 
 1095         s = splaudio();
 1096 
 1097         ad1848_mute_wave_output(sc, WAVE_MUTE0, 1);
 1098 
 1099         ad_set_MCE(sc, 1);      /* Enables changes to the format select reg */
 1100 
 1101         fs = sc->speed_bits | (sc->format_bits << 5);
 1102 
 1103         if (sc->channels == 2)
 1104                 fs |= FMT_STEREO;
 1105 
 1106         /*
 1107          * OPL3-SA2 (YMF711) is sometimes busy here.
 1108          * Wait until it becomes ready.
 1109          */
 1110         for (timeout = 0;
 1111             timeout < 1000 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT; timeout++)
 1112                 delay(10);
 1113 
 1114         ad_write(sc, SP_CLOCK_DATA_FORMAT, fs);
 1115 
 1116         /*
 1117          * If mode >= 2 (CS4231), set I28 also.
 1118          * It's the capture format register.
 1119          */
 1120         if (sc->mode >= 2) {
 1121                 /*
 1122                  * Gravis Ultrasound MAX SDK sources says something about
 1123                  * errata sheets, with the implication that these inb()s
 1124                  * are necessary.
 1125                  */
 1126                 (void)ADREAD(sc, AD1848_IDATA);
 1127                 (void)ADREAD(sc, AD1848_IDATA);
 1128                 /* Write to I8 starts resynchronization. Wait for completion. */
 1129                 timeout = 100000;
 1130                 while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
 1131                         timeout--;
 1132 
 1133                 ad_write(sc, CS_REC_FORMAT, fs);
 1134                 (void)ADREAD(sc, AD1848_IDATA);
 1135                 (void)ADREAD(sc, AD1848_IDATA);
 1136                 /* Now wait for resync for capture side of the house */
 1137         }
 1138         /*
 1139          * Write to I8 starts resynchronization. Wait until it completes.
 1140          */
 1141         timeout = 100000;
 1142         while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) {
 1143                 delay(10);
 1144                 timeout--;
 1145         }
 1146 
 1147         if (ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
 1148                 printf("ad1848_commit: Auto calibration timed out\n");
 1149 
 1150         /*
 1151          * Starts the calibration process and
 1152          * enters playback mode after it.
 1153          */
 1154         ad_set_MCE(sc, 0);
 1155         wait_for_calibration(sc);
 1156 
 1157         ad1848_mute_wave_output(sc, WAVE_MUTE0, 0);
 1158 
 1159         splx(s);
 1160 
 1161         sc->need_commit = 0;
 1162         return 0;
 1163 }
 1164 
 1165 void
 1166 ad1848_reset(struct ad1848_softc *sc)
 1167 {
 1168         u_char r;
 1169 
 1170         DPRINTF(("ad1848_reset\n"));
 1171 
 1172         /* Clear the PEN and CEN bits */
 1173         r = ad_read(sc, SP_INTERFACE_CONFIG);
 1174         r &= ~(CAPTURE_ENABLE | PLAYBACK_ENABLE);
 1175         ad_write(sc, SP_INTERFACE_CONFIG, r);
 1176 
 1177         if (sc->mode >= 2) {
 1178                 ADWRITE(sc, AD1848_IADDR, CS_IRQ_STATUS);
 1179                 ADWRITE(sc, AD1848_IDATA, 0);
 1180         }
 1181         /* Clear interrupt status */
 1182         ADWRITE(sc, AD1848_STATUS, 0);
 1183 #ifdef AUDIO_DEBUG
 1184         if (ad1848debug)
 1185                 ad1848_dump_regs(sc);
 1186 #endif
 1187 }
 1188 
 1189 int
 1190 ad1848_set_speed(struct ad1848_softc *sc, u_int *argp)
 1191 {
 1192         /*
 1193          * The sampling speed is encoded in the least significant nible of I8.
 1194          * The LSB selects the clock source (0=24.576 MHz, 1=16.9344 MHz) and
 1195          * other three bits select the divisor (indirectly):
 1196          *
 1197          * The available speeds are in the following table. Keep the speeds in
 1198          * the increasing order.
 1199          */
 1200         typedef struct {
 1201                 int     speed;
 1202                 u_char  bits;
 1203         } speed_struct;
 1204         u_long arg;
 1205 
 1206         static const speed_struct speed_table[] =  {
 1207                 {5510, (0 << 1) | 1},
 1208                 {5510, (0 << 1) | 1},
 1209                 {6620, (7 << 1) | 1},
 1210                 {8000, (0 << 1) | 0},
 1211                 {9600, (7 << 1) | 0},
 1212                 {11025, (1 << 1) | 1},
 1213                 {16000, (1 << 1) | 0},
 1214                 {18900, (2 << 1) | 1},
 1215                 {22050, (3 << 1) | 1},
 1216                 {27420, (2 << 1) | 0},
 1217                 {32000, (3 << 1) | 0},
 1218                 {33075, (6 << 1) | 1},
 1219                 {37800, (4 << 1) | 1},
 1220                 {44100, (5 << 1) | 1},
 1221                 {48000, (6 << 1) | 0}
 1222         };
 1223 
 1224         int i, n, selected;
 1225 
 1226         arg = *argp;
 1227         selected = -1;
 1228         n = sizeof(speed_table) / sizeof(speed_struct);
 1229 
 1230         if (arg < speed_table[0].speed)
 1231                 selected = 0;
 1232         if (arg > speed_table[n - 1].speed)
 1233                 selected = n - 1;
 1234 
 1235         for (i = 1 /*really*/ ; selected == -1 && i < n; i++)
 1236                 if (speed_table[i].speed == arg)
 1237                         selected = i;
 1238                 else if (speed_table[i].speed > arg) {
 1239                         int diff1, diff2;
 1240 
 1241                         diff1 = arg - speed_table[i - 1].speed;
 1242                         diff2 = speed_table[i].speed - arg;
 1243 
 1244                         if (diff1 < diff2)
 1245                                 selected = i - 1;
 1246                         else
 1247                                 selected = i;
 1248                 }
 1249 
 1250         if (selected == -1) {
 1251                 printf("ad1848: Can't find speed???\n");
 1252                 selected = 3;
 1253         }
 1254 
 1255         sc->speed_bits = speed_table[selected].bits;
 1256         sc->need_commit = 1;
 1257         *argp = speed_table[selected].speed;
 1258 
 1259         return 0;
 1260 }
 1261 
 1262 /*
 1263  * Halt I/O
 1264  */
 1265 int
 1266 ad1848_halt_output(void *addr)
 1267 {
 1268         struct ad1848_softc *sc;
 1269         u_char reg;
 1270 
 1271         DPRINTF(("ad1848: ad1848_halt_output\n"));
 1272         sc = addr;
 1273         reg = ad_read(sc, SP_INTERFACE_CONFIG);
 1274         ad_write(sc, SP_INTERFACE_CONFIG, reg & ~PLAYBACK_ENABLE);
 1275 
 1276         return 0;
 1277 }
 1278 
 1279 int
 1280 ad1848_halt_input(void *addr)
 1281 {
 1282         struct ad1848_softc *sc;
 1283         u_char reg;
 1284 
 1285         DPRINTF(("ad1848: ad1848_halt_input\n"));
 1286         sc = addr;
 1287         reg = ad_read(sc, SP_INTERFACE_CONFIG);
 1288         ad_write(sc, SP_INTERFACE_CONFIG, reg & ~CAPTURE_ENABLE);
 1289 
 1290         return 0;
 1291 }

Cache object: fa4361b4c0f61e506944dc52b069de3f


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