author | Pengfei Zhao <pengfei.zhao@amlogic.com> | 2019-10-10 06:40:30 (GMT) |
---|---|---|
committer | Jianxin Pan <jianxin.pan@amlogic.com> | 2019-10-10 08:53:28 (GMT) |
commit | e611bb331f9099d54274d5bd5cf68f233e254198 (patch) | |
tree | da42c6e859b9a4e386f384131d4f426dbcc2131a | |
parent | 77de3d55bb391070f91ff271ee81a2b2dd910884 (diff) | |
download | common-e611bb331f9099d54274d5bd5cf68f233e254198.zip common-e611bb331f9099d54274d5bd5cf68f233e254198.tar.gz common-e611bb331f9099d54274d5bd5cf68f233e254198.tar.bz2 |
HID: core: move Usage Page concatenation to Main item [1/1]
PD#SWPL-10069
Problem:
android.hardware.input.cts.tests.AsusGamepadTestCase#testAllMotions
android.hardware.input.cts.tests.AsusGamepadTestCase#testAllKeys
Solution:
adds usage_page_last to flag whether Usage Page is after
Usage ID items. usage_page_last is false default, it is set as true
once Usage Page item is encountered and is reverted by next Usage ID
item.
google bug=138556465
https://lkml.org/lkml/2019/10/9/430
Verify:
franklin
Change-Id: I7593132556e32fe0979906447b3162f1cf30bbc3
Signed-off-by: Pengfei Zhao <pengfei.zhao@amlogic.com>
-rw-r--r-- | drivers/hid/hid-core.c | 28 | ||||
-rw-r--r-- | include/linux/hid.h | 1 |
2 files changed, 23 insertions, 6 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index ceb4df9..eca445a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -37,6 +37,7 @@ #include <linux/hidraw.h> #include "hid-ids.h" +#define GET_COMPLETE_USAGE(page, id) (((page) << 16) + ((id) & 0xffff)) /* * Version Information @@ -206,7 +207,14 @@ static int hid_add_usage(struct hid_parser *parser, unsigned usage, u8 size) hid_err(parser->device, "usage index exceeded\n"); return -1; } - parser->local.usage[parser->local.usage_index] = usage; + if (size <= 2) { + parser->local.usage_page_last = false; + parser->local.usage[parser->local.usage_index] = + GET_COMPLETE_USAGE(parser->global.usage_page, usage); + } else { + parser->local.usage[parser->local.usage_index] = usage; + } + parser->local.usage_size[parser->local.usage_index] = size; parser->local.collection_index[parser->local.usage_index] = parser->collection_stack_ptr ? @@ -346,6 +354,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: parser->global.usage_page = item_udata(item); + parser->local.usage_page_last = true; return 0; case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: @@ -523,13 +532,20 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) * usage value." */ -static void hid_concatenate_usage_page(struct hid_parser *parser) +static void hid_concatenate_last_usage_page(struct hid_parser *parser) { int i; + unsigned int usage; + unsigned int usage_page = parser->global.usage_page; + if (!parser->local.usage_page_last) + return; for (i = 0; i < parser->local.usage_index; i++) - if (parser->local.usage_size[i] <= 2) - parser->local.usage[i] += parser->global.usage_page << 16; + if (parser->local.usage_size[i] <= 2) { + usage = parser->local.usage[i]; + parser->local.usage[i] = + GET_COMPLETE_USAGE(usage_page, usage); + } } /* @@ -541,7 +557,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) __u32 data; int ret; - hid_concatenate_usage_page(parser); + hid_concatenate_last_usage_page(parser); data = item_udata(item); @@ -756,7 +772,7 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) __u32 data; int i; - hid_concatenate_usage_page(parser); + hid_concatenate_last_usage_page(parser); data = item_udata(item); diff --git a/include/linux/hid.h b/include/linux/hid.h index 04bdf54..9748c67 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -380,6 +380,7 @@ struct hid_local { unsigned usage_minimum; unsigned delimiter_depth; unsigned delimiter_branch; + bool usage_page_last; }; /* |