summaryrefslogtreecommitdiffstats
path: root/drivers/input/tablet/wacom_wac.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-11-26 09:23:57 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-11-26 09:23:57 +1100
commit2a859ab07b6ab66f4134c4fffc341398bd3d328c (patch)
treec5e7eaf3bffbc18feb326940e39794328d98dc07 /drivers/input/tablet/wacom_wac.c
parentcedddd812a79a4fda3885a15711aee3de78c4a24 (diff)
parente716e014384688d1a50d1aa5213ee74748c6d4e0 (diff)
Merge branch 'merge' into next
Merge my own merge branch to get various fixes from there and upstream, especially the hvc console tty refcouting fixes which which testing is quite a bit harder...
Diffstat (limited to 'drivers/input/tablet/wacom_wac.c')
-rw-r--r--drivers/input/tablet/wacom_wac.c88
1 files changed, 85 insertions, 3 deletions
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index c3468c8dbd8..aa601013117 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -806,6 +806,70 @@ static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid)
return -1;
}
+static int int_dist(int x1, int y1, int x2, int y2)
+{
+ int x = x2 - x1;
+ int y = y2 - y1;
+
+ return int_sqrt(x*x + y*y);
+}
+
+static int wacom_24hdt_irq(struct wacom_wac *wacom)
+{
+ struct input_dev *input = wacom->input;
+ char *data = wacom->data;
+ int i;
+ int current_num_contacts = data[61];
+ int contacts_to_send = 0;
+
+ /*
+ * First packet resets the counter since only the first
+ * packet in series will have non-zero current_num_contacts.
+ */
+ if (current_num_contacts)
+ wacom->num_contacts_left = current_num_contacts;
+
+ /* There are at most 4 contacts per packet */
+ contacts_to_send = min(4, wacom->num_contacts_left);
+
+ for (i = 0; i < contacts_to_send; i++) {
+ int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1;
+ bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity;
+ int id = data[offset + 1];
+ int slot = find_slot_from_contactid(wacom, id);
+
+ if (slot < 0)
+ continue;
+ input_mt_slot(input, slot);
+ input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
+
+ if (touch) {
+ int t_x = le16_to_cpup((__le16 *)&data[offset + 2]);
+ int c_x = le16_to_cpup((__le16 *)&data[offset + 4]);
+ int t_y = le16_to_cpup((__le16 *)&data[offset + 6]);
+ int c_y = le16_to_cpup((__le16 *)&data[offset + 8]);
+ int w = le16_to_cpup((__le16 *)&data[offset + 10]);
+ int h = le16_to_cpup((__le16 *)&data[offset + 12]);
+
+ input_report_abs(input, ABS_MT_POSITION_X, t_x);
+ input_report_abs(input, ABS_MT_POSITION_Y, t_y);
+ input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h));
+ input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y));
+ input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
+ input_report_abs(input, ABS_MT_ORIENTATION, w > h);
+ }
+ wacom->slots[slot] = touch ? id : -1;
+ }
+
+ input_mt_report_pointer_emulation(input, true);
+
+ wacom->num_contacts_left -= contacts_to_send;
+ if (wacom->num_contacts_left <= 0)
+ wacom->num_contacts_left = 0;
+
+ return 1;
+}
+
static int wacom_mt_touch(struct wacom_wac *wacom)
{
struct input_dev *input = wacom->input;
@@ -1255,6 +1319,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
sync = wacom_intuos_irq(wacom_wac);
break;
+ case WACOM_24HDT:
+ sync = wacom_24hdt_irq(wacom_wac);
+ break;
+
case INTUOS5S:
case INTUOS5:
case INTUOS5L:
@@ -1340,7 +1408,8 @@ void wacom_setup_device_quirks(struct wacom_features *features)
/* these device have multiple inputs */
if (features->type >= WIRELESS ||
- (features->type >= INTUOS5S && features->type <= INTUOS5L))
+ (features->type >= INTUOS5S && features->type <= INTUOS5L) ||
+ (features->oVid && features->oPid))
features->quirks |= WACOM_QUIRK_MULTI_INPUT;
/* quirk for bamboo touch with 2 low res touches */
@@ -1575,6 +1644,15 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
break;
+ case WACOM_24HDT:
+ if (features->device_type == BTN_TOOL_FINGER) {
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);
+ }
+ /* fall through */
+
case MTSCREEN:
if (features->device_type == BTN_TOOL_FINGER) {
wacom_wac->slots = kmalloc(features->touch_max *
@@ -1869,8 +1947,11 @@ static const struct wacom_features wacom_features_0xF4 =
{ "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047,
63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
static const struct wacom_features wacom_features_0xF8 =
- { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047,
- 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+ { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, /* Pen */
+ 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
+static const struct wacom_features wacom_features_0xF6 =
+ { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
+ .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10 };
static const struct wacom_features wacom_features_0x3F =
{ "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023,
63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
@@ -2113,6 +2194,7 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0x47) },
{ USB_DEVICE_WACOM(0xF4) },
{ USB_DEVICE_WACOM(0xF8) },
+ { USB_DEVICE_WACOM(0xF6) },
{ USB_DEVICE_WACOM(0xFA) },
{ USB_DEVICE_LENOVO(0x6004) },
{ }