aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-core.c
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@gmail.com>2012-11-14 10:59:15 -0500
committerJiri Kosina <jkosina@suse.cz>2012-11-15 04:07:55 -0500
commit774638386826621c984ab6994439f474709cac5e (patch)
tree897fb8a15947768f7dc9521027c7c20fe830c1bf /drivers/hid/hid-core.c
parentccdd699411b77c463022ebac311eb4a06ca56db4 (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-core.c')
-rw-r--r--drivers/hid/hid-core.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index f4109fd657ff..f5004e2ca0c5 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -315,6 +315,7 @@ static s32 item_sdata(struct hid_item *item)
315 315
316static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) 316static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
317{ 317{
318 __u32 raw_value;
318 switch (item->tag) { 319 switch (item->tag) {
319 case HID_GLOBAL_ITEM_TAG_PUSH: 320 case HID_GLOBAL_ITEM_TAG_PUSH:
320 321
@@ -365,7 +366,14 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
365 return 0; 366 return 0;
366 367
367 case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: 368 case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
368 parser->global.unit_exponent = item_sdata(item); 369 /* Units exponent negative numbers are given through a
370 * two's complement.
371 * See "6.2.2.7 Global Items" for more information. */
372 raw_value = item_udata(item);
373 if (!(raw_value & 0xfffffff0))
374 parser->global.unit_exponent = hid_snto32(raw_value, 4);
375 else
376 parser->global.unit_exponent = raw_value;
369 return 0; 377 return 0;
370 378
371 case HID_GLOBAL_ITEM_TAG_UNIT: 379 case HID_GLOBAL_ITEM_TAG_UNIT:
@@ -865,6 +873,12 @@ static s32 snto32(__u32 value, unsigned n)
865 return value & (1 << (n - 1)) ? value | (-1 << n) : value; 873 return value & (1 << (n - 1)) ? value | (-1 << n) : value;
866} 874}
867 875
876s32 hid_snto32(__u32 value, unsigned n)
877{
878 return snto32(value, n);
879}
880EXPORT_SYMBOL_GPL(hid_snto32);
881
868/* 882/*
869 * Convert a signed 32-bit integer to a signed n-bit integer. 883 * Convert a signed 32-bit integer to a signed n-bit integer.
870 */ 884 */