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