aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/wacom_sys.c
diff options
context:
space:
mode:
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 @@
#include "wacom_wac.h"
#include "wacom.h"
+#include <linux/input/mt.h>
#define WAC_MSG_RETRIES 5
@@ -70,22 +71,15 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
static int wacom_open(struct input_dev *dev)
{
struct wacom *wacom = input_get_drvdata(dev);
- int retval;
-
- mutex_lock(&wacom->lock);
- retval = hid_hw_open(wacom->hdev);
- mutex_unlock(&wacom->lock);
- return retval;
+ return hid_hw_open(wacom->hdev);
}
static void wacom_close(struct input_dev *dev)
{
struct wacom *wacom = input_get_drvdata(dev);
- mutex_lock(&wacom->lock);
hid_hw_close(wacom->hdev);
- mutex_unlock(&wacom->lock);
}
/*
@@ -192,9 +186,15 @@ static void wacom_usage_mapping(struct hid_device *hdev,
if (!pen && !finger)
return;
- if (finger && !features->touch_max)
- /* touch device at least supports one touch point */
- features->touch_max = 1;
+ /*
+ * Bamboo models do not support HID_DG_CONTACTMAX.
+ * And, Bamboo Pen only descriptor contains touch.
+ */
+ if (features->type != BAMBOO_PT) {
+ /* ISDv4 touch devices at least supports one touch point */
+ if (finger && !features->touch_max)
+ features->touch_max = 1;
+ }
switch (usage->hid) {
case HID_GD_X:
@@ -230,6 +230,21 @@ static void wacom_usage_mapping(struct hid_device *hdev,
wacom_wac_usage_mapping(hdev, field, usage);
}
+static void wacom_post_parse_hid(struct hid_device *hdev,
+ struct wacom_features *features)
+{
+ struct wacom *wacom = hid_get_drvdata(hdev);
+ struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+
+ if (features->type == HID_GENERIC) {
+ /* Any last-minute generic device setup */
+ if (features->touch_max > 1) {
+ input_mt_init_slots(wacom_wac->input, wacom_wac->features.touch_max,
+ INPUT_MT_DIRECT);
+ }
+ }
+}
+
static void wacom_parse_hid(struct hid_device *hdev,
struct wacom_features *features)
{
@@ -264,6 +279,8 @@ static void wacom_parse_hid(struct hid_device *hdev,
wacom_usage_mapping(hdev, hreport->field[i],
hreport->field[i]->usage + j);
}
+
+ wacom_post_parse_hid(hdev, features);
}
static int wacom_hid_set_device_mode(struct hid_device *hdev)
@@ -1129,7 +1146,7 @@ static void wacom_clean_inputs(struct wacom *wacom)
input_free_device(wacom->wacom_wac.input);
}
if (wacom->wacom_wac.pad_input) {
- if (wacom->wacom_wac.input_registered)
+ if (wacom->wacom_wac.pad_registered)
input_unregister_device(wacom->wacom_wac.pad_input);
else
input_free_device(wacom->wacom_wac.pad_input);
@@ -1151,13 +1168,13 @@ static int wacom_register_inputs(struct wacom *wacom)
if (!input_dev || !pad_input_dev)
return -EINVAL;
- error = wacom_setup_input_capabilities(input_dev, wacom_wac);
- if (error)
- return error;
-
- error = input_register_device(input_dev);
- if (error)
- return error;
+ error = wacom_setup_pentouch_input_capabilities(input_dev, wacom_wac);
+ if (!error) {
+ error = input_register_device(input_dev);
+ if (error)
+ return error;
+ wacom_wac->input_registered = true;
+ }
error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac);
if (error) {
@@ -1169,22 +1186,23 @@ static int wacom_register_inputs(struct wacom *wacom)
error = input_register_device(pad_input_dev);
if (error)
goto fail_register_pad_input;
+ wacom_wac->pad_registered = true;
error = wacom_initialize_leds(wacom);
if (error)
goto fail_leds;
}
- wacom_wac->input_registered = true;
-
return 0;
fail_leds:
input_unregister_device(pad_input_dev);
pad_input_dev = NULL;
+ wacom_wac->pad_registered = false;
fail_register_pad_input:
input_unregister_device(input_dev);
wacom_wac->input = NULL;
+ wacom_wac->input_registered = false;
return error;
}
@@ -1321,12 +1339,6 @@ static void wacom_calculate_res(struct wacom_features *features)
features->unitExpo);
}
-static int wacom_hid_report_len(struct hid_report *report)
-{
- /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
- return ((report->size - 1) >> 3) + 1 + (report->id > 0);
-}
-
static size_t wacom_compute_pktlen(struct hid_device *hdev)
{
struct hid_report_enum *report_enum;
@@ -1336,7 +1348,7 @@ static size_t wacom_compute_pktlen(struct hid_device *hdev)
report_enum = hdev->report_enum + HID_INPUT_REPORT;
list_for_each_entry(report, &report_enum->report_list, list) {
- size_t report_size = wacom_hid_report_len(report);
+ size_t report_size = hid_report_len(report);
if (report_size > size)
size = report_size;
}