Add explicit support of OPL3-SA2 (YMF711).
Not well tested....
This commit is contained in:
parent
e889f54f2f
commit
d5f39a2d9c
|
@ -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
|
||||
|
|
|
@ -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 <sys/cdefs.h>
|
||||
__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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 <sys/cdefs.h>
|
||||
__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);
|
||||
}
|
||||
|
|
|
@ -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 <sys/cdefs.h>
|
||||
__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);
|
||||
}
|
||||
|
|
160
sys/dev/isa/ym.c
160
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 <sys/cdefs.h>
|
||||
__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);
|
||||
|
||||
|
|
|
@ -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 <sys/audioio.h> */
|
||||
#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;
|
||||
|
|
|
@ -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 <sys/cdefs.h>
|
||||
__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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue