summaryrefslogtreecommitdiffstats
path: root/drivers/input/tablet
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/tablet')
-rw-r--r--drivers/input/tablet/hanwang.c57
-rw-r--r--drivers/input/tablet/wacom_sys.c107
-rw-r--r--drivers/input/tablet/wacom_wac.c27
-rw-r--r--drivers/input/tablet/wacom_wac.h8
4 files changed, 130 insertions, 69 deletions
diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c
index b2db3cfe3084..5cc04124995c 100644
--- a/drivers/input/tablet/hanwang.c
+++ b/drivers/input/tablet/hanwang.c
@@ -63,6 +63,7 @@ MODULE_LICENSE(DRIVER_LICENSE);
enum hanwang_tablet_type {
HANWANG_ART_MASTER_III,
HANWANG_ART_MASTER_HD,
+ HANWANG_ART_MASTER_II,
};
struct hanwang {
@@ -99,6 +100,8 @@ static const struct hanwang_features features_array[] = {
ART_MASTER_PKGLEN_MAX, 0x7f00, 0x4f60, 0x3f, 0x7f, 2048 },
{ 0x8401, "Hanwang Art Master HD 5012", HANWANG_ART_MASTER_HD,
ART_MASTER_PKGLEN_MAX, 0x678e, 0x4150, 0x3f, 0x7f, 1024 },
+ { 0x8503, "Hanwang Art Master II", HANWANG_ART_MASTER_II,
+ ART_MASTER_PKGLEN_MAX, 0x27de, 0x1cfe, 0x3f, 0x7f, 1024 },
};
static const int hw_eventtypes[] = {
@@ -127,14 +130,30 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
struct usb_device *dev = hanwang->usbdev;
enum hanwang_tablet_type type = hanwang->features->type;
int i;
- u16 x, y, p;
+ u16 p;
+
+ if (type == HANWANG_ART_MASTER_II) {
+ hanwang->current_tool = BTN_TOOL_PEN;
+ hanwang->current_id = STYLUS_DEVICE_ID;
+ }
switch (data[0]) {
case 0x02: /* data packet */
switch (data[1]) {
case 0x80: /* tool prox out */
- hanwang->current_id = 0;
- input_report_key(input_dev, hanwang->current_tool, 0);
+ if (type != HANWANG_ART_MASTER_II) {
+ hanwang->current_id = 0;
+ input_report_key(input_dev,
+ hanwang->current_tool, 0);
+ }
+ break;
+
+ case 0x00: /* artmaster ii pen leave */
+ if (type == HANWANG_ART_MASTER_II) {
+ hanwang->current_id = 0;
+ input_report_key(input_dev,
+ hanwang->current_tool, 0);
+ }
break;
case 0xc2: /* first time tool prox in */
@@ -154,15 +173,12 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
default:
hanwang->current_id = 0;
dev_dbg(&dev->dev,
- "unknown tablet tool %02x ", data[0]);
+ "unknown tablet tool %02x\n", data[0]);
break;
}
break;
default: /* tool data packet */
- x = (data[2] << 8) | data[3];
- y = (data[4] << 8) | data[5];
-
switch (type) {
case HANWANG_ART_MASTER_III:
p = (data[6] << 3) |
@@ -171,6 +187,7 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
break;
case HANWANG_ART_MASTER_HD:
+ case HANWANG_ART_MASTER_II:
p = (data[7] >> 6) | (data[6] << 2);
break;
@@ -180,17 +197,23 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
}
input_report_abs(input_dev, ABS_X,
- le16_to_cpup((__le16 *)&x));
+ be16_to_cpup((__be16 *)&data[2]));
input_report_abs(input_dev, ABS_Y,
- le16_to_cpup((__le16 *)&y));
- input_report_abs(input_dev, ABS_PRESSURE,
- le16_to_cpup((__le16 *)&p));
+ be16_to_cpup((__be16 *)&data[4]));
+ input_report_abs(input_dev, ABS_PRESSURE, p);
input_report_abs(input_dev, ABS_TILT_X, data[7] & 0x3f);
input_report_abs(input_dev, ABS_TILT_Y, data[8] & 0x7f);
input_report_key(input_dev, BTN_STYLUS, data[1] & 0x02);
- input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04);
+
+ if (type != HANWANG_ART_MASTER_II)
+ input_report_key(input_dev, BTN_STYLUS2,
+ data[1] & 0x04);
+ else
+ input_report_key(input_dev, BTN_TOOL_PEN, 1);
+
break;
}
+
input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
input_event(input_dev, EV_MSC, MSC_SERIAL,
hanwang->features->pid);
@@ -202,8 +225,8 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
switch (type) {
case HANWANG_ART_MASTER_III:
- input_report_key(input_dev, BTN_TOOL_FINGER, data[1] ||
- data[2] || data[3]);
+ input_report_key(input_dev, BTN_TOOL_FINGER,
+ data[1] || data[2] || data[3]);
input_report_abs(input_dev, ABS_WHEEL, data[1]);
input_report_key(input_dev, BTN_0, data[2]);
for (i = 0; i < 8; i++)
@@ -227,6 +250,10 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
BTN_5 + i, data[6] & (1 << i));
}
break;
+
+ case HANWANG_ART_MASTER_II:
+ dev_dbg(&dev->dev, "error packet %02x\n", data[0]);
+ return;
}
input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
@@ -234,7 +261,7 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
break;
default:
- dev_dbg(&dev->dev, "error packet %02x ", data[0]);
+ dev_dbg(&dev->dev, "error packet %02x\n", data[0]);
break;
}
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index cad5602d3ce4..0d3219f29744 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -216,7 +216,7 @@ static void wacom_retrieve_report_data(struct usb_interface *intf,
rep_data[0] = 12;
result = wacom_get_report(intf, WAC_HID_FEATURE_REPORT,
- rep_data[0], &rep_data, 2,
+ rep_data[0], rep_data, 2,
WAC_MSG_RETRIES);
if (result >= 0 && rep_data[1] > 2)
@@ -401,7 +401,9 @@ static int wacom_parse_hid(struct usb_interface *intf,
break;
case HID_USAGE_CONTACTMAX:
- wacom_retrieve_report_data(intf, features);
+ /* leave touch_max as is if predefined */
+ if (!features->touch_max)
+ wacom_retrieve_report_data(intf, features);
i++;
break;
}
@@ -443,8 +445,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
/* 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) {
+ if (features->type > TABLETPC) {
do {
rep_data[0] = 3;
rep_data[1] = 4;
@@ -463,7 +464,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
} while ((error < 0 || rep_data[1] != 4) &&
limit++ < WAC_MSG_RETRIES);
}
- } else if (features->type != TABLETPC &&
+ } else if (features->type <= BAMBOO_PT &&
features->type != WIRELESS &&
features->device_type == BTN_TOOL_PEN) {
do {
@@ -507,16 +508,13 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
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->device_type = BTN_TOOL_FINGER;
features->pktlen = WACOM_PKGLEN_BBTOUCH3;
}
}
/* only devices that support touch need to retrieve the info */
- if (features->type != TABLETPC &&
- features->type != TABLETPC2FG &&
- features->type != BAMBOO_PT &&
- features->type != MTSCREEN) {
+ if (features->type < BAMBOO_PT) {
goto out;
}
@@ -858,6 +856,7 @@ static int wacom_initialize_leds(struct wacom *wacom)
/* Initialize default values */
switch (wacom->wacom_wac.features.type) {
+ case INTUOS4S:
case INTUOS4:
case INTUOS4L:
wacom->led.select[0] = 0;
@@ -911,6 +910,7 @@ static int wacom_initialize_leds(struct wacom *wacom)
static void wacom_destroy_leds(struct wacom *wacom)
{
switch (wacom->wacom_wac.features.type) {
+ case INTUOS4S:
case INTUOS4:
case INTUOS4L:
sysfs_remove_group(&wacom->intf->dev.kobj,
@@ -970,6 +970,10 @@ static int wacom_initialize_battery(struct wacom *wacom)
error = power_supply_register(&wacom->usbdev->dev,
&wacom->battery);
+
+ if (!error)
+ power_supply_powers(&wacom->battery,
+ &wacom->usbdev->dev);
}
return error;
@@ -977,8 +981,11 @@ static int wacom_initialize_battery(struct wacom *wacom)
static void wacom_destroy_battery(struct wacom *wacom)
{
- if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR)
+ if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR &&
+ wacom->battery.dev) {
power_supply_unregister(&wacom->battery);
+ wacom->battery.dev = NULL;
+ }
}
static int wacom_register_input(struct wacom *wacom)
@@ -1025,23 +1032,30 @@ 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;
+ struct wacom *wacom1, *wacom2;
+ struct wacom_wac *wacom_wac1, *wacom_wac2;
+ int error;
/*
* Regardless if this is a disconnect or a new tablet,
- * remove any existing input devices.
+ * remove any existing input and battery devices.
*/
+ wacom_destroy_battery(wacom);
+
/* 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 = NULL;
+ wacom1 = usb_get_intfdata(usbdev->config->interface[1]);
+ wacom_wac1 = &(wacom1->wacom_wac);
+ if (wacom_wac1->input)
+ input_unregister_device(wacom_wac1->input);
+ wacom_wac1->input = NULL;
/* 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 = NULL;
+ wacom2 = usb_get_intfdata(usbdev->config->interface[2]);
+ wacom_wac2 = &(wacom2->wacom_wac);
+ if (wacom_wac2->input)
+ input_unregister_device(wacom_wac2->input);
+ wacom_wac2->input = NULL;
if (wacom_wac->pid == 0) {
dev_info(&wacom->intf->dev, "wireless tablet disconnected\n");
@@ -1066,24 +1080,39 @@ static void wacom_wireless_work(struct work_struct *work)
}
/* Stylus interface */
- wacom = usb_get_intfdata(usbdev->config->interface[1]);
- wacom_wac = &wacom->wacom_wac;
- wacom_wac->features =
+ wacom_wac1->features =
*((struct wacom_features *)id->driver_info);
- wacom_wac->features.device_type = BTN_TOOL_PEN;
- wacom_register_input(wacom);
+ wacom_wac1->features.device_type = BTN_TOOL_PEN;
+ error = wacom_register_input(wacom1);
+ if (error)
+ goto fail1;
/* Touch interface */
- wacom = usb_get_intfdata(usbdev->config->interface[2]);
- wacom_wac = &wacom->wacom_wac;
- wacom_wac->features =
+ wacom_wac2->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);
+ wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
+ wacom_wac2->features.device_type = BTN_TOOL_FINGER;
+ wacom_set_phy_from_res(&wacom_wac2->features);
+ wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096;
+ error = wacom_register_input(wacom2);
+ if (error)
+ goto fail2;
+
+ error = wacom_initialize_battery(wacom);
+ if (error)
+ goto fail3;
}
+
+ return;
+
+fail3:
+ input_unregister_device(wacom_wac2->input);
+ wacom_wac2->input = NULL;
+fail2:
+ input_unregister_device(wacom_wac1->input);
+ wacom_wac1->input = NULL;
+fail1:
+ return;
}
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -1147,10 +1176,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
features->device_type = BTN_TOOL_FINGER;
features->pktlen = WACOM_PKGLEN_BBTOUCH3;
- features->x_phy =
- (features->x_max * 100) / features->x_resolution;
- features->y_phy =
- (features->y_max * 100) / features->y_resolution;
+ wacom_set_phy_from_res(features);
features->x_max = 4096;
features->y_max = 4096;
@@ -1186,14 +1212,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
if (error)
goto fail4;
- error = wacom_initialize_battery(wacom);
- if (error)
- goto fail5;
-
if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) {
error = wacom_register_input(wacom);
if (error)
- goto fail6;
+ goto fail5;
}
/* Note that if query fails it is not a hard failure */
@@ -1208,7 +1230,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
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);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 004bc1bb1544..6533f44be5bd 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -248,7 +248,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
if (wacom->tool[0] != BTN_TOOL_MOUSE) {
- input_report_abs(input, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8));
+ input_report_abs(input, ABS_PRESSURE, data[6] | ((data[7] & 0x03) << 8));
input_report_key(input, BTN_TOUCH, data[1] & 0x01);
input_report_key(input, BTN_STYLUS, data[1] & 0x02);
input_report_key(input, BTN_STYLUS2, data[1] & 0x04);
@@ -888,7 +888,7 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
prox = data[0] & 0x01;
x = get_unaligned_le16(&data[1]);
y = get_unaligned_le16(&data[3]);
- } else { /* with capacity */
+ } else {
prox = data[1] & 0x01;
x = le16_to_cpup((__le16 *)&data[2]);
y = le16_to_cpup((__le16 *)&data[4]);
@@ -961,6 +961,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
case WACOM_REPORT_TPC1FG:
case WACOM_REPORT_TPCHID:
case WACOM_REPORT_TPCST:
+ case WACOM_REPORT_TPC1FGE:
return wacom_tpc_single_touch(wacom, len);
case WACOM_REPORT_TPCMT:
@@ -1244,6 +1245,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
break;
case TABLETPC:
+ case TABLETPCE:
case TABLETPC2FG:
case MTSCREEN:
sync = wacom_tpc_irq(wacom_wac, len);
@@ -1317,10 +1319,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 == WIRELESS ||
- (features->type >= INTUOS5S && features->type <= INTUOS5L) ||
- features->type == MTSCREEN)
+ if (features->type >= WIRELESS ||
+ (features->type >= INTUOS5S && features->type <= INTUOS5L))
features->quirks |= WACOM_QUIRK_MULTI_INPUT;
/* quirk for bamboo touch with 2 low res touches */
@@ -1547,10 +1547,8 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
break;
- case TABLETPC2FG:
case MTSCREEN:
if (features->device_type == BTN_TOOL_FINGER) {
-
wacom_wac->slots = kmalloc(features->touch_max *
sizeof(int),
GFP_KERNEL);
@@ -1559,7 +1557,11 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
for (i = 0; i < features->touch_max; i++)
wacom_wac->slots[i] = -1;
+ }
+ /* fall through */
+ case TABLETPC2FG:
+ if (features->device_type == BTN_TOOL_FINGER) {
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);
@@ -1571,6 +1573,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
/* fall through */
case TABLETPC:
+ case TABLETPCE:
__clear_bit(ABS_MISC, input_dev->absbit);
__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
@@ -1888,6 +1891,12 @@ static const struct wacom_features wacom_features_0xE6 =
static const struct wacom_features wacom_features_0xEC =
{ "Wacom ISDv4 EC", WACOM_PKGLEN_GRAPHIRE, 25710, 14500, 255,
0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0xED =
+ { "Wacom ISDv4 ED", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255,
+ 0, TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0xEF =
+ { "Wacom ISDv4 EF", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255,
+ 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
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 };
@@ -2062,6 +2071,8 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0xE5) },
{ USB_DEVICE_WACOM(0xE6) },
{ USB_DEVICE_WACOM(0xEC) },
+ { USB_DEVICE_WACOM(0xED) },
+ { USB_DEVICE_WACOM(0xEF) },
{ USB_DEVICE_WACOM(0x47) },
{ USB_DEVICE_WACOM(0xF4) },
{ USB_DEVICE_LENOVO(0x6004) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 78fbd3f42009..bd5d37b28714 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -48,6 +48,7 @@
#define WACOM_REPORT_TPCMT 13
#define WACOM_REPORT_TPCHID 15
#define WACOM_REPORT_TPCST 16
+#define WACOM_REPORT_TPC1FGE 18
/* device quirks */
#define WACOM_QUIRK_MULTI_INPUT 0x0001
@@ -62,8 +63,6 @@ enum {
PTU,
PL,
DTU,
- BAMBOO_PT,
- WIRELESS,
INTUOS,
INTUOS3S,
INTUOS3,
@@ -79,7 +78,10 @@ enum {
CINTIQ,
WACOM_BEE,
WACOM_MO,
- TABLETPC,
+ WIRELESS,
+ BAMBOO_PT,
+ TABLETPC, /* add new TPC below */
+ TABLETPCE,
TABLETPC2FG,
MTSCREEN,
MAX_TYPE