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

Cache object: ad9e1214b5ea607d94261895cb14c4da


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