From 42f4f272746f9e4e3fecb4440dc2429822b6950b Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Wed, 15 Apr 2015 16:53:54 -0700 Subject: HID: wacom: move all quirks to wacom_setup_device_quirks It makes probe routine easy to follow. Signed-off-by: Ping Cheng Reviewed-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers/hid/wacom_wac.c') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index fa54d32..3609cbe 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2164,8 +2164,9 @@ static void wacom_setup_intuos(struct wacom_wac *wacom_wac) input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); } -void wacom_setup_device_quirks(struct wacom_features *features) +void wacom_setup_device_quirks(struct wacom *wacom) { + struct wacom_features *features = &wacom->wacom_wac.features; /* touch device found but size is not defined. use default */ if (features->device_type == BTN_TOOL_FINGER && !features->x_max) { @@ -2173,6 +2174,33 @@ void wacom_setup_device_quirks(struct wacom_features *features) features->y_max = 1023; } + /* + * Intuos5/Pro and Bamboo 3rd gen have no useful data about its + * touch interface in its HID descriptor. If this is the touch + * interface (PacketSize of WACOM_PKGLEN_BBTOUCH3), override the + * tablet values. + */ + if ((features->type >= INTUOS5S && features->type <= INTUOSHT) || + (features->type == BAMBOO_PT)) { + if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { + features->device_type = BTN_TOOL_FINGER; + + features->x_max = 4096; + features->y_max = 4096; + } else { + features->device_type = BTN_TOOL_PEN; + } + } + + /* + * Same thing for Bamboo PAD + */ + if (features->type == BAMBOO_PAD) + features->device_type = BTN_TOOL_FINGER; + + if (wacom->hdev->bus == BUS_BLUETOOTH) + features->quirks |= WACOM_QUIRK_BATTERY; + /* quirk for bamboo touch with 2 low res touches */ if (features->type == BAMBOO_PT && features->pktlen == WACOM_PKGLEN_BBTOUCH) { -- cgit v1.1 From 71b5c4766c1ca4c646a90f64552b140b1368f2f1 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Wed, 15 Apr 2015 17:22:32 -0700 Subject: HID: wacom: Simplify check for presence of single-finger touch To determine if a touch is present in the single-touch case, we can simply check if the BTN_TOUCH key is active or not. This will work for both HID_GENERIC and other device types. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/hid/wacom_wac.c') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 3609cbe..091bab4 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1072,9 +1072,8 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom) int count = 0; int i; - /* non-HID_GENERIC single touch input doesn't call this routine */ - if ((touch_max == 1) && (wacom->features.type == HID_GENERIC)) - return wacom->hid_data.tipswitch && + if (touch_max == 1) + return test_bit(BTN_TOUCH, input->key) && !wacom->shared->stylus_in_proximity; for (i = 0; i < input->mt->num_slots; i++) { -- cgit v1.1 From 007760cf082392b65a05c40eb615c5f8294b441a Mon Sep 17 00:00:00 2001 From: Aaron Skomra Date: Thu, 16 Apr 2015 15:01:14 -0700 Subject: HID: wacom: Add support for DTU-1141 Signed-off-by: Aaron Skomra Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/hid/wacom_wac.c') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 091bab4..dff99ff 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2946,6 +2946,9 @@ static const struct wacom_features wacom_features_0x32F = { "Wacom DTU1031X", 22472, 12728, 511, 0, DTUSX, WACOM_INTUOS_RES, WACOM_INTUOS_RES, WACOM_DTU_OFFSET, WACOM_DTU_OFFSET }; +static const struct wacom_features wacom_features_0x336 = + { "Wacom DTU1141", 23472, 13203, 1023, 0, + DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x57 = { "Wacom DTK2241", 95640, 54060, 2047, 63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, @@ -3299,6 +3302,7 @@ const struct hid_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x32F) }, { USB_DEVICE_WACOM(0x333) }, { USB_DEVICE_WACOM(0x335) }, + { USB_DEVICE_WACOM(0x336) }, { USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x4004) }, { USB_DEVICE_WACOM(0x5000) }, -- cgit v1.1 From 042628abd59c9a034797bd3083f806fa17cda62d Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Thu, 30 Apr 2015 17:51:54 -0700 Subject: HID: wacom: Discover device_type from HID descriptor for all devices Currently, we assume a device_type of BTN_TOOL_PEN before scanning the HID descriptor and then change the device_type if what we discover proves that assumption wrong. This way of doing things makes it more difficult to figure out if a device (particularly a HID_GENERIC device) actually does tablet/touch input or is something completley different. This patch leaves device_type at its initial value of 0 and then calls 'wacom_parse_hid' for every device (not just those that have touch). As we map the usages, we can set the device_type as before. After we're finished, we can then check if the value is still zero and do whatever is most appropriate. Detecting the pen can be a little tricky on most Wacom devices because the descriptors describe opaque blobs. Fortunately, older Wacom tablets have the HID_DG_DIGITIZER usage on the pen's application collection and newer tablets seem to have a similar vendor-defined usage that we can trigger on. Signed-off-by: Jason Gerecke Reviewed-by: Ping Cheng Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/hid/wacom_wac.c') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index dff99ff..a52fc25 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2186,13 +2186,15 @@ void wacom_setup_device_quirks(struct wacom *wacom) features->x_max = 4096; features->y_max = 4096; - } else { - features->device_type = BTN_TOOL_PEN; } } /* - * Same thing for Bamboo PAD + * Raw Wacom-mode pen and touch events both come from interface + * 0, whose HID descriptor has an application usage of 0xFF0D + * (i.e., WACOM_VENDORDEFINED_PEN). We route pen packets back + * out through the HID_GENERIC device created for interface 1, + * so rewrite this one to be of type BTN_TOOL_FINGER. */ if (features->type == BAMBOO_PAD) features->device_type = BTN_TOOL_FINGER; -- cgit v1.1 From aa86b18cc9cd147b40412a2d57b383a5e16fe3b5 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 15 Jun 2015 18:01:42 -0700 Subject: HID: wacom: Treat features->device_type values as flags The USB devices that this driver has historically supported segregate the pen and touch portions of the tablet. Oftentimes the segregation would be done at the interface level, though on occasion (e.g. Cintiq 24HDT) the tablet would combine two totally independent USB devices behind an internal USB hub. Because pen and touch never shared the same interface, it made sense for the 'device_type' to store a single value: "pen" or "touch". Recently, however, some I2C devices have been created which combine the two. A first step to accomodating this is to expand 'device_type' so that it can represent two (or potentially more) types simultaneously. To do this, we treat it as a bitfield and set/check individual bits rather than using the '=' and '==' operators. This should not result in any functional change since no supported devices (that I'm aware of, at least) have HID descriptors that indicate both pen and touch reports on a single interface. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/hid/wacom_wac.c') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index a52fc25..5e7710d 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2168,7 +2168,7 @@ void wacom_setup_device_quirks(struct wacom *wacom) struct wacom_features *features = &wacom->wacom_wac.features; /* touch device found but size is not defined. use default */ - if (features->device_type == BTN_TOOL_FINGER && !features->x_max) { + if (features->device_type & WACOM_DEVICETYPE_TOUCH && !features->x_max) { features->x_max = 1023; features->y_max = 1023; } @@ -2182,7 +2182,7 @@ void wacom_setup_device_quirks(struct wacom *wacom) if ((features->type >= INTUOS5S && features->type <= INTUOSHT) || (features->type == BAMBOO_PT)) { if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { - features->device_type = BTN_TOOL_FINGER; + features->device_type |= WACOM_DEVICETYPE_TOUCH; features->x_max = 4096; features->y_max = 4096; @@ -2197,7 +2197,7 @@ void wacom_setup_device_quirks(struct wacom *wacom) * so rewrite this one to be of type BTN_TOOL_FINGER. */ if (features->type == BAMBOO_PAD) - features->device_type = BTN_TOOL_FINGER; + features->device_type |= WACOM_DEVICETYPE_TOUCH; if (wacom->hdev->bus == BUS_BLUETOOTH) features->quirks |= WACOM_QUIRK_BATTERY; @@ -2218,7 +2218,7 @@ void wacom_setup_device_quirks(struct wacom *wacom) features->quirks |= WACOM_QUIRK_NO_INPUT; /* must be monitor interface if no device_type set */ - if (!features->device_type) { + if (features->device_type == WACOM_DEVICETYPE_NONE) { features->quirks |= WACOM_QUIRK_MONITOR; features->quirks |= WACOM_QUIRK_BATTERY; } @@ -2230,7 +2230,7 @@ static void wacom_abs_set_axis(struct input_dev *input_dev, { struct wacom_features *features = &wacom_wac->features; - if (features->device_type == BTN_TOOL_PEN) { + if (features->device_type & WACOM_DEVICETYPE_PEN) { input_set_abs_params(input_dev, ABS_X, features->x_min, features->x_max, features->x_fuzz, 0); input_set_abs_params(input_dev, ABS_Y, features->y_min, @@ -2349,7 +2349,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, case INTUOSPS: __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - if (features->device_type == BTN_TOOL_PEN) { + if (features->device_type & WACOM_DEVICETYPE_PEN) { input_set_abs_params(input_dev, ABS_DISTANCE, 0, features->distance_max, 0, 0); @@ -2358,7 +2358,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, input_abs_set_res(input_dev, ABS_Z, 287); wacom_setup_intuos(wacom_wac); - } else if (features->device_type == BTN_TOOL_FINGER) { + } else if (features->device_type & WACOM_DEVICETYPE_TOUCH) { __clear_bit(ABS_MISC, input_dev->absbit); input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, @@ -2370,7 +2370,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, break; case WACOM_24HDT: - if (features->device_type == BTN_TOOL_FINGER) { + if (features->device_type & WACOM_DEVICETYPE_TOUCH) { 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); @@ -2383,7 +2383,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, case MTTPC: case MTTPC_B: case TABLETPC2FG: - if (features->device_type == BTN_TOOL_FINGER && features->touch_max > 1) + if (features->device_type & WACOM_DEVICETYPE_TOUCH && features->touch_max > 1) input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_DIRECT); /* fall through */ @@ -2393,7 +2393,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - if (features->device_type != BTN_TOOL_PEN) + if (!(features->device_type & WACOM_DEVICETYPE_PEN)) break; /* no need to process stylus stuff */ /* fall through */ @@ -2424,7 +2424,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, case INTUOSHT: if (features->touch_max && - features->device_type == BTN_TOOL_FINGER) { + features->device_type & WACOM_DEVICETYPE_TOUCH) { input_dev->evbit[0] |= BIT_MASK(EV_SW); __set_bit(SW_MUTE_DEVICE, input_dev->swbit); } @@ -2433,7 +2433,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, case BAMBOO_PT: __clear_bit(ABS_MISC, input_dev->absbit); - if (features->device_type == BTN_TOOL_FINGER) { + if (features->device_type & WACOM_DEVICETYPE_TOUCH) { if (features->touch_max) { if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { @@ -2454,7 +2454,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, /* PAD is setup by wacom_setup_pad_input_capabilities later */ return 1; } - } else if (features->device_type == BTN_TOOL_PEN) { + } else if (features->device_type & WACOM_DEVICETYPE_PEN) { __set_bit(INPUT_PROP_POINTER, input_dev->propbit); __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); __set_bit(BTN_TOOL_PEN, input_dev->keybit); @@ -2619,7 +2619,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, case INTUOS5S: case INTUOSPS: /* touch interface does not have the pad device */ - if (features->device_type != BTN_TOOL_PEN) + if (!(features->device_type & WACOM_DEVICETYPE_PEN)) return -ENODEV; for (i = 0; i < 7; i++) @@ -2664,7 +2664,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, case INTUOSHT: case BAMBOO_PT: /* pad device is on the touch interface */ - if ((features->device_type != BTN_TOOL_FINGER) || + if (!(features->device_type & WACOM_DEVICETYPE_TOUCH) || /* Bamboo Pen only tablet does not have pad */ ((features->type == BAMBOO_PT) && !features->touch_max)) return -ENODEV; -- cgit v1.1 From 862cf5535c0cf4b39ce71a3b7e9a1c22ae4f70ae Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 15 Jun 2015 18:01:43 -0700 Subject: HID: wacom: Introduce a new WACOM_DEVICETYPE_PAD device_type Historically, both the touch and pad tools would have shared the 'BTN_TOOL_FINGER' type. Any time you needed to distinguish the two, you had to use some other bit of knowledge (e.g. that the pad was on the same interface as the pen, and thus 'touch_max' would be zero). To make these checks more readable, we introduce WACOM_DEVICETYPE_PAD. Although we still have to rely on other bits of knowledge to set this bit on the right interface (since it cannot be detected from the HID descriptor), it can be done just once inside 'wacom_setup_device_quirks'. This patch introduces no functional changes. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 71 ++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 34 deletions(-) (limited to 'drivers/hid/wacom_wac.c') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 5e7710d..564a06d 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2167,6 +2167,15 @@ void wacom_setup_device_quirks(struct wacom *wacom) { struct wacom_features *features = &wacom->wacom_wac.features; + /* The pen and pad share the same interface on most devices */ + if (features->type == GRAPHIRE_BT || features->type == WACOM_G4 || + features->type == DTUS || features->type == WACOM_MO || + (features->type >= INTUOS3S && features->type <= WACOM_13HD && + features->type != INTUOSHT)) { + if (features->device_type & WACOM_DEVICETYPE_PEN) + features->device_type |= WACOM_DEVICETYPE_PAD; + } + /* touch device found but size is not defined. use default */ if (features->device_type & WACOM_DEVICETYPE_TOUCH && !features->x_max) { features->x_max = 1023; @@ -2182,7 +2191,10 @@ void wacom_setup_device_quirks(struct wacom *wacom) if ((features->type >= INTUOS5S && features->type <= INTUOSHT) || (features->type == BAMBOO_PT)) { if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { - features->device_type |= WACOM_DEVICETYPE_TOUCH; + if (features->touch_max) + features->device_type |= WACOM_DEVICETYPE_TOUCH; + if (features->type == BAMBOO_PT || features->type == INTUOSHT) + features->device_type |= WACOM_DEVICETYPE_PAD; features->x_max = 4096; features->y_max = 4096; @@ -2241,7 +2253,7 @@ static void wacom_abs_set_axis(struct input_dev *input_dev, /* penabled devices have fixed resolution for each model */ input_abs_set_res(input_dev, ABS_X, features->x_resolution); input_abs_set_res(input_dev, ABS_Y, features->y_resolution); - } else { + } else if (features->device_type & WACOM_DEVICETYPE_TOUCH) { if (features->touch_max == 1) { input_set_abs_params(input_dev, ABS_X, 0, features->x_max, features->x_fuzz, 0); @@ -2423,8 +2435,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, break; case INTUOSHT: - if (features->touch_max && - features->device_type & WACOM_DEVICETYPE_TOUCH) { + if (features->device_type & WACOM_DEVICETYPE_TOUCH) { input_dev->evbit[0] |= BIT_MASK(EV_SW); __set_bit(SW_MUTE_DEVICE, input_dev->swbit); } @@ -2434,27 +2445,26 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, __clear_bit(ABS_MISC, input_dev->absbit); if (features->device_type & WACOM_DEVICETYPE_TOUCH) { - - if (features->touch_max) { - if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { - input_set_abs_params(input_dev, - ABS_MT_TOUCH_MAJOR, - 0, features->x_max, 0, 0); - input_set_abs_params(input_dev, - ABS_MT_TOUCH_MINOR, - 0, features->y_max, 0, 0); - } - input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER); - } else { - /* buttons/keys only interface */ - __clear_bit(ABS_X, input_dev->absbit); - __clear_bit(ABS_Y, input_dev->absbit); - __clear_bit(BTN_TOUCH, input_dev->keybit); - - /* PAD is setup by wacom_setup_pad_input_capabilities later */ - return 1; + if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { + input_set_abs_params(input_dev, + ABS_MT_TOUCH_MAJOR, + 0, features->x_max, 0, 0); + input_set_abs_params(input_dev, + ABS_MT_TOUCH_MINOR, + 0, features->y_max, 0, 0); } - } else if (features->device_type & WACOM_DEVICETYPE_PEN) { + input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER); + } + if (features->device_type & WACOM_DEVICETYPE_PAD) { + /* buttons/keys only interface */ + __clear_bit(ABS_X, input_dev->absbit); + __clear_bit(ABS_Y, input_dev->absbit); + __clear_bit(BTN_TOUCH, input_dev->keybit); + + /* PAD is setup by wacom_setup_pad_input_capabilities later */ + return 1; + } + if (features->device_type & WACOM_DEVICETYPE_PEN) { __set_bit(INPUT_PROP_POINTER, input_dev->propbit); __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); __set_bit(BTN_TOOL_PEN, input_dev->keybit); @@ -2482,6 +2492,9 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, struct wacom_features *features = &wacom_wac->features; int i; + if (!(features->device_type & WACOM_DEVICETYPE_PAD)) + return -ENODEV; + input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); /* kept for making legacy xf86-input-wacom working with the wheels */ @@ -2618,10 +2631,6 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, case INTUOS5S: case INTUOSPS: - /* touch interface does not have the pad device */ - if (!(features->device_type & WACOM_DEVICETYPE_PEN)) - return -ENODEV; - for (i = 0; i < 7; i++) __set_bit(BTN_0 + i, input_dev->keybit); @@ -2663,12 +2672,6 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, case INTUOSHT: case BAMBOO_PT: - /* pad device is on the touch interface */ - if (!(features->device_type & WACOM_DEVICETYPE_TOUCH) || - /* Bamboo Pen only tablet does not have pad */ - ((features->type == BAMBOO_PT) && !features->touch_max)) - return -ENODEV; - __clear_bit(ABS_MISC, input_dev->absbit); __set_bit(BTN_LEFT, input_dev->keybit); -- cgit v1.1 From 2636a3f2d1421e3e629dfc96489c23727bab17d7 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 15 Jun 2015 18:01:44 -0700 Subject: HID: wacom: Split apart 'wacom_setup_pentouch_input_capabilites' This splits the 'wacom_setup_pentouch_input_capabilites' function into pieces dedicated to doing setup for just the pen interface and just the touch interface. This makes it easier to focus on the relevant piece when making changes. This patch introduces no functional changes. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 234 +++++++++++++++++++++++++----------------------- 1 file changed, 122 insertions(+), 112 deletions(-) (limited to 'drivers/hid/wacom_wac.c') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 564a06d..b80a67a 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2237,54 +2237,16 @@ void wacom_setup_device_quirks(struct wacom *wacom) } } -static void wacom_abs_set_axis(struct input_dev *input_dev, - struct wacom_wac *wacom_wac) -{ - struct wacom_features *features = &wacom_wac->features; - - if (features->device_type & WACOM_DEVICETYPE_PEN) { - input_set_abs_params(input_dev, ABS_X, features->x_min, - features->x_max, features->x_fuzz, 0); - input_set_abs_params(input_dev, ABS_Y, features->y_min, - features->y_max, features->y_fuzz, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, - features->pressure_max, features->pressure_fuzz, 0); - - /* penabled devices have fixed resolution for each model */ - input_abs_set_res(input_dev, ABS_X, features->x_resolution); - input_abs_set_res(input_dev, ABS_Y, features->y_resolution); - } else if (features->device_type & WACOM_DEVICETYPE_TOUCH) { - if (features->touch_max == 1) { - input_set_abs_params(input_dev, ABS_X, 0, - features->x_max, features->x_fuzz, 0); - input_set_abs_params(input_dev, ABS_Y, 0, - features->y_max, features->y_fuzz, 0); - input_abs_set_res(input_dev, ABS_X, - features->x_resolution); - input_abs_set_res(input_dev, ABS_Y, - features->y_resolution); - } - - if (features->touch_max > 1) { - input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, - features->x_max, features->x_fuzz, 0); - input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, - features->y_max, features->y_fuzz, 0); - input_abs_set_res(input_dev, ABS_MT_POSITION_X, - features->x_resolution); - input_abs_set_res(input_dev, ABS_MT_POSITION_Y, - features->y_resolution); - } - } -} - -int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, +int wacom_setup_pen_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); + if (!(features->device_type & WACOM_DEVICETYPE_PEN)) + return -ENODEV; + if (features->type == HID_GENERIC) /* setup has already been done */ return 0; @@ -2292,7 +2254,17 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, __set_bit(BTN_TOUCH, input_dev->keybit); __set_bit(ABS_MISC, input_dev->absbit); - wacom_abs_set_axis(input_dev, wacom_wac); + input_set_abs_params(input_dev, ABS_X, features->x_min, + features->x_max, features->x_fuzz, 0); + input_set_abs_params(input_dev, ABS_Y, features->y_min, + features->y_max, features->y_fuzz, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, + features->pressure_max, features->pressure_fuzz, 0); + + /* penabled devices have fixed resolution for each model */ + input_abs_set_res(input_dev, ABS_X, features->x_resolution); + input_abs_set_res(input_dev, ABS_Y, features->y_resolution); + switch (features->type) { case GRAPHIRE_BT: @@ -2361,53 +2333,25 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, case INTUOSPS: __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - if (features->device_type & WACOM_DEVICETYPE_PEN) { - input_set_abs_params(input_dev, ABS_DISTANCE, 0, - features->distance_max, - 0, 0); - - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); - input_abs_set_res(input_dev, ABS_Z, 287); + input_set_abs_params(input_dev, ABS_DISTANCE, 0, + features->distance_max, + 0, 0); - wacom_setup_intuos(wacom_wac); - } else if (features->device_type & WACOM_DEVICETYPE_TOUCH) { - __clear_bit(ABS_MISC, input_dev->absbit); + input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_abs_set_res(input_dev, ABS_Z, 287); - input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, - 0, features->x_max, 0, 0); - input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, - 0, features->y_max, 0, 0); - input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER); - } + wacom_setup_intuos(wacom_wac); break; case WACOM_24HDT: - if (features->device_type & WACOM_DEVICETYPE_TOUCH) { - 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 WACOM_27QHDT: case MTSCREEN: case MTTPC: case MTTPC_B: case TABLETPC2FG: - if (features->device_type & WACOM_DEVICETYPE_TOUCH && features->touch_max > 1) - input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_DIRECT); - /* fall through */ - case TABLETPC: case TABLETPCE: __clear_bit(ABS_MISC, input_dev->absbit); - - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - - if (!(features->device_type & WACOM_DEVICETYPE_PEN)) - break; /* no need to process stylus stuff */ - /* fall through */ case DTUS: @@ -2435,48 +2379,114 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev, break; case INTUOSHT: - if (features->device_type & WACOM_DEVICETYPE_TOUCH) { - input_dev->evbit[0] |= BIT_MASK(EV_SW); - __set_bit(SW_MUTE_DEVICE, input_dev->swbit); - } - /* fall through */ - case BAMBOO_PT: __clear_bit(ABS_MISC, input_dev->absbit); - if (features->device_type & WACOM_DEVICETYPE_TOUCH) { - if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { - input_set_abs_params(input_dev, - ABS_MT_TOUCH_MAJOR, - 0, features->x_max, 0, 0); - input_set_abs_params(input_dev, - ABS_MT_TOUCH_MINOR, - 0, features->y_max, 0, 0); - } - input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER); - } - if (features->device_type & WACOM_DEVICETYPE_PAD) { - /* buttons/keys only interface */ - __clear_bit(ABS_X, input_dev->absbit); - __clear_bit(ABS_Y, input_dev->absbit); - __clear_bit(BTN_TOUCH, input_dev->keybit); + __set_bit(INPUT_PROP_POINTER, input_dev->propbit); + __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); + __set_bit(BTN_TOOL_PEN, input_dev->keybit); + __set_bit(BTN_STYLUS, input_dev->keybit); + __set_bit(BTN_STYLUS2, input_dev->keybit); + input_set_abs_params(input_dev, ABS_DISTANCE, 0, + features->distance_max, + 0, 0); + break; + case BAMBOO_PAD: + __clear_bit(ABS_MISC, input_dev->absbit); + break; + } + return 0; +} - /* PAD is setup by wacom_setup_pad_input_capabilities later */ - return 1; - } - if (features->device_type & WACOM_DEVICETYPE_PEN) { - __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); - __set_bit(BTN_TOOL_PEN, input_dev->keybit); - __set_bit(BTN_STYLUS, input_dev->keybit); - __set_bit(BTN_STYLUS2, input_dev->keybit); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, - features->distance_max, - 0, 0); +int wacom_setup_touch_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); + + if (!(features->device_type & WACOM_DEVICETYPE_TOUCH)) + return -ENODEV; + + if (features->type == HID_GENERIC) + /* setup has already been done */ + return 0; + + __set_bit(BTN_TOUCH, input_dev->keybit); + + if (features->touch_max == 1) { + input_set_abs_params(input_dev, ABS_X, 0, + features->x_max, features->x_fuzz, 0); + input_set_abs_params(input_dev, ABS_Y, 0, + features->y_max, features->y_fuzz, 0); + input_abs_set_res(input_dev, ABS_X, + features->x_resolution); + input_abs_set_res(input_dev, ABS_Y, + features->y_resolution); + } + else if (features->touch_max > 1) { + input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, + features->x_max, features->x_fuzz, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, + features->y_max, features->y_fuzz, 0); + input_abs_set_res(input_dev, ABS_MT_POSITION_X, + features->x_resolution); + input_abs_set_res(input_dev, ABS_MT_POSITION_Y, + features->y_resolution); + } + + switch (features->type) { + case INTUOS5: + case INTUOS5L: + case INTUOSPM: + case INTUOSPL: + case INTUOS5S: + case INTUOSPS: + __set_bit(INPUT_PROP_POINTER, input_dev->propbit); + + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0); + input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, 0, features->y_max, 0, 0); + input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER); + break; + + case WACOM_24HDT: + 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 WACOM_27QHDT: + case MTSCREEN: + case MTTPC: + case MTTPC_B: + case TABLETPC2FG: + input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_DIRECT); + /*fall through */ + + case TABLETPC: + case TABLETPCE: + __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); + break; + + case INTUOSHT: + input_dev->evbit[0] |= BIT_MASK(EV_SW); + __set_bit(SW_MUTE_DEVICE, input_dev->swbit); + /* fall through */ + + case BAMBOO_PT: + if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { + input_set_abs_params(input_dev, + ABS_MT_TOUCH_MAJOR, + 0, features->x_max, 0, 0); + input_set_abs_params(input_dev, + ABS_MT_TOUCH_MINOR, + 0, features->y_max, 0, 0); } + input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER); break; + case BAMBOO_PAD: - __clear_bit(ABS_MISC, input_dev->absbit); input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER); __set_bit(BTN_LEFT, input_dev->keybit); -- cgit v1.1 From 2a6cdbdd4cc0da0b0190b9a43648dff7b44adc0a Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 15 Jun 2015 18:01:45 -0700 Subject: HID: wacom: Introduce new 'touch_input' device Instead of having a single 'input_dev' device that will take either pen or touch data depending on the type of the device, create seperate devices devices for each. By splitting things like this, we can support devices (e.g. the I2C "AES" sensors in some newer tablet PCs) that send both pen and touch reports from a single endpoint. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 115 ++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 52 deletions(-) (limited to 'drivers/hid/wacom_wac.c') diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index b80a67a..d811e87 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -69,7 +69,7 @@ static void wacom_notify_battery(struct wacom_wac *wacom_wac, static int wacom_penpartner_irq(struct wacom_wac *wacom) { unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->pen_input; switch (data[0]) { case 1: @@ -114,7 +114,7 @@ static int wacom_pl_irq(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->pen_input; int prox, pressure; if (data[0] != WACOM_REPORT_PENABLED) { @@ -186,7 +186,7 @@ static int wacom_pl_irq(struct wacom_wac *wacom) static int wacom_ptu_irq(struct wacom_wac *wacom) { unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->pen_input; if (data[0] != WACOM_REPORT_PENABLED) { dev_dbg(input->dev.parent, @@ -215,7 +215,7 @@ static int wacom_ptu_irq(struct wacom_wac *wacom) static int wacom_dtu_irq(struct wacom_wac *wacom) { unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->pen_input; int prox = data[1] & 0x20; dev_dbg(input->dev.parent, @@ -245,7 +245,7 @@ static int wacom_dtu_irq(struct wacom_wac *wacom) static int wacom_dtus_irq(struct wacom_wac *wacom) { char *data = wacom->data; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->pen_input; unsigned short prox, pressure = 0; if (data[0] != WACOM_REPORT_DTUS && data[0] != WACOM_REPORT_DTUSPAD) { @@ -297,7 +297,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->pen_input; struct input_dev *pad_input = wacom->pad_input; int battery_capacity, ps_connected; int prox; @@ -464,7 +464,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->pen_input; int idx = 0; /* tool number */ @@ -649,7 +649,7 @@ static void wacom_intuos_general(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->pen_input; unsigned int t; /* general pen packet */ @@ -681,7 +681,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->pen_input; unsigned int t; int idx = 0, result; @@ -1025,7 +1025,7 @@ static void wacom_intuos_bt_process_data(struct wacom_wac *wacom, memcpy(wacom->data, data, 10); wacom_intuos_irq(wacom); - input_sync(wacom->input); + input_sync(wacom->pen_input); if (wacom->pad_input) input_sync(wacom->pad_input); } @@ -1057,7 +1057,7 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len) ps_connected); break; default: - dev_dbg(wacom->input->dev.parent, + dev_dbg(wacom->pen_input->dev.parent, "Unknown report: %d,%d size:%zu\n", data[0], data[1], len); return 0; @@ -1067,7 +1067,7 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len) static int wacom_wac_finger_count_touches(struct wacom_wac *wacom) { - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->touch_input; unsigned touch_max = wacom->features.touch_max; int count = 0; int i; @@ -1088,7 +1088,7 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom) static int wacom_24hdt_irq(struct wacom_wac *wacom) { - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->touch_input; unsigned char *data = wacom->data; int i; int current_num_contacts = data[61]; @@ -1156,7 +1156,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) static int wacom_mt_touch(struct wacom_wac *wacom) { - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->touch_input; unsigned char *data = wacom->data; int i; int current_num_contacts = data[2]; @@ -1207,7 +1207,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom) static int wacom_tpc_mt_touch(struct wacom_wac *wacom) { - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->touch_input; unsigned char *data = wacom->data; int i; @@ -1236,7 +1236,7 @@ static int wacom_tpc_mt_touch(struct wacom_wac *wacom) static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) { unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->touch_input; bool prox = !wacom->shared->stylus_in_proximity; int x = 0, y = 0; @@ -1272,7 +1272,7 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) static int wacom_tpc_pen(struct wacom_wac *wacom) { unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->pen_input; bool prox = data[1] & 0x20; if (!wacom->shared->stylus_in_proximity) /* first in prox */ @@ -1301,8 +1301,12 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) { unsigned char *data = wacom->data; - dev_dbg(wacom->input->dev.parent, - "%s: received report #%d\n", __func__, data[0]); + if (wacom->pen_input) + dev_dbg(wacom->pen_input->dev.parent, + "%s: received report #%d\n", __func__, data[0]); + else if (wacom->touch_input) + dev_dbg(wacom->touch_input->dev.parent, + "%s: received report #%d\n", __func__, data[0]); switch (len) { case WACOM_PKGLEN_TPC1FG: @@ -1334,11 +1338,9 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) return 0; } -static void wacom_map_usage(struct wacom *wacom, struct hid_usage *usage, +static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage, struct hid_field *field, __u8 type, __u16 code, int fuzz) { - struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct input_dev *input = wacom_wac->input; int fmin = field->logical_minimum; int fmax = field->logical_maximum; @@ -1366,36 +1368,38 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage) { struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = &wacom->wacom_wac; + struct input_dev *input = wacom_wac->pen_input; switch (usage->hid) { case HID_GD_X: - wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4); + wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 4); break; case HID_GD_Y: - wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4); + wacom_map_usage(input, usage, field, EV_ABS, ABS_Y, 4); break; case HID_DG_TIPPRESSURE: - wacom_map_usage(wacom, usage, field, EV_ABS, ABS_PRESSURE, 0); + wacom_map_usage(input, usage, field, EV_ABS, ABS_PRESSURE, 0); break; case HID_DG_INRANGE: - wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOOL_PEN, 0); + wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_PEN, 0); break; case HID_DG_INVERT: - wacom_map_usage(wacom, usage, field, EV_KEY, + wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_RUBBER, 0); break; case HID_DG_ERASER: case HID_DG_TIPSWITCH: - wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0); + wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0); break; case HID_DG_BARRELSWITCH: - wacom_map_usage(wacom, usage, field, EV_KEY, BTN_STYLUS, 0); + wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS, 0); break; case HID_DG_BARRELSWITCH2: - wacom_map_usage(wacom, usage, field, EV_KEY, BTN_STYLUS2, 0); + wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS2, 0); break; case HID_DG_TOOLSERIALNUMBER: - wacom_map_usage(wacom, usage, field, EV_MSC, MSC_SERIAL, 0); + wacom_map_usage(input, usage, field, EV_MSC, MSC_SERIAL, 0); break; } } @@ -1405,7 +1409,7 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field, { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct input_dev *input = wacom_wac->input; + struct input_dev *input = wacom_wac->pen_input; /* checking which Tool / tip switch to send */ switch (usage->hid) { @@ -1435,7 +1439,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev, { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct input_dev *input = wacom_wac->input; + struct input_dev *input = wacom_wac->pen_input; bool prox = wacom_wac->hid_data.inrange_state; if (!wacom_wac->shared->stylus_in_proximity) /* first in prox */ @@ -1464,23 +1468,24 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; struct wacom_features *features = &wacom_wac->features; + struct input_dev *input = wacom_wac->touch_input; unsigned touch_max = wacom_wac->features.touch_max; switch (usage->hid) { case HID_GD_X: features->last_slot_field = usage->hid; if (touch_max == 1) - wacom_map_usage(wacom, usage, field, EV_ABS, ABS_X, 4); + wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 4); else - wacom_map_usage(wacom, usage, field, EV_ABS, + wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_POSITION_X, 4); break; case HID_GD_Y: features->last_slot_field = usage->hid; if (touch_max == 1) - wacom_map_usage(wacom, usage, field, EV_ABS, ABS_Y, 4); + wacom_map_usage(input, usage, field, EV_ABS, ABS_Y, 4); else - wacom_map_usage(wacom, usage, field, EV_ABS, + wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_POSITION_Y, 4); break; case HID_DG_CONTACTID: @@ -1494,7 +1499,7 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, break; case HID_DG_TIPSWITCH: features->last_slot_field = usage->hid; - wacom_map_usage(wacom, usage, field, EV_KEY, BTN_TOUCH, 0); + wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0); break; } } @@ -1550,7 +1555,7 @@ static int wacom_wac_finger_event(struct hid_device *hdev, if (usage->usage_index + 1 == field->report_count) { if (usage->hid == wacom_wac->features.last_slot_field) - wacom_wac_finger_slot(wacom_wac, wacom_wac->input); + wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); } return 0; @@ -1561,7 +1566,7 @@ static void wacom_wac_finger_report(struct hid_device *hdev, { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct input_dev *input = wacom_wac->input; + struct input_dev *input = wacom_wac->touch_input; unsigned touch_max = wacom_wac->features.touch_max; if (touch_max > 1) @@ -1578,10 +1583,10 @@ void wacom_wac_usage_mapping(struct hid_device *hdev, { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct input_dev *input = wacom_wac->input; /* currently, only direct devices have proper hid report descriptors */ - __set_bit(INPUT_PROP_DIRECT, input->propbit); + __set_bit(INPUT_PROP_DIRECT, wacom_wac->pen_input->propbit); + __set_bit(INPUT_PROP_DIRECT, wacom_wac->touch_input->propbit); if (WACOM_PEN_FIELD(field)) return wacom_wac_pen_usage_mapping(hdev, field, usage); @@ -1626,7 +1631,7 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) static int wacom_bpt_touch(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->touch_input; struct input_dev *pad_input = wacom->pad_input; unsigned char *data = wacom->data; int i; @@ -1674,7 +1679,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) { struct wacom_features *features = &wacom->features; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->touch_input; bool touch = data[1] & 0x80; int slot = input_mt_get_slot_by_key(input, data[0]); @@ -1732,7 +1737,6 @@ static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data) static int wacom_bpt3_touch(struct wacom_wac *wacom) { - struct input_dev *input = wacom->input; unsigned char *data = wacom->data; int count = data[1] & 0x07; int i; @@ -1751,8 +1755,12 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom) wacom_bpt3_button_msg(wacom, data + offset); } - input_mt_sync_frame(input); - wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom); + + /* only update the touch if we actually have a touchpad */ + if (wacom->touch_registered) { + input_mt_sync_frame(wacom->touch_input); + wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom); + } return 1; } @@ -1760,7 +1768,7 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom) static int wacom_bpt_pen(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->pen_input; unsigned char *data = wacom->data; int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; @@ -1869,7 +1877,7 @@ static void wacom_bamboo_pad_pen_event(struct wacom_wac *wacom, static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom, unsigned char *data) { - struct input_dev *input = wacom->input; + struct input_dev *input = wacom->touch_input; unsigned char *finger_data, prefix; unsigned id; int x, y; @@ -2113,7 +2121,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) } if (sync) { - input_sync(wacom_wac->input); + if (wacom_wac->pen_input) + input_sync(wacom_wac->pen_input); + if (wacom_wac->touch_input) + input_sync(wacom_wac->touch_input); if (wacom_wac->pad_input) input_sync(wacom_wac->pad_input); } @@ -2121,7 +2132,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) { - struct input_dev *input_dev = wacom_wac->input; + struct input_dev *input_dev = wacom_wac->pen_input; input_set_capability(input_dev, EV_MSC, MSC_SERIAL); @@ -2144,7 +2155,7 @@ static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) static void wacom_setup_intuos(struct wacom_wac *wacom_wac) { - struct input_dev *input_dev = wacom_wac->input; + struct input_dev *input_dev = wacom_wac->pen_input; input_set_capability(input_dev, EV_REL, REL_WHEEL); -- cgit v1.1