aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/wacom_wac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/wacom_wac.c')
-rw-r--r--drivers/hid/wacom_wac.c422
1 files changed, 241 insertions, 181 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index fa54d3290659..232da89f4e88 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,14 +1067,16 @@ 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;
- /* 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)
+ return 0;
+
+ 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++) {
@@ -1089,7 +1091,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];
@@ -1157,7 +1159,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];
@@ -1208,7 +1210,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;
@@ -1237,7 +1239,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;
@@ -1273,7 +1275,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 */
@@ -1302,8 +1304,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:
@@ -1335,11 +1341,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;
@@ -1367,36 +1371,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;
}
}
@@ -1406,7 +1412,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) {
@@ -1436,7 +1442,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 */
@@ -1465,23 +1471,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:
@@ -1495,7 +1502,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;
}
}
@@ -1551,7 +1558,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;
@@ -1562,7 +1569,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)
@@ -1579,10 +1586,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);
@@ -1627,7 +1634,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;
@@ -1675,7 +1682,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]);
@@ -1733,7 +1740,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;
@@ -1752,8 +1758,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;
}
@@ -1761,7 +1771,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;
@@ -1870,7 +1880,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;
@@ -2114,7 +2124,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);
}
@@ -2122,7 +2135,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);
@@ -2145,7 +2158,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);
@@ -2164,15 +2177,57 @@ 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;
+
+ /* 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 == BTN_TOOL_FINGER && !features->x_max) {
+ if (features->device_type & WACOM_DEVICETYPE_TOUCH && !features->x_max) {
features->x_max = 1023;
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) {
+ 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;
+ }
+ }
+
+ /*
+ * 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 |= WACOM_DEVICETYPE_TOUCH;
+
+ 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) {
@@ -2189,61 +2244,23 @@ void wacom_setup_device_quirks(struct wacom_features *features)
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;
}
}
}
-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 == BTN_TOOL_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->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;
@@ -2251,7 +2268,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:
@@ -2320,53 +2347,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 == BTN_TOOL_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 == BTN_TOOL_FINGER) {
- __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 == 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 WACOM_27QHDT:
case MTSCREEN:
case MTTPC:
case MTTPC_B:
case TABLETPC2FG:
- if (features->device_type == BTN_TOOL_FINGER && 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 != BTN_TOOL_PEN)
- break; /* no need to process stylus stuff */
-
/* fall through */
case DTUS:
@@ -2394,50 +2393,114 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev,
break;
case INTUOSHT:
- if (features->touch_max &&
- features->device_type == BTN_TOOL_FINGER) {
- 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 == BTN_TOOL_FINGER) {
+ __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;
+}
- 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);
+int wacom_setup_touch_input_capabilities(struct input_dev *input_dev,
+ struct wacom_wac *wacom_wac)
+{
+ struct wacom_features *features = &wacom_wac->features;
- /* PAD is setup by wacom_setup_pad_input_capabilities later */
- return 1;
- }
- } else if (features->device_type == BTN_TOOL_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);
+ 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);
@@ -2453,6 +2516,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 */
@@ -2589,10 +2655,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 != BTN_TOOL_PEN)
- return -ENODEV;
-
for (i = 0; i < 7; i++)
__set_bit(BTN_0 + i, input_dev->keybit);
@@ -2634,12 +2696,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 != BTN_TOOL_FINGER) ||
- /* 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);
@@ -2919,6 +2975,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,
@@ -3272,6 +3331,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) },