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.25 2006/11/16 01:32:50 christos 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.25 2006/11/16 01:32:50 christos 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 
  305         /* Set register addr */
  306         ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT);
  307         /* Wait for address to appear when read back. */
  308         timeout = 100000;
  309         while (timeout > 0 &&
  310                (ADREAD(sc, AD1848_IADDR)&SP_IADDR_MASK) != SP_TEST_AND_INIT) {
  311                 delay(10);
  312                 timeout--;
  313         }
  314         if (timeout <= 0) {
  315                 DPRINTF(("ad1848: Auto calibration timed out(1.5).\n"));
  316         }
  317 
  318         if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) {
  319                 if (sc->mode > 1) {
  320                         /* A new chip, just delay a little. */
  321                         delay(100);     /* XXX what should it be? */
  322                 } else {
  323                         timeout = 10000;
  324                         while (timeout > 0 &&
  325                                !(ad_read(sc, SP_TEST_AND_INIT) &
  326                                  AUTO_CAL_IN_PROG)) {
  327                                 delay(10);
  328                                 timeout--;
  329                         }
  330                         if (timeout <= 0) {
  331                                 DPRINTF(("ad1848: Auto calibration timed out(2).\n"));
  332                         }
  333                 }
  334         }
  335 
  336         timeout = 10000;
  337         while (timeout > 0 &&
  338                ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG) {
  339                 delay(10);
  340                 timeout--;
  341         }
  342         if (timeout <= 0) {
  343                 DPRINTF(("ad1848: Auto calibration timed out(3).\n"));
  344         }
  345 }
  346 
  347 #ifdef AUDIO_DEBUG
  348 void
  349 ad1848_dump_regs(struct ad1848_softc *sc)
  350 {
  351         int i;
  352         u_char r;
  353 
  354         printf("ad1848 status=%02x", ADREAD(sc, AD1848_STATUS));
  355         printf(" regs: ");
  356         for (i = 0; i < 16; i++) {
  357                 r = ad_read(sc, i);
  358                 printf("%02x ", r);
  359         }
  360         if (sc->mode >= 2) {
  361                 for (i = 16; i < 32; i++) {
  362                         r = ad_read(sc, i);
  363                         printf("%02x ", r);
  364                 }
  365         }
  366         printf("\n");
  367 }
  368 #endif /* AUDIO_DEBUG */
  369 
  370 
  371 /*
  372  * Attach hardware to driver, attach hardware driver to audio
  373  * pseudo-device driver .
  374  */
  375 void
  376 ad1848_attach(struct ad1848_softc *sc)
  377 {
  378         static struct ad1848_volume vol_mid = {220, 220};
  379         static struct ad1848_volume vol_0   = {0, 0};
  380         int i;
  381         int timeout;
  382 
  383         /* Initialize the ad1848... */
  384         for (i = 0; i < 0x10; i++) {
  385                 ad_write(sc, i, ad1848_init_values[i]);
  386                 timeout = 100000;
  387                 while (timeout > 0 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT)
  388                         timeout--;
  389         }
  390         /* ...and additional CS4231 stuff too */
  391         if (sc->mode >= 2) {
  392                 ad_write(sc, SP_INTERFACE_CONFIG, 0); /* disable SINGLE_DMA */
  393                 for (i = 0x10; i < 0x20; i++)
  394                         if (ad1848_init_values[i] != 0) {
  395                                 ad_write(sc, i, ad1848_init_values[i]);
  396                                 timeout = 100000;
  397                                 while (timeout > 0 &&
  398                                        ADREAD(sc, AD1848_IADDR) & SP_IN_INIT)
  399                                         timeout--;
  400                         }
  401         }
  402         ad1848_reset(sc);
  403 
  404         /* Set default gains */
  405         ad1848_set_rec_gain(sc, &vol_mid);
  406         ad1848_set_channel_gain(sc, AD1848_DAC_CHANNEL, &vol_mid);
  407         ad1848_set_channel_gain(sc, AD1848_MONITOR_CHANNEL, &vol_0);
  408         ad1848_set_channel_gain(sc, AD1848_AUX1_CHANNEL, &vol_mid);     /* CD volume */
  409         sc->mute[AD1848_MONITOR_CHANNEL] = MUTE_ALL;
  410         if (sc->mode >= 2
  411 #if AD1845_HACK
  412             && sc->is_ad1845 == 0
  413 #endif
  414                 ) {
  415                 ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_mid); /* CD volume */
  416                 ad1848_set_channel_gain(sc, AD1848_LINE_CHANNEL, &vol_mid);
  417                 ad1848_set_channel_gain(sc, AD1848_MONO_CHANNEL, &vol_0);
  418                 sc->mute[AD1848_MONO_CHANNEL] = MUTE_ALL;
  419         } else
  420                 ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_0);
  421 
  422         /* Set default port */
  423         ad1848_set_rec_port(sc, MIC_IN_PORT);
  424 
  425         printf(": %s", sc->chip_name);
  426 }
  427 
  428 /*
  429  * Various routines to interface to higher level audio driver
  430  */
  431 static const struct ad1848_mixerinfo {
  432         int  left_reg;
  433         int  right_reg;
  434         int  atten_bits;
  435         int  atten_mask;
  436 } mixer_channel_info[] =
  437 {
  438   { SP_LEFT_AUX2_CONTROL, SP_RIGHT_AUX2_CONTROL, AUX_INPUT_ATTEN_BITS,
  439     AUX_INPUT_ATTEN_MASK },
  440   { SP_LEFT_AUX1_CONTROL, SP_RIGHT_AUX1_CONTROL, AUX_INPUT_ATTEN_BITS,
  441     AUX_INPUT_ATTEN_MASK },
  442   { SP_LEFT_OUTPUT_CONTROL, SP_RIGHT_OUTPUT_CONTROL,
  443     OUTPUT_ATTEN_BITS, OUTPUT_ATTEN_MASK },
  444   { CS_LEFT_LINE_CONTROL, CS_RIGHT_LINE_CONTROL, LINE_INPUT_ATTEN_BITS,
  445     LINE_INPUT_ATTEN_MASK },
  446   { CS_MONO_IO_CONTROL, 0, MONO_INPUT_ATTEN_BITS, MONO_INPUT_ATTEN_MASK },
  447   { CS_MONO_IO_CONTROL, 0, 0, 0 },
  448   { SP_DIGITAL_MIX, 0, OUTPUT_ATTEN_BITS, MIX_ATTEN_MASK }
  449 };
  450 
  451 /*
  452  *  This function doesn't set the mute flags but does use them.
  453  *  The mute flags reflect the mutes that have been applied by the user.
  454  *  However, the driver occasionally wants to mute devices (e.g. when chaing
  455  *  sampling rate). These operations should not affect the mute flags.
  456  */
  457 
  458 void
  459 ad1848_mute_channel(struct ad1848_softc *sc, int device, int mute)
  460 {
  461         u_char reg;
  462 
  463         reg = ad_read(sc, mixer_channel_info[device].left_reg);
  464 
  465         if (mute & MUTE_LEFT) {
  466                 if (device == AD1848_MONITOR_CHANNEL) {
  467                         if (sc->open_mode & FREAD)
  468                                 ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 0);
  469                         ad_write(sc, mixer_channel_info[device].left_reg,
  470                                  reg & ~DIGITAL_MIX1_ENABLE);
  471                 } else if (device == AD1848_OUT_CHANNEL)
  472                         ad_write(sc, mixer_channel_info[device].left_reg,
  473                                  reg | MONO_OUTPUT_MUTE);
  474                 else
  475                         ad_write(sc, mixer_channel_info[device].left_reg,
  476                                  reg | 0x80);
  477         } else if (!(sc->mute[device] & MUTE_LEFT)) {
  478                 if (device == AD1848_MONITOR_CHANNEL) {
  479                         ad_write(sc, mixer_channel_info[device].left_reg,
  480                                  reg | DIGITAL_MIX1_ENABLE);
  481                         if (sc->open_mode & FREAD)
  482                                 ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 1);
  483                 } else if (device == AD1848_OUT_CHANNEL)
  484                         ad_write(sc, mixer_channel_info[device].left_reg,
  485                                  reg & ~MONO_OUTPUT_MUTE);
  486                 else
  487                         ad_write(sc, mixer_channel_info[device].left_reg,
  488                                  reg & ~0x80);
  489         }
  490 
  491         if (!mixer_channel_info[device].right_reg)
  492                 return;
  493 
  494         reg = ad_read(sc, mixer_channel_info[device].right_reg);
  495 
  496         if (mute & MUTE_RIGHT) {
  497                 ad_write(sc, mixer_channel_info[device].right_reg, reg | 0x80);
  498         } else if (!(sc->mute[device] & MUTE_RIGHT)) {
  499                 ad_write(sc, mixer_channel_info[device].right_reg, reg &~0x80);
  500         }
  501 }
  502 
  503 int
  504 ad1848_set_channel_gain(struct ad1848_softc *sc, int device,
  505     struct ad1848_volume *gp)
  506 {
  507         const struct ad1848_mixerinfo *info;
  508         u_char reg;
  509         u_int atten;
  510 
  511         info = &mixer_channel_info[device];
  512         sc->gains[device] = *gp;
  513 
  514         atten = (AUDIO_MAX_GAIN - gp->left) * (info->atten_bits + 1) /
  515                 (AUDIO_MAX_GAIN + 1);
  516 
  517         reg = ad_read(sc, info->left_reg) & (info->atten_mask);
  518         if (device == AD1848_MONITOR_CHANNEL)
  519                 reg |= ((atten & info->atten_bits) << 2);
  520         else
  521                 reg |= ((atten & info->atten_bits));
  522 
  523         ad_write(sc, info->left_reg, reg);
  524 
  525         if (!info->right_reg)
  526                 return 0;
  527 
  528         atten = (AUDIO_MAX_GAIN - gp->right) * (info->atten_bits + 1) /
  529                 (AUDIO_MAX_GAIN + 1);
  530         reg = ad_read(sc, info->right_reg);
  531         reg &= info->atten_mask;
  532         ad_write(sc, info->right_reg, (atten & info->atten_bits) | reg);
  533 
  534         return 0;
  535 }
  536 
  537 int
  538 ad1848_get_device_gain(struct ad1848_softc *sc, int device,
  539     struct ad1848_volume *gp)
  540 {
  541 
  542         *gp = sc->gains[device];
  543         return 0;
  544 }
  545 
  546 int
  547 ad1848_get_rec_gain(struct ad1848_softc *sc, struct ad1848_volume *gp)
  548 {
  549 
  550         *gp = sc->rec_gain;
  551         return 0;
  552 }
  553 
  554 int
  555 ad1848_set_rec_gain(struct ad1848_softc *sc, struct ad1848_volume *gp)
  556 {
  557         u_char reg, gain;
  558 
  559         DPRINTF(("ad1848_set_rec_gain: %d:%d\n", gp->left, gp->right));
  560 
  561         sc->rec_gain = *gp;
  562 
  563         gain = (gp->left * (GAIN_22_5 + 1)) / (AUDIO_MAX_GAIN + 1);
  564         reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
  565         reg &= INPUT_GAIN_MASK;
  566         ad_write(sc, SP_LEFT_INPUT_CONTROL, (gain & 0x0f) | reg);
  567 
  568         gain = (gp->right * (GAIN_22_5 + 1)) / (AUDIO_MAX_GAIN + 1);
  569         reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL);
  570         reg &= INPUT_GAIN_MASK;
  571         ad_write(sc, SP_RIGHT_INPUT_CONTROL, (gain & 0x0f) | reg);
  572 
  573         return 0;
  574 }
  575 
  576 void
  577 ad1848_mute_wave_output(struct ad1848_softc *sc, int mute, int set)
  578 {
  579         int m;
  580 
  581         DPRINTF(("ad1848_mute_wave_output: %d, %d\n", mute, set));
  582 
  583         if (mute == WAVE_MUTE2_INIT) {
  584                 sc->wave_mute_status = 0;
  585                 mute = WAVE_MUTE2;
  586         }
  587         if (set)
  588                 m = sc->wave_mute_status |= mute;
  589         else
  590                 m = sc->wave_mute_status &= ~mute;
  591 
  592         if (m & WAVE_MUTE0 || ((m & WAVE_UNMUTE1) == 0 && m & WAVE_MUTE2))
  593                 ad1848_mute_channel(sc, AD1848_DAC_CHANNEL, MUTE_ALL);
  594         else
  595                 ad1848_mute_channel(sc, AD1848_DAC_CHANNEL,
  596                                             sc->mute[AD1848_DAC_CHANNEL]);
  597 }
  598 
  599 int
  600 ad1848_set_mic_gain(struct ad1848_softc *sc, struct ad1848_volume *gp)
  601 {
  602         u_char reg;
  603 
  604         DPRINTF(("cs4231_set_mic_gain: %d\n", gp->left));
  605 
  606         if (gp->left > AUDIO_MAX_GAIN/2) {
  607                 sc->mic_gain_on = 1;
  608                 reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
  609                 ad_write(sc, SP_LEFT_INPUT_CONTROL,
  610                          reg | INPUT_MIC_GAIN_ENABLE);
  611         } else {
  612                 sc->mic_gain_on = 0;
  613                 reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
  614                 ad_write(sc, SP_LEFT_INPUT_CONTROL,
  615                          reg & ~INPUT_MIC_GAIN_ENABLE);
  616         }
  617 
  618         return 0;
  619 }
  620 
  621 int
  622 ad1848_get_mic_gain(struct ad1848_softc *sc, struct ad1848_volume *gp)
  623 {
  624         if (sc->mic_gain_on)
  625                 gp->left = gp->right = AUDIO_MAX_GAIN;
  626         else
  627                 gp->left = gp->right = AUDIO_MIN_GAIN;
  628         return 0;
  629 }
  630 
  631 static ad1848_devmap_t *
  632 ad1848_mixer_find_dev(ad1848_devmap_t *map, int cnt, mixer_ctrl_t *cp)
  633 {
  634         int i;
  635 
  636         for (i = 0; i < cnt; i++) {
  637                 if (map[i].id == cp->dev) {
  638                         return (&map[i]);
  639                 }
  640         }
  641         return 0;
  642 }
  643 
  644 int
  645 ad1848_mixer_get_port(struct ad1848_softc *ac, struct ad1848_devmap *map,
  646     int cnt, mixer_ctrl_t *cp)
  647 {
  648         ad1848_devmap_t *entry;
  649         struct ad1848_volume vol;
  650         int error;
  651         int dev;
  652 
  653         error = EINVAL;
  654         if (!(entry = ad1848_mixer_find_dev(map, cnt, cp)))
  655                 return ENXIO;
  656 
  657         dev = entry->dev;
  658 
  659         switch (entry->kind) {
  660         case AD1848_KIND_LVL:
  661                 if (cp->type != AUDIO_MIXER_VALUE)
  662                         break;
  663 
  664                 if (dev < AD1848_AUX2_CHANNEL ||
  665                     dev > AD1848_MONITOR_CHANNEL)
  666                         break;
  667 
  668                 if (cp->un.value.num_channels != 1 &&
  669                     mixer_channel_info[dev].right_reg == 0)
  670                         break;
  671 
  672                 error = ad1848_get_device_gain(ac, dev, &vol);
  673                 if (!error)
  674                         ad1848_from_vol(cp, &vol);
  675 
  676                 break;
  677 
  678         case AD1848_KIND_MUTE:
  679                 if (cp->type != AUDIO_MIXER_ENUM) break;
  680 
  681                 cp->un.ord = ac->mute[dev] ? 1 : 0;
  682                 error = 0;
  683                 break;
  684 
  685         case AD1848_KIND_RECORDGAIN:
  686                 if (cp->type != AUDIO_MIXER_VALUE) break;
  687 
  688                 error = ad1848_get_rec_gain(ac, &vol);
  689                 if (!error)
  690                         ad1848_from_vol(cp, &vol);
  691 
  692                 break;
  693 
  694         case AD1848_KIND_MICGAIN:
  695                 if (cp->type != AUDIO_MIXER_VALUE) break;
  696 
  697                 error = ad1848_get_mic_gain(ac, &vol);
  698                 if (!error)
  699                         ad1848_from_vol(cp, &vol);
  700 
  701                 break;
  702 
  703         case AD1848_KIND_RECORDSOURCE:
  704                 if (cp->type != AUDIO_MIXER_ENUM) break;
  705                 cp->un.ord = ad1848_get_rec_port(ac);
  706                 error = 0;
  707                 break;
  708 
  709         default:
  710                 printf ("Invalid kind\n");
  711                 break;
  712         }
  713 
  714         return error;
  715 }
  716 
  717 int
  718 ad1848_mixer_set_port(struct ad1848_softc *ac, struct ad1848_devmap *map,
  719     int cnt, mixer_ctrl_t *cp)
  720 {
  721         ad1848_devmap_t *entry;
  722         struct ad1848_volume vol;
  723         int error;
  724         int dev;
  725 
  726         error = EINVAL;
  727         if (!(entry = ad1848_mixer_find_dev(map, cnt, cp)))
  728                 return ENXIO;
  729 
  730         dev = entry->dev;
  731 
  732         switch (entry->kind) {
  733         case AD1848_KIND_LVL:
  734                 if (cp->type != AUDIO_MIXER_VALUE)
  735                         break;
  736 
  737                 if (dev < AD1848_AUX2_CHANNEL ||
  738                     dev > AD1848_MONITOR_CHANNEL)
  739                         break;
  740 
  741                 if (cp->un.value.num_channels != 1 &&
  742                     mixer_channel_info[dev].right_reg == 0)
  743                         break;
  744 
  745                 ad1848_to_vol(cp, &vol);
  746                 error = ad1848_set_channel_gain(ac, dev, &vol);
  747                 break;
  748 
  749         case AD1848_KIND_MUTE:
  750                 if (cp->type != AUDIO_MIXER_ENUM) break;
  751 
  752                 ac->mute[dev] = (cp->un.ord ? MUTE_ALL : 0);
  753                 ad1848_mute_channel(ac, dev, ac->mute[dev]);
  754                 error = 0;
  755                 break;
  756 
  757         case AD1848_KIND_RECORDGAIN:
  758                 if (cp->type != AUDIO_MIXER_VALUE) break;
  759 
  760                 ad1848_to_vol(cp, &vol);
  761                 error = ad1848_set_rec_gain(ac, &vol);
  762                 break;
  763 
  764         case AD1848_KIND_MICGAIN:
  765                 if (cp->type != AUDIO_MIXER_VALUE) break;
  766 
  767                 ad1848_to_vol(cp, &vol);
  768                 error = ad1848_set_mic_gain(ac, &vol);
  769                 break;
  770 
  771         case AD1848_KIND_RECORDSOURCE:
  772                 if (cp->type != AUDIO_MIXER_ENUM) break;
  773 
  774                 error = ad1848_set_rec_port(ac,  cp->un.ord);
  775                 break;
  776 
  777         default:
  778                 printf ("Invalid kind\n");
  779                 break;
  780         }
  781 
  782         return error;
  783 }
  784 
  785 int
  786 ad1848_query_encoding(void *addr, struct audio_encoding *fp)
  787 {
  788         struct ad1848_softc *sc;
  789 
  790         sc = addr;
  791         switch (fp->index) {
  792         case 0:
  793                 strcpy(fp->name, AudioEmulaw);
  794                 fp->encoding = AUDIO_ENCODING_ULAW;
  795                 fp->precision = 8;
  796                 fp->flags = 0;
  797                 break;
  798         case 1:
  799                 strcpy(fp->name, AudioEalaw);
  800                 fp->encoding = AUDIO_ENCODING_ALAW;
  801                 fp->precision = 8;
  802                 fp->flags = 0;
  803                 break;
  804         case 2:
  805                 strcpy(fp->name, AudioEslinear_le);
  806                 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
  807                 fp->precision = 16;
  808                 fp->flags = 0;
  809                 break;
  810         case 3:
  811                 strcpy(fp->name, AudioEulinear);
  812                 fp->encoding = AUDIO_ENCODING_ULINEAR;
  813                 fp->precision = 8;
  814                 fp->flags = 0;
  815                 break;
  816 
  817         case 4: /* only on CS4231 */
  818                 strcpy(fp->name, AudioEslinear_be);
  819                 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
  820                 fp->precision = 16;
  821                 fp->flags = sc->mode == 1
  822 #if AD1845_HACK
  823                     || sc->is_ad1845
  824 #endif
  825                         ? AUDIO_ENCODINGFLAG_EMULATED : 0;
  826                 break;
  827 
  828                 /* emulate some modes */
  829         case 5:
  830                 strcpy(fp->name, AudioEslinear);
  831                 fp->encoding = AUDIO_ENCODING_SLINEAR;
  832                 fp->precision = 8;
  833                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  834                 break;
  835         case 6:
  836                 strcpy(fp->name, AudioEulinear_le);
  837                 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
  838                 fp->precision = 16;
  839                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  840                 break;
  841         case 7:
  842                 strcpy(fp->name, AudioEulinear_be);
  843                 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
  844                 fp->precision = 16;
  845                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  846                 break;
  847 
  848         case 8: /* only on CS4231 */
  849                 if (sc->mode == 1 || sc->is_ad1845)
  850                         return EINVAL;
  851                 strcpy(fp->name, AudioEadpcm);
  852                 fp->encoding = AUDIO_ENCODING_ADPCM;
  853                 fp->precision = 4;
  854                 fp->flags = 0;
  855                 break;
  856         default:
  857                 return EINVAL;
  858                 /*NOTREACHED*/
  859         }
  860         return 0;
  861 }
  862 
  863 int
  864 ad1848_set_params(void *addr, int setmode, int usemode,
  865     audio_params_t *p, audio_params_t *r, stream_filter_list_t *pfil,
  866     stream_filter_list_t *rfil)
  867 {
  868         audio_params_t phw, rhw;
  869         struct ad1848_softc *sc;
  870         int error, bits, enc;
  871         stream_filter_factory_t *pswcode;
  872         stream_filter_factory_t *rswcode;
  873 
  874         DPRINTF(("ad1848_set_params: %u %u %u %u\n",
  875                  p->encoding, p->precision, p->channels, p->sample_rate));
  876 
  877         sc = addr;
  878         enc = p->encoding;
  879         pswcode = rswcode = 0;
  880         phw = *p;
  881         rhw = *r;
  882         switch (enc) {
  883         case AUDIO_ENCODING_SLINEAR_LE:
  884                 if (p->precision == 8) {
  885                         enc = AUDIO_ENCODING_ULINEAR_LE;
  886                         phw.encoding = AUDIO_ENCODING_ULINEAR_LE;
  887                         rhw.encoding = AUDIO_ENCODING_ULINEAR_LE;
  888                         pswcode = rswcode = change_sign8;
  889                 }
  890                 break;
  891         case AUDIO_ENCODING_SLINEAR_BE:
  892                 if (p->precision == 16 && (sc->mode == 1
  893 #if AD1845_HACK
  894                     || sc->is_ad1845
  895 #endif
  896                         )) {
  897                         enc = AUDIO_ENCODING_SLINEAR_LE;
  898                         phw.encoding = AUDIO_ENCODING_SLINEAR_LE;
  899                         rhw.encoding = AUDIO_ENCODING_SLINEAR_LE;
  900                         pswcode = rswcode = swap_bytes;
  901                 }
  902                 break;
  903         case AUDIO_ENCODING_ULINEAR_LE:
  904                 if (p->precision == 16) {
  905                         enc = AUDIO_ENCODING_SLINEAR_LE;
  906                         phw.encoding = AUDIO_ENCODING_SLINEAR_LE;
  907                         rhw.encoding = AUDIO_ENCODING_SLINEAR_LE;
  908                         pswcode = rswcode = change_sign16;
  909                 }
  910                 break;
  911         case AUDIO_ENCODING_ULINEAR_BE:
  912                 if (p->precision == 16) {
  913                         if (sc->mode == 1
  914 #if AD1845_HACK
  915                             || sc->is_ad1845
  916 #endif
  917                                 ) {
  918                                 enc = AUDIO_ENCODING_SLINEAR_LE;
  919                                 phw.encoding = AUDIO_ENCODING_SLINEAR_LE;
  920                                 rhw.encoding = AUDIO_ENCODING_SLINEAR_LE;
  921                                 pswcode = swap_bytes_change_sign16;
  922                                 rswcode = swap_bytes_change_sign16;
  923                         } else {
  924                                 enc = AUDIO_ENCODING_SLINEAR_BE;
  925                                 phw.encoding = AUDIO_ENCODING_SLINEAR_BE;
  926                                 rhw.encoding = AUDIO_ENCODING_SLINEAR_BE;
  927                                 pswcode = rswcode = change_sign16;
  928                         }
  929                 }
  930                 break;
  931         }
  932         switch (enc) {
  933         case AUDIO_ENCODING_ULAW:
  934                 bits = FMT_ULAW >> 5;
  935                 break;
  936         case AUDIO_ENCODING_ALAW:
  937                 bits = FMT_ALAW >> 5;
  938                 break;
  939         case AUDIO_ENCODING_ADPCM:
  940                 bits = FMT_ADPCM >> 5;
  941                 break;
  942         case AUDIO_ENCODING_SLINEAR_LE:
  943                 if (p->precision == 16)
  944                         bits = FMT_TWOS_COMP >> 5;
  945                 else
  946                         return EINVAL;
  947                 break;
  948         case AUDIO_ENCODING_SLINEAR_BE:
  949                 if (p->precision == 16)
  950                         bits = FMT_TWOS_COMP_BE >> 5;
  951                 else
  952                         return EINVAL;
  953                 break;
  954         case AUDIO_ENCODING_ULINEAR_LE:
  955                 if (p->precision == 8)
  956                         bits = FMT_PCM8 >> 5;
  957                 else
  958                         return EINVAL;
  959                 break;
  960         default:
  961                 return EINVAL;
  962         }
  963 
  964         if (p->channels < 1 || p->channels > 2)
  965                 return EINVAL;
  966 
  967         error = ad1848_set_speed(sc, &p->sample_rate);
  968         if (error)
  969                 return error;
  970         phw.sample_rate = p->sample_rate;
  971 
  972         if (pswcode != NULL)
  973                 pfil->append(pfil, pswcode, &phw);
  974         if (rswcode != NULL)
  975                 rfil->append(rfil, rswcode, &rhw);
  976 
  977         sc->format_bits = bits;
  978         sc->channels = p->channels;
  979         sc->precision = p->precision;
  980         sc->need_commit = 1;
  981 
  982         DPRINTF(("ad1848_set_params succeeded, bits=%x\n", bits));
  983         return 0;
  984 }
  985 
  986 int
  987 ad1848_set_rec_port(struct ad1848_softc *sc, int port)
  988 {
  989         u_char inp, reg;
  990 
  991         DPRINTF(("ad1848_set_rec_port: 0x%x\n", port));
  992 
  993         if (port == MIC_IN_PORT)
  994                 inp = MIC_INPUT;
  995         else if (port == LINE_IN_PORT)
  996                 inp = LINE_INPUT;
  997         else if (port == DAC_IN_PORT)
  998                 inp = MIXED_DAC_INPUT;
  999         else if (sc->mode >= 2 && port == AUX1_IN_PORT)
 1000                 inp = AUX_INPUT;
 1001         else
 1002                 return EINVAL;
 1003 
 1004         reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
 1005         reg &= INPUT_SOURCE_MASK;
 1006         ad_write(sc, SP_LEFT_INPUT_CONTROL, (inp|reg));
 1007 
 1008         reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL);
 1009         reg &= INPUT_SOURCE_MASK;
 1010         ad_write(sc, SP_RIGHT_INPUT_CONTROL, (inp|reg));
 1011 
 1012         sc->rec_port = port;
 1013 
 1014         return 0;
 1015 }
 1016 
 1017 int
 1018 ad1848_get_rec_port(struct ad1848_softc *sc)
 1019 {
 1020         return sc->rec_port;
 1021 }
 1022 
 1023 int
 1024 ad1848_round_blocksize(void *addr, int blk,
 1025     int mode, const audio_params_t *param)
 1026 {
 1027 
 1028         /* Round to a multiple of the biggest sample size. */
 1029         return blk &= -4;
 1030 }
 1031 
 1032 int
 1033 ad1848_open(void *addr, int flags)
 1034 {
 1035         struct ad1848_softc *sc;
 1036         u_char reg;
 1037 
 1038         sc = addr;
 1039         DPRINTF(("ad1848_open: sc=%p\n", sc));
 1040 
 1041         sc->open_mode = flags;
 1042 
 1043         /* Enable interrupts */
 1044         DPRINTF(("ad1848_open: enable intrs\n"));
 1045         reg = ad_read(sc, SP_PIN_CONTROL);
 1046         ad_write(sc, SP_PIN_CONTROL, reg | INTERRUPT_ENABLE);
 1047 
 1048         /* If recording && monitoring, the playback part is also used. */
 1049         if (flags & FREAD && sc->mute[AD1848_MONITOR_CHANNEL] == 0)
 1050                 ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 1);
 1051 
 1052 #ifdef AUDIO_DEBUG
 1053         if (ad1848debug)
 1054                 ad1848_dump_regs(sc);
 1055 #endif
 1056 
 1057         return 0;
 1058 }
 1059 
 1060 /*
 1061  * Close function is called at splaudio().
 1062  */
 1063 void
 1064 ad1848_close(void *addr)
 1065 {
 1066         struct ad1848_softc *sc;
 1067         u_char reg;
 1068 
 1069         sc = addr;
 1070         sc->open_mode = 0;
 1071 
 1072         ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 0);
 1073 
 1074         /* Disable interrupts */
 1075         DPRINTF(("ad1848_close: disable intrs\n"));
 1076         reg = ad_read(sc, SP_PIN_CONTROL);
 1077         ad_write(sc, SP_PIN_CONTROL, reg & ~INTERRUPT_ENABLE);
 1078 
 1079 #ifdef AUDIO_DEBUG
 1080         if (ad1848debug)
 1081                 ad1848_dump_regs(sc);
 1082 #endif
 1083 }
 1084 
 1085 /*
 1086  * Lower-level routines
 1087  */
 1088 int
 1089 ad1848_commit_settings(void *addr)
 1090 {
 1091         struct ad1848_softc *sc;
 1092         int timeout;
 1093         u_char fs;
 1094         int s;
 1095 
 1096         sc = addr;
 1097         if (!sc->need_commit)
 1098                 return 0;
 1099 
 1100         s = splaudio();
 1101 
 1102         ad1848_mute_wave_output(sc, WAVE_MUTE0, 1);
 1103 
 1104         ad_set_MCE(sc, 1);      /* Enables changes to the format select reg */
 1105 
 1106         fs = sc->speed_bits | (sc->format_bits << 5);
 1107 
 1108         if (sc->channels == 2)
 1109                 fs |= FMT_STEREO;
 1110 
 1111         /*
 1112          * OPL3-SA2 (YMF711) is sometimes busy here.
 1113          * Wait until it becomes ready.
 1114          */
 1115         for (timeout = 0;
 1116             timeout < 1000 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT; timeout++)
 1117                 delay(10);
 1118 
 1119         ad_write(sc, SP_CLOCK_DATA_FORMAT, fs);
 1120 
 1121         /*
 1122          * If mode >= 2 (CS4231), set I28 also.
 1123          * It's the capture format register.
 1124          */
 1125         if (sc->mode >= 2) {
 1126                 /*
 1127                  * Gravis Ultrasound MAX SDK sources says something about
 1128                  * errata sheets, with the implication that these inb()s
 1129                  * are necessary.
 1130                  */
 1131                 (void)ADREAD(sc, AD1848_IDATA);
 1132                 (void)ADREAD(sc, AD1848_IDATA);
 1133                 /* Write to I8 starts resynchronization. Wait for completion. */
 1134                 timeout = 100000;
 1135                 while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
 1136                         timeout--;
 1137 
 1138                 ad_write(sc, CS_REC_FORMAT, fs);
 1139                 (void)ADREAD(sc, AD1848_IDATA);
 1140                 (void)ADREAD(sc, AD1848_IDATA);
 1141                 /* Now wait for resync for capture side of the house */
 1142         }
 1143         /*
 1144          * Write to I8 starts resynchronization. Wait until it completes.
 1145          */
 1146         timeout = 100000;
 1147         while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) {
 1148                 delay(10);
 1149                 timeout--;
 1150         }
 1151 
 1152         if (ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
 1153                 printf("ad1848_commit: Auto calibration timed out\n");
 1154 
 1155         /*
 1156          * Starts the calibration process and
 1157          * enters playback mode after it.
 1158          */
 1159         ad_set_MCE(sc, 0);
 1160         wait_for_calibration(sc);
 1161 
 1162         ad1848_mute_wave_output(sc, WAVE_MUTE0, 0);
 1163 
 1164         splx(s);
 1165 
 1166         sc->need_commit = 0;
 1167         return 0;
 1168 }
 1169 
 1170 void
 1171 ad1848_reset(struct ad1848_softc *sc)
 1172 {
 1173         u_char r;
 1174 
 1175         DPRINTF(("ad1848_reset\n"));
 1176 
 1177         /* Clear the PEN and CEN bits */
 1178         r = ad_read(sc, SP_INTERFACE_CONFIG);
 1179         r &= ~(CAPTURE_ENABLE | PLAYBACK_ENABLE);
 1180         ad_write(sc, SP_INTERFACE_CONFIG, r);
 1181 
 1182         if (sc->mode >= 2) {
 1183                 ADWRITE(sc, AD1848_IADDR, CS_IRQ_STATUS);
 1184                 ADWRITE(sc, AD1848_IDATA, 0);
 1185         }
 1186         /* Clear interrupt status */
 1187         ADWRITE(sc, AD1848_STATUS, 0);
 1188 #ifdef AUDIO_DEBUG
 1189         if (ad1848debug)
 1190                 ad1848_dump_regs(sc);
 1191 #endif
 1192 }
 1193 
 1194 int
 1195 ad1848_set_speed(struct ad1848_softc *sc, u_int *argp)
 1196 {
 1197         /*
 1198          * The sampling speed is encoded in the least significant nible of I8.
 1199          * The LSB selects the clock source (0=24.576 MHz, 1=16.9344 MHz) and
 1200          * other three bits select the divisor (indirectly):
 1201          *
 1202          * The available speeds are in the following table. Keep the speeds in
 1203          * the increasing order.
 1204          */
 1205         typedef struct {
 1206                 int     speed;
 1207                 u_char  bits;
 1208         } speed_struct;
 1209         u_long arg;
 1210 
 1211         static const speed_struct speed_table[] =  {
 1212                 {5510, (0 << 1) | 1},
 1213                 {5510, (0 << 1) | 1},
 1214                 {6620, (7 << 1) | 1},
 1215                 {8000, (0 << 1) | 0},
 1216                 {9600, (7 << 1) | 0},
 1217                 {11025, (1 << 1) | 1},
 1218                 {16000, (1 << 1) | 0},
 1219                 {18900, (2 << 1) | 1},
 1220                 {22050, (3 << 1) | 1},
 1221                 {27420, (2 << 1) | 0},
 1222                 {32000, (3 << 1) | 0},
 1223                 {33075, (6 << 1) | 1},
 1224                 {37800, (4 << 1) | 1},
 1225                 {44100, (5 << 1) | 1},
 1226                 {48000, (6 << 1) | 0}
 1227         };
 1228 
 1229         int i, n, selected;
 1230 
 1231         arg = *argp;
 1232         selected = -1;
 1233         n = sizeof(speed_table) / sizeof(speed_struct);
 1234 
 1235         if (arg < speed_table[0].speed)
 1236                 selected = 0;
 1237         if (arg > speed_table[n - 1].speed)
 1238                 selected = n - 1;
 1239 
 1240         for (i = 1 /*really*/ ; selected == -1 && i < n; i++)
 1241                 if (speed_table[i].speed == arg)
 1242                         selected = i;
 1243                 else if (speed_table[i].speed > arg) {
 1244                         int diff1, diff2;
 1245 
 1246                         diff1 = arg - speed_table[i - 1].speed;
 1247                         diff2 = speed_table[i].speed - arg;
 1248 
 1249                         if (diff1 < diff2)
 1250                                 selected = i - 1;
 1251                         else
 1252                                 selected = i;
 1253                 }
 1254 
 1255         if (selected == -1) {
 1256                 printf("ad1848: Can't find speed???\n");
 1257                 selected = 3;
 1258         }
 1259 
 1260         sc->speed_bits = speed_table[selected].bits;
 1261         sc->need_commit = 1;
 1262         *argp = speed_table[selected].speed;
 1263 
 1264         return 0;
 1265 }
 1266 
 1267 /*
 1268  * Halt I/O
 1269  */
 1270 int
 1271 ad1848_halt_output(void *addr)
 1272 {
 1273         struct ad1848_softc *sc;
 1274         u_char reg;
 1275 
 1276         DPRINTF(("ad1848: ad1848_halt_output\n"));
 1277         sc = addr;
 1278         reg = ad_read(sc, SP_INTERFACE_CONFIG);
 1279         ad_write(sc, SP_INTERFACE_CONFIG, reg & ~PLAYBACK_ENABLE);
 1280 
 1281         return 0;
 1282 }
 1283 
 1284 int
 1285 ad1848_halt_input(void *addr)
 1286 {
 1287         struct ad1848_softc *sc;
 1288         u_char reg;
 1289 
 1290         DPRINTF(("ad1848: ad1848_halt_input\n"));
 1291         sc = addr;
 1292         reg = ad_read(sc, SP_INTERFACE_CONFIG);
 1293         ad_write(sc, SP_INTERFACE_CONFIG, reg & ~CAPTURE_ENABLE);
 1294 
 1295         return 0;
 1296 }

Cache object: b33b062e44b7e91976282fb0c7c797ca


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