|
@@ -215,13 +215,14 @@ static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
|
|
|
* Add a usage to the temporary parser table.
|
|
* Add a usage to the temporary parser table.
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
-static int hid_add_usage(struct hid_parser *parser, unsigned usage)
|
|
|
|
|
|
|
+static int hid_add_usage(struct hid_parser *parser, unsigned usage, u8 size)
|
|
|
{
|
|
{
|
|
|
if (parser->local.usage_index >= HID_MAX_USAGES) {
|
|
if (parser->local.usage_index >= HID_MAX_USAGES) {
|
|
|
hid_err(parser->device, "usage index exceeded\n");
|
|
hid_err(parser->device, "usage index exceeded\n");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
parser->local.usage[parser->local.usage_index] = usage;
|
|
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->local.collection_index[parser->local.usage_index] =
|
|
|
parser->collection_stack_ptr ?
|
|
parser->collection_stack_ptr ?
|
|
|
parser->collection_stack[parser->collection_stack_ptr - 1] : 0;
|
|
parser->collection_stack[parser->collection_stack_ptr - 1] : 0;
|
|
@@ -482,10 +483,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (item->size <= 2)
|
|
|
|
|
- data = (parser->global.usage_page << 16) + data;
|
|
|
|
|
-
|
|
|
|
|
- return hid_add_usage(parser, data);
|
|
|
|
|
|
|
+ return hid_add_usage(parser, data, item->size);
|
|
|
|
|
|
|
|
case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
|
|
case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
|
|
|
|
|
|
|
@@ -494,9 +492,6 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (item->size <= 2)
|
|
|
|
|
- data = (parser->global.usage_page << 16) + data;
|
|
|
|
|
-
|
|
|
|
|
parser->local.usage_minimum = data;
|
|
parser->local.usage_minimum = data;
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
@@ -507,9 +502,6 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (item->size <= 2)
|
|
|
|
|
- data = (parser->global.usage_page << 16) + data;
|
|
|
|
|
-
|
|
|
|
|
count = data - parser->local.usage_minimum;
|
|
count = data - parser->local.usage_minimum;
|
|
|
if (count + parser->local.usage_index >= HID_MAX_USAGES) {
|
|
if (count + parser->local.usage_index >= HID_MAX_USAGES) {
|
|
|
/*
|
|
/*
|
|
@@ -529,7 +521,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
for (n = parser->local.usage_minimum; n <= data; n++)
|
|
for (n = parser->local.usage_minimum; n <= data; n++)
|
|
|
- if (hid_add_usage(parser, n)) {
|
|
|
|
|
|
|
+ if (hid_add_usage(parser, n, item->size)) {
|
|
|
dbg_hid("hid_add_usage failed\n");
|
|
dbg_hid("hid_add_usage failed\n");
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
@@ -543,6 +535,22 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+ * Concatenate Usage Pages into Usages where relevant:
|
|
|
|
|
+ * As per specification, 6.2.2.8: "When the parser encounters a main item it
|
|
|
|
|
+ * concatenates the last declared Usage Page with a Usage to form a complete
|
|
|
|
|
+ * usage value."
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+static void hid_concatenate_usage_page(struct hid_parser *parser)
|
|
|
|
|
+{
|
|
|
|
|
+ int i;
|
|
|
|
|
+
|
|
|
|
|
+ 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;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/*
|
|
/*
|
|
|
* Process a main item.
|
|
* Process a main item.
|
|
|
*/
|
|
*/
|
|
@@ -552,6 +560,8 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
|
|
|
__u32 data;
|
|
__u32 data;
|
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
+ hid_concatenate_usage_page(parser);
|
|
|
|
|
+
|
|
|
data = item_udata(item);
|
|
data = item_udata(item);
|
|
|
|
|
|
|
|
switch (item->tag) {
|
|
switch (item->tag) {
|
|
@@ -761,6 +771,8 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
|
|
|
__u32 data;
|
|
__u32 data;
|
|
|
int i;
|
|
int i;
|
|
|
|
|
|
|
|
|
|
+ hid_concatenate_usage_page(parser);
|
|
|
|
|
+
|
|
|
data = item_udata(item);
|
|
data = item_udata(item);
|
|
|
|
|
|
|
|
switch (item->tag) {
|
|
switch (item->tag) {
|