1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
From 4655dc18074e0be9d239f51dac32b61435da8549 Mon Sep 17 00:00:00 2001
From: Richard Purdie <richard.purdie@linuxfoundation.org>
Date: Thu, 27 Nov 2014 14:04:29 +0000
Subject: [PATCH] qemu: Add missing wacom HID descriptor
The USB wacom device is missing a HID descriptor which causes it
to fail to operate with recent kernels (e.g. 3.17).
This patch adds a HID desriptor to the device, based upon one from
real wcom device.
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Upstream-Status: Submitted
2014/11/27
---
hw/usb/dev-wacom.c | 94 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 93 insertions(+), 1 deletion(-)
diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
index 8c43db93..3ff8ca28 100644
--- a/hw/usb/dev-wacom.c
+++ b/hw/usb/dev-wacom.c
@@ -74,6 +74,89 @@ static const USBDescStrings desc_strings = {
[STR_SERIALNUMBER] = "1",
};
+static const uint8_t qemu_tablet_hid_report_descriptor[] = {
+ 0x05, 0x01, /* Usage Page (Generic Desktop) */
+ 0x09, 0x02, /* Usage (Mouse) */
+ 0xa1, 0x01, /* Collection (Application) */
+ 0x85, 0x01, /* Report ID (1) */
+ 0x09, 0x01, /* Usage (Pointer) */
+ 0xa1, 0x00, /* Collection (Physical) */
+ 0x05, 0x09, /* Usage Page (Button) */
+ 0x19, 0x01, /* Usage Minimum (1) */
+ 0x29, 0x05, /* Usage Maximum (5) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x25, 0x01, /* Logical Maximum (1) */
+ 0x95, 0x05, /* Report Count (5) */
+ 0x75, 0x01, /* Report Size (1) */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0x95, 0x01, /* Report Count (1) */
+ 0x75, 0x03, /* Report Size (3) */
+ 0x81, 0x01, /* Input (Constant) */
+ 0x05, 0x01, /* Usage Page (Generic Desktop) */
+ 0x09, 0x30, /* Usage (X) */
+ 0x09, 0x31, /* Usage (Y) */
+ 0x15, 0x81, /* Logical Minimum (-127) */
+ 0x25, 0x7f, /* Logical Maximum (127) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x02, /* Report Count (2) */
+ 0x81, 0x06, /* Input (Data, Variable, Relative) */
+ 0xc0, /* End Collection */
+ 0xc0, /* End Collection */
+ 0x05, 0x0d, /* Usage Page (Digitizer) */
+ 0x09, 0x01, /* Usage (Digitizer) */
+ 0xa1, 0x01, /* Collection (Application) */
+ 0x85, 0x02, /* Report ID (2) */
+ 0xa1, 0x00, /* Collection (Physical) */
+ 0x06, 0x00, 0xff, /* Usage Page (Vendor 0xff00) */
+ 0x09, 0x01, /* Usage (Digitizer) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x26, 0xff, 0x00, /* Logical Maximum (255) */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x08, /* Report Count (8) */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0xc0, /* End Collection */
+ 0x09, 0x01, /* Usage (Digitizer) */
+ 0x85, 0x02, /* Report ID (2) */
+ 0x95, 0x01, /* Report Count (1) */
+ 0xb1, 0x02, /* FEATURE (2) */
+ 0xc0, /* End Collection */
+ 0x06, 0x00, 0xff, /* Usage Page (Vendor 0xff00) */
+ 0x09, 0x01, /* Usage (Digitizer) */
+ 0xa1, 0x01, /* Collection (Application) */
+ 0x85, 0x02, /* Report ID (2) */
+ 0x05, 0x0d, /* Usage Page (Digitizer) */
+ 0x09, 0x22, /* Usage (Finger) */
+ 0xa1, 0x00, /* Collection (Physical) */
+ 0x06, 0x00, 0xff, /* Usage Page (Vendor 0xff00) */
+ 0x09, 0x01, /* Usage (Digitizer) */
+ 0x15, 0x00, /* Logical Minimum (0) */
+ 0x26, 0xff, 0x00, /* Logical Maximum */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x02, /* Report Count (2) */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0x05, 0x01, /* Usage Page (Generic Desktop) */
+ 0x09, 0x30, /* Usage (X) */
+ 0x35, 0x00, /* Physical Minimum */
+ 0x46, 0xe0, 0x2e, /* Physical Maximum */
+ 0x26, 0xe0, 0x01, /* Logical Maximum */
+ 0x75, 0x10, /* Report Size (16) */
+ 0x95, 0x01, /* Report Count (1) */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0x09, 0x31, /* Usage (Y) */
+ 0x46, 0x40, 0x1f, /* Physical Maximum */
+ 0x26, 0x40, 0x01, /* Logical Maximum */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0x06, 0x00, 0xff, /* Usage Page (Vendor 0xff00) */
+ 0x09, 0x01, /* Usage (Digitizer) */
+ 0x26, 0xff, 0x00, /* Logical Maximum */
+ 0x75, 0x08, /* Report Size (8) */
+ 0x95, 0x0d, /* Report Count (13) */
+ 0x81, 0x02, /* Input (Data, Variable, Absolute) */
+ 0xc0, /* End Collection */
+ 0xc0, /* End Collection */
+};
+
+
static const USBDescIface desc_iface_wacom = {
.bInterfaceNumber = 0,
.bNumEndpoints = 1,
@@ -91,7 +174,7 @@ static const USBDescIface desc_iface_wacom = {
0x00, /* u8 country_code */
0x01, /* u8 num_descriptors */
0x22, /* u8 type: Report */
- 0x6e, 0, /* u16 len */
+ sizeof(qemu_tablet_hid_report_descriptor), 0, /* u16 len */
},
},
},
@@ -271,6 +354,15 @@ static void usb_wacom_handle_control(USBDevice *dev, USBPacket *p,
}
switch (request) {
+ case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
+ switch (value >> 8) {
+ case 0x22:
+ memcpy(data, qemu_tablet_hid_report_descriptor,
+ sizeof(qemu_tablet_hid_report_descriptor));
+ p->actual_length = sizeof(qemu_tablet_hid_report_descriptor);
+ break;
+ }
+ break;
case WACOM_SET_REPORT:
if (s->mouse_grabbed) {
qemu_remove_mouse_event_handler(s->eh_entry);
|