- When acknowledging interrupts, write the value 0xff to the interrupt

status register rather than 0.  Without this, a single hardware volume
  event triggers an interrupt storm.
- Implement hardware volume control for the Maestro chips.  This version
  only handles the case where both channels are adjusted at the same time.

Reviewed by:	cg
This commit is contained in:
jhb 2001-01-03 01:32:57 +00:00
parent 99e2a84a1f
commit 9598ea3cc7
2 changed files with 28 additions and 19 deletions

View File

@ -463,9 +463,9 @@ agg_init(struct agg_info* ess)
bus_space_write_2(ess->st, ess->sh, PORT_HOSTINT_CTRL, 0); bus_space_write_2(ess->st, ess->sh, PORT_HOSTINT_CTRL, 0);
DELAY(10000); DELAY(10000);
/* Enable direct sound interruption. */ /* Enable direct sound interruption and hardware volume control. */
bus_space_write_2(ess->st, ess->sh, PORT_HOSTINT_CTRL, bus_space_write_2(ess->st, ess->sh, PORT_HOSTINT_CTRL,
HOSTINT_CTRL_DSOUND_INT_ENABLED); HOSTINT_CTRL_DSOUND_INT_ENABLED | HOSTINT_CTRL_HWVOL_ENABLED);
/* Setup Wave Processor. */ /* Setup Wave Processor. */
@ -843,26 +843,31 @@ agg_intr(void *sc)
/* Acknowledge all. */ /* Acknowledge all. */
bus_space_write_2(ess->st, ess->sh, PORT_INT_STAT, 1); bus_space_write_2(ess->st, ess->sh, PORT_INT_STAT, 1);
bus_space_write_1(ess->st, ess->sh, PORT_HOSTINT_STAT, 0); bus_space_write_1(ess->st, ess->sh, PORT_HOSTINT_STAT, 0xff);
#if 0 /* XXX - HWVOL */
if (status & HOSTINT_STAT_HWVOL) { if (status & HOSTINT_STAT_HWVOL) {
u_int delta; u_int event;
delta = bus_space_read_1(ess->st, ess->sh, PORT_HWVOL_MASTER)
- 0x88; event = bus_space_read_1(ess->st, ess->sh, PORT_HWVOL_MASTER);
if (delta & 0x11) switch (event) {
mixer_set(device_get_softc(ess->dev), case HWVOL_MUTE:
SOUND_MIXER_VOLUME, 0); mixer_hwmute(ess->dev);
else { break;
mixer_set(device_get_softc(ess->dev), case HWVOL_UP:
SOUND_MIXER_VOLUME, mixer_hwstep(ess->dev, 1, 1);
mixer_get(device_get_softc(ess->dev), break;
SOUND_MIXER_VOLUME) case HWVOL_DOWN:
+ ((delta >> 5) & 0x7) - 4 mixer_hwstep(ess->dev, -1, -1);
+ ((delta << 7) & 0x700) - 0x400); break;
case HWVOL_NOP:
break;
default:
device_printf(ess->dev, "%s: unknown HWVOL event 0x%x\n",
device_get_nameunit(ess->dev), event);
} }
bus_space_write_1(ess->st, ess->sh, PORT_HWVOL_MASTER, 0x88); bus_space_write_1(ess->st, ess->sh, PORT_HWVOL_MASTER,
HWVOL_NOP);
} }
#endif /* XXX - HWVOL */
for (i = 0; i < ess->playchns; i++) for (i = 0; i < ess->playchns; i++)
if (ess->active & (1 << i)) { if (ess->active & (1 << i)) {

View File

@ -139,6 +139,10 @@
#define PORT_HWVOL_VOICE 0x1d /* BYTE RW */ #define PORT_HWVOL_VOICE 0x1d /* BYTE RW */
#define PORT_HWVOL_MASTER_SHADOW 0x1e /* BYTE RW */ #define PORT_HWVOL_MASTER_SHADOW 0x1e /* BYTE RW */
#define PORT_HWVOL_MASTER 0x1f /* BYTE RW */ #define PORT_HWVOL_MASTER 0x1f /* BYTE RW */
#define HWVOL_NOP 0x88
#define HWVOL_MUTE 0x99
#define HWVOL_UP 0xaa
#define HWVOL_DOWN 0x66
/* CODEC */ /* CODEC */
#define PORT_CODEC_CMD 0x30 /* BYTE W */ #define PORT_CODEC_CMD 0x30 /* BYTE W */