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