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