* [PATCH v3 1/7] Input: wacom - isolate input registration
2012-02-11 21:55 [PATCH v3 0/7] Wireless Bamboo and 0xE5 device support chris
@ 2012-02-11 21:55 ` chris
2012-02-11 21:55 ` [PATCH v3 2/7] Input: wacom - Bamboo wireless monitor framework chris
` (6 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: chris @ 2012-02-11 21:55 UTC (permalink / raw)
To: linux-input, dmitry.torokhov, Ping Cheng; +Cc: Chris Bagwell
From: Chris Bagwell <chris@cnpbagwell.com>
Although this better co-locates input registration logic,
the main goal is to make it easier to optionally create
input devices or delay creation to later time periods.
Signed-off-by: Chris Bagwell <chris@cnpbagwell.com>
---
drivers/input/tablet/wacom_sys.c | 53 +++++++++++++++++++++++--------------
1 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index c9588ee..99fad7c 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -822,6 +822,37 @@ static void wacom_destroy_leds(struct wacom *wacom)
}
}
+static int wacom_register_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)
+ return -ENOMEM;
+
+ input_dev->name = wacom_wac->name;
+ input_dev->dev.parent = &intf->dev;
+ input_dev->open = wacom_open;
+ input_dev->close = wacom_close;
+ usb_to_input_id(dev, &input_dev->id);
+ input_set_drvdata(input_dev, wacom);
+
+ wacom_wac->input = input_dev;
+ wacom_setup_input_capabilities(input_dev, wacom_wac);
+
+ error = input_register_device(input_dev);
+ if (error) {
+ input_free_device(input_dev);
+ wacom_wac->input = NULL;
+ }
+
+ return error;
+}
+
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
@@ -829,18 +860,12 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
struct wacom *wacom;
struct wacom_wac *wacom_wac;
struct wacom_features *features;
- struct input_dev *input_dev;
int error;
if (!id->driver_info)
return -EINVAL;
wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!wacom || !input_dev) {
- error = -ENOMEM;
- goto fail1;
- }
wacom_wac = &wacom->wacom_wac;
wacom_wac->features = *((struct wacom_features *)id->driver_info);
@@ -869,8 +894,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
- wacom_wac->input = input_dev;
-
endpoint = &intf->cur_altsetting->endpoint[0].desc;
/* Retrieve the physical and logical size for OEM devices */
@@ -894,15 +917,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
goto fail3;
}
- input_dev->name = wacom_wac->name;
- input_dev->dev.parent = &intf->dev;
- input_dev->open = wacom_open;
- input_dev->close = wacom_close;
- usb_to_input_id(dev, &input_dev->id);
- input_set_drvdata(input_dev, wacom);
-
- wacom_setup_input_capabilities(input_dev, wacom_wac);
-
usb_fill_int_urb(wacom->irq, dev,
usb_rcvintpipe(dev, endpoint->bEndpointAddress),
wacom_wac->data, features->pktlen,
@@ -914,7 +928,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
if (error)
goto fail4;
- error = input_register_device(input_dev);
+ error = wacom_register_input(wacom);
if (error)
goto fail5;
@@ -928,8 +942,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
fail4: wacom_remove_shared_data(wacom_wac);
fail3: usb_free_urb(wacom->irq);
fail2: usb_free_coherent(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma);
- fail1: input_free_device(input_dev);
- kfree(wacom);
+ fail1: kfree(wacom);
return error;
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 2/7] Input: wacom - Bamboo wireless monitor framework
2012-02-11 21:55 [PATCH v3 0/7] Wireless Bamboo and 0xE5 device support chris
2012-02-11 21:55 ` [PATCH v3 1/7] Input: wacom - isolate input registration chris
@ 2012-02-11 21:55 ` chris
2012-02-11 21:55 ` [PATCH v3 3/7] Input: wacom - create inputs when wireless connect chris
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: chris @ 2012-02-11 21:55 UTC (permalink / raw)
To: linux-input, dmitry.torokhov, Ping Cheng; +Cc: Chris Bagwell
From: Chris Bagwell <chris@cnpbagwell.com>
The 3rd gen Bamboo Pen & Touch tablets support an optional
wireless module. When its receiver is plugged into USB it
presents 3 interfaces: 0) Monitor 1) Pen and 2) Touch.
The exact capabilities of the Pen and Touch interfaces can
not be determined until a tablet connection is established
and reported over the Monitor interface.
This patch detects this wireless receiver and enables interrupt
packets to be processed for the Monitor interface. Processing
the data in packets will be left to another patch.
Since it doesn't make sense to create an input device for the
Monitor interface, it is not created. Creation of Pen and Touch
input device is also delayed until monitor packets can be processed.
Signed-off-by: Chris Bagwell <chris@cnpbagwell.com>
---
drivers/input/tablet/wacom_sys.c | 35 ++++++++++++++++++++++++++++++-----
drivers/input/tablet/wacom_wac.c | 28 +++++++++++++++++++++++++++-
drivers/input/tablet/wacom_wac.h | 4 ++++
3 files changed, 61 insertions(+), 6 deletions(-)
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 99fad7c..ac63f53 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -422,6 +422,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
report_id, rep_data, 4, 1);
} while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES);
} else if (features->type != TABLETPC &&
+ features->type != BAMBOO_WIRELESS &&
features->device_type == BTN_TOOL_PEN) {
do {
rep_data[0] = 2;
@@ -454,6 +455,21 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
features->pressure_fuzz = 0;
features->distance_fuzz = 0;
+ /*
+ * The wireless device HID is basic and layout conflicts with
+ * other tablets (monitor and touch interface can look like pen).
+ * Skip the query for this type and modify defaults based on
+ * interface number.
+ */
+ if (features->type == BAMBOO_WIRELESS) {
+ if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
+ features->device_type = 0;
+ } else if (intf->cur_altsetting->desc.bInterfaceNumber == 2) {
+ features->device_type = BTN_TOOL_DOUBLETAP;
+ features->pktlen = WACOM_PKGLEN_BBTOUCH3;
+ }
+ }
+
/* only Tablet PCs and Bamboo P&T need to retrieve the info */
if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) &&
(features->type != BAMBOO_PT))
@@ -928,9 +944,16 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
if (error)
goto fail4;
- error = wacom_register_input(wacom);
- if (error)
- goto fail5;
+ if (features->quirks & WACOM_QUIRK_MONITOR) {
+ if (usb_submit_urb(wacom->irq, GFP_KERNEL))
+ goto fail5;
+ }
+
+ if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) {
+ error = wacom_register_input(wacom);
+ if (error)
+ goto fail5;
+ }
/* Note that if query fails it is not a hard failure */
wacom_query_tablet_data(intf, features);
@@ -953,7 +976,8 @@ static void wacom_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
usb_kill_urb(wacom->irq);
- input_unregister_device(wacom->wacom_wac.input);
+ if (wacom->wacom_wac.input)
+ input_unregister_device(wacom->wacom_wac.input);
wacom_destroy_leds(wacom);
usb_free_urb(wacom->irq);
usb_free_coherent(interface_to_usbdev(intf), WACOM_PKGLEN_MAX,
@@ -985,7 +1009,8 @@ static int wacom_resume(struct usb_interface *intf)
wacom_query_tablet_data(intf, features);
wacom_led_control(wacom);
- if (wacom->open && usb_submit_urb(wacom->irq, GFP_NOIO) < 0)
+ if ((wacom->open || features->quirks & WACOM_QUIRK_MONITOR)
+ && usb_submit_urb(wacom->irq, GFP_NOIO) < 0)
rv = -EIO;
mutex_unlock(&wacom->lock);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 9283507..5b3c58f 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -1044,6 +1044,14 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
return 0;
}
+static int wacom_bpt_wireless_irq(struct wacom_wac *wacom, size_t len)
+{
+ if (len != WACOM_PKGLEN_WIRELESS)
+ return 0;
+
+ return 0;
+}
+
void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
{
bool sync;
@@ -1094,6 +1102,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
sync = wacom_bpt_irq(wacom_wac, len);
break;
+ case BAMBOO_WIRELESS:
+ sync = wacom_bpt_wireless_irq(wacom_wac, len);
+ break;
+
default:
sync = false;
break;
@@ -1155,7 +1167,7 @@ void wacom_setup_device_quirks(struct wacom_features *features)
/* these device have multiple inputs */
if (features->type == TABLETPC || features->type == TABLETPC2FG ||
- features->type == BAMBOO_PT)
+ features->type == BAMBOO_PT || features->type == BAMBOO_WIRELESS)
features->quirks |= WACOM_QUIRK_MULTI_INPUT;
/* quirk for bamboo touch with 2 low res touches */
@@ -1167,6 +1179,16 @@ void wacom_setup_device_quirks(struct wacom_features *features)
features->y_fuzz <<= 5;
features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES;
}
+
+ if (features->type == BAMBOO_WIRELESS) {
+
+ /* monitor never has input and pen/touch have delayed create */
+ features->quirks |= WACOM_QUIRK_NO_INPUT;
+
+ /* must be monitor interface if no device_type set */
+ if (!features->device_type)
+ features->quirks |= WACOM_QUIRK_MONITOR;
+ }
}
static unsigned int wacom_calculate_touch_res(unsigned int logical_max,
@@ -1637,6 +1659,9 @@ static const struct wacom_features wacom_features_0xE6 =
static const struct wacom_features wacom_features_0x47 =
{ "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023,
31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0x84 =
+ { "Wacom Wireless Receiver", WACOM_PKGLEN_WIRELESS, 0, 0, 0,
+ 0, BAMBOO_WIRELESS, 0, 0 };
static const struct wacom_features wacom_features_0xD0 =
{ "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -1763,6 +1788,7 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_DETAILED(0xCE, USB_CLASS_HID,
USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_MOUSE) },
+ { USB_DEVICE_WACOM(0x84) },
{ USB_DEVICE_WACOM(0xD0) },
{ USB_DEVICE_WACOM(0xD1) },
{ USB_DEVICE_WACOM(0xD2) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 4f0ba21..fcee9c5 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -24,6 +24,7 @@
#define WACOM_PKGLEN_BBTOUCH 20
#define WACOM_PKGLEN_BBTOUCH3 64
#define WACOM_PKGLEN_BBPEN 10
+#define WACOM_PKGLEN_WIRELESS 32
/* device IDs */
#define STYLUS_DEVICE_ID 0x02
@@ -45,6 +46,8 @@
/* device quirks */
#define WACOM_QUIRK_MULTI_INPUT 0x0001
#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002
+#define WACOM_QUIRK_NO_INPUT 0x0004
+#define WACOM_QUIRK_MONITOR 0x0008
enum {
PENPARTNER = 0,
@@ -54,6 +57,7 @@ enum {
PL,
DTU,
BAMBOO_PT,
+ BAMBOO_WIRELESS,
INTUOS,
INTUOS3S,
INTUOS3,
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 3/7] Input: wacom - create inputs when wireless connect
2012-02-11 21:55 [PATCH v3 0/7] Wireless Bamboo and 0xE5 device support chris
2012-02-11 21:55 ` [PATCH v3 1/7] Input: wacom - isolate input registration chris
2012-02-11 21:55 ` [PATCH v3 2/7] Input: wacom - Bamboo wireless monitor framework chris
@ 2012-02-11 21:55 ` chris
2012-02-11 21:55 ` [PATCH v3 4/7] Input: wacom - wireless Bamboo battery status chris
` (4 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: chris @ 2012-02-11 21:55 UTC (permalink / raw)
To: linux-input, dmitry.torokhov, Ping Cheng; +Cc: Chris Bagwell
From: Chris Bagwell <chris@cnpbagwell.com>
When a tablet connect or disconnect is detected, schedule
work queue to register or unregister related input devices.
When a wireless tablet connects, it reports same USB PID
used if tablet is connected with USB cable. Use this to
update features values, set input capabilities, and then
register device. From there, the Pen and Touch interfaces
will reuse the existing Bamboo IRQ routines.
Its possible that 1 receiver is shared with 2 tablets with
different PID (small and medium Bamboo for example) so the
input is unregister at disconnect to better support this case.
Signed-off-by: Chris Bagwell <chris@cnpbagwell.com>
---
drivers/input/tablet/wacom.h | 7 +++
drivers/input/tablet/wacom_sys.c | 91 ++++++++++++++++++++++++++++++++++----
drivers/input/tablet/wacom_wac.c | 20 ++++++++-
drivers/input/tablet/wacom_wac.h | 1 +
4 files changed, 109 insertions(+), 10 deletions(-)
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index 0783864..febbfd9 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -112,6 +112,7 @@ struct wacom {
struct urb *irq;
struct wacom_wac wacom_wac;
struct mutex lock;
+ struct work_struct work;
bool open;
char phys[32];
struct wacom_led {
@@ -122,6 +123,12 @@ struct wacom {
} led;
};
+static inline void wacom_schedule_work(struct wacom_wac *wacom_wac)
+{
+ struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
+ schedule_work(&wacom->work);
+}
+
extern const struct usb_device_id wacom_ids[];
void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index ac63f53..40e0358 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -167,6 +167,19 @@ static void wacom_close(struct input_dev *dev)
usb_autopm_put_interface(wacom->intf);
}
+/*
+ * Static values for max X/Y and resolution of Pen interface is stored in
+ * features. This mean physical size of active area can be computed.
+ * This is useful to do when Pen and Touch have same active area of tablet.
+ * This means for Touch device, we only need to find max X/Y value and we
+ * have enough information to compute resolution of touch.
+ */
+static void wacom_set_phy_from_res(struct wacom_features *features)
+{
+ features->x_phy = (features->x_max * features->x_resolution) / 100;
+ features->y_phy = (features->y_max * features->y_resolution) / 100;
+}
+
static int wacom_parse_logical_collection(unsigned char *report,
struct wacom_features *features)
{
@@ -178,15 +191,7 @@ static int wacom_parse_logical_collection(unsigned char *report,
features->pktlen = WACOM_PKGLEN_BBTOUCH3;
features->device_type = BTN_TOOL_FINGER;
- /*
- * Stylus and Touch have same active area
- * so compute physical size based on stylus
- * data before its overwritten.
- */
- features->x_phy =
- (features->x_max * features->x_resolution) / 100;
- features->y_phy =
- (features->y_max * features->y_resolution) / 100;
+ wacom_set_phy_from_res(features);
features->x_max = features->y_max =
get_unaligned_le16(&report[10]);
@@ -869,6 +874,72 @@ static int wacom_register_input(struct wacom *wacom)
return error;
}
+static void wacom_wireless_work(struct work_struct *work)
+{
+ struct wacom *wacom = container_of(work, struct wacom, work);
+ struct usb_device *usbdev = wacom->usbdev;
+ struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+
+ /*
+ * Regardless if this is a disconnect or a new tablet,
+ * remove any existing input devices.
+ */
+
+ /* Stylus interface */
+ wacom = usb_get_intfdata(usbdev->config->interface[1]);
+ if (wacom->wacom_wac.input)
+ input_unregister_device(wacom->wacom_wac.input);
+ wacom->wacom_wac.input = 0;
+
+ /* Touch interface */
+ wacom = usb_get_intfdata(usbdev->config->interface[2]);
+ if (wacom->wacom_wac.input)
+ input_unregister_device(wacom->wacom_wac.input);
+ wacom->wacom_wac.input = 0;
+
+ if (wacom_wac->pid == 0) {
+ printk(KERN_INFO "wacom: wireless tablet disconnected\n");
+ } else {
+ const struct usb_device_id *id = wacom_ids;
+
+ printk(KERN_INFO
+ "wacom: wireless tablet connected with PID %x\n",
+ wacom_wac->pid);
+
+ while (id->match_flags) {
+ if (id->idVendor == USB_VENDOR_ID_WACOM &&
+ id->idProduct == wacom_wac->pid)
+ break;
+ id++;
+ }
+
+ if (!id->match_flags) {
+ printk(KERN_INFO
+ "wacom: ignorning unknown PID.\n");
+ return;
+ }
+
+ /* Stylus interface */
+ wacom = usb_get_intfdata(usbdev->config->interface[1]);
+ wacom_wac = &wacom->wacom_wac;
+ wacom_wac->features =
+ *((struct wacom_features *)id->driver_info);
+ wacom_wac->features.device_type = BTN_TOOL_PEN;
+ wacom_register_input(wacom);
+
+ /* Touch interface */
+ wacom = usb_get_intfdata(usbdev->config->interface[2]);
+ wacom_wac = &wacom->wacom_wac;
+ wacom_wac->features =
+ *((struct wacom_features *)id->driver_info);
+ wacom_wac->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
+ wacom_wac->features.device_type = BTN_TOOL_FINGER;
+ wacom_set_phy_from_res(&wacom_wac->features);
+ wacom_wac->features.x_max = wacom_wac->features.y_max = 4096;
+ wacom_register_input(wacom);
+ }
+}
+
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
@@ -907,6 +978,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom->usbdev = dev;
wacom->intf = intf;
mutex_init(&wacom->lock);
+ INIT_WORK(&wacom->work, wacom_wireless_work);
usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
@@ -976,6 +1048,7 @@ static void wacom_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
usb_kill_urb(wacom->irq);
+ cancel_work_sync(&wacom->work);
if (wacom->wacom_wac.input)
input_unregister_device(wacom->wacom_wac.input);
wacom_destroy_leds(wacom);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 5b3c58f..b649eba 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -1046,9 +1046,27 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
static int wacom_bpt_wireless_irq(struct wacom_wac *wacom, size_t len)
{
- if (len != WACOM_PKGLEN_WIRELESS)
+ unsigned char *data = wacom->data;
+ int connected;
+
+ if (len != WACOM_PKGLEN_WIRELESS || data[0] != 0x80)
return 0;
+ connected = data[1] & 0x01;
+ if (connected) {
+ int pid;
+
+ pid = get_unaligned_be16(&data[6]);
+ if (wacom->pid != pid) {
+ wacom->pid = pid;
+ wacom_schedule_work(wacom);
+ }
+ } else if (wacom->pid != 0) {
+ /* disconnected while previously connected */
+ wacom->pid = 0;
+ wacom_schedule_work(wacom);
+ }
+
return 0;
}
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index fcee9c5..873b9bf 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -111,6 +111,7 @@ struct wacom_wac {
struct wacom_features features;
struct wacom_shared *shared;
struct input_dev *input;
+ int pid;
};
#endif
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 4/7] Input: wacom - wireless Bamboo battery status
2012-02-11 21:55 [PATCH v3 0/7] Wireless Bamboo and 0xE5 device support chris
` (2 preceding siblings ...)
2012-02-11 21:55 ` [PATCH v3 3/7] Input: wacom - create inputs when wireless connect chris
@ 2012-02-11 21:55 ` chris
2012-02-11 21:55 ` [PATCH v3 5/7] Input: wacom : Add missing LEDS_CLASS to Kconfig chris
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: chris @ 2012-02-11 21:55 UTC (permalink / raw)
To: linux-input, dmitry.torokhov, Ping Cheng; +Cc: Chris Bagwell
From: Chris Bagwell <chris@cnpbagwell.com>
Signed-off-by: Chris Bagwell <chris@cnpbagwell.com>
---
drivers/input/tablet/Kconfig | 1 +
drivers/input/tablet/wacom.h | 2 +
drivers/input/tablet/wacom_sys.c | 57 +++++++++++++++++++++++++++++++++++++-
drivers/input/tablet/wacom_wac.c | 5 ++-
drivers/input/tablet/wacom_wac.h | 1 +
5 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig
index 58a8775..0edeb94 100644
--- a/drivers/input/tablet/Kconfig
+++ b/drivers/input/tablet/Kconfig
@@ -76,6 +76,7 @@ config TABLET_USB_KBTAB
config TABLET_USB_WACOM
tristate "Wacom Intuos/Graphire tablet support (USB)"
depends on USB_ARCH_HAS_HCD
+ select POWER_SUPPLY
select USB
help
Say Y here if you want to use the USB version of the Wacom Intuos
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index febbfd9..b4842d0 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -88,6 +88,7 @@
#include <linux/mod_devicetable.h>
#include <linux/init.h>
#include <linux/usb/input.h>
+#include <linux/power_supply.h>
#include <asm/unaligned.h>
/*
@@ -121,6 +122,7 @@ struct wacom {
u8 hlv; /* status led brightness button pressed (1..127) */
u8 img_lum; /* OLED matrix display brightness */
} led;
+ struct power_supply battery;
};
static inline void wacom_schedule_work(struct wacom_wac *wacom_wac)
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 40e0358..b09d939 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -843,6 +843,55 @@ static void wacom_destroy_leds(struct wacom *wacom)
}
}
+static enum power_supply_property wacom_battery_props[] = {
+ POWER_SUPPLY_PROP_CAPACITY
+};
+
+static int wacom_battery_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct wacom *wacom = container_of(psy, struct wacom, battery);
+ int ret = 0;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_CAPACITY:
+ val->intval =
+ wacom->wacom_wac.battery_capacity * 100 / 31;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+static int wacom_initialize_battery(struct wacom *wacom)
+{
+ int error = 0;
+
+ if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR) {
+ wacom->battery.properties = wacom_battery_props;
+ wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
+ wacom->battery.get_property = wacom_battery_get_property;
+ wacom->battery.name = "wacom_battery";
+ wacom->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+ wacom->battery.use_for_apm = 0;
+
+ error = power_supply_register(&wacom->usbdev->dev,
+ &wacom->battery);
+ }
+
+ return error;
+}
+
+static void wacom_destroy_battery(struct wacom *wacom)
+{
+ if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR) {
+ power_supply_unregister(&wacom->battery);
+ }
+}
+
static int wacom_register_input(struct wacom *wacom)
{
struct input_dev *input_dev;
@@ -1021,10 +1070,14 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
goto fail5;
}
+ error = wacom_initialize_battery(wacom);
+ if (error)
+ goto fail5;
+
if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) {
error = wacom_register_input(wacom);
if (error)
- goto fail5;
+ goto fail6;
}
/* Note that if query fails it is not a hard failure */
@@ -1033,6 +1086,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
usb_set_intfdata(intf, wacom);
return 0;
+ fail6: wacom_destroy_battery(wacom);
fail5: wacom_destroy_leds(wacom);
fail4: wacom_remove_shared_data(wacom_wac);
fail3: usb_free_urb(wacom->irq);
@@ -1051,6 +1105,7 @@ 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);
+ wacom_destroy_battery(wacom);
wacom_destroy_leds(wacom);
usb_free_urb(wacom->irq);
usb_free_coherent(interface_to_usbdev(intf), WACOM_PKGLEN_MAX,
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index b649eba..a30f229 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -1054,17 +1054,20 @@ static int wacom_bpt_wireless_irq(struct wacom_wac *wacom, size_t len)
connected = data[1] & 0x01;
if (connected) {
- int pid;
+ int pid, battery;
pid = get_unaligned_be16(&data[6]);
+ battery = data[5] & 0x3f;
if (wacom->pid != pid) {
wacom->pid = pid;
wacom_schedule_work(wacom);
}
+ wacom->battery_capacity = battery;
} else if (wacom->pid != 0) {
/* disconnected while previously connected */
wacom->pid = 0;
wacom_schedule_work(wacom);
+ wacom->battery_capacity = 0;
}
return 0;
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 873b9bf..2d5e9ee 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -112,6 +112,7 @@ struct wacom_wac {
struct wacom_shared *shared;
struct input_dev *input;
int pid;
+ int battery_capacity;
};
#endif
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 5/7] Input: wacom : Add missing LEDS_CLASS to Kconfig
2012-02-11 21:55 [PATCH v3 0/7] Wireless Bamboo and 0xE5 device support chris
` (3 preceding siblings ...)
2012-02-11 21:55 ` [PATCH v3 4/7] Input: wacom - wireless Bamboo battery status chris
@ 2012-02-11 21:55 ` chris
2012-02-11 21:55 ` [PATCH v3 6/7] input : wacom - retrieve maximum number of touch points chris
` (2 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: chris @ 2012-02-11 21:55 UTC (permalink / raw)
To: linux-input, dmitry.torokhov, Ping Cheng; +Cc: Chris Bagwell
From: Chris Bagwell <chris@cnpbagwell.com>
Signed-off-by: Chris Bagwell <chris@cnpbagwell.com>
---
drivers/input/tablet/Kconfig | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig
index 0edeb94..6c927a4 100644
--- a/drivers/input/tablet/Kconfig
+++ b/drivers/input/tablet/Kconfig
@@ -76,6 +76,7 @@ config TABLET_USB_KBTAB
config TABLET_USB_WACOM
tristate "Wacom Intuos/Graphire tablet support (USB)"
depends on USB_ARCH_HAS_HCD
+ select LEDS_CLASS
select POWER_SUPPLY
select USB
help
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 6/7] input : wacom - retrieve maximum number of touch points
2012-02-11 21:55 [PATCH v3 0/7] Wireless Bamboo and 0xE5 device support chris
` (4 preceding siblings ...)
2012-02-11 21:55 ` [PATCH v3 5/7] Input: wacom : Add missing LEDS_CLASS to Kconfig chris
@ 2012-02-11 21:55 ` chris
2012-02-11 21:55 ` [PATCH v3 7/7] input: wacom - add 0xE5 (MT device) support chris
2012-02-20 8:24 ` Henrik Rydberg
7 siblings, 0 replies; 11+ messages in thread
From: chris @ 2012-02-11 21:55 UTC (permalink / raw)
To: linux-input, dmitry.torokhov, Ping Cheng; +Cc: Chris Bagwell, Ping Cheng
From: Ping Cheng <pinglinux@gmail.com>
>From the HID usage table when it is supported.
Tested-by: Chris Bagwell <chris@cnpbagwell.com>
Signed-off-by: Chris Bagwell <chris@cnpbagwell.com>
Signed-off-by: Ping Cheng <pingc@wacom.com>
---
drivers/input/tablet/wacom_sys.c | 22 ++++++++++++++-
drivers/input/tablet/wacom_wac.c | 57 +++++++++++++++++++++++--------------
drivers/input/tablet/wacom_wac.h | 1 +
3 files changed, 57 insertions(+), 23 deletions(-)
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index b09d939..950af65 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -28,6 +28,7 @@
#define HID_USAGE_Y_TILT 0x3e
#define HID_USAGE_FINGER 0x22
#define HID_USAGE_STYLUS 0x20
+#define HID_USAGE_CONTACTMAX 0x55
#define HID_COLLECTION 0xa1
#define HID_COLLECTION_LOGICAL 0x02
#define HID_COLLECTION_END 0xc0
@@ -201,6 +202,20 @@ static int wacom_parse_logical_collection(unsigned char *report,
return length;
}
+static void wacom_retrieve_report_data(struct usb_interface *intf,
+ struct wacom_features *features)
+{
+ int result = 0;
+ unsigned char rep_data[2];
+
+ rep_data[0] = 12;
+ result = wacom_get_report(intf, WAC_HID_FEATURE_REPORT,
+ rep_data[0], &rep_data, 2, WAC_MSG_RETRIES);
+
+ if ((result >= 0) && (rep_data[1] > 2))
+ features->touch_max = rep_data[1];
+}
+
/*
* Interface Descriptor of wacom devices can be incomplete and
* inconsistent so wacom_features table is used to store stylus
@@ -374,6 +389,11 @@ static int wacom_parse_hid(struct usb_interface *intf,
pen = 1;
i++;
break;
+
+ case HID_USAGE_CONTACTMAX:
+ wacom_retrieve_report_data(intf, features);
+ i++;
+ break;
}
break;
@@ -1033,7 +1053,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
endpoint = &intf->cur_altsetting->endpoint[0].desc;
- /* Retrieve the physical and logical size for OEM devices */
+ /* Retrieve the physical and logical size for touch devices */
error = wacom_retrieve_hid_descriptor(intf, features);
if (error)
goto fail3;
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index a30f229..c8eede1 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -830,7 +830,8 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
{
char *data = wacom->data;
- dbg("wacom_tpc_irq: received report #%d", data[0]);
+ dbg("wacom_tpc_irq: received report #%d with %d contacts",
+ data[0], wacom->features.touch_max);
switch (len) {
case WACOM_PKGLEN_TPC1FG:
@@ -1374,7 +1375,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
case TABLETPC2FG:
if (features->device_type == BTN_TOOL_FINGER) {
- input_mt_init_slots(input_dev, 2);
+ input_mt_init_slots(input_dev, features->touch_max);
input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE,
0, MT_TOOL_MAX, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_X,
@@ -1429,6 +1430,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+ input_mt_init_slots(input_dev, features->touch_max);
if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
__set_bit(BTN_TOOL_TRIPLETAP,
@@ -1436,13 +1438,9 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
__set_bit(BTN_TOOL_QUADTAP,
input_dev->keybit);
- input_mt_init_slots(input_dev, 16);
-
input_set_abs_params(input_dev,
ABS_MT_TOUCH_MAJOR,
0, 255, 0, 0);
- } else {
- input_mt_init_slots(input_dev, 2);
}
input_set_abs_params(input_dev, ABS_MT_POSITION_X,
@@ -1658,43 +1656,51 @@ static const struct wacom_features wacom_features_0x90 =
0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x93 =
{ "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255,
- 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 1 };
static const struct wacom_features wacom_features_0x97 =
{ "Wacom ISDv4 97", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 511,
0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x9A =
{ "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255,
- 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 1 };
static const struct wacom_features wacom_features_0x9F =
{ "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255,
0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xE2 =
{ "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255,
- 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xE3 =
{ "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255,
- 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xE6 =
{ "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255,
- 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0x47 =
{ "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023,
31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x84 =
{ "Wacom Wireless Receiver", WACOM_PKGLEN_WIRELESS, 0, 0, 0,
- 0, BAMBOO_WIRELESS, 0, 0 };
+ 0, BAMBOO_WIRELESS, 0, 0, .touch_max = 16 };
static const struct wacom_features wacom_features_0xD0 =
{ "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xD1 =
{ "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xD2 =
{ "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD3 =
{ "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xD4 =
{ "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -1703,28 +1709,35 @@ static const struct wacom_features wacom_features_0xD5 =
31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xD6 =
{ "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xD7 =
{ "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xD8 =
{ "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xDA =
{ "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static struct wacom_features wacom_features_0xDB =
{ "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 2 };
static const struct wacom_features wacom_features_0xDD =
{ "Wacom Bamboo Connect", WACOM_PKGLEN_BBPEN, 14720, 9200, 1023,
31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xDE =
{ "Wacom Bamboo 16FG 4x5", WACOM_PKGLEN_BBPEN, 14720, 9200, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 16 };
static const struct wacom_features wacom_features_0xDF =
{ "Wacom Bamboo 16FG 6x8", WACOM_PKGLEN_BBPEN, 21648, 13700, 1023,
- 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+ 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ .touch_max = 16 };
static const struct wacom_features wacom_features_0x6004 =
{ "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255,
0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 2d5e9ee..a0a5b1a 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -95,6 +95,7 @@ struct wacom_features {
int pressure_fuzz;
int distance_fuzz;
unsigned quirks;
+ unsigned touch_max;
};
struct wacom_shared {
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 7/7] input: wacom - add 0xE5 (MT device) support
2012-02-11 21:55 [PATCH v3 0/7] Wireless Bamboo and 0xE5 device support chris
` (5 preceding siblings ...)
2012-02-11 21:55 ` [PATCH v3 6/7] input : wacom - retrieve maximum number of touch points chris
@ 2012-02-11 21:55 ` chris
2012-02-20 8:24 ` Henrik Rydberg
7 siblings, 0 replies; 11+ messages in thread
From: chris @ 2012-02-11 21:55 UTC (permalink / raw)
To: linux-input, dmitry.torokhov, Ping Cheng; +Cc: Ping Cheng
From: Ping Cheng <pinglinux@gmail.com>
And getting rid of duplicate code since X/Y will always be present.
Tested-by: Chris Bagwell <chris@cnpbagwell.com>
Reviewed-by: Chris Bagwell <chris@cnpbagwell.com>
Signed-off-by: Ping Cheng <pingc@wacom.com>
---
drivers/input/tablet/wacom_sys.c | 57 ++++++++++++------------
drivers/input/tablet/wacom_wac.c | 89 ++++++++++++++++++++++++++++++++++++-
drivers/input/tablet/wacom_wac.h | 8 +++
3 files changed, 123 insertions(+), 31 deletions(-)
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 950af65..9441589 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -307,6 +307,10 @@ static int wacom_parse_hid(struct usb_interface *intf,
/* need to reset back */
features->pktlen = WACOM_PKGLEN_TPC2FG;
}
+
+ if (features->type == MTSCREEN)
+ features->pktlen = WACOM_PKGLEN_MTOUCH;
+
if (features->type == BAMBOO_PT) {
/* need to reset back */
features->pktlen = WACOM_PKGLEN_BBTOUCH;
@@ -339,18 +343,15 @@ static int wacom_parse_hid(struct usb_interface *intf,
case HID_USAGE_Y:
if (usage == WCM_DESKTOP) {
if (finger) {
- features->device_type = BTN_TOOL_FINGER;
- if (features->type == TABLETPC2FG) {
- /* need to reset back */
- features->pktlen = WACOM_PKGLEN_TPC2FG;
+ int type = features->type;
+
+ if (type == TABLETPC2FG || type == MTSCREEN) {
features->y_max =
get_unaligned_le16(&report[i + 3]);
features->y_phy =
get_unaligned_le16(&report[i + 6]);
i += 7;
- } else if (features->type == BAMBOO_PT) {
- /* need to reset back */
- features->pktlen = WACOM_PKGLEN_BBTOUCH;
+ } else if (type == BAMBOO_PT) {
features->y_phy =
get_unaligned_le16(&report[i + 3]);
features->y_max =
@@ -364,10 +365,6 @@ static int wacom_parse_hid(struct usb_interface *intf,
i += 4;
}
} else if (pen) {
- /* penabled only accepts exact bytes of data */
- if (features->type == TABLETPC2FG)
- features->pktlen = WACOM_PKGLEN_GRAPHIRE;
- features->device_type = BTN_TOOL_PEN;
features->y_max =
get_unaligned_le16(&report[i + 3]);
i += 4;
@@ -430,25 +427,29 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
if (!rep_data)
return error;
- /* ask to report tablet data if it is MT Tablet PC or
- * not a Tablet PC */
- if (features->type == TABLETPC2FG) {
- do {
- rep_data[0] = 3;
- rep_data[1] = 4;
- rep_data[2] = 0;
- rep_data[3] = 0;
- report_id = 3;
- error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT,
+ /* ask to report Wacom data */
+ if (features->device_type == BTN_TOOL_FINGER) {
+ /* if it is an MT Tablet PC touch */
+ if ((features->type == TABLETPC2FG) ||
+ (features->type == MTSCREEN)) {
+ do {
+ rep_data[0] = 3;
+ rep_data[1] = 4;
+ rep_data[2] = 0;
+ rep_data[3] = 0;
+ report_id = 3;
+ error = wacom_set_report(intf,
+ WAC_HID_FEATURE_REPORT,
report_id, rep_data, 4, 1);
- if (error >= 0)
- error = wacom_get_report(intf,
+ if (error >= 0)
+ error = wacom_get_report(intf,
WAC_HID_FEATURE_REPORT,
report_id, rep_data, 4, 1);
- } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES);
+ } while ((error < 0 || rep_data[1] != 4) &&
+ limit++ < WAC_MSG_RETRIES);
+ }
} else if (features->type != TABLETPC &&
- features->type != BAMBOO_WIRELESS &&
- features->device_type == BTN_TOOL_PEN) {
+ features->type != BAMBOO_WIRELESS) {
do {
rep_data[0] = 2;
rep_data[1] = 2;
@@ -495,9 +496,9 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
}
}
- /* only Tablet PCs and Bamboo P&T need to retrieve the info */
+ /* only devices that support touch need to retrieve the info */
if ((features->type != TABLETPC) && (features->type != TABLETPC2FG) &&
- (features->type != BAMBOO_PT))
+ (features->type != BAMBOO_PT) && (features->type != MTSCREEN))
goto out;
if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index c8eede1..99d7e4e 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -729,6 +729,75 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
return 1;
}
+static int wacom_mt_touch(struct wacom_wac *wacom)
+{
+ struct wacom_features *features = &wacom->features;
+ struct input_dev *input = wacom->input;
+ char *data = wacom->data;
+ struct input_mt_slot *mt;
+ int i, id = -1, j = 0, k = 4;
+ int x = 0, y = 0;
+ int current_num_contacts = data[2];
+ int contacts_to_send = 0;
+ bool touch = false;
+
+ /* reset the counter by the first packet since only the first
+ * packet in series will have non-zero current_num_contacts
+ */
+ if (current_num_contacts) {
+ features->num_contacts = current_num_contacts;
+ features->num_contacts_left = current_num_contacts;
+ }
+
+ /* There are at most 5 contacts per packet */
+ contacts_to_send = min(5, (int)features->num_contacts_left);
+
+ for (i = 0; i < contacts_to_send; i++) {
+ id = le16_to_cpup((__le16 *)&data[k]);
+
+ /* is there an existing slot for this contact? */
+ for (j = 0; j < features->touch_max; j++) {
+ mt = &input->mt[j];
+ if (input_mt_get_value(mt, ABS_MT_TRACKING_ID) == id )
+ break;
+ }
+
+ /* no. then find an unused slot to fill */
+ if (j >= features->touch_max) {
+ for (j = 0; j < features->touch_max; j++) {
+ mt = &input->mt[j];
+ if (input_mt_get_value(mt, ABS_MT_TRACKING_ID) == -1 )
+ break;
+ }
+ }
+
+ touch = data[k - 1] & 0x1;
+ input_mt_slot(input, j);
+ if (touch) {
+ x = le16_to_cpup((__le16 *)&data[k + 6]);
+ y = le16_to_cpup((__le16 *)&data[k + 8]);
+
+ input_report_abs(input, ABS_MT_POSITION_X, x);
+ input_report_abs(input, ABS_MT_POSITION_Y, y);
+ } else
+ id = -1;
+
+ /* keep the id from firmware since we need
+ * it to process future events
+ */
+ input_report_abs(input, ABS_MT_TRACKING_ID, id);
+
+ k += WACOM_BYTES_PER_MT_PACKET;
+ }
+
+ input_mt_report_pointer_emulation(input, true);
+
+ features->num_contacts_left -= contacts_to_send;
+ if (features->num_contacts_left < 0)
+ features->num_contacts_left = 0;
+ return 1;
+}
+
static int wacom_tpc_mt_touch(struct wacom_wac *wacom)
{
struct input_dev *input = wacom->input;
@@ -767,6 +836,10 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
bool prox;
int x = 0, y = 0;
+ if ((wacom->features.touch_max > 1) ||
+ (len > WACOM_PKGLEN_TPC2FG))
+ return 0;
+
if (!wacom->shared->stylus_in_proximity) {
if (len == WACOM_PKGLEN_TPC1FG) {
prox = data[0] & 0x01;
@@ -835,10 +908,10 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
switch (len) {
case WACOM_PKGLEN_TPC1FG:
- return wacom_tpc_single_touch(wacom, len);
+ return wacom_tpc_single_touch(wacom, len);
case WACOM_PKGLEN_TPC2FG:
- return wacom_tpc_mt_touch(wacom);
+ return wacom_tpc_mt_touch(wacom);
default:
switch (data[0]) {
@@ -847,6 +920,9 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
case WACOM_REPORT_TPCST:
return wacom_tpc_single_touch(wacom, len);
+ case WACOM_REPORT_TPCMT:
+ return wacom_mt_touch(wacom);
+
case WACOM_REPORT_PENABLED:
return wacom_tpc_pen(wacom);
}
@@ -1117,6 +1193,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
case TABLETPC:
case TABLETPC2FG:
+ case MTSCREEN:
sync = wacom_tpc_irq(wacom_wac, len);
break;
@@ -1189,7 +1266,8 @@ void wacom_setup_device_quirks(struct wacom_features *features)
/* these device have multiple inputs */
if (features->type == TABLETPC || features->type == TABLETPC2FG ||
- features->type == BAMBOO_PT || features->type == BAMBOO_WIRELESS)
+ features->type == BAMBOO_PT || features->type == BAMBOO_WIRELESS ||
+ features->type == MTSCREEN)
features->quirks |= WACOM_QUIRK_MULTI_INPUT;
/* quirk for bamboo touch with 2 low res touches */
@@ -1373,6 +1451,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
break;
case TABLETPC2FG:
+ case MTSCREEN:
if (features->device_type == BTN_TOOL_FINGER) {
input_mt_init_slots(input_dev, features->touch_max);
@@ -1676,6 +1755,9 @@ static const struct wacom_features wacom_features_0xE3 =
{ "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255,
0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
.touch_max = 2 };
+static const struct wacom_features wacom_features_0xE5 =
+ { "Wacom ISDv4 E5", WACOM_PKGLEN_MTOUCH, 26202, 16325, 255,
+ 0, MTSCREEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xE6 =
{ "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255,
0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
@@ -1846,6 +1928,7 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0x9F) },
{ USB_DEVICE_WACOM(0xE2) },
{ USB_DEVICE_WACOM(0xE3) },
+ { USB_DEVICE_WACOM(0xE5) },
{ USB_DEVICE_WACOM(0xE6) },
{ USB_DEVICE_WACOM(0x47) },
{ USB_DEVICE_WACOM(0xF4) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index a0a5b1a..8174a79 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -25,6 +25,10 @@
#define WACOM_PKGLEN_BBTOUCH3 64
#define WACOM_PKGLEN_BBPEN 10
#define WACOM_PKGLEN_WIRELESS 32
+#define WACOM_PKGLEN_MTOUCH 62
+
+/* wacom data size per MT contact */
+#define WACOM_BYTES_PER_MT_PACKET 11
/* device IDs */
#define STYLUS_DEVICE_ID 0x02
@@ -40,6 +44,7 @@
#define WACOM_REPORT_INTUOSPAD 12
#define WACOM_REPORT_TPC1FG 6
#define WACOM_REPORT_TPC2FG 13
+#define WACOM_REPORT_TPCMT 13
#define WACOM_REPORT_TPCHID 15
#define WACOM_REPORT_TPCST 16
@@ -72,6 +77,7 @@ enum {
WACOM_MO,
TABLETPC,
TABLETPC2FG,
+ MTSCREEN,
MAX_TYPE
};
@@ -96,6 +102,8 @@ struct wacom_features {
int distance_fuzz;
unsigned quirks;
unsigned touch_max;
+ unsigned num_contacts;
+ unsigned num_contacts_left;
};
struct wacom_shared {
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v3 7/7] input: wacom - add 0xE5 (MT device) support
2012-02-11 21:55 [PATCH v3 0/7] Wireless Bamboo and 0xE5 device support chris
` (6 preceding siblings ...)
2012-02-11 21:55 ` [PATCH v3 7/7] input: wacom - add 0xE5 (MT device) support chris
@ 2012-02-20 8:24 ` Henrik Rydberg
2012-02-20 19:30 ` Chris Bagwell
7 siblings, 1 reply; 11+ messages in thread
From: Henrik Rydberg @ 2012-02-20 8:24 UTC (permalink / raw)
To: Chris Bagwell; +Cc: Ping Cheng, Dmitry Torokhov, linux-input
Hi Chris,
The input_mt_report_slot_state should be used instead of directly
setting the tracking id. If the id reported by the hardware is not
bounded by some small number (so that it maps to slots), you will have
to keep the translation table in the driver.
Also, the commit message could need some love.
Thanks,
Henrik
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 7/7] input: wacom - add 0xE5 (MT device) support
2012-02-20 8:24 ` Henrik Rydberg
@ 2012-02-20 19:30 ` Chris Bagwell
2012-02-22 23:33 ` Jason Gerecke
0 siblings, 1 reply; 11+ messages in thread
From: Chris Bagwell @ 2012-02-20 19:30 UTC (permalink / raw)
To: Henrik Rydberg; +Cc: Ping Cheng, Dmitry Torokhov, linux-input
On Mon, Feb 20, 2012 at 2:24 AM, Henrik Rydberg <rydberg@euromail.se> wrote:
> Hi Chris,
>
> The input_mt_report_slot_state should be used instead of directly
> setting the tracking id. If the id reported by the hardware is not
> bounded by some small number (so that it maps to slots), you will have
> to keep the translation table in the driver.
>
> Also, the commit message could need some love.
>
> Thanks,
> Henrik
Thank you for review, Henrik.
Makes sense. hid-multitouch has an example find_slot_from_contactid()
that could be used as reference here if the ID's are not bound.
I'll have to table patches 6 and 7 until either Ping is available to
update them or can provide me some more details on tracking ID
behavior.
Anyone have comments on patches 1-5 that are for Wireless Bamboo support?
Thanks again,
Chris
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 7/7] input: wacom - add 0xE5 (MT device) support
2012-02-20 19:30 ` Chris Bagwell
@ 2012-02-22 23:33 ` Jason Gerecke
0 siblings, 0 replies; 11+ messages in thread
From: Jason Gerecke @ 2012-02-22 23:33 UTC (permalink / raw)
To: Chris Bagwell; +Cc: Henrik Rydberg, Ping Cheng, Dmitry Torokhov, linux-input
On Mon, Feb 20, 2012 at 11:30 AM, Chris Bagwell <chris@cnpbagwell.com> wrote:
> On Mon, Feb 20, 2012 at 2:24 AM, Henrik Rydberg <rydberg@euromail.se> wrote:
>> Hi Chris,
>>
>> The input_mt_report_slot_state should be used instead of directly
>> setting the tracking id. If the id reported by the hardware is not
>> bounded by some small number (so that it maps to slots), you will have
>> to keep the translation table in the driver.
>>
>> Also, the commit message could need some love.
>>
>> Thanks,
>> Henrik
>
> Thank you for review, Henrik.
>
> Makes sense. hid-multitouch has an example find_slot_from_contactid()
> that could be used as reference here if the ID's are not bound.
>
> I'll have to table patches 6 and 7 until either Ping is available to
> update them or can provide me some more details on tracking ID
> behavior.
>
> Anyone have comments on patches 1-5 that are for Wireless Bamboo support?
>
> Thanks again,
> Chris
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Chris,
I got my hands on the hardware, and it looks like the it keeps track
of the total number of touches that have occurred since it was plugged
in. The 1st touch gets an ID of 1, the 10th an ID of 10, and the 100th
an ID of 100. The 256th touch overflows the available byte of space
and is assigned an ID of 0.
Jason
---
Day xee-nee-svsh duu-'ushtlh-ts'it;
nuu-wee-ya' duu-xan' 'vm-nvshtlh-ts'it.
Huu-chan xuu naa~-gha.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 11+ messages in thread