1 /* $NetBSD: ad1848.c,v 1.22 2005/12/24 20:27:29 perry 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.22 2005/12/24 20:27:29 perry Exp $"); 106 107 #include <sys/param.h> 108 #include <sys/systm.h> 109 #include <sys/errno.h> 110 #include <sys/ioctl.h> 111 #include <sys/device.h> 112 #include <sys/fcntl.h> 113 /*#include <sys/syslog.h>*/ 114 /*#include <sys/proc.h>*/ 115 116 #include <machine/cpu.h> 117 #include <machine/bus.h> 118 119 #include <sys/audioio.h> 120 121 #include <dev/audio_if.h> 122 #include <dev/auconv.h> 123 124 #include <dev/ic/ad1848reg.h> 125 #include <dev/ic/cs4231reg.h> 126 #include <dev/ic/cs4237reg.h> 127 #include <dev/ic/ad1848var.h> 128 #if 0 129 #include <dev/isa/cs4231var.h> 130 #endif 131 132 /* 133 * AD1845 on some machines don't match the AD1845 doc 134 * and defining AD1845_HACK to 1 works around the problems. 135 * options AD1845_HACK=0 should work if you have ``correct'' one. 136 */ 137 #ifndef AD1845_HACK 138 #define AD1845_HACK 1 /* weird mixer, can't play slinear_be */ 139 #endif 140 141 #ifdef AUDIO_DEBUG 142 #define DPRINTF(x) if (ad1848debug) printf x 143 int ad1848debug = 0; 144 #else 145 #define DPRINTF(x) 146 #endif 147 148 /* 149 * Initial values for the indirect registers of CS4248/AD1848. 150 */ 151 static const int ad1848_init_values[] = { 152 GAIN_12|INPUT_MIC_GAIN_ENABLE, /* Left Input Control */ 153 GAIN_12|INPUT_MIC_GAIN_ENABLE, /* Right Input Control */ 154 ATTEN_12, /* Left Aux #1 Input Control */ 155 ATTEN_12, /* Right Aux #1 Input Control */ 156 ATTEN_12, /* Left Aux #2 Input Control */ 157 ATTEN_12, /* Right Aux #2 Input Control */ 158 /* bits 5-0 are attenuation select */ 159 ATTEN_12, /* Left DAC output Control */ 160 ATTEN_12, /* Right DAC output Control */ 161 CLOCK_XTAL1|FMT_PCM8, /* Clock and Data Format */ 162 SINGLE_DMA|AUTO_CAL_ENABLE, /* Interface Config */ 163 INTERRUPT_ENABLE, /* Pin control */ 164 0x00, /* Test and Init */ 165 MODE2, /* Misc control */ 166 ATTEN_0<<2, /* Digital Mix Control */ 167 0, /* Upper base Count */ 168 0, /* Lower base Count */ 169 170 /* These are for CS4231 &c. only (additional registers): */ 171 0, /* Alt feature 1 */ 172 0, /* Alt feature 2 */ 173 ATTEN_12, /* Left line in */ 174 ATTEN_12, /* Right line in */ 175 0, /* Timer low */ 176 0, /* Timer high */ 177 0, /* unused */ 178 0, /* unused */ 179 0, /* IRQ status */ 180 0, /* unused */ 181 /* Mono input (a.k.a speaker) (mic) Control */ 182 MONO_INPUT_MUTE|ATTEN_6, /* mute speaker by default */ 183 0, /* unused */ 184 0, /* record format */ 185 0, /* Crystal Clock Select */ 186 0, /* upper record count */ 187 0 /* lower record count */ 188 }; 189 190 191 int 192 ad1848_to_vol(mixer_ctrl_t *cp, struct ad1848_volume *vol) 193 { 194 195 if (cp->un.value.num_channels == 1) { 196 vol->left = 197 vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 198 return 1; 199 } 200 else if (cp->un.value.num_channels == 2) { 201 vol->left = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 202 vol->right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 203 return 1; 204 } 205 return 0; 206 } 207 208 int 209 ad1848_from_vol(mixer_ctrl_t *cp, struct ad1848_volume *vol) 210 { 211 212 if (cp->un.value.num_channels == 1) { 213 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = vol->left; 214 return 1; 215 } 216 else if (cp->un.value.num_channels == 2) { 217 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = vol->left; 218 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = vol->right; 219 return 1; 220 } 221 return 0; 222 } 223 224 225 inline int 226 ad_read(struct ad1848_softc *sc, int reg) 227 { 228 int x; 229 230 ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit); 231 x = ADREAD(sc, AD1848_IDATA); 232 /* printf("(%02x<-%02x) ", reg|sc->MCE_bit, x); */ 233 return x; 234 } 235 236 inline void 237 ad_write(struct ad1848_softc *sc, int reg, int data) 238 { 239 240 ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit); 241 ADWRITE(sc, AD1848_IDATA, data & 0xff); 242 /* printf("(%02x->%02x) ", reg|sc->MCE_bit, data); */ 243 } 244 245 /* 246 * extended registers (mode 3) require an additional level of 247 * indirection through CS_XREG (I23). 248 */ 249 250 inline int 251 ad_xread(struct ad1848_softc *sc, int reg) 252 { 253 int x; 254 255 ADWRITE(sc, AD1848_IADDR, CS_XREG | sc->MCE_bit); 256 ADWRITE(sc, AD1848_IDATA, (reg | ALT_F3_XRAE) & 0xff); 257 x = ADREAD(sc, AD1848_IDATA); 258 259 return x; 260 } 261 262 inline void 263 ad_xwrite(struct ad1848_softc *sc, int reg, int val) 264 { 265 266 ADWRITE(sc, AD1848_IADDR, CS_XREG | sc->MCE_bit); 267 ADWRITE(sc, AD1848_IDATA, (reg | ALT_F3_XRAE) & 0xff); 268 ADWRITE(sc, AD1848_IDATA, val & 0xff); 269 } 270 271 static void 272 ad_set_MCE(struct ad1848_softc *sc, int state) 273 { 274 275 if (state) 276 sc->MCE_bit = MODE_CHANGE_ENABLE; 277 else 278 sc->MCE_bit = 0; 279 ADWRITE(sc, AD1848_IADDR, sc->MCE_bit); 280 } 281 282 static void 283 wait_for_calibration(struct ad1848_softc *sc) 284 { 285 int timeout; 286 287 DPRINTF(("ad1848: Auto calibration started.\n")); 288 /* 289 * Wait until the auto calibration process has finished. 290 * 291 * 1) Wait until the chip becomes ready (reads don't return 0x80). 292 * 2) Wait until the ACI bit of I11 gets on and then off. 293 * Because newer chips are fast we may never see the ACI 294 * bit go on. Just delay a little instead. 295 */ 296 timeout = 10000; 297 while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) { 298 delay(10); 299 timeout--; 300 } 301 if (timeout <= 0) 302 DPRINTF(("ad1848: Auto calibration timed out(1).\n")); 303 304 /* Set register addr */ 305 ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT); 306 /* Wait for address to appear when read back. */ 307 timeout = 100000; 308 while (timeout > 0 && 309 (ADREAD(sc, AD1848_IADDR)&SP_IADDR_MASK) != SP_TEST_AND_INIT) { 310 delay(10); 311 timeout--; 312 } 313 if (timeout <= 0) 314 DPRINTF(("ad1848: Auto calibration timed out(1.5).\n")); 315 316 if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) { 317 if (sc->mode > 1) { 318 /* A new chip, just delay a little. */ 319 delay(100); /* XXX what should it be? */ 320 } else { 321 timeout = 10000; 322 while (timeout > 0 && 323 !(ad_read(sc, SP_TEST_AND_INIT) & 324 AUTO_CAL_IN_PROG)) { 325 delay(10); 326 timeout--; 327 } 328 if (timeout <= 0) 329 DPRINTF(("ad1848: Auto calibration timed out(2).\n")); 330 } 331 } 332 333 timeout = 10000; 334 while (timeout > 0 && 335 ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG) { 336 delay(10); 337 timeout--; 338 } 339 if (timeout <= 0) 340 DPRINTF(("ad1848: Auto calibration timed out(3).\n")); 341 } 342 343 #ifdef AUDIO_DEBUG 344 void 345 ad1848_dump_regs(struct ad1848_softc *sc) 346 { 347 int i; 348 u_char r; 349 350 printf("ad1848 status=%02x", ADREAD(sc, AD1848_STATUS)); 351 printf(" regs: "); 352 for (i = 0; i < 16; i++) { 353 r = ad_read(sc, i); 354 printf("%02x ", r); 355 } 356 if (sc->mode >= 2) { 357 for (i = 16; i < 32; i++) { 358 r = ad_read(sc, i); 359 printf("%02x ", r); 360 } 361 } 362 printf("\n"); 363 } 364 #endif /* AUDIO_DEBUG */ 365 366 367 /* 368 * Attach hardware to driver, attach hardware driver to audio 369 * pseudo-device driver . 370 */ 371 void 372 ad1848_attach(struct ad1848_softc *sc) 373 { 374 static struct ad1848_volume vol_mid = {220, 220}; 375 static struct ad1848_volume vol_0 = {0, 0}; 376 int i; 377 int timeout; 378 379 /* Initialize the ad1848... */ 380 for (i = 0; i < 0x10; i++) { 381 ad_write(sc, i, ad1848_init_values[i]); 382 timeout = 100000; 383 while (timeout > 0 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT) 384 timeout--; 385 } 386 /* ...and additional CS4231 stuff too */ 387 if (sc->mode >= 2) { 388 ad_write(sc, SP_INTERFACE_CONFIG, 0); /* disable SINGLE_DMA */ 389 for (i = 0x10; i < 0x20; i++) 390 if (ad1848_init_values[i] != 0) { 391 ad_write(sc, i, ad1848_init_values[i]); 392 timeout = 100000; 393 while (timeout > 0 && 394 ADREAD(sc, AD1848_IADDR) & SP_IN_INIT) 395 timeout--; 396 } 397 } 398 ad1848_reset(sc); 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 int 500 ad1848_set_channel_gain(struct ad1848_softc *sc, int device, 501 struct ad1848_volume *gp) 502 { 503 const struct ad1848_mixerinfo *info; 504 u_char reg; 505 u_int atten; 506 507 info = &mixer_channel_info[device]; 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 int 534 ad1848_get_device_gain(struct ad1848_softc *sc, int device, 535 struct ad1848_volume *gp) 536 { 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 546 *gp = sc->rec_gain; 547 return 0; 548 } 549 550 int 551 ad1848_set_rec_gain(struct ad1848_softc *sc, struct ad1848_volume *gp) 552 { 553 u_char reg, gain; 554 555 DPRINTF(("ad1848_set_rec_gain: %d:%d\n", gp->left, gp->right)); 556 557 sc->rec_gain = *gp; 558 559 gain = (gp->left * (GAIN_22_5 + 1)) / (AUDIO_MAX_GAIN + 1); 560 reg = ad_read(sc, SP_LEFT_INPUT_CONTROL); 561 reg &= INPUT_GAIN_MASK; 562 ad_write(sc, SP_LEFT_INPUT_CONTROL, (gain & 0x0f) | reg); 563 564 gain = (gp->right * (GAIN_22_5 + 1)) / (AUDIO_MAX_GAIN + 1); 565 reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL); 566 reg &= INPUT_GAIN_MASK; 567 ad_write(sc, SP_RIGHT_INPUT_CONTROL, (gain & 0x0f) | reg); 568 569 return 0; 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 static ad1848_devmap_t * 628 ad1848_mixer_find_dev(ad1848_devmap_t *map, int cnt, mixer_ctrl_t *cp) 629 { 630 int i; 631 632 for (i = 0; i < cnt; i++) { 633 if (map[i].id == cp->dev) { 634 return (&map[i]); 635 } 636 } 637 return 0; 638 } 639 640 int 641 ad1848_mixer_get_port(struct ad1848_softc *ac, struct ad1848_devmap *map, 642 int cnt, mixer_ctrl_t *cp) 643 { 644 ad1848_devmap_t *entry; 645 struct ad1848_volume vol; 646 int error; 647 int dev; 648 649 error = EINVAL; 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; 720 int dev; 721 722 error = EINVAL; 723 if (!(entry = ad1848_mixer_find_dev(map, cnt, cp))) 724 return ENXIO; 725 726 dev = entry->dev; 727 728 switch (entry->kind) { 729 case AD1848_KIND_LVL: 730 if (cp->type != AUDIO_MIXER_VALUE) 731 break; 732 733 if (dev < AD1848_AUX2_CHANNEL || 734 dev > AD1848_MONITOR_CHANNEL) 735 break; 736 737 if (cp->un.value.num_channels != 1 && 738 mixer_channel_info[dev].right_reg == 0) 739 break; 740 741 ad1848_to_vol(cp, &vol); 742 error = ad1848_set_channel_gain(ac, dev, &vol); 743 break; 744 745 case AD1848_KIND_MUTE: 746 if (cp->type != AUDIO_MIXER_ENUM) break; 747 748 ac->mute[dev] = (cp->un.ord ? MUTE_ALL : 0); 749 ad1848_mute_channel(ac, dev, ac->mute[dev]); 750 error = 0; 751 break; 752 753 case AD1848_KIND_RECORDGAIN: 754 if (cp->type != AUDIO_MIXER_VALUE) break; 755 756 ad1848_to_vol(cp, &vol); 757 error = ad1848_set_rec_gain(ac, &vol); 758 break; 759 760 case AD1848_KIND_MICGAIN: 761 if (cp->type != AUDIO_MIXER_VALUE) break; 762 763 ad1848_to_vol(cp, &vol); 764 error = ad1848_set_mic_gain(ac, &vol); 765 break; 766 767 case AD1848_KIND_RECORDSOURCE: 768 if (cp->type != AUDIO_MIXER_ENUM) break; 769 770 error = ad1848_set_rec_port(ac, cp->un.ord); 771 break; 772 773 default: 774 printf ("Invalid kind\n"); 775 break; 776 } 777 778 return error; 779 } 780 781 int 782 ad1848_query_encoding(void *addr, struct audio_encoding *fp) 783 { 784 struct ad1848_softc *sc; 785 786 sc = addr; 787 switch (fp->index) { 788 case 0: 789 strcpy(fp->name, AudioEmulaw); 790 fp->encoding = AUDIO_ENCODING_ULAW; 791 fp->precision = 8; 792 fp->flags = 0; 793 break; 794 case 1: 795 strcpy(fp->name, AudioEalaw); 796 fp->encoding = AUDIO_ENCODING_ALAW; 797 fp->precision = 8; 798 fp->flags = 0; 799 break; 800 case 2: 801 strcpy(fp->name, AudioEslinear_le); 802 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 803 fp->precision = 16; 804 fp->flags = 0; 805 break; 806 case 3: 807 strcpy(fp->name, AudioEulinear); 808 fp->encoding = AUDIO_ENCODING_ULINEAR; 809 fp->precision = 8; 810 fp->flags = 0; 811 break; 812 813 case 4: /* only on CS4231 */ 814 strcpy(fp->name, AudioEslinear_be); 815 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 816 fp->precision = 16; 817 fp->flags = sc->mode == 1 818 #if AD1845_HACK 819 || sc->is_ad1845 820 #endif 821 ? AUDIO_ENCODINGFLAG_EMULATED : 0; 822 break; 823 824 /* emulate some modes */ 825 case 5: 826 strcpy(fp->name, AudioEslinear); 827 fp->encoding = AUDIO_ENCODING_SLINEAR; 828 fp->precision = 8; 829 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 830 break; 831 case 6: 832 strcpy(fp->name, AudioEulinear_le); 833 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 834 fp->precision = 16; 835 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 836 break; 837 case 7: 838 strcpy(fp->name, AudioEulinear_be); 839 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 840 fp->precision = 16; 841 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 842 break; 843 844 case 8: /* only on CS4231 */ 845 if (sc->mode == 1 || sc->is_ad1845) 846 return EINVAL; 847 strcpy(fp->name, AudioEadpcm); 848 fp->encoding = AUDIO_ENCODING_ADPCM; 849 fp->precision = 4; 850 fp->flags = 0; 851 break; 852 default: 853 return EINVAL; 854 /*NOTREACHED*/ 855 } 856 return 0; 857 } 858 859 int 860 ad1848_set_params(void *addr, int setmode, int usemode, audio_params_t *p, 861 audio_params_t *r, stream_filter_list_t *pfil, stream_filter_list_t *rfil) 862 { 863 audio_params_t phw, rhw; 864 struct ad1848_softc *sc; 865 int error, bits, enc; 866 stream_filter_factory_t *pswcode; 867 stream_filter_factory_t *rswcode; 868 869 DPRINTF(("ad1848_set_params: %u %u %u %u\n", 870 p->encoding, p->precision, p->channels, p->sample_rate)); 871 872 sc = addr; 873 enc = p->encoding; 874 pswcode = rswcode = 0; 875 phw = *p; 876 rhw = *r; 877 switch (enc) { 878 case AUDIO_ENCODING_SLINEAR_LE: 879 if (p->precision == 8) { 880 enc = AUDIO_ENCODING_ULINEAR_LE; 881 phw.encoding = AUDIO_ENCODING_ULINEAR_LE; 882 rhw.encoding = AUDIO_ENCODING_ULINEAR_LE; 883 pswcode = rswcode = change_sign8; 884 } 885 break; 886 case AUDIO_ENCODING_SLINEAR_BE: 887 if (p->precision == 16 && (sc->mode == 1 888 #if AD1845_HACK 889 || sc->is_ad1845 890 #endif 891 )) { 892 enc = AUDIO_ENCODING_SLINEAR_LE; 893 phw.encoding = AUDIO_ENCODING_SLINEAR_LE; 894 rhw.encoding = AUDIO_ENCODING_SLINEAR_LE; 895 pswcode = rswcode = swap_bytes; 896 } 897 break; 898 case AUDIO_ENCODING_ULINEAR_LE: 899 if (p->precision == 16) { 900 enc = AUDIO_ENCODING_SLINEAR_LE; 901 phw.encoding = AUDIO_ENCODING_SLINEAR_LE; 902 rhw.encoding = AUDIO_ENCODING_SLINEAR_LE; 903 pswcode = rswcode = change_sign16; 904 } 905 break; 906 case AUDIO_ENCODING_ULINEAR_BE: 907 if (p->precision == 16) { 908 if (sc->mode == 1 909 #if AD1845_HACK 910 || sc->is_ad1845 911 #endif 912 ) { 913 enc = AUDIO_ENCODING_SLINEAR_LE; 914 phw.encoding = AUDIO_ENCODING_SLINEAR_LE; 915 rhw.encoding = AUDIO_ENCODING_SLINEAR_LE; 916 pswcode = swap_bytes_change_sign16; 917 rswcode = swap_bytes_change_sign16; 918 } else { 919 enc = AUDIO_ENCODING_SLINEAR_BE; 920 phw.encoding = AUDIO_ENCODING_SLINEAR_BE; 921 rhw.encoding = AUDIO_ENCODING_SLINEAR_BE; 922 pswcode = rswcode = change_sign16; 923 } 924 } 925 break; 926 } 927 switch (enc) { 928 case AUDIO_ENCODING_ULAW: 929 bits = FMT_ULAW >> 5; 930 break; 931 case AUDIO_ENCODING_ALAW: 932 bits = FMT_ALAW >> 5; 933 break; 934 case AUDIO_ENCODING_ADPCM: 935 bits = FMT_ADPCM >> 5; 936 break; 937 case AUDIO_ENCODING_SLINEAR_LE: 938 if (p->precision == 16) 939 bits = FMT_TWOS_COMP >> 5; 940 else 941 return EINVAL; 942 break; 943 case AUDIO_ENCODING_SLINEAR_BE: 944 if (p->precision == 16) 945 bits = FMT_TWOS_COMP_BE >> 5; 946 else 947 return EINVAL; 948 break; 949 case AUDIO_ENCODING_ULINEAR_LE: 950 if (p->precision == 8) 951 bits = FMT_PCM8 >> 5; 952 else 953 return EINVAL; 954 break; 955 default: 956 return EINVAL; 957 } 958 959 if (p->channels < 1 || p->channels > 2) 960 return EINVAL; 961 962 error = ad1848_set_speed(sc, &p->sample_rate); 963 if (error) 964 return error; 965 phw.sample_rate = p->sample_rate; 966 967 if (pswcode != NULL) 968 pfil->append(pfil, pswcode, &phw); 969 if (rswcode != NULL) 970 rfil->append(rfil, rswcode, &rhw); 971 972 sc->format_bits = bits; 973 sc->channels = p->channels; 974 sc->precision = p->precision; 975 sc->need_commit = 1; 976 977 DPRINTF(("ad1848_set_params succeeded, bits=%x\n", bits)); 978 return 0; 979 } 980 981 int 982 ad1848_set_rec_port(struct ad1848_softc *sc, int port) 983 { 984 u_char inp, reg; 985 986 DPRINTF(("ad1848_set_rec_port: 0x%x\n", port)); 987 988 if (port == MIC_IN_PORT) 989 inp = MIC_INPUT; 990 else if (port == LINE_IN_PORT) 991 inp = LINE_INPUT; 992 else if (port == DAC_IN_PORT) 993 inp = MIXED_DAC_INPUT; 994 else if (sc->mode >= 2 && port == AUX1_IN_PORT) 995 inp = AUX_INPUT; 996 else 997 return EINVAL; 998 999 reg = ad_read(sc, SP_LEFT_INPUT_CONTROL); 1000 reg &= INPUT_SOURCE_MASK; 1001 ad_write(sc, SP_LEFT_INPUT_CONTROL, (inp|reg)); 1002 1003 reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL); 1004 reg &= INPUT_SOURCE_MASK; 1005 ad_write(sc, SP_RIGHT_INPUT_CONTROL, (inp|reg)); 1006 1007 sc->rec_port = port; 1008 1009 return 0; 1010 } 1011 1012 int 1013 ad1848_get_rec_port(struct ad1848_softc *sc) 1014 { 1015 return sc->rec_port; 1016 } 1017 1018 int 1019 ad1848_round_blocksize(void *addr, int blk, 1020 int mode, const audio_params_t *param) 1021 { 1022 1023 /* Round to a multiple of the biggest sample size. */ 1024 return blk &= -4; 1025 } 1026 1027 int 1028 ad1848_open(void *addr, int flags) 1029 { 1030 struct ad1848_softc *sc; 1031 u_char reg; 1032 1033 sc = addr; 1034 DPRINTF(("ad1848_open: sc=%p\n", sc)); 1035 1036 sc->open_mode = flags; 1037 1038 /* Enable interrupts */ 1039 DPRINTF(("ad1848_open: enable intrs\n")); 1040 reg = ad_read(sc, SP_PIN_CONTROL); 1041 ad_write(sc, SP_PIN_CONTROL, reg | INTERRUPT_ENABLE); 1042 1043 /* If recording && monitoring, the playback part is also used. */ 1044 if (flags & FREAD && sc->mute[AD1848_MONITOR_CHANNEL] == 0) 1045 ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 1); 1046 1047 #ifdef AUDIO_DEBUG 1048 if (ad1848debug) 1049 ad1848_dump_regs(sc); 1050 #endif 1051 1052 return 0; 1053 } 1054 1055 /* 1056 * Close function is called at splaudio(). 1057 */ 1058 void 1059 ad1848_close(void *addr) 1060 { 1061 struct ad1848_softc *sc; 1062 u_char reg; 1063 1064 sc = addr; 1065 sc->open_mode = 0; 1066 1067 ad1848_mute_wave_output(sc, WAVE_UNMUTE1, 0); 1068 1069 /* Disable interrupts */ 1070 DPRINTF(("ad1848_close: disable intrs\n")); 1071 reg = ad_read(sc, SP_PIN_CONTROL); 1072 ad_write(sc, SP_PIN_CONTROL, reg & ~INTERRUPT_ENABLE); 1073 1074 #ifdef AUDIO_DEBUG 1075 if (ad1848debug) 1076 ad1848_dump_regs(sc); 1077 #endif 1078 } 1079 1080 /* 1081 * Lower-level routines 1082 */ 1083 int 1084 ad1848_commit_settings(void *addr) 1085 { 1086 struct ad1848_softc *sc; 1087 int timeout; 1088 u_char fs; 1089 int s; 1090 1091 sc = addr; 1092 if (!sc->need_commit) 1093 return 0; 1094 1095 s = splaudio(); 1096 1097 ad1848_mute_wave_output(sc, WAVE_MUTE0, 1); 1098 1099 ad_set_MCE(sc, 1); /* Enables changes to the format select reg */ 1100 1101 fs = sc->speed_bits | (sc->format_bits << 5); 1102 1103 if (sc->channels == 2) 1104 fs |= FMT_STEREO; 1105 1106 /* 1107 * OPL3-SA2 (YMF711) is sometimes busy here. 1108 * Wait until it becomes ready. 1109 */ 1110 for (timeout = 0; 1111 timeout < 1000 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT; timeout++) 1112 delay(10); 1113 1114 ad_write(sc, SP_CLOCK_DATA_FORMAT, fs); 1115 1116 /* 1117 * If mode >= 2 (CS4231), set I28 also. 1118 * It's the capture format register. 1119 */ 1120 if (sc->mode >= 2) { 1121 /* 1122 * Gravis Ultrasound MAX SDK sources says something about 1123 * errata sheets, with the implication that these inb()s 1124 * are necessary. 1125 */ 1126 (void)ADREAD(sc, AD1848_IDATA); 1127 (void)ADREAD(sc, AD1848_IDATA); 1128 /* Write to I8 starts resynchronization. Wait for completion. */ 1129 timeout = 100000; 1130 while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) 1131 timeout--; 1132 1133 ad_write(sc, CS_REC_FORMAT, fs); 1134 (void)ADREAD(sc, AD1848_IDATA); 1135 (void)ADREAD(sc, AD1848_IDATA); 1136 /* Now wait for resync for capture side of the house */ 1137 } 1138 /* 1139 * Write to I8 starts resynchronization. Wait until it completes. 1140 */ 1141 timeout = 100000; 1142 while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) { 1143 delay(10); 1144 timeout--; 1145 } 1146 1147 if (ADREAD(sc, AD1848_IADDR) == SP_IN_INIT) 1148 printf("ad1848_commit: Auto calibration timed out\n"); 1149 1150 /* 1151 * Starts the calibration process and 1152 * enters playback mode after it. 1153 */ 1154 ad_set_MCE(sc, 0); 1155 wait_for_calibration(sc); 1156 1157 ad1848_mute_wave_output(sc, WAVE_MUTE0, 0); 1158 1159 splx(s); 1160 1161 sc->need_commit = 0; 1162 return 0; 1163 } 1164 1165 void 1166 ad1848_reset(struct ad1848_softc *sc) 1167 { 1168 u_char r; 1169 1170 DPRINTF(("ad1848_reset\n")); 1171 1172 /* Clear the PEN and CEN bits */ 1173 r = ad_read(sc, SP_INTERFACE_CONFIG); 1174 r &= ~(CAPTURE_ENABLE | PLAYBACK_ENABLE); 1175 ad_write(sc, SP_INTERFACE_CONFIG, r); 1176 1177 if (sc->mode >= 2) { 1178 ADWRITE(sc, AD1848_IADDR, CS_IRQ_STATUS); 1179 ADWRITE(sc, AD1848_IDATA, 0); 1180 } 1181 /* Clear interrupt status */ 1182 ADWRITE(sc, AD1848_STATUS, 0); 1183 #ifdef AUDIO_DEBUG 1184 if (ad1848debug) 1185 ad1848_dump_regs(sc); 1186 #endif 1187 } 1188 1189 int 1190 ad1848_set_speed(struct ad1848_softc *sc, u_int *argp) 1191 { 1192 /* 1193 * The sampling speed is encoded in the least significant nible of I8. 1194 * The LSB selects the clock source (0=24.576 MHz, 1=16.9344 MHz) and 1195 * other three bits select the divisor (indirectly): 1196 * 1197 * The available speeds are in the following table. Keep the speeds in 1198 * the increasing order. 1199 */ 1200 typedef struct { 1201 int speed; 1202 u_char bits; 1203 } speed_struct; 1204 u_long arg; 1205 1206 static const speed_struct speed_table[] = { 1207 {5510, (0 << 1) | 1}, 1208 {5510, (0 << 1) | 1}, 1209 {6620, (7 << 1) | 1}, 1210 {8000, (0 << 1) | 0}, 1211 {9600, (7 << 1) | 0}, 1212 {11025, (1 << 1) | 1}, 1213 {16000, (1 << 1) | 0}, 1214 {18900, (2 << 1) | 1}, 1215 {22050, (3 << 1) | 1}, 1216 {27420, (2 << 1) | 0}, 1217 {32000, (3 << 1) | 0}, 1218 {33075, (6 << 1) | 1}, 1219 {37800, (4 << 1) | 1}, 1220 {44100, (5 << 1) | 1}, 1221 {48000, (6 << 1) | 0} 1222 }; 1223 1224 int i, n, selected; 1225 1226 arg = *argp; 1227 selected = -1; 1228 n = sizeof(speed_table) / sizeof(speed_struct); 1229 1230 if (arg < speed_table[0].speed) 1231 selected = 0; 1232 if (arg > speed_table[n - 1].speed) 1233 selected = n - 1; 1234 1235 for (i = 1 /*really*/ ; selected == -1 && i < n; i++) 1236 if (speed_table[i].speed == arg) 1237 selected = i; 1238 else if (speed_table[i].speed > arg) { 1239 int diff1, diff2; 1240 1241 diff1 = arg - speed_table[i - 1].speed; 1242 diff2 = speed_table[i].speed - arg; 1243 1244 if (diff1 < diff2) 1245 selected = i - 1; 1246 else 1247 selected = i; 1248 } 1249 1250 if (selected == -1) { 1251 printf("ad1848: Can't find speed???\n"); 1252 selected = 3; 1253 } 1254 1255 sc->speed_bits = speed_table[selected].bits; 1256 sc->need_commit = 1; 1257 *argp = speed_table[selected].speed; 1258 1259 return 0; 1260 } 1261 1262 /* 1263 * Halt I/O 1264 */ 1265 int 1266 ad1848_halt_output(void *addr) 1267 { 1268 struct ad1848_softc *sc; 1269 u_char reg; 1270 1271 DPRINTF(("ad1848: ad1848_halt_output\n")); 1272 sc = addr; 1273 reg = ad_read(sc, SP_INTERFACE_CONFIG); 1274 ad_write(sc, SP_INTERFACE_CONFIG, reg & ~PLAYBACK_ENABLE); 1275 1276 return 0; 1277 } 1278 1279 int 1280 ad1848_halt_input(void *addr) 1281 { 1282 struct ad1848_softc *sc; 1283 u_char reg; 1284 1285 DPRINTF(("ad1848: ad1848_halt_input\n")); 1286 sc = addr; 1287 reg = ad_read(sc, SP_INTERFACE_CONFIG); 1288 ad_write(sc, SP_INTERFACE_CONFIG, reg & ~CAPTURE_ENABLE); 1289 1290 return 0; 1291 } 1292