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