summaryrefslogtreecommitdiff
authorPengfei 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)
commite611bb331f9099d54274d5bd5cf68f233e254198 (patch)
treeda42c6e859b9a4e386f384131d4f426dbcc2131a
parent77de3d55bb391070f91ff271ee81a2b2dd910884 (diff)
downloadcommon-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>
Diffstat
-rw-r--r--drivers/hid/hid-core.c28
-rw-r--r--include/linux/hid.h1
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;
};
/*