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