# This is a BitKeeper generated patch for the following project: # Project Name: # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.328 -> 1.329 # drivers/sound/dmasound/dmasound_awacs.c 1.17 -> 1.18 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 00/12/13 drow@voltaire.res.cmu.edu 1.327.1.1 # dmasound_awacs.c Cache volumes locally # -------------------------------------------- # 00/12/13 drow@voltaire.res.cmu.edu 1.329 # Merge bk://hq.fsmlabs.com:5005 # into voltaire.res.cmu.edu:/home/drow/bk/linuxppc_2_5 # -------------------------------------------- # diff -Nru a/drivers/sound/dmasound/dmasound_awacs.c b/drivers/sound/dmasound/dmasound_awacs.c --- a/drivers/sound/dmasound/dmasound_awacs.c Wed Dec 13 22:51:46 2000 +++ b/drivers/sound/dmasound/dmasound_awacs.c Wed Dec 13 22:51:46 2000 @@ -71,6 +71,15 @@ */ int awacs_reg[8]; +/* Cached volumes - these simulate a 0-100 volume scale, though we only + * have a 15-0 volume scale internally. + * Should include other volumes we don't support? Probably not. + */ +#define MASTER_VOLUME 0 +#define SPEAKER_VOLUME 1 +#define RECORD_VOLUME 2 +static int awacs_volumes[3]; + #define HAS_16BIT_TABLES #undef HAS_8BIT_TABLES @@ -969,8 +978,23 @@ return format; } -#define AWACS_VOLUME_TO_MASK(x) (15 - ((((x) - 1) * 15) / 99)) -#define AWACS_MASK_TO_VOLUME(y) (100 - ((y) * 99 / 15)) +/* Go from 1-100 to 15-0 and vice versa. */ +/* Volume 15 on AWACS is "softest", not muted; volume 0 on Linux is muted. */ +#define AWACS_VOLUME_TO_MASK(x) (15 - ((((x) - 1) * 16) / 100)) +#define AWACS_MASK_TO_VOLUME(y) (100 - ((y) * 100 / 16)) + +static int verify_volume(int volume) +{ + unsigned int left, right; + + left = volume & 0xFF; + if(left > 100) + left = 100; + right = (volume >> 8) & 0xFF; + if(right > 100) + right = 100; + return left | (right << 8); +} static int awacs_get_volume(int reg, int lshift) { @@ -989,12 +1013,20 @@ r1 = awacs_reg[1] | mute; } else { r1 = awacs_reg[1] & ~mute; +#if 0 + printk(KERN_DEBUG "Setting volume to %d/%d\n", volume&0xff, (volume>>8)&0xff); + printk(KERN_DEBUG "Old register setting was %d/%d\n", (awacs_reg[n]>>lshift)&0xf, awacs_reg[n]&0xf); +#endif rn = awacs_reg[n] & ~(0xf | (0xf << lshift)); rn |= ((AWACS_VOLUME_TO_MASK(volume & 0xff) & 0xf) << lshift); rn |= AWACS_VOLUME_TO_MASK((volume >> 8) & 0xff) & 0xf; awacs_reg[n] = rn; awacs_write((n << 12) | rn); volume = awacs_get_volume(rn, lshift); +#if 0 + printk(KERN_DEBUG "Got back volume %d/%d\n", volume&0xff, (volume>>8)&0xff); + printk(KERN_DEBUG "New register setting is %d/%d\n", (awacs_reg[n]>>lshift)&0xf, awacs_reg[n]&0xf); +#endif } if (r1 != awacs_reg[1]) { awacs_reg[1] = r1; @@ -1005,7 +1037,10 @@ static int PMacSetVolume(int volume) { - return awacs_volume_setter(volume, 2, MASK_AMUTE, 6); + volume = verify_volume(volume); + awacs_volume_setter(volume, 2, MASK_AMUTE, 6); + awacs_volumes[MASTER_VOLUME] = volume; + return volume; } static void PMacPlay(void) @@ -1657,7 +1692,7 @@ return IOCTL_OUT(arg, 0); case SOUND_MIXER_READ_VOLUME: data = (awacs_reg[1] & MASK_AMUTE)? 0: - awacs_get_volume(awacs_reg[2], 6); + awacs_volumes[MASTER_VOLUME]; return IOCTL_OUT(arg, data); case SOUND_MIXER_WRITE_VOLUME: IOCTL_IN(arg, data); @@ -1668,16 +1703,19 @@ data = awacs_spkr_vol; else data = (awacs_reg[1] & MASK_CMUTE)? 0: - awacs_get_volume(awacs_reg[4], 6); + awacs_volumes[SPEAKER_VOLUME]; return IOCTL_OUT(arg, data); case SOUND_MIXER_WRITE_SPEAKER: IOCTL_IN(arg, data); if (awacs_revision == 3 && sys_ctrler == SYS_CTRLER_CUDA) awacs_enable_amp(data); - else + else { + data = verify_volume(data); + awacs_volumes[SPEAKER_VOLUME] = data; data = awacs_volume_setter(data, 4, MASK_CMUTE, 6); - return IOCTL_OUT(arg, data); + } + return IOCTL_OUT(arg, awacs_volumes[SPEAKER_VOLUME]); case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */ IOCTL_IN(arg, data); beep_volume = data & 0xff; @@ -1721,10 +1759,12 @@ return IOCTL_OUT(arg, data); case SOUND_MIXER_WRITE_RECLEV: IOCTL_IN(arg, data); + data = verify_volume(data); + awacs_volumes[RECORD_VOLUME] = data; data = awacs_volume_setter(data, 0, 0, 4); - return IOCTL_OUT(arg, data); + return IOCTL_OUT(arg, awacs_volumes[RECORD_VOLUME]); case SOUND_MIXER_READ_RECLEV: - data = awacs_get_volume(awacs_reg[0], 4); + data = awacs_volumes[RECORD_VOLUME]; return IOCTL_OUT(arg, data); case MIXER_WRITE(SOUND_MIXER_MONITOR): IOCTL_IN(arg, data); @@ -1857,10 +1897,12 @@ return IOCTL_OUT(arg, data); case SOUND_MIXER_WRITE_RECLEV: IOCTL_IN(arg, data); + data = verify_volume(data); + awacs_volumes[RECORD_VOLUME] = data; data = awacs_volume_setter(data, 0, 0, 4); - return IOCTL_OUT(arg, data); + return IOCTL_OUT(arg, awacs_volumes[RECORD_VOLUME]); case SOUND_MIXER_READ_RECLEV: - data = awacs_get_volume(awacs_reg[0], 4); + data = awacs_volumes[RECORD_VOLUME]; return IOCTL_OUT(arg, data); case SOUND_MIXER_OUTMASK: break; @@ -2124,6 +2166,10 @@ awacs_write(awacs_reg[6] + MASK_ADDR6); awacs_write(awacs_reg[7] + MASK_ADDR7); } + + awacs_volumes[MASTER_VOLUME] = (AWACS_MASK_TO_VOLUME(vol) << 8) + AWACS_MASK_TO_VOLUME(vol); + awacs_volumes[SPEAKER_VOLUME] = (AWACS_MASK_TO_VOLUME(vol) << 8) + AWACS_MASK_TO_VOLUME(vol); + awacs_volumes[RECORD_VOLUME] = 0; /* Initialize recent versions of the awacs */ if (awacs_revision == 0) {