diff options
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 8593047bb72..654202941d3 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; } |