From: Daniel Jacobowitz <dmj+@andrew.cmu.edu>
To: linuxppc-dev@lists.linuxppc.org
Subject: [PATCH] improve dmasound volume handling
Date: Sat, 16 Dec 2000 13:29:32 -0500 [thread overview]
Message-ID: <20001216132932.A16741@drow.them.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 850 bytes --]
I was having a very strange problem with dmasound: aumix would let me
decrease but not increase the volume. The problem was that aumix only
internally kept the volume on a 0-15 scale, but Linux used 0 (mute) and
1-100. The rounding error made a 2% increase turn into a 0% change.
I'm not sure this is a good solution, but it's the best I could come up
with; it keeps a 1-100 scale internally, but sets the hardware according to
the converted value. It's against the linuxppc_2_5 tree.
Dan
/--------------------------------\ /--------------------------------\
| Daniel Jacobowitz |__| SCS Class of 2002 |
| Debian GNU/Linux Developer __ Carnegie Mellon University |
| dan@debian.org | | dmj+@andrew.cmu.edu |
\--------------------------------/ \--------------------------------/
[-- Attachment #2: dmasound.diff --]
[-- Type: text/plain, Size: 5599 bytes --]
# 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) {
reply other threads:[~2000-12-16 18:29 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20001216132932.A16741@drow.them.org \
--to=dmj+@andrew.cmu.edu \
--cc=linuxppc-dev@lists.linuxppc.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).