From 36c0ec31f502c373aa3860518fa82ed931115f66 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 28 Mar 2006 17:58:28 +0200 Subject: [PATCH] --- yaml --- r: 25262 b: refs/heads/master c: 14790f1c73cfa4d4a22ac10b4501b4831380683c h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/sound/usb/usbmixer.c | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 909eeb9dd490..f3891ab1486a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0b2dcd5d6a9a3e27fdd67053e526388f9f2ea33b +refs/heads/master: 14790f1c73cfa4d4a22ac10b4501b4831380683c diff --git a/trunk/sound/usb/usbmixer.c b/trunk/sound/usb/usbmixer.c index 8d08b34a1cb5..ce86283ee0fa 100644 --- a/trunk/sound/usb/usbmixer.c +++ b/trunk/sound/usb/usbmixer.c @@ -306,8 +306,8 @@ static int get_relative_value(struct usb_mixer_elem_info *cval, int val) 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; } @@ -670,6 +670,36 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) } 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; @@ -695,7 +725,8 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ 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; }