diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-12 13:26:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-12 13:26:47 -0500 |
commit | 0349678ccd74d16c1f2bb58ecafec13ef7110e36 (patch) | |
tree | f9ec0afd9659bebb37ab116064137bd5192e255e /drivers/hid/wacom_sys.c | |
parent | a7cb7bb664543e4562ab0e9a072470d2d18c761f (diff) | |
parent | 019e129f9b2d582e5901c0594427cb4026daa413 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina:
- i2c-hid race condition fix from Jean-Baptiste Maneyrol
- Logitech driver now supports vendor-specific HID++ protocol, allowing
us to deliver a full multitouch support on wider range of Logitech
touchpads. Written by Benjamin Tissoires
- MS Surface Pro 3 Type Cover support added by Alan Wu
- RMI touchpad support improvements from Andrew Duggan
- a lot of updates to Wacom driver from Jason Gerecke and Ping Cheng
- various small fixes all over the place
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (56 commits)
HID: rmi: The address of query8 must be calculated based on which query registers are present
HID: rmi: Check for additional ACM registers appended to F11 data report
HID: i2c-hid: prevent buffer overflow in early IRQ
HID: logitech-hidpp: disable io in probe error path
HID: logitech-hidpp: add boundary check for name retrieval
HID: logitech-hidpp: check name retrieval return code
HID: logitech-hidpp: do not return the name length
HID: wacom: Report input events for each finger on generic devices
HID: wacom: Initialize MT slots for generic devices at post_parse_hid
HID: wacom: Update maximum X/Y accounding to outbound offset
HID: wacom: Add support for DTU-1031X
HID: wacom: add defines for new Cintiq and DTU outbound tracking
HID: wacom: fix freeze on open when autosuspend is on
HID: wacom: re-add accidentally dropped Lenovo PID
HID: make hid_report_len as a static inline function in hid.h
HID: wacom: Consult the application usage when determining field type
HID: wacom: PAD is independent with pen/touch
HID: multitouch: Add quirk for VTL touch panels
HID: i2c-hid: fix race condition reading reports
HID: wacom: Add angular resolution data to some ABS axes
...
Diffstat (limited to 'drivers/hid/wacom_sys.c')
-rw-r--r-- | drivers/hid/wacom_sys.c | 68 |
1 files changed, 40 insertions, 28 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 8593047bb726..654202941d30 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include "wacom_wac.h" | 14 | #include "wacom_wac.h" |
15 | #include "wacom.h" | 15 | #include "wacom.h" |
16 | #include <linux/input/mt.h> | ||
16 | 17 | ||
17 | #define WAC_MSG_RETRIES 5 | 18 | #define WAC_MSG_RETRIES 5 |
18 | 19 | ||
@@ -70,22 +71,15 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
70 | static int wacom_open(struct input_dev *dev) | 71 | static int wacom_open(struct input_dev *dev) |
71 | { | 72 | { |
72 | struct wacom *wacom = input_get_drvdata(dev); | 73 | struct wacom *wacom = input_get_drvdata(dev); |
73 | int retval; | ||
74 | |||
75 | mutex_lock(&wacom->lock); | ||
76 | retval = hid_hw_open(wacom->hdev); | ||
77 | mutex_unlock(&wacom->lock); | ||
78 | 74 | ||
79 | return retval; | 75 | return hid_hw_open(wacom->hdev); |
80 | } | 76 | } |
81 | 77 | ||
82 | static void wacom_close(struct input_dev *dev) | 78 | static void wacom_close(struct input_dev *dev) |
83 | { | 79 | { |
84 | struct wacom *wacom = input_get_drvdata(dev); | 80 | struct wacom *wacom = input_get_drvdata(dev); |
85 | 81 | ||
86 | mutex_lock(&wacom->lock); | ||
87 | hid_hw_close(wacom->hdev); | 82 | hid_hw_close(wacom->hdev); |
88 | mutex_unlock(&wacom->lock); | ||
89 | } | 83 | } |
90 | 84 | ||
91 | /* | 85 | /* |
@@ -192,9 +186,15 @@ static void wacom_usage_mapping(struct hid_device *hdev, | |||
192 | if (!pen && !finger) | 186 | if (!pen && !finger) |
193 | return; | 187 | return; |
194 | 188 | ||
195 | if (finger && !features->touch_max) | 189 | /* |
196 | /* touch device at least supports one touch point */ | 190 | * Bamboo models do not support HID_DG_CONTACTMAX. |
197 | features->touch_max = 1; | 191 | * And, Bamboo Pen only descriptor contains touch. |
192 | */ | ||
193 | if (features->type != BAMBOO_PT) { | ||
194 | /* ISDv4 touch devices at least supports one touch point */ | ||
195 | if (finger && !features->touch_max) | ||
196 | features->touch_max = 1; | ||
197 | } | ||
198 | 198 | ||
199 | switch (usage->hid) { | 199 | switch (usage->hid) { |
200 | case HID_GD_X: | 200 | case HID_GD_X: |
@@ -230,6 +230,21 @@ static void wacom_usage_mapping(struct hid_device *hdev, | |||
230 | wacom_wac_usage_mapping(hdev, field, usage); | 230 | wacom_wac_usage_mapping(hdev, field, usage); |
231 | } | 231 | } |
232 | 232 | ||
233 | static void wacom_post_parse_hid(struct hid_device *hdev, | ||
234 | struct wacom_features *features) | ||
235 | { | ||
236 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
237 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
238 | |||
239 | if (features->type == HID_GENERIC) { | ||
240 | /* Any last-minute generic device setup */ | ||
241 | if (features->touch_max > 1) { | ||
242 | input_mt_init_slots(wacom_wac->input, wacom_wac->features.touch_max, | ||
243 | INPUT_MT_DIRECT); | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | |||
233 | static void wacom_parse_hid(struct hid_device *hdev, | 248 | static void wacom_parse_hid(struct hid_device *hdev, |
234 | struct wacom_features *features) | 249 | struct wacom_features *features) |
235 | { | 250 | { |
@@ -264,6 +279,8 @@ static void wacom_parse_hid(struct hid_device *hdev, | |||
264 | wacom_usage_mapping(hdev, hreport->field[i], | 279 | wacom_usage_mapping(hdev, hreport->field[i], |
265 | hreport->field[i]->usage + j); | 280 | hreport->field[i]->usage + j); |
266 | } | 281 | } |
282 | |||
283 | wacom_post_parse_hid(hdev, features); | ||
267 | } | 284 | } |
268 | 285 | ||
269 | static int wacom_hid_set_device_mode(struct hid_device *hdev) | 286 | static int wacom_hid_set_device_mode(struct hid_device *hdev) |
@@ -1129,7 +1146,7 @@ static void wacom_clean_inputs(struct wacom *wacom) | |||
1129 | input_free_device(wacom->wacom_wac.input); | 1146 | input_free_device(wacom->wacom_wac.input); |
1130 | } | 1147 | } |
1131 | if (wacom->wacom_wac.pad_input) { | 1148 | if (wacom->wacom_wac.pad_input) { |
1132 | if (wacom->wacom_wac.input_registered) | 1149 | if (wacom->wacom_wac.pad_registered) |
1133 | input_unregister_device(wacom->wacom_wac.pad_input); | 1150 | input_unregister_device(wacom->wacom_wac.pad_input); |
1134 | else | 1151 | else |
1135 | input_free_device(wacom->wacom_wac.pad_input); | 1152 | input_free_device(wacom->wacom_wac.pad_input); |
@@ -1151,13 +1168,13 @@ static int wacom_register_inputs(struct wacom *wacom) | |||
1151 | if (!input_dev || !pad_input_dev) | 1168 | if (!input_dev || !pad_input_dev) |
1152 | return -EINVAL; | 1169 | return -EINVAL; |
1153 | 1170 | ||
1154 | error = wacom_setup_input_capabilities(input_dev, wacom_wac); | 1171 | error = wacom_setup_pentouch_input_capabilities(input_dev, wacom_wac); |
1155 | if (error) | 1172 | if (!error) { |
1156 | return error; | 1173 | error = input_register_device(input_dev); |
1157 | 1174 | if (error) | |
1158 | error = input_register_device(input_dev); | 1175 | return error; |
1159 | if (error) | 1176 | wacom_wac->input_registered = true; |
1160 | return error; | 1177 | } |
1161 | 1178 | ||
1162 | error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); | 1179 | error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); |
1163 | if (error) { | 1180 | if (error) { |
@@ -1169,22 +1186,23 @@ static int wacom_register_inputs(struct wacom *wacom) | |||
1169 | error = input_register_device(pad_input_dev); | 1186 | error = input_register_device(pad_input_dev); |
1170 | if (error) | 1187 | if (error) |
1171 | goto fail_register_pad_input; | 1188 | goto fail_register_pad_input; |
1189 | wacom_wac->pad_registered = true; | ||
1172 | 1190 | ||
1173 | error = wacom_initialize_leds(wacom); | 1191 | error = wacom_initialize_leds(wacom); |
1174 | if (error) | 1192 | if (error) |
1175 | goto fail_leds; | 1193 | goto fail_leds; |
1176 | } | 1194 | } |
1177 | 1195 | ||
1178 | wacom_wac->input_registered = true; | ||
1179 | |||
1180 | return 0; | 1196 | return 0; |
1181 | 1197 | ||
1182 | fail_leds: | 1198 | fail_leds: |
1183 | input_unregister_device(pad_input_dev); | 1199 | input_unregister_device(pad_input_dev); |
1184 | pad_input_dev = NULL; | 1200 | pad_input_dev = NULL; |
1201 | wacom_wac->pad_registered = false; | ||
1185 | fail_register_pad_input: | 1202 | fail_register_pad_input: |
1186 | input_unregister_device(input_dev); | 1203 | input_unregister_device(input_dev); |
1187 | wacom_wac->input = NULL; | 1204 | wacom_wac->input = NULL; |
1205 | wacom_wac->input_registered = false; | ||
1188 | return error; | 1206 | return error; |
1189 | } | 1207 | } |
1190 | 1208 | ||
@@ -1321,12 +1339,6 @@ static void wacom_calculate_res(struct wacom_features *features) | |||
1321 | features->unitExpo); | 1339 | features->unitExpo); |
1322 | } | 1340 | } |
1323 | 1341 | ||
1324 | static int wacom_hid_report_len(struct hid_report *report) | ||
1325 | { | ||
1326 | /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */ | ||
1327 | return ((report->size - 1) >> 3) + 1 + (report->id > 0); | ||
1328 | } | ||
1329 | |||
1330 | static size_t wacom_compute_pktlen(struct hid_device *hdev) | 1342 | static size_t wacom_compute_pktlen(struct hid_device *hdev) |
1331 | { | 1343 | { |
1332 | struct hid_report_enum *report_enum; | 1344 | struct hid_report_enum *report_enum; |
@@ -1336,7 +1348,7 @@ static size_t wacom_compute_pktlen(struct hid_device *hdev) | |||
1336 | report_enum = hdev->report_enum + HID_INPUT_REPORT; | 1348 | report_enum = hdev->report_enum + HID_INPUT_REPORT; |
1337 | 1349 | ||
1338 | list_for_each_entry(report, &report_enum->report_list, list) { | 1350 | list_for_each_entry(report, &report_enum->report_list, list) { |
1339 | size_t report_size = wacom_hid_report_len(report); | 1351 | size_t report_size = hid_report_len(report); |
1340 | if (report_size > size) | 1352 | if (report_size > size) |
1341 | size = report_size; | 1353 | size = report_size; |
1342 | } | 1354 | } |