From 7a3c4ca27908ce3f8cf4c61564b300fd9646a8cc Mon Sep 17 00:00:00 2001 From: Deanna Phillips Date: Tue, 31 Jul 2007 16:14:27 +0000 Subject: In the mixer to device level conversions, round down to the nearest valid step, and keep them in sync. This lets audio(4) set exact gain levels based on the mixer delta, and unbreaks volume up/down buttons in wscons. This also avoids a divide by zero that could occur if the generic mixer init found an amplifier with zero steps. Problem noticed and tested by jmc@, similar diff tested by krw@ --- sys/dev/pci/azalia_codec.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'sys/dev/pci') diff --git a/sys/dev/pci/azalia_codec.c b/sys/dev/pci/azalia_codec.c index dbcae5b1332..656175b7112 100644 --- a/sys/dev/pci/azalia_codec.c +++ b/sys/dev/pci/azalia_codec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: azalia_codec.c,v 1.27 2007/07/23 03:41:03 deanna Exp $ */ +/* $OpenBSD: azalia_codec.c,v 1.28 2007/07/31 16:14:26 deanna Exp $ */ /* $NetBSD: azalia_codec.c,v 1.8 2006/05/10 11:17:27 kent Exp $ */ /*- @@ -1320,7 +1320,11 @@ azalia_generic_mixer_from_device_value(const codec_t *this, nid_t nid, int targe printf("unknown target: %d\n", target); dmax = 255; } - return dv * AUDIO_MAX_GAIN / dmax; + if (dv <= 0 || dmax == 0) + return AUDIO_MIN_GAIN; + if (dv >= dmax) + return AUDIO_MAX_GAIN - AUDIO_MAX_GAIN % dmax; + return dv * (AUDIO_MAX_GAIN - AUDIO_MAX_GAIN % dmax) / dmax; #else return dv; #endif @@ -1343,7 +1347,11 @@ azalia_generic_mixer_to_device_value(const codec_t *this, nid_t nid, int target, printf("unknown target: %d\n", target); dmax = 255; } - return uv * dmax / AUDIO_MAX_GAIN; + if (uv <= AUDIO_MIN_GAIN || dmax == 0) + return 0; + if (uv >= AUDIO_MAX_GAIN - AUDIO_MAX_GAIN % dmax) + return dmax; + return uv * dmax / (AUDIO_MAX_GAIN - AUDIO_MAX_GAIN % dmax); #else return uv; #endif -- cgit v1.2.3