diff --git a/share/man/man4/ym.4 b/share/man/man4/ym.4 index f2b8f74a9186..54f73d2846f6 100644 --- a/share/man/man4/ym.4 +++ b/share/man/man4/ym.4 @@ -1,4 +1,4 @@ -.\" $NetBSD: ym.4,v 1.13 2002/02/13 08:17:52 ross Exp $ +.\" $NetBSD: ym.4,v 1.14 2002/03/10 13:57:12 itohy Exp $ .\" .\" Copyright (c) 1999 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -39,7 +39,7 @@ .Os .Sh NAME .Nm ym -.Nd Yamaha OPL3-SA3 audio device driver +.Nd Yamaha OPL3-SA2 and OPL3-SA3 audio device driver .Sh SYNOPSIS .Cd "ym* at isapnp?" .Cd "ym* at pnpbios? index ?" @@ -49,13 +49,14 @@ .Sh DESCRIPTION The .Nm -driver provides support for Yamaha YMF715x (OPL3-SA3) sound devices. +driver provides support for +Yamaha YMF711 (OPL3-SA2) and YMF715x (OPL3-SA3) sound devices. .Pp -The OPL3-SA3 device has +The OPL3-SAx device has WSS compatible full-duplex 16bit CODEC, -OPL3 FM synthesizer, -MPU401 compatible MIDI I/O port interface, -and built-in +OPL3 FM synthesizer, and +MPU401 compatible MIDI I/O port interface. +Additionally, OPL3-SA3 has built-in .Sq 3D Enhanced equalizer. .Pp @@ -75,9 +76,10 @@ midi(OPL3/ZV)-\*[Gt]-+----------------------------+-\*[Gt]|inputs.midi | cd -\*[Gt]------+-*--------------------------+-\*[Gt]|inputs.cd | line -\*[Gt]----*-+-+--------------------------+-\*[Gt]|inputs.line | speaker -\*[Gt]----+-+-+--------------------------+-\*[Gt]|inputs.speaker | - inputs.mic v v v monitor.monitor | | | - | --------------- ------- | ------- | | | -mic ---\*[Gt]|record.record|-\*[Gt]| A/D |----\*[Gt]| D/A |-*-\*[Gt]|inputs.dac |analog +mic -\*[Gt]--*-+-+-+--------------------------+-\*[Gt]|inputs.mic | + v v v v monitor.monitor | | | + --------------- ------- | ------- | | | + |record.record|-\*[Gt]| A/D |----\*[Gt]| D/A |-*-\*[Gt]|inputs.dac |analog | | |conv.|-- -\*[Gt]|conv.| | |output --------------- ------- | | ------- | outputs.master|--\*[Gt] wave v | wave | equalization.*| @@ -102,12 +104,22 @@ the device is never put in global power down or power save mode. This is because if the device is in global power down or power save mode, the output is automatically muted. .Pp -All the external input sources (CD playback, line input, and speaker) +All the external input sources (CD playback, line input, speaker, and MIC) are muted by default. +.Pp +The +.Sq Dv equalization.* +variables does not exists on OPL3-SA2. +The +.Sq equalization.treble +and +.Sq equalization.bass +are enhancement only, and any values below the center position (128) +don't take any effect. .Sh POWER MANAGEMENT The .Nm -driver is capable of power management on the OPL3-SA3 devices. +driver is capable of power management on the OPL3-SAx devices. The following modes can be selected by setting .Sq Dv power.save variable of @@ -134,7 +146,7 @@ the driver puts the device in mode. .Pp On the global power down mode, the power consumption is minimized -(10\(*mA typ.), +(10\(*mA (SA3) or 200\(*mA (SA2) typ.), .\" Note: \(*m is Greek mu but the click noise on power up/down the device is rather loud. .Bf Em diff --git a/sys/arch/i386/pnpbios/ym_pnpbios.c b/sys/arch/i386/pnpbios/ym_pnpbios.c index 8ba321c2ff06..7d6c3c5f832e 100644 --- a/sys/arch/i386/pnpbios/ym_pnpbios.c +++ b/sys/arch/i386/pnpbios/ym_pnpbios.c @@ -1,4 +1,4 @@ -/* $NetBSD: ym_pnpbios.c,v 1.5 2001/11/15 07:03:35 lukem Exp $ */ +/* $NetBSD: ym_pnpbios.c,v 1.6 2002/03/10 13:57:12 itohy Exp $ */ /* * Copyright (c) 1999 * Matthias Drochner. All rights reserved. @@ -27,7 +27,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ym_pnpbios.c,v 1.5 2001/11/15 07:03:35 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ym_pnpbios.c,v 1.6 2002/03/10 13:57:12 itohy Exp $"); #include "mpu_ym.h" @@ -146,7 +146,6 @@ ym_pnpbios_attach(parent, self, aux) } ac->mode = 2; ac->MCE_bit = MODE_CHANGE_ENABLE; - ac->chip_name = "OPL3-SA3"; sc->sc_ad1848.sc_ic = sc->sc_ic; diff --git a/sys/dev/ic/opl3sa3reg.h b/sys/dev/ic/opl3sa3reg.h index 3f12dfc31568..1a2dd8d6e037 100644 --- a/sys/dev/ic/opl3sa3reg.h +++ b/sys/dev/ic/opl3sa3reg.h @@ -1,4 +1,4 @@ -/* $NetBSD: opl3sa3reg.h,v 1.1 1999/10/05 03:38:17 itohy Exp $ */ +/* $NetBSD: opl3sa3reg.h,v 1.2 2002/03/10 13:57:10 itohy Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -37,12 +37,15 @@ */ /* + * YAMAHA YMF711 (OPL3 Single-chip Audio System 2; OPL3-SA2) * YAMAHA YMF715x (OPL3 Single-chip Audio System 3; OPL3-SA3) * control register description * * Other ports (SBpro, WSS CODEC, MPU401, OPL3, etc.) are NOT listed here. */ +/* [2]: OPL3-SA2 only, [3]: OPL3-SA3 only */ + /* * direct registers */ @@ -58,7 +61,10 @@ */ #define SA3_PWR_MNG 0x01 /* Power management (R/W) */ -#define SA3_PWR_MNG_ADOWN 0x20 /* Analog Down */ +#define SA2_PWR_MNG_SRST 0x80 /* [2] Software reset */ +#define SA3_PWR_MNG_ADOWN 0x20 /* [3] Analog Down */ +#define SA2_PWR_MNG_CLKO 0x10 /* [2] Master Clock disable */ +#define SA2_PWR_MNG_FMPS 0x08 /* [2] OPL3 power down */ #define SA3_PWR_MNG_PSV 0x04 /* Power save */ #define SA3_PWR_MNG_PDN 0x02 /* Power down */ #define SA3_PWR_MNG_PDX 0x01 /* Oscillation stop */ @@ -66,7 +72,7 @@ #define SA3_SYS_CTL 0x02 /* System control (R/W) */ #define SA3_SYS_CTL_SBHE 0x80 /* 0: AT-bus, 1: XT-bus */ -#define SA3_SYS_CTL_YMODE 0x30 /* 3D Enhancement mode */ +#define SA3_SYS_CTL_YMODE 0x30 /* [3] 3D Enhancement mode */ #define SA3_SYS_CTL_YMODE0 0x00 /* Desktop mode (speaker 5-12cm) */ #define SA3_SYS_CTL_YMODE1 0x10 /* Notebook PC mode (1) (3cm) */ #define SA3_SYS_CTL_YMODE2 0x20 /* Notebook PC mode (2) (1.5cm) */ @@ -93,7 +99,7 @@ #define SA3_IRQA_STAT 0x04 /* Interrupt (IRQ-A) STATUS (RO) */ #define SA3_IRQB_STAT 0x05 /* Interrupt (IRQ-B) STATUS (RO) */ -#define SA3_IRQ_STAT_MV 0x40 /* Hardware Volume Interrupt */ +#define SA3_IRQ_STAT_MV 0x40 /* [3] Hardware Volume Interrupt */ #define SA3_IRQ_STAT_OPL3 0x20 /* Internal FM-synthesizer timer */ #define SA3_IRQ_STAT_MPU 0x10 /* MPU401 Interrupt */ #define SA3_IRQ_STAT_SB 0x08 /* Sound Blaster Playback Interrupt */ @@ -175,9 +181,13 @@ #define SA3_MISC_MCSW 0x10 /* A/D is connected to 0: Rch of Mic, 1: loopback of monaural output */ #define SA3_MISC_MODE 0x08 /* 0: SB mode, 1: WSS mode (RO) */ -#define SA3_MISC_VER 0x07 /* Version of OPL3-SA3 (RO) */ - /* (4 or 5?) */ -/*#define SA3_MISC_DEFAULT (SA3_MISC_VEN | (4 or 5?)) */ +#define SA3_MISC_VER 0x07 /* Version of OPL3-SA2/OPL3-SA3 (RO) */ +#define SA3_MISC_VER_711 1 /* OPL3-SA2 (YMF711) */ +#define SA3_MISC_VER_715 2 /* OPL3-SA3 (YMF715) */ +#define SA3_MISC_VER_715B 3 /* OPL3-SA3 (YMF715B) */ +#define SA3_MISC_VER_715E 4 /* OPL3-SA3 (YMF715E) */ + /* (4 or 5?) */ +/*#define SA3_MISC_DEFAULT (SA3_MISC_VEN | version) */ /* WSS DMA Base counters (R/W) used for suspend/resume */ #define SA3_DMA_CNT_PLAY_LOW 0x0b /* Playback Base Counter (Low) */ @@ -185,12 +195,14 @@ #define SA3_DMA_CNT_REC_LOW 0x0d /* Recording Base Counter (Low) */ #define SA3_DMA_CNT_REC_HIGH 0x0e /* Recording Base Counter (High) */ -#define SA3_WSS_INT_SCAN 0x0f /* WSS Interrupt Scan out/in (R/W) */ +/* [3] */ +#define SA3_WSS_INT_SCAN 0x0f /* WSS Interrupt Scan out/in (R/W)*/ #define SA3_WSS_INT_SCAN_STI 0x04 /* 1: TI = "1" and IRQ active */ #define SA3_WSS_INT_SCAN_SCI 0x02 /* 1: CI = "1" and IRQ active */ #define SA3_WSS_INT_SCAN_SPI 0x01 /* 1: PI = "1" and IRQ active */ #define SA3_WSS_INT_DEFAULT 0x00 /* default value */ +/* [3] */ #define SA3_SB_SCAN 0x10 /* SB Internal State Scan out/in (R/W)*/ #define SA3_SB_SCAN_SBPDA 0x80 /* Sound Blaster Power Down ack */ #define SA3_SB_SCAN_SS 0x08 /* Scan Select */ @@ -199,8 +211,10 @@ #define SA3_SB_SCAN_SBPDR 0x01 /* Sound Blaster Power Down Request */ #define SA3_SB_SCAN_DEFAULT 0x00 /* default value */ +/* [3] */ #define SA3_SB_SCAN_DATA 0x11 /* SB Internal State Scan Data (R/W)*/ +/* [3] */ #define SA3_DPWRDWN 0x12 /* Digital Partial Power Down (R/W) */ #define SA3_DPWRDWN_JOY 0x80 /* Joystick power down */ #define SA3_DPWRDWN_MPU 0x40 /* MPU401 power down */ @@ -212,6 +226,7 @@ #define SA3_DPWRDWN_PNP 0x01 /* PnP power down */ #define SA3_DPWRDWN_DEFAULT 0x00 /* default value */ +/* [3] */ #define SA3_APWRDWN 0x13 /* Analog Partial Power Down (R/W) */ #define SA3_APWRDWN_FMDAC 0x10 /* FMDAC for OPL3 power down */ #define SA3_APWRDWN_AD 0x08 /* A/D for WSS recording power down */ @@ -220,16 +235,19 @@ #define SA3_APWRDWN_WIDE 0x01 /* Wide Stereo power down */ #define SA3_APWRDWN_DEFAULT 0x00 /* default value */ +/* [3] */ #define SA3_3D_WIDE 0x14 /* 3D Enhanced control (WIDE) (R/W) */ #define SA3_3D_WIDE_WIDER 0x70 /* Rch of wide 3D enhanced control */ #define SA3_3D_WIDE_WIDEL 0x07 /* Lch of wide 3D enhanced control */ #define SA3_3D_WIDE_DEFAULT 0x00 /* default value */ +/* [3] */ #define SA3_3D_BASS 0x15 /* 3D Enhanced control (BASS) (R/W) */ #define SA3_3D_BASS_BASSR 0x70 /* Rch of bass 3D enhanced control */ #define SA3_3D_BASS_BASSL 0x07 /* Lch of bass 3D enhanced control */ #define SA3_3D_BASS_DEFAULT 0x00 /* default value */ +/* [3] */ #define SA3_3D_TREBLE 0x16 /* 3D Enhanced control (TREBLE) (R/W) */ #define SA3_3D_TREBLE_TRER 0x70 /* Rch of treble 3D enhanced control */ #define SA3_3D_TREBLE_TREL 0x07 /* Lch of treble 3D enhanced control */ @@ -240,10 +258,12 @@ #define SA3_3D_LSHIFT 0 #define SA3_3D_RSHIFT 4 +/* [3] */ #define SA3_HVOL_INTR_CNF 0x17 /* Hardware Volume Intr Channel (R/W) */ #define SA3_HVOL_INTR_CNF_B 0x20 /* Hardware Volume uses IRQ-B */ #define SA3_HVOL_INTR_CNF_A 0x10 /* Hardware Volume uses IRQ-A */ #define SA3_HVOL_INTR_CNF_DEFAULT 0x00 +/* [3] */ #define SA3_MULTI_STAT 0x18 /* Multi-purpose Select Pin Stat (RO) */ #define SA3_MULTI_STAT_SEL 0x70 /* State of SEL2-0 pins */ diff --git a/sys/dev/isa/mpu_ym.c b/sys/dev/isa/mpu_ym.c index 719fa9ca23ed..22a3b992ebc1 100644 --- a/sys/dev/isa/mpu_ym.c +++ b/sys/dev/isa/mpu_ym.c @@ -1,4 +1,4 @@ -/* $NetBSD: mpu_ym.c,v 1.2 2001/11/13 08:01:26 lukem Exp $ */ +/* $NetBSD: mpu_ym.c,v 1.3 2002/03/10 13:57:11 itohy Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mpu_ym.c,v 1.2 2001/11/13 08:01:26 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mpu_ym.c,v 1.3 2002/03/10 13:57:11 itohy Exp $"); #define NMPU_YM 1 @@ -105,7 +105,8 @@ mpu_ym_attach(parent, self, aux) sc->powerctl = mpu_ym_power_ctl; sc->powerarg = ssc; #endif - sc->model = "OPL3-SA3 MPU-401 MIDI UART"; + sc->model = YM_IS_SA3(ssc) ? + "OPL3-SA3 MPU-401 MIDI UART" : "OPL3-SA2 MPU-401 MIDI UART"; mpu_attach(sc); } diff --git a/sys/dev/isa/opl_ym.c b/sys/dev/isa/opl_ym.c index 2c85228d61a1..58d769a212f1 100644 --- a/sys/dev/isa/opl_ym.c +++ b/sys/dev/isa/opl_ym.c @@ -1,4 +1,4 @@ -/* $NetBSD: opl_ym.c,v 1.2 2001/11/13 08:01:27 lukem Exp $ */ +/* $NetBSD: opl_ym.c,v 1.3 2002/03/10 13:57:11 itohy Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: opl_ym.c,v 1.2 2001/11/13 08:01:27 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: opl_ym.c,v 1.3 2002/03/10 13:57:11 itohy Exp $"); #include "mpu_ym.h" @@ -108,7 +108,7 @@ opl_ym_attach(parent, self, aux) sc->powerctl = opl_ym_power_ctl; sc->powerarg = ssc; #endif - strcpy(sc->syn.name, "OPL3-SA3 "); + sprintf(sc->syn.name, "%s ", ssc->sc_ad1848.sc_ad1848.chip_name); opl_attach(sc); } diff --git a/sys/dev/isa/ym.c b/sys/dev/isa/ym.c index 0e035dd294b7..b52ccd902180 100644 --- a/sys/dev/isa/ym.c +++ b/sys/dev/isa/ym.c @@ -1,4 +1,4 @@ -/* $NetBSD: ym.c,v 1.20 2002/02/26 14:57:36 itohy Exp $ */ +/* $NetBSD: ym.c,v 1.21 2002/03/10 13:57:11 itohy Exp $ */ /*- * Copyright (c) 1999-2002 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ym.c,v 1.20 2002/02/26 14:57:36 itohy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ym.c,v 1.21 2002/03/10 13:57:11 itohy Exp $"); #include "mpu_ym.h" #include "opt_ym.h" @@ -170,6 +170,7 @@ void ym_power_ctl __P((struct ym_softc *, int, int)); static void ym_init __P((struct ym_softc *)); static void ym_mute __P((struct ym_softc *, int, int)); static void ym_set_master_gain __P((struct ym_softc *, struct ad1848_volume*)); +static void ym_hvol_to_master_gain __P((struct ym_softc *)); static void ym_set_mic_gain __P((struct ym_softc *, int)); static void ym_set_3d __P((struct ym_softc *, mixer_ctrl_t *, struct ad1848_volume *, int)); @@ -225,6 +226,9 @@ ym_attach(sc) ym_mute(sc, SA3_VOL_L, 1); ym_mute(sc, SA3_VOL_R, 1); + sc->sc_version = ym_read(sc, SA3_MISC) & SA3_MISC_VER; + ac->chip_name = YM_IS_SA3(sc) ? "OPL3-SA3" : "OPL3-SA2"; + sc->sc_ad1848.sc_ih = isa_intr_establish(sc->sc_ic, sc->ym_irq, IST_EDGE, IPL_AUDIO, ym_intr, sc); @@ -259,8 +263,6 @@ ym_attach(sc) ac->mute[AD1848_LINE_CHANNEL] = MUTE_ALL; /* speaker is muted by default */ - sc->sc_version = ym_read(sc, SA3_MISC) & SA3_MISC_VER; - /* We use only one IRQ (IRQ-A). */ ym_write(sc, SA3_IRQ_CONF, SA3_IRQ_CONF_MPU_A | SA3_IRQ_CONF_WSS_A); ym_write(sc, SA3_HVOL_INTR_CNF, SA3_HVOL_INTR_CNF_A); @@ -363,6 +365,14 @@ ym_init(sc) 0x00); } + if (!YM_IS_SA3(sc)) { + /* OPL3-SA2 */ + ym_write(sc, SA3_PWR_MNG, SA2_PWR_MNG_CLKO | + (sc->sc_opl_ioh == 0 ? SA2_PWR_MNG_FMPS : 0)); + return; + } + + /* OPL3-SA3 */ /* Figure out which part can be power down. */ dpd = SA3_DPWRDWN_SB /* we never use SB */ #if NMPU_YM > 0 @@ -404,8 +414,9 @@ ym_getdev(addr, retp) struct audio_device *retp; { struct ym_softc *sc = addr; + struct ad1848_softc *ac = &sc->sc_ad1848.sc_ad1848; - strcpy(retp->name, "OPL3-SA3"); + strcpy(retp->name, ac->chip_name); sprintf(retp->version, "%d", sc->sc_version); strcpy(retp->config, "ym"); @@ -438,7 +449,6 @@ ym_mute(sc, left_reg, mute) struct ym_softc *sc; int left_reg; int mute; - { u_int8_t reg; @@ -455,7 +465,7 @@ ym_set_master_gain(sc, vol) struct ym_softc *sc; struct ad1848_volume *vol; { - u_int atten; + u_int atten; sc->master_gain = *vol; @@ -470,6 +480,43 @@ ym_set_master_gain(sc, vol) ym_write(sc, SA3_VOL_R, (ym_read(sc, SA3_VOL_R) & ~SA3_VOL_MV) | atten); } +/* + * Read current setting of master volume from hardware + * and update the software value if changed. + * [SA3] This function clears hardware volume interrupt. + */ +static void +ym_hvol_to_master_gain(sc) + struct ym_softc *sc; +{ + u_int prevval, val; + int changed = 0; + + val = SA3_VOL_MV & ~ym_read(sc, SA3_VOL_L); + prevval = (sc->master_gain.left * (SA3_VOL_MV + 1)) / + (AUDIO_MAX_GAIN + 1); + if (val != prevval) { + sc->master_gain.left = + val * ((AUDIO_MAX_GAIN + 1) / (SA3_VOL_MV + 1)); + changed = 1; + } + + val = SA3_VOL_MV & ~ym_read(sc, SA3_VOL_R); + prevval = (sc->master_gain.right * (SA3_VOL_MV + 1)) / + (AUDIO_MAX_GAIN + 1); + if (val != prevval) { + sc->master_gain.right = + val * ((AUDIO_MAX_GAIN + 1) / (SA3_VOL_MV + 1)); + changed = 1; + } + +#if 0 /* XXX NOT YET */ + /* Notify the change to async processes. */ + if (changed && sc->sc_audiodev) + mixer_signal(sc->sc_audiodev); +#endif +} + static void ym_set_mic_gain(sc, vol) struct ym_softc *sc; @@ -542,6 +589,10 @@ ym_mixer_set_port(addr, cp) cp->un.value.num_channels, cp->un.value.level[0], cp->un.value.level[1])); + /* SA2 doesn't have equalizer */ + if (!YM_IS_SA3(sc) && YM_MIXER_SA3_ONLY(cp->dev)) + return ENXIO; + #ifndef AUDIO_NO_POWER_CTL /* Power-up chip */ ym_power_ctl(sc, YM_POWER_CODEC_CTL, 1); @@ -675,8 +726,27 @@ ym_mixer_get_port(addr, cp) struct ym_softc *sc = ac->parent; int error; + /* SA2 doesn't have equalizer */ + if (!YM_IS_SA3(sc) && YM_MIXER_SA3_ONLY(cp->dev)) + return ENXIO; + switch (cp->dev) { case YM_OUTPUT_LVL: + if (!YM_IS_SA3(sc)) { + /* + * SA2 doesn't have hardware volume interrupt. + * Read current value and update every time. + */ +#ifndef AUDIO_NO_POWER_CTL + /* Power-up chip */ + ym_power_ctl(sc, YM_POWER_CODEC_CTL, 1); +#endif + ym_hvol_to_master_gain(sc); +#ifndef AUDIO_NO_POWER_CTL + /* Power-down chip */ + ym_power_ctl(sc, YM_POWER_CODEC_CTL, 0); +#endif + } ad1848_from_vol(cp, &sc->master_gain); return 0; @@ -741,10 +811,10 @@ ym_mixer_get_port(addr, cp) static char *mixer_classes[] = { AudioCinputs, AudioCrecord, AudioCoutputs, AudioCmonitor, - AudioCequalization #ifndef AUDIO_NO_POWER_CTL - , AudioCpower + AudioCpower, #endif + AudioCequalization }; int @@ -756,18 +826,24 @@ ym_query_devinfo(addr, dip) AudioNdac, AudioNmidi, AudioNcd, AudioNline, AudioNspeaker, AudioNmicrophone, AudioNmonitor }; + struct ad1848_softc *ac = addr; + struct ym_softc *sc = ac->parent; + + /* SA2 doesn't have equalizer */ + if (!YM_IS_SA3(sc) && YM_MIXER_SA3_ONLY(dip->index)) + return ENXIO; dip->next = dip->prev = AUDIO_MIXER_LAST; switch(dip->index) { - case YM_INPUT_CLASS: /* input class descriptor */ + case YM_INPUT_CLASS: case YM_OUTPUT_CLASS: case YM_MONITOR_CLASS: case YM_RECORD_CLASS: - case YM_EQ_CLASS: #ifndef AUDIO_NO_POWER_CTL case YM_PWR_CLASS: #endif + case YM_EQ_CLASS: dip->type = AUDIO_MIXER_CLASS; dip->mixer_class = dip->index; strcpy(dip->label.name, @@ -990,22 +1066,11 @@ ym_intr(arg) } #endif /* - * Hardware volume interrupt. + * Hardware volume interrupt (SA3 only). * Recalculate master volume from the hardware setting. */ - if (ist & SA3_IRQ_STAT_MV) { - sc->master_gain.left = - (SA3_VOL_MV & ~ym_read(sc, SA3_VOL_L)) * - (SA3_VOL_MV + 1) + (SA3_VOL_MV + 1) / 2; - sc->master_gain.right = - (SA3_VOL_MV & ~ym_read(sc, SA3_VOL_R)) * - (SA3_VOL_MV + 1) + (SA3_VOL_MV + 1) / 2; - -#if 0 /* XXX NOT YET */ - /* Notify the change to async processes. */ - if (sc->sc_audiodev) - mixer_signal(sc->sc_audiodev); -#endif + if ((ist & SA3_IRQ_STAT_MV) && YM_IS_SA3(sc)) { + ym_hvol_to_master_gain(sc); processed = 1; } } while (processed && (ist = ym_read(sc, SA3_IRQA_STAT))); @@ -1067,7 +1132,7 @@ ym_power_hook(why, v) void *v; { struct ym_softc *sc = v; - int i; + int i, max; int s; DPRINTF(("%s: ym_power_hook: why = %d\n", DVNAME(sc), why)); @@ -1110,7 +1175,8 @@ ym_power_hook(why, v) ym_init(sc); /* power-on CODEC */ /* Restore control registers. */ - for (i = SA3_PWR_MNG + 1; i <= YM_SAVE_REG_MAX; i++) { + max = YM_IS_SA3(sc)? YM_SAVE_REG_MAX_SA3 : YM_SAVE_REG_MAX_SA2; + for (i = SA3_PWR_MNG + 1; i <= max; i++) { if (i == SA3_SB_SCAN || i == SA3_SB_SCAN_DATA || i == SA3_DPWRDWN) continue; @@ -1122,7 +1188,8 @@ ym_power_hook(why, v) /* Restore global/digital power-down state. */ ym_write(sc, SA3_PWR_MNG, sc->sc_sa3_scan[SA3_PWR_MNG]); - ym_write(sc, SA3_DPWRDWN, sc->sc_sa3_scan[SA3_DPWRDWN]); + if (YM_IS_SA3(sc)) + ym_write(sc, SA3_DPWRDWN, sc->sc_sa3_scan[SA3_DPWRDWN]); break; case PWR_SOFTSUSPEND: case PWR_SOFTSTANDBY: @@ -1171,12 +1238,14 @@ static void ym_chip_powerdown(sc) struct ym_softc *sc; { - int i; + int i, max; DPRINTF(("%s: ym_chip_powerdown\n", DVNAME(sc))); + max = YM_IS_SA3(sc) ? YM_SAVE_REG_MAX_SA3 : YM_SAVE_REG_MAX_SA2; + /* Save control registers. */ - for (i = SA3_PWR_MNG + 1; i <= YM_SAVE_REG_MAX; i++) { + for (i = SA3_PWR_MNG + 1; i <= max; i++) { if (i == SA3_SB_SCAN || i == SA3_SB_SCAN_DATA) continue; sc->sc_sa3_scan[i] = ym_read(sc, i); @@ -1269,8 +1338,18 @@ ym_powerdown_blocks(arg) YM_POWER_CODEC_DIGITAL) == 0) ym_save_codec_regs(sc); - ym_write(sc, SA3_DPWRDWN, ym_read(sc, SA3_DPWRDWN) | (u_int8_t) parts); - ym_write(sc, SA3_APWRDWN, ym_read(sc, SA3_APWRDWN) | (parts >> 8)); + if (YM_IS_SA3(sc)) { + /* OPL3-SA3 */ + ym_write(sc, SA3_DPWRDWN, + ym_read(sc, SA3_DPWRDWN) | (u_int8_t) parts); + ym_write(sc, SA3_APWRDWN, + ym_read(sc, SA3_APWRDWN) | (parts >> 8)); + } else { + /* OPL3-SA2 (only OPL3 can be off partially) */ + if (parts & YM_POWER_OPL3) + ym_write(sc, SA3_PWR_MNG, + ym_read(sc, SA3_PWR_MNG) | SA2_PWR_MNG_FMPS); + } if (((sc->sc_on_blocks &= ~sc->sc_turning_off) & YM_POWER_ACTIVE) == 0) ym_chip_powerdown(sc); @@ -1348,10 +1427,19 @@ ym_power_ctl(sc, parts, onoff) s = splaudio(); - ym_write(sc, SA3_DPWRDWN, - ym_read(sc, SA3_DPWRDWN) & (u_int8_t)~parts); - ym_write(sc, SA3_APWRDWN, - ym_read(sc, SA3_APWRDWN) & ~(parts >> 8)); + if (YM_IS_SA3(sc)) { + /* OPL3-SA3 */ + ym_write(sc, SA3_DPWRDWN, + ym_read(sc, SA3_DPWRDWN) & (u_int8_t)~parts); + ym_write(sc, SA3_APWRDWN, + ym_read(sc, SA3_APWRDWN) & ~(parts >> 8)); + } else { + /* OPL3-SA2 (only OPL3 can be off partially) */ + if (parts & YM_POWER_OPL3) + ym_write(sc, SA3_PWR_MNG, + ym_read(sc, SA3_PWR_MNG) + & ~SA2_PWR_MNG_FMPS); + } if (need_restore_codec) ym_restore_codec_regs(sc); diff --git a/sys/dev/isa/ymvar.h b/sys/dev/isa/ymvar.h index 74ba22faa2d8..e0b2e9a7a0ea 100644 --- a/sys/dev/isa/ymvar.h +++ b/sys/dev/isa/ymvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: ymvar.h,v 1.7 2002/02/26 14:57:36 itohy Exp $ */ +/* $NetBSD: ymvar.h,v 1.8 2002/03/10 13:57:11 itohy Exp $ */ /*- * Copyright (c) 1999-2000, 2002 The NetBSD Foundation, Inc. @@ -80,52 +80,57 @@ /* * Mixer devices */ -#define YM_DAC_LVL 0 -#define YM_MIDI_LVL 1 -#define YM_CD_LVL 2 -#define YM_LINE_LVL 3 -#define YM_SPEAKER_LVL 4 -#define YM_MIC_LVL 5 -#define YM_MONITOR_LVL 6 -#define YM_DAC_MUTE 7 -#define YM_MIDI_MUTE 8 -#define YM_CD_MUTE 9 -#define YM_LINE_MUTE 10 -#define YM_SPEAKER_MUTE 11 -#define YM_MIC_MUTE 12 -#define YM_MONITOR_MUTE 13 +#define YM_DAC_LVL 0 /* inputs.dac */ +#define YM_MIDI_LVL 1 /* inputs.midi */ +#define YM_CD_LVL 2 /* inputs.cd */ +#define YM_LINE_LVL 3 /* inputs.line */ +#define YM_SPEAKER_LVL 4 /* inputs.speaker */ +#define YM_MIC_LVL 5 /* inputs.mic */ +#define YM_MONITOR_LVL 6 /* monitor.monitor */ +#define YM_DAC_MUTE 7 /* inputs.dac.mute */ +#define YM_MIDI_MUTE 8 /* inputs.midi.mute */ +#define YM_CD_MUTE 9 /* inputs.cd.mute */ +#define YM_LINE_MUTE 10 /* inputs.line.mute */ +#define YM_SPEAKER_MUTE 11 /* inputs.speaker.mute */ +#define YM_MIC_MUTE 12 /* inputs.mic.mute */ +#define YM_MONITOR_MUTE 13 /* monitor.monitor.mute */ -#define YM_REC_LVL 14 -#define YM_RECORD_SOURCE 15 +#define YM_REC_LVL 14 /* record.record */ +#define YM_RECORD_SOURCE 15 /* record.record.source */ -#define YM_OUTPUT_LVL 16 -#define YM_OUTPUT_MUTE 17 - -#define YM_MASTER_EQMODE 18 -#define YM_MASTER_TREBLE 19 -#define YM_MASTER_BASS 20 -#define YM_MASTER_WIDE 21 +#define YM_OUTPUT_LVL 16 /* outputs.master */ +#define YM_OUTPUT_MUTE 17 /* outputs.master.mute */ #ifndef AUDIO_NO_POWER_CTL -#define YM_PWR_MODE 22 -#define YM_PWR_TIMEOUT 23 +#define YM_PWR_MODE 18 /* power.save */ +#define YM_PWR_TIMEOUT 19 /* power.save.timeout */ #endif /* Classes - don't change this without looking at mixer_classes array */ #ifdef AUDIO_NO_POWER_CTL -#define YM_CLASS_TOP 22 +#define YM_CLASS_TOP 18 #else -#define YM_CLASS_TOP 24 +#define YM_CLASS_TOP 20 #endif #define YM_INPUT_CLASS (YM_CLASS_TOP + 0) #define YM_RECORD_CLASS (YM_CLASS_TOP + 1) #define YM_OUTPUT_CLASS (YM_CLASS_TOP + 2) #define YM_MONITOR_CLASS (YM_CLASS_TOP + 3) +#ifdef AUDIO_NO_POWER_CTL #define YM_EQ_CLASS (YM_CLASS_TOP + 4) -#ifndef AUDIO_NO_POWER_CTL -#define YM_PWR_CLASS (YM_CLASS_TOP + 5) +#else +#define YM_PWR_CLASS (YM_CLASS_TOP + 4) +#define YM_EQ_CLASS (YM_CLASS_TOP + 5) #endif +/* equalizer is SA3 only */ +#define YM_MASTER_EQMODE (YM_EQ_CLASS+1) /* equalization.mode */ +#define YM_MASTER_TREBLE (YM_EQ_CLASS+2) /* equalization.treble */ +#define YM_MASTER_BASS (YM_EQ_CLASS+3) /* equalization.bass */ +#define YM_MASTER_WIDE (YM_EQ_CLASS+4) /* equalization.surround */ + +#define YM_MIXER_SA3_ONLY(m) ((m) >= YM_EQ_CLASS) + /* XXX should be in */ #define AudioNdesktop "desktop" #define AudioNlaptop "laptop" @@ -165,6 +170,7 @@ struct ym_softc { u_int8_t sc_external_sources; /* non-zero value prevents power down */ u_int8_t sc_version; /* hardware version */ +#define YM_IS_SA3(sc) ((sc)->sc_version > SA3_MISC_VER_711) /* 3D encehamcement */ u_int8_t sc_eqmode; @@ -199,8 +205,9 @@ struct ym_softc { int sc_pow_timeout; u_int8_t sc_codec_scan[0x20]; -#define YM_SAVE_REG_MAX SA3_HVOL_INTR_CNF - u_int8_t sc_sa3_scan[YM_SAVE_REG_MAX + 1]; +#define YM_SAVE_REG_MAX_SA3 SA3_HVOL_INTR_CNF +#define YM_SAVE_REG_MAX_SA2 SA3_DMA_CNT_REC_HIGH + u_int8_t sc_sa3_scan[YM_SAVE_REG_MAX_SA3 + 1]; u_int16_t sc_on_blocks; u_int16_t sc_turning_off; diff --git a/sys/dev/isapnp/ym_isapnp.c b/sys/dev/isapnp/ym_isapnp.c index 0ab99dd67ad5..ed6a1ab0bee0 100644 --- a/sys/dev/isapnp/ym_isapnp.c +++ b/sys/dev/isapnp/ym_isapnp.c @@ -1,4 +1,4 @@ -/* $NetBSD: ym_isapnp.c,v 1.12 2001/11/13 07:56:44 lukem Exp $ */ +/* $NetBSD: ym_isapnp.c,v 1.13 2002/03/10 13:57:11 itohy Exp $ */ /* @@ -43,7 +43,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ym_isapnp.c,v 1.12 2001/11/13 07:56:44 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ym_isapnp.c,v 1.13 2002/03/10 13:57:11 itohy Exp $"); #include "mpu_ym.h" @@ -144,7 +144,6 @@ ym_isapnp_attach(parent, self, aux) } ac->mode = 2; ac->MCE_bit = MODE_CHANGE_ENABLE; - ac->chip_name = "OPL3-SA3"; sc->sc_ad1848.sc_ic = sc->sc_ic;