summaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/tablet/wacom.h2
-rw-r--r--drivers/input/tablet/wacom_sys.c63
-rw-r--r--drivers/input/tablet/wacom_wac.c27
-rw-r--r--drivers/input/tablet/wacom_wac.h2
4 files changed, 85 insertions, 9 deletions
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index 9ebf0ed3b3b3..caa59cab2c5f 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -136,4 +136,6 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
void wacom_setup_device_quirks(struct wacom_features *features);
int wacom_setup_input_capabilities(struct input_dev *input_dev,
struct wacom_wac *wacom_wac);
+int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
+ struct wacom_wac *wacom_wac);
#endif
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 7cd0886cddd2..b25848581fc1 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -135,6 +135,9 @@ static int wacom_open(struct input_dev *dev)
mutex_lock(&wacom->lock);
+ if (wacom->open)
+ goto out;
+
if (usb_submit_urb(wacom->irq, GFP_KERNEL)) {
retval = -EIO;
goto out;
@@ -157,9 +160,14 @@ static void wacom_close(struct input_dev *dev)
autopm_error = usb_autopm_get_interface(wacom->intf);
mutex_lock(&wacom->lock);
+ if (!wacom->open)
+ goto out;
+
usb_kill_urb(wacom->irq);
wacom->open = false;
wacom->intf->needs_remote_wakeup = 0;
+
+out:
mutex_unlock(&wacom->lock);
if (!autopm_error)
@@ -1112,19 +1120,16 @@ static void wacom_destroy_battery(struct wacom *wacom)
}
}
-static int wacom_register_input(struct wacom *wacom)
+static struct input_dev *wacom_allocate_input(struct wacom *wacom)
{
struct input_dev *input_dev;
struct usb_interface *intf = wacom->intf;
struct usb_device *dev = interface_to_usbdev(intf);
struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
- int error;
input_dev = input_allocate_device();
- if (!input_dev) {
- error = -ENOMEM;
- goto fail1;
- }
+ if (!input_dev)
+ return NULL;
input_dev->name = wacom_wac->name;
input_dev->phys = wacom->phys;
@@ -1134,21 +1139,59 @@ static int wacom_register_input(struct wacom *wacom)
usb_to_input_id(dev, &input_dev->id);
input_set_drvdata(input_dev, wacom);
+ return input_dev;
+}
+
+static int wacom_register_input(struct wacom *wacom)
+{
+ struct input_dev *input_dev, *pad_input_dev;
+ struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
+ int error;
+
+ input_dev = wacom_allocate_input(wacom);
+ pad_input_dev = wacom_allocate_input(wacom);
+ if (!input_dev || !pad_input_dev) {
+ error = -ENOMEM;
+ goto fail1;
+ }
+
wacom_wac->input = input_dev;
+ wacom_wac->pad_input = pad_input_dev;
+ wacom_wac->pad_input->name = wacom_wac->pad_name;
+
error = wacom_setup_input_capabilities(input_dev, wacom_wac);
if (error)
- goto fail1;
+ goto fail2;
error = input_register_device(input_dev);
if (error)
goto fail2;
+ error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac);
+ if (error) {
+ /* no pad in use on this interface */
+ input_free_device(pad_input_dev);
+ wacom_wac->pad_input = NULL;
+ pad_input_dev = NULL;
+ } else {
+ error = input_register_device(pad_input_dev);
+ if (error)
+ goto fail3;
+ }
+
return 0;
+fail3:
+ input_unregister_device(input_dev);
+ input_dev = NULL;
fail2:
- input_free_device(input_dev);
wacom_wac->input = NULL;
+ wacom_wac->pad_input = NULL;
fail1:
+ if (input_dev)
+ input_free_device(input_dev);
+ if (pad_input_dev)
+ input_free_device(pad_input_dev);
return error;
}
@@ -1367,6 +1410,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom_calculate_res(features);
strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
+ snprintf(wacom_wac->pad_name, sizeof(wacom_wac->pad_name),
+ "%s Pad", features->name);
if (features->quirks & WACOM_QUIRK_MULTI_INPUT) {
struct usb_device *other_dev;
@@ -1441,6 +1486,8 @@ static void wacom_disconnect(struct usb_interface *intf)
cancel_work_sync(&wacom->work);
if (wacom->wacom_wac.input)
input_unregister_device(wacom->wacom_wac.input);
+ if (wacom->wacom_wac.pad_input)
+ input_unregister_device(wacom->wacom_wac.pad_input);
wacom_destroy_battery(wacom);
wacom_destroy_leds(wacom);
usb_free_urb(wacom->irq);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 977d05cd9e2e..4b16a34c95fb 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -1489,8 +1489,11 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
break;
}
- if (sync)
+ if (sync) {
input_sync(wacom_wac->input);
+ if (wacom_wac->pad_input)
+ input_sync(wacom_wac->pad_input);
+ }
}
static void wacom_setup_cintiq(struct wacom_wac *wacom_wac)
@@ -1939,6 +1942,28 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
return 0;
}
+int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
+ struct wacom_wac *wacom_wac)
+{
+ struct wacom_features *features = &wacom_wac->features;
+
+ input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+
+ /* kept for making legacy xf86-input-wacom working with the wheels */
+ __set_bit(ABS_MISC, input_dev->absbit);
+
+ /* kept for making legacy xf86-input-wacom accepting the pad */
+ input_set_abs_params(input_dev, ABS_X, 0, 1, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, 1, 0, 0);
+
+ switch (features->type) {
+ default:
+ /* no pad supported */
+ return 1;
+ }
+ return 0;
+}
+
static const struct wacom_features wacom_features_0x00 =
{ "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255,
0, PENPARTNER, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES };
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index b2c9a9c1b551..f48164c780f4 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -150,6 +150,7 @@ struct wacom_shared {
struct wacom_wac {
char name[WACOM_NAME_MAX];
+ char pad_name[WACOM_NAME_MAX];
unsigned char *data;
int tool[2];
int id[2];
@@ -157,6 +158,7 @@ struct wacom_wac {
struct wacom_features features;
struct wacom_shared *shared;
struct input_dev *input;
+ struct input_dev *pad_input;
int pid;
int battery_capacity;
int num_contacts_left;