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