1 /* $NetBSD: ym.c,v 1.44 2013/11/08 03:12:17 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1999-2002, 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by ITOH Yasufumi. 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1998 Constantine Sapuntzakis. All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 3. The name of the author may not be used to endorse or promote products 44 * derived from this software without specific prior written permission. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 48 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 50 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 51 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 52 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 53 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 54 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 55 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 */ 57 58 /* 59 * Original code from OpenBSD. 60 */ 61 62 #include <sys/cdefs.h> 63 __KERNEL_RCSID(0, "$NetBSD: ym.c,v 1.44 2013/11/08 03:12:17 christos Exp $"); 64 65 #include "mpu_ym.h" 66 #include "opt_ym.h" 67 68 #include <sys/param.h> 69 #include <sys/systm.h> 70 #include <sys/errno.h> 71 #include <sys/device.h> 72 #include <sys/fcntl.h> 73 #include <sys/kernel.h> 74 #include <sys/proc.h> 75 76 #include <sys/cpu.h> 77 #include <sys/intr.h> 78 #include <sys/bus.h> 79 80 #include <sys/audioio.h> 81 #include <dev/audio_if.h> 82 83 #include <dev/isa/isavar.h> 84 #include <dev/isa/isadmavar.h> 85 86 #include <dev/ic/ad1848reg.h> 87 #include <dev/isa/ad1848var.h> 88 #include <dev/ic/opl3sa3reg.h> 89 #include <dev/isa/wssreg.h> 90 #if NMPU_YM > 0 91 #include <dev/ic/mpuvar.h> 92 #endif 93 #include <dev/isa/ymvar.h> 94 #include <dev/isa/sbreg.h> 95 96 /* Power management mode. */ 97 #ifndef YM_POWER_MODE 98 #define YM_POWER_MODE YM_POWER_POWERSAVE 99 #endif 100 101 /* Time in second before power down the chip. */ 102 #ifndef YM_POWER_OFF_SEC 103 #define YM_POWER_OFF_SEC 5 104 #endif 105 106 /* Default mixer settings. */ 107 #ifndef YM_VOL_MASTER 108 #define YM_VOL_MASTER 208 109 #endif 110 111 #ifndef YM_VOL_DAC 112 #define YM_VOL_DAC 224 113 #endif 114 115 #ifndef YM_VOL_OPL3 116 #define YM_VOL_OPL3 184 117 #endif 118 119 /* 120 * Default position of the equalizer. 121 */ 122 #ifndef YM_DEFAULT_TREBLE 123 #define YM_DEFAULT_TREBLE YM_EQ_FLAT_OFFSET 124 #endif 125 #ifndef YM_DEFAULT_BASS 126 #define YM_DEFAULT_BASS YM_EQ_FLAT_OFFSET 127 #endif 128 129 #ifdef __i386__ /* XXX */ 130 # include "joy.h" 131 #else 132 # define NJOY 0 133 #endif 134 135 #ifdef AUDIO_DEBUG 136 #define DPRINTF(x) if (ymdebug) printf x 137 int ymdebug = 0; 138 #else 139 #define DPRINTF(x) 140 #endif 141 #define DVNAME(softc) (device_xname((softc)->sc_ad1848.sc_ad1848.sc_dev)) 142 143 int ym_getdev(void *, struct audio_device *); 144 int ym_mixer_set_port(void *, mixer_ctrl_t *); 145 int ym_mixer_get_port(void *, mixer_ctrl_t *); 146 int ym_query_devinfo(void *, mixer_devinfo_t *); 147 int ym_intr(void *); 148 #ifndef AUDIO_NO_POWER_CTL 149 static void ym_save_codec_regs(struct ym_softc *); 150 static void ym_restore_codec_regs(struct ym_softc *); 151 int ym_codec_power_ctl(void *, int); 152 static void ym_chip_powerdown(struct ym_softc *); 153 static void ym_chip_powerup(struct ym_softc *, int); 154 static void ym_powerdown_blocks(struct ym_softc *); 155 static void ym_powerdown_callout(void *); 156 void ym_power_ctl(struct ym_softc *, int, int); 157 #endif 158 159 static void ym_init(struct ym_softc *); 160 static void ym_mute(struct ym_softc *, int, int); 161 static void ym_set_master_gain(struct ym_softc *, struct ad1848_volume*); 162 static void ym_hvol_to_master_gain(struct ym_softc *); 163 static void ym_set_mic_gain(struct ym_softc *, int); 164 static void ym_set_3d(struct ym_softc *, mixer_ctrl_t *, 165 struct ad1848_volume *, int); 166 static bool ym_suspend(device_t, const pmf_qual_t *); 167 static bool ym_resume(device_t, const pmf_qual_t *); 168 169 170 const struct audio_hw_if ym_hw_if = { 171 ad1848_isa_open, 172 ad1848_isa_close, 173 NULL, 174 ad1848_query_encoding, 175 ad1848_set_params, 176 ad1848_round_blocksize, 177 ad1848_commit_settings, 178 NULL, 179 NULL, 180 NULL, 181 NULL, 182 ad1848_isa_halt_output, 183 ad1848_isa_halt_input, 184 NULL, 185 ym_getdev, 186 NULL, 187 ym_mixer_set_port, 188 ym_mixer_get_port, 189 ym_query_devinfo, 190 ad1848_isa_malloc, 191 ad1848_isa_free, 192 ad1848_isa_round_buffersize, 193 ad1848_isa_mappage, 194 ad1848_isa_get_props, 195 ad1848_isa_trigger_output, 196 ad1848_isa_trigger_input, 197 NULL, 198 ad1848_get_locks, 199 }; 200 201 static inline int ym_read(struct ym_softc *, int); 202 static inline void ym_write(struct ym_softc *, int, int); 203 204 void 205 ym_attach(struct ym_softc *sc) 206 { 207 static struct ad1848_volume vol_master = {YM_VOL_MASTER, YM_VOL_MASTER}; 208 static struct ad1848_volume vol_dac = {YM_VOL_DAC, YM_VOL_DAC}; 209 static struct ad1848_volume vol_opl3 = {YM_VOL_OPL3, YM_VOL_OPL3}; 210 struct ad1848_softc *ac; 211 mixer_ctrl_t mctl; 212 struct audio_attach_args arg; 213 214 ac = &sc->sc_ad1848.sc_ad1848; 215 callout_init(&sc->sc_powerdown_ch, CALLOUT_MPSAFE); 216 cv_init(&sc->sc_cv, "ym"); 217 ad1848_init_locks(ac, IPL_AUDIO); 218 219 /* Mute the output to reduce noise during initialization. */ 220 ym_mute(sc, SA3_VOL_L, 1); 221 ym_mute(sc, SA3_VOL_R, 1); 222 223 sc->sc_version = ym_read(sc, SA3_MISC) & SA3_MISC_VER; 224 ac->chip_name = YM_IS_SA3(sc) ? "OPL3-SA3" : "OPL3-SA2"; 225 226 sc->sc_ad1848.sc_ih = isa_intr_establish(sc->sc_ic, sc->ym_irq, 227 IST_EDGE, IPL_AUDIO, ym_intr, sc); 228 229 #ifndef AUDIO_NO_POWER_CTL 230 sc->sc_ad1848.powerctl = ym_codec_power_ctl; 231 sc->sc_ad1848.powerarg = sc; 232 #endif 233 ad1848_isa_attach(&sc->sc_ad1848); 234 printf("\n"); 235 ac->parent = sc; 236 237 /* Establish chip in well known mode */ 238 ym_set_master_gain(sc, &vol_master); 239 ym_set_mic_gain(sc, 0); 240 sc->master_mute = 0; 241 242 /* Override ad1848 settings. */ 243 ad1848_set_channel_gain(ac, AD1848_DAC_CHANNEL, &vol_dac); 244 ad1848_set_channel_gain(ac, AD1848_AUX2_CHANNEL, &vol_opl3); 245 246 /* 247 * Mute all external sources. If you change this, you must 248 * also change the initial value of sc->sc_external_sources 249 * (currently 0 --- no external source is active). 250 */ 251 sc->mic_mute = 1; 252 ym_mute(sc, SA3_MIC_VOL, sc->mic_mute); 253 ad1848_mute_channel(ac, AD1848_AUX1_CHANNEL, MUTE_ALL); /* CD */ 254 ad1848_mute_channel(ac, AD1848_LINE_CHANNEL, MUTE_ALL); /* line */ 255 ac->mute[AD1848_AUX1_CHANNEL] = MUTE_ALL; 256 ac->mute[AD1848_LINE_CHANNEL] = MUTE_ALL; 257 /* speaker is muted by default */ 258 259 /* We use only one IRQ (IRQ-A). */ 260 ym_write(sc, SA3_IRQ_CONF, SA3_IRQ_CONF_MPU_A | SA3_IRQ_CONF_WSS_A); 261 ym_write(sc, SA3_HVOL_INTR_CNF, SA3_HVOL_INTR_CNF_A); 262 263 /* audio at ym attachment */ 264 sc->sc_audiodev = audio_attach_mi(&ym_hw_if, ac, ac->sc_dev); 265 266 /* opl at ym attachment */ 267 if (sc->sc_opl_ioh) { 268 arg.type = AUDIODEV_TYPE_OPL; 269 arg.hwif = 0; 270 arg.hdl = 0; 271 (void)config_found(ac->sc_dev, &arg, audioprint); 272 } 273 274 #if NMPU_YM > 0 275 /* mpu at ym attachment */ 276 if (sc->sc_mpu_ioh) { 277 arg.type = AUDIODEV_TYPE_MPU; 278 arg.hwif = 0; 279 arg.hdl = 0; 280 sc->sc_mpudev = config_found(ac->sc_dev, &arg, audioprint); 281 } 282 #endif 283 284 /* This must be AFTER the attachment of sub-devices. */ 285 mutex_spin_enter(&sc->sc_ad1848.sc_ad1848.sc_intr_lock); 286 ym_init(sc); 287 288 #ifndef AUDIO_NO_POWER_CTL 289 /* 290 * Initialize power control. 291 */ 292 sc->sc_pow_mode = YM_POWER_MODE; 293 sc->sc_pow_timeout = YM_POWER_OFF_SEC; 294 295 sc->sc_on_blocks = sc->sc_turning_off = 296 YM_POWER_CODEC_P | YM_POWER_CODEC_R | 297 YM_POWER_OPL3 | YM_POWER_MPU401 | YM_POWER_3D | 298 YM_POWER_CODEC_DA | YM_POWER_CODEC_AD | YM_POWER_OPL3_DA; 299 #if NJOY > 0 300 sc->sc_on_blocks |= YM_POWER_JOYSTICK; /* prevents chip powerdown */ 301 #endif 302 ym_powerdown_blocks(sc); 303 mutex_spin_exit(&sc->sc_ad1848.sc_ad1848.sc_intr_lock); 304 305 if (!pmf_device_register(ac->sc_dev, ym_suspend, ym_resume)) { 306 aprint_error_dev(ac->sc_dev, 307 "cannot set power mgmt handler\n"); 308 } 309 #endif 310 311 /* Set tone control to the default position. */ 312 mctl.un.value.num_channels = 1; 313 mctl.un.value.level[AUDIO_MIXER_LEVEL_MONO] = YM_DEFAULT_TREBLE; 314 mctl.dev = YM_MASTER_TREBLE; 315 ym_mixer_set_port(sc, &mctl); 316 mctl.un.value.level[AUDIO_MIXER_LEVEL_MONO] = YM_DEFAULT_BASS; 317 mctl.dev = YM_MASTER_BASS; 318 ym_mixer_set_port(sc, &mctl); 319 320 /* Unmute the output now if the chip is on. */ 321 #ifndef AUDIO_NO_POWER_CTL 322 if (sc->sc_on_blocks & YM_POWER_ACTIVE) 323 #endif 324 { 325 ym_mute(sc, SA3_VOL_L, sc->master_mute); 326 ym_mute(sc, SA3_VOL_R, sc->master_mute); 327 } 328 } 329 330 static inline int 331 ym_read(struct ym_softc *sc, int reg) 332 { 333 334 bus_space_write_1(sc->sc_iot, sc->sc_controlioh, 335 SA3_CTL_INDEX, (reg & 0xff)); 336 return bus_space_read_1(sc->sc_iot, sc->sc_controlioh, SA3_CTL_DATA); 337 } 338 339 static inline void 340 ym_write(struct ym_softc *sc, int reg, int data) 341 { 342 343 bus_space_write_1(sc->sc_iot, sc->sc_controlioh, 344 SA3_CTL_INDEX, (reg & 0xff)); 345 bus_space_write_1(sc->sc_iot, sc->sc_controlioh, 346 SA3_CTL_DATA, (data & 0xff)); 347 } 348 349 static void 350 ym_init(struct ym_softc *sc) 351 { 352 uint8_t dpd, apd; 353 354 KASSERT(mutex_owned(&sc->sc_ad1848.sc_ad1848.sc_intr_lock)); 355 356 /* Mute SoundBlaster output if possible. */ 357 if (sc->sc_sb_ioh) { 358 bus_space_write_1(sc->sc_iot, sc->sc_sb_ioh, SBP_MIXER_ADDR, 359 SBP_MASTER_VOL); 360 bus_space_write_1(sc->sc_iot, sc->sc_sb_ioh, SBP_MIXER_DATA, 361 0x00); 362 } 363 364 if (!YM_IS_SA3(sc)) { 365 /* OPL3-SA2 */ 366 ym_write(sc, SA3_PWR_MNG, SA2_PWR_MNG_CLKO | 367 (sc->sc_opl_ioh == 0 ? SA2_PWR_MNG_FMPS : 0)); 368 return; 369 } 370 371 /* OPL3-SA3 */ 372 /* Figure out which part can be power down. */ 373 dpd = SA3_DPWRDWN_SB /* we never use SB */ 374 #if NMPU_YM > 0 375 | (sc->sc_mpu_ioh ? 0 : SA3_DPWRDWN_MPU) 376 #else 377 | SA3_DPWRDWN_MPU 378 #endif 379 #if NJOY == 0 380 | SA3_DPWRDWN_JOY 381 #endif 382 | SA3_DPWRDWN_PNP /* ISA Plug and Play is done */ 383 /* 384 * The master clock is for external wavetable synthesizer 385 * OPL4-ML (YMF704) or OPL4-ML2 (YMF721), 386 * and is currently unused. 387 */ 388 | SA3_DPWRDWN_MCLKO; 389 390 apd = SA3_APWRDWN_SBDAC; /* we never use SB */ 391 392 /* Power down OPL3 if not attached. */ 393 if (sc->sc_opl_ioh == 0) { 394 dpd |= SA3_DPWRDWN_FM; 395 apd |= SA3_APWRDWN_FMDAC; 396 } 397 /* CODEC is always attached. */ 398 399 /* Power down unused digital parts. */ 400 ym_write(sc, SA3_DPWRDWN, dpd); 401 402 /* Power down unused analog parts. */ 403 ym_write(sc, SA3_APWRDWN, apd); 404 } 405 406 407 int 408 ym_getdev(void *addr, struct audio_device *retp) 409 { 410 struct ym_softc *sc; 411 struct ad1848_softc *ac; 412 413 sc = addr; 414 ac = &sc->sc_ad1848.sc_ad1848; 415 strlcpy(retp->name, ac->chip_name, sizeof(retp->name)); 416 snprintf(retp->version, sizeof(retp->version), "%d", sc->sc_version); 417 strlcpy(retp->config, "ym", sizeof(retp->config)); 418 419 return 0; 420 } 421 422 423 static ad1848_devmap_t mappings[] = { 424 { YM_DAC_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL }, 425 { YM_MIDI_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL }, 426 { YM_CD_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL }, 427 { YM_LINE_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL }, 428 { YM_SPEAKER_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL }, 429 { YM_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL }, 430 { YM_DAC_MUTE, AD1848_KIND_MUTE, AD1848_DAC_CHANNEL }, 431 { YM_MIDI_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL }, 432 { YM_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL }, 433 { YM_LINE_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL }, 434 { YM_SPEAKER_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL }, 435 { YM_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL }, 436 { YM_REC_LVL, AD1848_KIND_RECORDGAIN, -1 }, 437 { YM_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1} 438 }; 439 440 #define NUMMAP (sizeof(mappings) / sizeof(mappings[0])) 441 442 443 static void 444 ym_mute(struct ym_softc *sc, int left_reg, int mute) 445 { 446 uint8_t reg; 447 448 reg = ym_read(sc, left_reg); 449 if (mute) 450 ym_write(sc, left_reg, reg | 0x80); 451 else 452 ym_write(sc, left_reg, reg & ~0x80); 453 } 454 455 456 static void 457 ym_set_master_gain(struct ym_softc *sc, struct ad1848_volume *vol) 458 { 459 u_int atten; 460 461 sc->master_gain = *vol; 462 463 atten = ((AUDIO_MAX_GAIN - vol->left) * (SA3_VOL_MV + 1)) / 464 (AUDIO_MAX_GAIN + 1); 465 466 ym_write(sc, SA3_VOL_L, (ym_read(sc, SA3_VOL_L) & ~SA3_VOL_MV) | atten); 467 468 atten = ((AUDIO_MAX_GAIN - vol->right) * (SA3_VOL_MV + 1)) / 469 (AUDIO_MAX_GAIN + 1); 470 471 ym_write(sc, SA3_VOL_R, (ym_read(sc, SA3_VOL_R) & ~SA3_VOL_MV) | atten); 472 } 473 474 /* 475 * Read current setting of master volume from hardware 476 * and update the software value if changed. 477 * [SA3] This function clears hardware volume interrupt. 478 */ 479 static void 480 ym_hvol_to_master_gain(struct ym_softc *sc) 481 { 482 u_int prevval, val; 483 int changed; 484 485 changed = 0; 486 val = SA3_VOL_MV & ~ym_read(sc, SA3_VOL_L); 487 prevval = (sc->master_gain.left * (SA3_VOL_MV + 1)) / 488 (AUDIO_MAX_GAIN + 1); 489 if (val != prevval) { 490 sc->master_gain.left = 491 val * ((AUDIO_MAX_GAIN + 1) / (SA3_VOL_MV + 1)); 492 changed = 1; 493 } 494 495 val = SA3_VOL_MV & ~ym_read(sc, SA3_VOL_R); 496 prevval = (sc->master_gain.right * (SA3_VOL_MV + 1)) / 497 (AUDIO_MAX_GAIN + 1); 498 if (val != prevval) { 499 sc->master_gain.right = 500 val * ((AUDIO_MAX_GAIN + 1) / (SA3_VOL_MV + 1)); 501 changed = 1; 502 } 503 504 #if 0 /* XXX NOT YET */ 505 /* Notify the change to async processes. */ 506 if (changed && sc->sc_audiodev) 507 mixer_signal(sc->sc_audiodev); 508 #else 509 __USE(changed); 510 #endif 511 } 512 513 static void 514 ym_set_mic_gain(struct ym_softc *sc, int vol) 515 { 516 u_int atten; 517 518 sc->mic_gain = vol; 519 520 atten = ((AUDIO_MAX_GAIN - vol) * (SA3_MIC_MCV + 1)) / 521 (AUDIO_MAX_GAIN + 1); 522 523 ym_write(sc, SA3_MIC_VOL, 524 (ym_read(sc, SA3_MIC_VOL) & ~SA3_MIC_MCV) | atten); 525 } 526 527 static void 528 ym_set_3d(struct ym_softc *sc, mixer_ctrl_t *cp, 529 struct ad1848_volume *val, int reg) 530 { 531 uint8_t l, r, e; 532 533 KASSERT(mutex_owned(&sc->sc_ad1848.sc_ad1848.sc_intr_lock)); 534 535 ad1848_to_vol(cp, val); 536 537 l = val->left; 538 r = val->right; 539 if (reg != SA3_3D_WIDE) { 540 /* flat on center */ 541 l = YM_EQ_EXPAND_VALUE(l); 542 r = YM_EQ_EXPAND_VALUE(r); 543 } 544 545 e = (l * (SA3_3D_BITS + 1) + (SA3_3D_BITS + 1) / 2) / 546 (AUDIO_MAX_GAIN + 1) << SA3_3D_LSHIFT | 547 (r * (SA3_3D_BITS + 1) + (SA3_3D_BITS + 1) / 2) / 548 (AUDIO_MAX_GAIN + 1) << SA3_3D_RSHIFT; 549 550 #ifndef AUDIO_NO_POWER_CTL 551 /* turn wide stereo on if necessary */ 552 if (e) 553 ym_power_ctl(sc, YM_POWER_3D, 1); 554 #endif 555 556 ym_write(sc, reg, e); 557 558 #ifndef AUDIO_NO_POWER_CTL 559 /* turn wide stereo off if necessary */ 560 if (YM_EQ_OFF(&sc->sc_treble) && YM_EQ_OFF(&sc->sc_bass) && 561 YM_WIDE_OFF(&sc->sc_wide)) 562 ym_power_ctl(sc, YM_POWER_3D, 0); 563 #endif 564 } 565 566 int 567 ym_mixer_set_port(void *addr, mixer_ctrl_t *cp) 568 { 569 struct ad1848_softc *ac; 570 struct ym_softc *sc; 571 struct ad1848_volume vol; 572 int error; 573 uint8_t extsources; 574 575 ac = addr; 576 sc = ac->parent; 577 error = 0; 578 DPRINTF(("%s: ym_mixer_set_port: dev 0x%x, type 0x%x, 0x%x (%d; %d, %d)\n", 579 DVNAME(sc), cp->dev, cp->type, cp->un.ord, 580 cp->un.value.num_channels, cp->un.value.level[0], 581 cp->un.value.level[1])); 582 583 /* SA2 doesn't have equalizer */ 584 if (!YM_IS_SA3(sc) && YM_MIXER_SA3_ONLY(cp->dev)) 585 return ENXIO; 586 587 mutex_spin_enter(&ac->sc_intr_lock); 588 589 #ifndef AUDIO_NO_POWER_CTL 590 /* Power-up chip */ 591 ym_power_ctl(sc, YM_POWER_CODEC_CTL, 1); 592 #endif 593 594 switch (cp->dev) { 595 case YM_OUTPUT_LVL: 596 ad1848_to_vol(cp, &vol); 597 ym_set_master_gain(sc, &vol); 598 goto out; 599 600 case YM_OUTPUT_MUTE: 601 sc->master_mute = (cp->un.ord != 0); 602 ym_mute(sc, SA3_VOL_L, sc->master_mute); 603 ym_mute(sc, SA3_VOL_R, sc->master_mute); 604 goto out; 605 606 case YM_MIC_LVL: 607 if (cp->un.value.num_channels != 1) 608 error = EINVAL; 609 else 610 ym_set_mic_gain(sc, 611 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 612 goto out; 613 614 case YM_MASTER_EQMODE: 615 sc->sc_eqmode = cp->un.ord & SA3_SYS_CTL_YMODE; 616 ym_write(sc, SA3_SYS_CTL, (ym_read(sc, SA3_SYS_CTL) & 617 ~SA3_SYS_CTL_YMODE) | sc->sc_eqmode); 618 goto out; 619 620 case YM_MASTER_TREBLE: 621 ym_set_3d(sc, cp, &sc->sc_treble, SA3_3D_TREBLE); 622 goto out; 623 624 case YM_MASTER_BASS: 625 ym_set_3d(sc, cp, &sc->sc_bass, SA3_3D_BASS); 626 goto out; 627 628 case YM_MASTER_WIDE: 629 ym_set_3d(sc, cp, &sc->sc_wide, SA3_3D_WIDE); 630 goto out; 631 632 #ifndef AUDIO_NO_POWER_CTL 633 case YM_PWR_MODE: 634 if ((unsigned) cp->un.ord > YM_POWER_NOSAVE) 635 error = EINVAL; 636 else 637 sc->sc_pow_mode = cp->un.ord; 638 goto out; 639 640 case YM_PWR_TIMEOUT: 641 if (cp->un.value.num_channels != 1) 642 error = EINVAL; 643 else 644 sc->sc_pow_timeout = 645 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 646 goto out; 647 648 /* 649 * Needs power-up to hear external sources. 650 */ 651 case YM_CD_MUTE: 652 case YM_LINE_MUTE: 653 case YM_SPEAKER_MUTE: 654 case YM_MIC_MUTE: 655 extsources = YM_MIXER_TO_XS(cp->dev); 656 if (cp->un.ord) { 657 if ((sc->sc_external_sources &= ~extsources) == 0) { 658 /* 659 * All the external sources are muted 660 * --- no need to keep the chip on. 661 */ 662 ym_power_ctl(sc, YM_POWER_EXT_SRC, 0); 663 DPRINTF(("%s: ym_mixer_set_port: off for ext\n", 664 DVNAME(sc))); 665 } 666 } else { 667 /* mute off - power-up the chip */ 668 sc->sc_external_sources |= extsources; 669 ym_power_ctl(sc, YM_POWER_EXT_SRC, 1); 670 DPRINTF(("%s: ym_mixer_set_port: on for ext\n", 671 DVNAME(sc))); 672 } 673 break; /* fall to ad1848_mixer_set_port() */ 674 675 /* 676 * Power on/off the playback part for monitoring. 677 */ 678 case YM_MONITOR_MUTE: 679 if ((ac->open_mode & (FREAD | FWRITE)) == FREAD) 680 ym_power_ctl(sc, YM_POWER_CODEC_P | YM_POWER_CODEC_DA, 681 cp->un.ord == 0); 682 break; /* fall to ad1848_mixer_set_port() */ 683 #endif 684 } 685 686 error = ad1848_mixer_set_port(ac, mappings, NUMMAP, cp); 687 688 if (error != ENXIO) 689 goto out; 690 691 error = 0; 692 693 switch (cp->dev) { 694 case YM_MIC_MUTE: 695 sc->mic_mute = (cp->un.ord != 0); 696 ym_mute(sc, SA3_MIC_VOL, sc->mic_mute); 697 break; 698 699 default: 700 error = ENXIO; 701 break; 702 } 703 704 out: 705 #ifndef AUDIO_NO_POWER_CTL 706 /* Power-down chip */ 707 ym_power_ctl(sc, YM_POWER_CODEC_CTL, 0); 708 #endif 709 mutex_spin_exit(&ac->sc_intr_lock); 710 711 return error; 712 } 713 714 int 715 ym_mixer_get_port(void *addr, mixer_ctrl_t *cp) 716 { 717 struct ad1848_softc *ac; 718 struct ym_softc *sc; 719 int error; 720 721 ac = addr; 722 sc = ac->parent; 723 /* SA2 doesn't have equalizer */ 724 if (!YM_IS_SA3(sc) && YM_MIXER_SA3_ONLY(cp->dev)) 725 return ENXIO; 726 727 switch (cp->dev) { 728 case YM_OUTPUT_LVL: 729 if (!YM_IS_SA3(sc)) { 730 /* 731 * SA2 doesn't have hardware volume interrupt. 732 * Read current value and update every time. 733 */ 734 mutex_spin_enter(&ac->sc_intr_lock); 735 #ifndef AUDIO_NO_POWER_CTL 736 /* Power-up chip */ 737 ym_power_ctl(sc, YM_POWER_CODEC_CTL, 1); 738 #endif 739 ym_hvol_to_master_gain(sc); 740 #ifndef AUDIO_NO_POWER_CTL 741 /* Power-down chip */ 742 ym_power_ctl(sc, YM_POWER_CODEC_CTL, 0); 743 #endif 744 mutex_spin_exit(&ac->sc_intr_lock); 745 } 746 ad1848_from_vol(cp, &sc->master_gain); 747 return 0; 748 749 case YM_OUTPUT_MUTE: 750 cp->un.ord = sc->master_mute; 751 return 0; 752 753 case YM_MIC_LVL: 754 if (cp->un.value.num_channels != 1) 755 return EINVAL; 756 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->mic_gain; 757 return 0; 758 759 case YM_MASTER_EQMODE: 760 cp->un.ord = sc->sc_eqmode; 761 return 0; 762 763 case YM_MASTER_TREBLE: 764 ad1848_from_vol(cp, &sc->sc_treble); 765 return 0; 766 767 case YM_MASTER_BASS: 768 ad1848_from_vol(cp, &sc->sc_bass); 769 return 0; 770 771 case YM_MASTER_WIDE: 772 ad1848_from_vol(cp, &sc->sc_wide); 773 return 0; 774 775 #ifndef AUDIO_NO_POWER_CTL 776 case YM_PWR_MODE: 777 cp->un.ord = sc->sc_pow_mode; 778 return 0; 779 780 case YM_PWR_TIMEOUT: 781 if (cp->un.value.num_channels != 1) 782 return EINVAL; 783 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_pow_timeout; 784 return 0; 785 #endif 786 } 787 788 error = ad1848_mixer_get_port(ac, mappings, NUMMAP, cp); 789 790 if (error != ENXIO) 791 return error; 792 793 error = 0; 794 795 switch (cp->dev) { 796 case YM_MIC_MUTE: 797 cp->un.ord = sc->mic_mute; 798 break; 799 800 default: 801 error = ENXIO; 802 break; 803 } 804 805 return error; 806 } 807 808 static const char *mixer_classes[] = { 809 AudioCinputs, AudioCrecord, AudioCoutputs, AudioCmonitor, 810 #ifndef AUDIO_NO_POWER_CTL 811 AudioCpower, 812 #endif 813 AudioCequalization 814 }; 815 816 int 817 ym_query_devinfo(void *addr, mixer_devinfo_t *dip) 818 { 819 static const char *mixer_port_names[] = { 820 AudioNdac, AudioNmidi, AudioNcd, AudioNline, AudioNspeaker, 821 AudioNmicrophone, AudioNmonitor 822 }; 823 struct ad1848_softc *ac; 824 struct ym_softc *sc; 825 826 ac = addr; 827 sc = ac->parent; 828 /* SA2 doesn't have equalizer */ 829 if (!YM_IS_SA3(sc) && YM_MIXER_SA3_ONLY(dip->index)) 830 return ENXIO; 831 832 dip->next = dip->prev = AUDIO_MIXER_LAST; 833 834 switch(dip->index) { 835 case YM_INPUT_CLASS: 836 case YM_OUTPUT_CLASS: 837 case YM_MONITOR_CLASS: 838 case YM_RECORD_CLASS: 839 #ifndef AUDIO_NO_POWER_CTL 840 case YM_PWR_CLASS: 841 #endif 842 case YM_EQ_CLASS: 843 dip->type = AUDIO_MIXER_CLASS; 844 dip->mixer_class = dip->index; 845 strcpy(dip->label.name, 846 mixer_classes[dip->index - YM_INPUT_CLASS]); 847 break; 848 849 case YM_DAC_LVL: 850 case YM_MIDI_LVL: 851 case YM_CD_LVL: 852 case YM_LINE_LVL: 853 case YM_SPEAKER_LVL: 854 case YM_MIC_LVL: 855 case YM_MONITOR_LVL: 856 dip->type = AUDIO_MIXER_VALUE; 857 if (dip->index == YM_MONITOR_LVL) 858 dip->mixer_class = YM_MONITOR_CLASS; 859 else 860 dip->mixer_class = YM_INPUT_CLASS; 861 862 dip->next = dip->index + 7; 863 864 strcpy(dip->label.name, 865 mixer_port_names[dip->index - YM_DAC_LVL]); 866 867 if (dip->index == YM_SPEAKER_LVL || 868 dip->index == YM_MIC_LVL) 869 dip->un.v.num_channels = 1; 870 else 871 dip->un.v.num_channels = 2; 872 873 if (dip->index == YM_SPEAKER_LVL) 874 dip->un.v.delta = 1 << (8 - 4 /* valid bits */); 875 else if (dip->index == YM_DAC_LVL || 876 dip->index == YM_MONITOR_LVL) 877 dip->un.v.delta = 1 << (8 - 6 /* valid bits */); 878 else 879 dip->un.v.delta = 1 << (8 - 5 /* valid bits */); 880 881 strcpy(dip->un.v.units.name, AudioNvolume); 882 break; 883 884 case YM_DAC_MUTE: 885 case YM_MIDI_MUTE: 886 case YM_CD_MUTE: 887 case YM_LINE_MUTE: 888 case YM_SPEAKER_MUTE: 889 case YM_MIC_MUTE: 890 case YM_MONITOR_MUTE: 891 if (dip->index == YM_MONITOR_MUTE) 892 dip->mixer_class = YM_MONITOR_CLASS; 893 else 894 dip->mixer_class = YM_INPUT_CLASS; 895 dip->type = AUDIO_MIXER_ENUM; 896 dip->prev = dip->index - 7; 897 mute: 898 strcpy(dip->label.name, AudioNmute); 899 dip->un.e.num_mem = 2; 900 strcpy(dip->un.e.member[0].label.name, AudioNoff); 901 dip->un.e.member[0].ord = 0; 902 strcpy(dip->un.e.member[1].label.name, AudioNon); 903 dip->un.e.member[1].ord = 1; 904 break; 905 906 907 case YM_OUTPUT_LVL: 908 dip->type = AUDIO_MIXER_VALUE; 909 dip->mixer_class = YM_OUTPUT_CLASS; 910 dip->next = YM_OUTPUT_MUTE; 911 strcpy(dip->label.name, AudioNmaster); 912 dip->un.v.num_channels = 2; 913 dip->un.v.delta = (AUDIO_MAX_GAIN + 1) / (SA3_VOL_MV + 1); 914 strcpy(dip->un.v.units.name, AudioNvolume); 915 break; 916 917 case YM_OUTPUT_MUTE: 918 dip->mixer_class = YM_OUTPUT_CLASS; 919 dip->type = AUDIO_MIXER_ENUM; 920 dip->prev = YM_OUTPUT_LVL; 921 goto mute; 922 923 924 case YM_REC_LVL: /* record level */ 925 dip->type = AUDIO_MIXER_VALUE; 926 dip->mixer_class = YM_RECORD_CLASS; 927 dip->next = YM_RECORD_SOURCE; 928 strcpy(dip->label.name, AudioNrecord); 929 dip->un.v.num_channels = 2; 930 dip->un.v.delta = 1 << (8 - 4 /* valid bits */); 931 strcpy(dip->un.v.units.name, AudioNvolume); 932 break; 933 934 case YM_RECORD_SOURCE: 935 dip->mixer_class = YM_RECORD_CLASS; 936 dip->type = AUDIO_MIXER_ENUM; 937 dip->prev = YM_REC_LVL; 938 strcpy(dip->label.name, AudioNsource); 939 dip->un.e.num_mem = 4; 940 strcpy(dip->un.e.member[0].label.name, AudioNmicrophone); 941 dip->un.e.member[0].ord = MIC_IN_PORT; 942 strcpy(dip->un.e.member[1].label.name, AudioNline); 943 dip->un.e.member[1].ord = LINE_IN_PORT; 944 strcpy(dip->un.e.member[2].label.name, AudioNdac); 945 dip->un.e.member[2].ord = DAC_IN_PORT; 946 strcpy(dip->un.e.member[3].label.name, AudioNcd); 947 dip->un.e.member[3].ord = AUX1_IN_PORT; 948 break; 949 950 951 case YM_MASTER_EQMODE: 952 dip->type = AUDIO_MIXER_ENUM; 953 dip->mixer_class = YM_EQ_CLASS; 954 strcpy(dip->label.name, AudioNmode); 955 strcpy(dip->un.v.units.name, AudioNmode); 956 dip->un.e.num_mem = 4; 957 strcpy(dip->un.e.member[0].label.name, AudioNdesktop); 958 dip->un.e.member[0].ord = SA3_SYS_CTL_YMODE0; 959 strcpy(dip->un.e.member[1].label.name, AudioNlaptop); 960 dip->un.e.member[1].ord = SA3_SYS_CTL_YMODE1; 961 strcpy(dip->un.e.member[2].label.name, AudioNsubnote); 962 dip->un.e.member[2].ord = SA3_SYS_CTL_YMODE2; 963 strcpy(dip->un.e.member[3].label.name, AudioNhifi); 964 dip->un.e.member[3].ord = SA3_SYS_CTL_YMODE3; 965 break; 966 967 case YM_MASTER_TREBLE: 968 dip->type = AUDIO_MIXER_VALUE; 969 dip->mixer_class = YM_EQ_CLASS; 970 strcpy(dip->label.name, AudioNtreble); 971 dip->un.v.num_channels = 2; 972 dip->un.v.delta = (AUDIO_MAX_GAIN + 1) / (SA3_3D_BITS + 1) 973 >> YM_EQ_REDUCE_BIT; 974 strcpy(dip->un.v.units.name, AudioNtreble); 975 break; 976 977 case YM_MASTER_BASS: 978 dip->type = AUDIO_MIXER_VALUE; 979 dip->mixer_class = YM_EQ_CLASS; 980 strcpy(dip->label.name, AudioNbass); 981 dip->un.v.num_channels = 2; 982 dip->un.v.delta = (AUDIO_MAX_GAIN + 1) / (SA3_3D_BITS + 1) 983 >> YM_EQ_REDUCE_BIT; 984 strcpy(dip->un.v.units.name, AudioNbass); 985 break; 986 987 case YM_MASTER_WIDE: 988 dip->type = AUDIO_MIXER_VALUE; 989 dip->mixer_class = YM_EQ_CLASS; 990 strcpy(dip->label.name, AudioNsurround); 991 dip->un.v.num_channels = 2; 992 dip->un.v.delta = (AUDIO_MAX_GAIN + 1) / (SA3_3D_BITS + 1); 993 strcpy(dip->un.v.units.name, AudioNsurround); 994 break; 995 996 997 #ifndef AUDIO_NO_POWER_CTL 998 case YM_PWR_MODE: 999 dip->type = AUDIO_MIXER_ENUM; 1000 dip->mixer_class = YM_PWR_CLASS; 1001 dip->next = YM_PWR_TIMEOUT; 1002 strcpy(dip->label.name, AudioNsave); 1003 dip->un.e.num_mem = 3; 1004 strcpy(dip->un.e.member[0].label.name, AudioNpowerdown); 1005 dip->un.e.member[0].ord = YM_POWER_POWERDOWN; 1006 strcpy(dip->un.e.member[1].label.name, AudioNpowersave); 1007 dip->un.e.member[1].ord = YM_POWER_POWERSAVE; 1008 strcpy(dip->un.e.member[2].label.name, AudioNnosave); 1009 dip->un.e.member[2].ord = YM_POWER_NOSAVE; 1010 break; 1011 1012 case YM_PWR_TIMEOUT: 1013 dip->type = AUDIO_MIXER_VALUE; 1014 dip->mixer_class = YM_PWR_CLASS; 1015 dip->prev = YM_PWR_MODE; 1016 strcpy(dip->label.name, AudioNtimeout); 1017 dip->un.v.num_channels = 1; 1018 strcpy(dip->un.v.units.name, AudioNtimeout); 1019 break; 1020 #endif /* not AUDIO_NO_POWER_CTL */ 1021 1022 default: 1023 return ENXIO; 1024 /*NOTREACHED*/ 1025 } 1026 1027 return 0; 1028 } 1029 1030 int 1031 ym_intr(void *arg) 1032 { 1033 struct ym_softc *sc = arg; 1034 #if NMPU_YM > 0 1035 struct mpu_softc *sc_mpu = device_private(sc->sc_mpudev); 1036 #endif 1037 u_int8_t ist; 1038 int processed; 1039 1040 mutex_spin_enter(&sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1041 1042 /* OPL3 timer is currently unused. */ 1043 if (((ist = ym_read(sc, SA3_IRQA_STAT)) & 1044 ~(SA3_IRQ_STAT_SB|SA3_IRQ_STAT_OPL3)) == 0) { 1045 DPRINTF(("%s: ym_intr: spurious interrupt\n", DVNAME(sc))); 1046 mutex_spin_exit(&sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1047 return 0; 1048 } 1049 1050 /* Process pending interrupts. */ 1051 do { 1052 processed = 0; 1053 /* 1054 * CODEC interrupts. 1055 */ 1056 if (ist & (SA3_IRQ_STAT_TI|SA3_IRQ_STAT_CI|SA3_IRQ_STAT_PI)) { 1057 ad1848_isa_intr(&sc->sc_ad1848); 1058 processed = 1; 1059 } 1060 #if NMPU_YM > 0 1061 /* 1062 * MPU401 interrupt. 1063 */ 1064 if (ist & SA3_IRQ_STAT_MPU) { 1065 mpu_intr(sc_mpu); 1066 processed = 1; 1067 } 1068 #endif 1069 /* 1070 * Hardware volume interrupt (SA3 only). 1071 * Recalculate master volume from the hardware setting. 1072 */ 1073 if ((ist & SA3_IRQ_STAT_MV) && YM_IS_SA3(sc)) { 1074 ym_hvol_to_master_gain(sc); 1075 processed = 1; 1076 } 1077 } while (processed && (ist = ym_read(sc, SA3_IRQA_STAT))); 1078 1079 mutex_spin_exit(&sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1080 return 1; 1081 } 1082 1083 1084 #ifndef AUDIO_NO_POWER_CTL 1085 static void 1086 ym_save_codec_regs(struct ym_softc *sc) 1087 { 1088 struct ad1848_softc *ac; 1089 int i; 1090 1091 DPRINTF(("%s: ym_save_codec_regs\n", DVNAME(sc))); 1092 ac = &sc->sc_ad1848.sc_ad1848; 1093 for (i = 0; i <= 0x1f; i++) 1094 sc->sc_codec_scan[i] = ad_read(ac, i); 1095 } 1096 1097 static void 1098 ym_restore_codec_regs(struct ym_softc *sc) 1099 { 1100 struct ad1848_softc *ac; 1101 int i, t; 1102 1103 DPRINTF(("%s: ym_restore_codec_regs\n", DVNAME(sc))); 1104 ac = &sc->sc_ad1848.sc_ad1848; 1105 for (i = 0; i <= 0x1f; i++) { 1106 /* 1107 * Wait til the chip becomes ready. 1108 * This is required after suspend/resume. 1109 */ 1110 for (t = 0; 1111 t < 100000 && ADREAD(ac, AD1848_IADDR) & SP_IN_INIT; t++) 1112 ; 1113 #ifdef AUDIO_DEBUG 1114 if (t) 1115 DPRINTF(("%s: ym_restore_codec_regs: reg %d, t %d\n", 1116 DVNAME(sc), i, t)); 1117 #endif 1118 ad_write(ac, i, sc->sc_codec_scan[i]); 1119 } 1120 } 1121 1122 /* 1123 * Save and restore the state on suspending / resumning. 1124 * 1125 * XXX This is not complete. 1126 * Currently only the parameters, such as output gain, are restored. 1127 * DMA state should also be restored. FIXME. 1128 */ 1129 static bool 1130 ym_suspend(device_t self, const pmf_qual_t *qual) 1131 { 1132 struct ym_softc *sc = device_private(self); 1133 1134 DPRINTF(("%s: ym_power_hook: suspend\n", DVNAME(sc))); 1135 1136 mutex_spin_enter(&sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1137 1138 /* 1139 * suspending... 1140 */ 1141 callout_halt(&sc->sc_powerdown_ch, 1142 &sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1143 if (sc->sc_turning_off) 1144 ym_powerdown_blocks(sc); 1145 1146 /* 1147 * Save CODEC registers. 1148 * Note that the registers read incorrect 1149 * if the CODEC part is in power-down mode. 1150 */ 1151 if (sc->sc_on_blocks & YM_POWER_CODEC_DIGITAL) 1152 ym_save_codec_regs(sc); 1153 1154 /* 1155 * Save OPL3-SA3 control registers and power-down the chip. 1156 * Note that the registers read incorrect 1157 * if the chip is in global power-down mode. 1158 */ 1159 sc->sc_sa3_scan[SA3_PWR_MNG] = ym_read(sc, SA3_PWR_MNG); 1160 if (sc->sc_on_blocks) 1161 ym_chip_powerdown(sc); 1162 mutex_spin_exit(&sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1163 return true; 1164 } 1165 1166 static bool 1167 ym_resume(device_t self, const pmf_qual_t *qual) 1168 { 1169 struct ym_softc *sc = device_private(self); 1170 int i, xmax; 1171 1172 DPRINTF(("%s: ym_power_hook: resume\n", DVNAME(sc))); 1173 1174 mutex_spin_enter(&sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1175 /* 1176 * resuming... 1177 */ 1178 ym_chip_powerup(sc, 1); 1179 ym_init(sc); /* power-on CODEC */ 1180 1181 /* Restore control registers. */ 1182 xmax = YM_IS_SA3(sc)? YM_SAVE_REG_MAX_SA3 : YM_SAVE_REG_MAX_SA2; 1183 for (i = SA3_PWR_MNG + 1; i <= xmax; i++) { 1184 if (i == SA3_SB_SCAN || i == SA3_SB_SCAN_DATA || 1185 i == SA3_DPWRDWN) 1186 continue; 1187 ym_write(sc, i, sc->sc_sa3_scan[i]); 1188 } 1189 1190 /* Restore CODEC registers (including mixer). */ 1191 ym_restore_codec_regs(sc); 1192 1193 /* Restore global/digital power-down state. */ 1194 ym_write(sc, SA3_PWR_MNG, sc->sc_sa3_scan[SA3_PWR_MNG]); 1195 if (YM_IS_SA3(sc)) 1196 ym_write(sc, SA3_DPWRDWN, sc->sc_sa3_scan[SA3_DPWRDWN]); 1197 mutex_spin_exit(&sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1198 return true; 1199 } 1200 1201 int 1202 ym_codec_power_ctl(void *arg, int flags) 1203 { 1204 struct ym_softc *sc; 1205 struct ad1848_softc *ac; 1206 int parts; 1207 1208 sc = arg; 1209 ac = &sc->sc_ad1848.sc_ad1848; 1210 DPRINTF(("%s: ym_codec_power_ctl: flags = 0x%x\n", DVNAME(sc), flags)); 1211 KASSERT(mutex_owned(&ac->sc_intr_lock)); 1212 1213 if (flags != 0) { 1214 parts = 0; 1215 if (flags & FREAD) { 1216 parts |= YM_POWER_CODEC_R | YM_POWER_CODEC_AD; 1217 if (ac->mute[AD1848_MONITOR_CHANNEL] == 0) 1218 parts |= YM_POWER_CODEC_P | YM_POWER_CODEC_DA; 1219 } 1220 if (flags & FWRITE) 1221 parts |= YM_POWER_CODEC_P | YM_POWER_CODEC_DA; 1222 } else 1223 parts = YM_POWER_CODEC_P | YM_POWER_CODEC_R | 1224 YM_POWER_CODEC_DA | YM_POWER_CODEC_AD; 1225 1226 ym_power_ctl(sc, parts, flags); 1227 1228 return 0; 1229 } 1230 1231 /* 1232 * Enter Power Save mode or Global Power Down mode. 1233 * Total dissipation becomes 5mA and 10uA (typ.) respective. 1234 */ 1235 static void 1236 ym_chip_powerdown(struct ym_softc *sc) 1237 { 1238 int i, xmax; 1239 1240 DPRINTF(("%s: ym_chip_powerdown\n", DVNAME(sc))); 1241 KASSERT(mutex_owned(&sc->sc_ad1848.sc_ad1848.sc_intr_lock)); 1242 1243 xmax = YM_IS_SA3(sc) ? YM_SAVE_REG_MAX_SA3 : YM_SAVE_REG_MAX_SA2; 1244 1245 /* Save control registers. */ 1246 for (i = SA3_PWR_MNG + 1; i <= xmax; i++) { 1247 if (i == SA3_SB_SCAN || i == SA3_SB_SCAN_DATA) 1248 continue; 1249 sc->sc_sa3_scan[i] = ym_read(sc, i); 1250 } 1251 ym_write(sc, SA3_PWR_MNG, 1252 (sc->sc_pow_mode == YM_POWER_POWERDOWN ? 1253 SA3_PWR_MNG_PDN : SA3_PWR_MNG_PSV) | SA3_PWR_MNG_PDX); 1254 } 1255 1256 /* 1257 * Power up from Power Save / Global Power Down Mode. 1258 */ 1259 static void 1260 ym_chip_powerup(struct ym_softc *sc, int nosleep) 1261 { 1262 uint8_t pw; 1263 1264 DPRINTF(("%s: ym_chip_powerup\n", DVNAME(sc))); 1265 KASSERT(mutex_owned(&sc->sc_ad1848.sc_ad1848.sc_intr_lock)); 1266 1267 pw = ym_read(sc, SA3_PWR_MNG); 1268 1269 if ((pw & (SA3_PWR_MNG_PSV | SA3_PWR_MNG_PDN | SA3_PWR_MNG_PDX)) == 0) 1270 return; /* already on */ 1271 1272 pw &= ~SA3_PWR_MNG_PDX; 1273 ym_write(sc, SA3_PWR_MNG, pw); 1274 1275 /* wait 100 ms */ 1276 if (nosleep) 1277 delay(100000); 1278 else 1279 kpause("ym_pu1", false, hz / 10, 1280 &sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1281 1282 pw &= ~(SA3_PWR_MNG_PSV | SA3_PWR_MNG_PDN); 1283 ym_write(sc, SA3_PWR_MNG, pw); 1284 1285 /* wait 70 ms */ 1286 if (nosleep) 1287 delay(70000); 1288 else 1289 kpause("ym_pu1", false, hz / 10, 1290 &sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1291 1292 /* The chip is muted automatically --- unmute it now. */ 1293 ym_mute(sc, SA3_VOL_L, sc->master_mute); 1294 ym_mute(sc, SA3_VOL_R, sc->master_mute); 1295 } 1296 1297 /* callout handler for power-down */ 1298 static void 1299 ym_powerdown_callout(void *arg) 1300 { 1301 struct ym_softc *sc; 1302 1303 sc = arg; 1304 1305 mutex_spin_enter(&sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1306 if ((sc->sc_in_power_ctl & YM_POWER_CTL_INUSE) == 0) { 1307 ym_powerdown_blocks(sc); 1308 } 1309 mutex_spin_exit(&sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1310 } 1311 1312 static void 1313 ym_powerdown_blocks(struct ym_softc *sc) 1314 { 1315 uint16_t parts; 1316 uint16_t on_blocks; 1317 uint8_t sv; 1318 1319 on_blocks = sc->sc_on_blocks; 1320 DPRINTF(("%s: ym_powerdown_blocks: turning_off 0x%x\n", 1321 DVNAME(sc), sc->sc_turning_off)); 1322 KASSERT(mutex_owned(&sc->sc_ad1848.sc_ad1848.sc_intr_lock)); 1323 1324 on_blocks = sc->sc_on_blocks; 1325 1326 /* Be sure not to change the state of the chip. Save it first. */ 1327 sv = bus_space_read_1(sc->sc_iot, sc->sc_controlioh, SA3_CTL_INDEX); 1328 1329 parts = sc->sc_turning_off; 1330 1331 if (on_blocks & ~parts & YM_POWER_CODEC_CTL) 1332 parts &= ~(YM_POWER_CODEC_P | YM_POWER_CODEC_R); 1333 if (parts & YM_POWER_CODEC_CTL) { 1334 if ((on_blocks & YM_POWER_CODEC_P) == 0) 1335 parts |= YM_POWER_CODEC_P; 1336 if ((on_blocks & YM_POWER_CODEC_R) == 0) 1337 parts |= YM_POWER_CODEC_R; 1338 } 1339 parts &= ~YM_POWER_CODEC_PSEUDO; 1340 1341 /* If CODEC is being off, save the state. */ 1342 if ((sc->sc_on_blocks & YM_POWER_CODEC_DIGITAL) && 1343 (sc->sc_on_blocks & ~sc->sc_turning_off & 1344 YM_POWER_CODEC_DIGITAL) == 0) 1345 ym_save_codec_regs(sc); 1346 1347 if (YM_IS_SA3(sc)) { 1348 /* OPL3-SA3 */ 1349 ym_write(sc, SA3_DPWRDWN, 1350 ym_read(sc, SA3_DPWRDWN) | (u_int8_t) parts); 1351 ym_write(sc, SA3_APWRDWN, 1352 ym_read(sc, SA3_APWRDWN) | (parts >> 8)); 1353 } else { 1354 /* OPL3-SA2 (only OPL3 can be off partially) */ 1355 if (parts & YM_POWER_OPL3) 1356 ym_write(sc, SA3_PWR_MNG, 1357 ym_read(sc, SA3_PWR_MNG) | SA2_PWR_MNG_FMPS); 1358 } 1359 1360 if (((sc->sc_on_blocks &= ~sc->sc_turning_off) & YM_POWER_ACTIVE) == 0) 1361 ym_chip_powerdown(sc); 1362 1363 sc->sc_turning_off = 0; 1364 1365 /* Restore the state of the chip. */ 1366 bus_space_write_1(sc->sc_iot, sc->sc_controlioh, SA3_CTL_INDEX, sv); 1367 } 1368 1369 /* 1370 * Power control entry point. 1371 */ 1372 void 1373 ym_power_ctl(struct ym_softc *sc, int parts, int onoff) 1374 { 1375 int need_restore_codec; 1376 1377 KASSERT(mutex_owned(&sc->sc_ad1848.sc_ad1848.sc_intr_lock)); 1378 1379 DPRINTF(("%s: ym_power_ctl: parts = 0x%x, %s\n", 1380 DVNAME(sc), parts, onoff ? "on" : "off")); 1381 1382 /* This function may sleep --- needs locking. */ 1383 while (sc->sc_in_power_ctl & YM_POWER_CTL_INUSE) { 1384 sc->sc_in_power_ctl |= YM_POWER_CTL_WANTED; 1385 DPRINTF(("%s: ym_power_ctl: sleeping\n", DVNAME(sc))); 1386 cv_wait(&sc->sc_cv, &sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1387 DPRINTF(("%s: ym_power_ctl: awaken\n", DVNAME(sc))); 1388 } 1389 sc->sc_in_power_ctl |= YM_POWER_CTL_INUSE; 1390 1391 /* If ON requested to parts which are scheduled to OFF, cancel it. */ 1392 if (onoff && sc->sc_turning_off && (sc->sc_turning_off &= ~parts) == 0) 1393 callout_halt(&sc->sc_powerdown_ch, 1394 &sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1395 1396 if (!onoff && sc->sc_turning_off) 1397 parts &= ~sc->sc_turning_off; 1398 1399 /* Discard bits which are currently {on,off}. */ 1400 parts &= onoff ? ~sc->sc_on_blocks : sc->sc_on_blocks; 1401 1402 /* Cancel previous timeout if needed. */ 1403 if (parts != 0 && sc->sc_turning_off) 1404 callout_halt(&sc->sc_powerdown_ch, 1405 &sc->sc_ad1848.sc_ad1848.sc_intr_lock); 1406 1407 if (parts == 0) 1408 goto unlock; /* no work to do */ 1409 1410 if (onoff) { 1411 /* Turning on is done immediately. */ 1412 1413 /* If the chip is off, turn it on. */ 1414 if ((sc->sc_on_blocks & YM_POWER_ACTIVE) == 0) 1415 ym_chip_powerup(sc, 0); 1416 1417 need_restore_codec = (parts & YM_POWER_CODEC_DIGITAL) && 1418 (sc->sc_on_blocks & YM_POWER_CODEC_DIGITAL) == 0; 1419 1420 sc->sc_on_blocks |= parts; 1421 if (parts & YM_POWER_CODEC_CTL) 1422 parts |= YM_POWER_CODEC_P | YM_POWER_CODEC_R; 1423 1424 if (YM_IS_SA3(sc)) { 1425 /* OPL3-SA3 */ 1426 ym_write(sc, SA3_DPWRDWN, 1427 ym_read(sc, SA3_DPWRDWN) & (u_int8_t)~parts); 1428 ym_write(sc, SA3_APWRDWN, 1429 ym_read(sc, SA3_APWRDWN) & ~(parts >> 8)); 1430 } else { 1431 /* OPL3-SA2 (only OPL3 can be off partially) */ 1432 if (parts & YM_POWER_OPL3) 1433 ym_write(sc, SA3_PWR_MNG, 1434 ym_read(sc, SA3_PWR_MNG) 1435 & ~SA2_PWR_MNG_FMPS); 1436 } 1437 if (need_restore_codec) 1438 ym_restore_codec_regs(sc); 1439 } else { 1440 /* Turning off is delayed. */ 1441 sc->sc_turning_off |= parts; 1442 } 1443 1444 /* Schedule turning off. */ 1445 if (sc->sc_pow_mode != YM_POWER_NOSAVE && sc->sc_turning_off) 1446 callout_reset(&sc->sc_powerdown_ch, hz * sc->sc_pow_timeout, 1447 ym_powerdown_callout, sc); 1448 1449 unlock: 1450 if (sc->sc_in_power_ctl & YM_POWER_CTL_WANTED) 1451 cv_broadcast(&sc->sc_cv); 1452 sc->sc_in_power_ctl = 0; 1453 } 1454 #endif /* not AUDIO_NO_POWER_CTL */ 1455