aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/wacom_sys.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-12 13:26:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-12 13:26:47 -0500
commit0349678ccd74d16c1f2bb58ecafec13ef7110e36 (patch)
treef9ec0afd9659bebb37ab116064137bd5192e255e /drivers/hid/wacom_sys.c
parenta7cb7bb664543e4562ab0e9a072470d2d18c761f (diff)
parent019e129f9b2d582e5901c0594427cb4026daa413 (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.c68
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,
70static int wacom_open(struct input_dev *dev) 71static 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
82static void wacom_close(struct input_dev *dev) 78static 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
233static 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
233static void wacom_parse_hid(struct hid_device *hdev, 248static 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
269static int wacom_hid_set_device_mode(struct hid_device *hdev) 286static 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
1182fail_leds: 1198fail_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;
1185fail_register_pad_input: 1202fail_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
1324static 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
1330static size_t wacom_compute_pktlen(struct hid_device *hdev) 1342static 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 }