diff options
author | Benjamin Tissoires <benjamin.tissoires@gmail.com> | 2012-11-14 10:59:15 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-11-15 04:07:55 -0500 |
commit | 774638386826621c984ab6994439f474709cac5e (patch) | |
tree | 897fb8a15947768f7dc9521027c7c20fe830c1bf /drivers/hid/hid-input.c | |
parent | ccdd699411b77c463022ebac311eb4a06ca56db4 (diff) |
HID: fix unit exponent parsing
HID spec details special values for the HID field unit exponent.
Basically, the range [0x8..0xf] correspond to [-8..-1], so this is
a standard two's complement on a half-byte.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Acked-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-input.c')
-rw-r--r-- | drivers/hid/hid-input.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 1b0adc3f7803..007a9433bfa7 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -192,7 +192,6 @@ static int hidinput_setkeycode(struct input_dev *dev, | |||
192 | return -EINVAL; | 192 | return -EINVAL; |
193 | } | 193 | } |
194 | 194 | ||
195 | |||
196 | /** | 195 | /** |
197 | * hidinput_calc_abs_res - calculate an absolute axis resolution | 196 | * hidinput_calc_abs_res - calculate an absolute axis resolution |
198 | * @field: the HID report field to calculate resolution for | 197 | * @field: the HID report field to calculate resolution for |
@@ -235,17 +234,23 @@ __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | |||
235 | case ABS_MT_TOOL_Y: | 234 | case ABS_MT_TOOL_Y: |
236 | case ABS_MT_TOUCH_MAJOR: | 235 | case ABS_MT_TOUCH_MAJOR: |
237 | case ABS_MT_TOUCH_MINOR: | 236 | case ABS_MT_TOUCH_MINOR: |
238 | if (field->unit == 0x11) { /* If centimeters */ | 237 | if (field->unit & 0xffffff00) /* Not a length */ |
238 | return 0; | ||
239 | unit_exponent += hid_snto32(field->unit >> 4, 4) - 1; | ||
240 | switch (field->unit & 0xf) { | ||
241 | case 0x1: /* If centimeters */ | ||
239 | /* Convert to millimeters */ | 242 | /* Convert to millimeters */ |
240 | unit_exponent += 1; | 243 | unit_exponent += 1; |
241 | } else if (field->unit == 0x13) { /* If inches */ | 244 | break; |
245 | case 0x3: /* If inches */ | ||
242 | /* Convert to millimeters */ | 246 | /* Convert to millimeters */ |
243 | prev = physical_extents; | 247 | prev = physical_extents; |
244 | physical_extents *= 254; | 248 | physical_extents *= 254; |
245 | if (physical_extents < prev) | 249 | if (physical_extents < prev) |
246 | return 0; | 250 | return 0; |
247 | unit_exponent -= 1; | 251 | unit_exponent -= 1; |
248 | } else { | 252 | break; |
253 | default: | ||
249 | return 0; | 254 | return 0; |
250 | } | 255 | } |
251 | break; | 256 | break; |