[PATCH 1/3] [UBUNTU:sound/usb] Fix to properly resolve volume at initialization

crimsun at fungus.sh.nu crimsun at fungus.sh.nu
Thu Mar 30 22:19:25 UTC 2006


Subject: [PATCH 1/3] [UBUNTU:sound/usb] Fix to properly resolve volume at initialization

UpstreamStatus: Added in upstream usb/usbmixer.c r1.56

This patch from Takashi Iwai adds proper volume resolution at
initialization. A significant number of USB audio devices erroneously
report lower resolutions, so the usb-audio driver now tests and adjusts
the resolution first.

Signed-off-by: Daniel T Chen <crimsun at ubuntu.com>

---

 sound/usb/usbmixer.c |   37 ++++++++++++++++++++++++++++++++++---
 1 files changed, 34 insertions(+), 3 deletions(-)

53701c29e601c726f796b630bd4cc6e638e8edfe
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index e570d14..9c1ad1a 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -311,8 +311,8 @@ static int get_relative_value(usb_mixer_
 		cval->res = 1;
 	if (val < cval->min)
 		return 0;
-	else if (val > cval->max)
-		return (cval->max - cval->min) / cval->res;
+	else if (val >= cval->max)
+		return (cval->max - cval->min + cval->res - 1) / cval->res;
 	else
 		return (val - cval->min) / cval->res;
 }
@@ -676,6 +676,36 @@ static int get_min_max(usb_mixer_elem_in
 		}
 		if (cval->res == 0)
 			cval->res = 1;
+
+		/* Additional checks for the proper resolution
+		 *
+		 * Some devices report smaller resolutions than actually
+		 * reacting.  They don't return errors but simply clip
+		 * to the lower aligned value.
+		 */
+		if (cval->min + cval->res < cval->max) {
+			int last_valid_res = cval->res;
+			int saved, test, check;
+			get_cur_mix_value(cval, minchn, &saved);
+			for (;;) {
+				test = saved;
+				if (test < cval->max)
+					test += cval->res;
+				else
+					test -= cval->res;
+				if (test < cval->min || test > cval->max ||
+				    set_cur_mix_value(cval, minchn, test) ||
+				    get_cur_mix_value(cval, minchn, &check)) {
+					cval->res = last_valid_res;
+					break;
+				}
+				if (test == check)
+					break;
+				cval->res *= 2;
+			}
+			set_cur_mix_value(cval, minchn, saved);
+		}
+
 		cval->initialized = 1;
 	}
 	return 0;
@@ -701,7 +731,8 @@ static int mixer_ctl_feature_info(snd_kc
 		if (! cval->initialized)
 			get_min_max(cval,  0);
 		uinfo->value.integer.min = 0;
-		uinfo->value.integer.max = (cval->max - cval->min) / cval->res;
+		uinfo->value.integer.max =
+			(cval->max - cval->min + cval->res - 1) / cval->res;
 	}
 	return 0;
 }
-- 
1.1.3


-- 
Daniel T. Chen            crimsun at ubuntu.com
GPG key:   www.sh.nu/~crimsun/pubkey.gpg.asc
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20060330/7bfbe2d3/attachment.sig>


More information about the kernel-team mailing list