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