HID: wacom: Slim down wacom_intuos_pad processing

Seperate the function into two halves: first gather data from the packet,
next report all gathered data. The input subsystem should automatically
mute any events that aren't actually declared for the tablet at hand.

Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
Jason Gerecke 2015-11-30 17:13:47 -08:00 committed by Jiri Kosina
parent fb013a01d4
commit c7f0522a1a

View file

@ -34,6 +34,9 @@
*/ */
#define WACOM_CONTACT_AREA_SCALE 2607 #define WACOM_CONTACT_AREA_SCALE 2607
static void wacom_report_numbered_buttons(struct input_dev *input_dev,
int button_count, int mask);
/* /*
* Percent of battery capacity for Graphire. * Percent of battery capacity for Graphire.
* 8th value means AC online and show 100% capacity. * 8th value means AC online and show 100% capacity.
@ -451,6 +454,12 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
struct wacom_features *features = &wacom->features; struct wacom_features *features = &wacom->features;
unsigned char *data = wacom->data; unsigned char *data = wacom->data;
struct input_dev *input = wacom->pad_input; struct input_dev *input = wacom->pad_input;
int i;
int buttons = 0, nbuttons = features->numbered_buttons;
int keys = 0, nkeys = 0;
int ring1 = 0, ring2 = 0;
int strip1 = 0, strip2 = 0;
bool prox = false;
/* pad packets. Works as a second tool and is always in prox */ /* pad packets. Works as a second tool and is always in prox */
if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
@ -458,72 +467,16 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
return 0; return 0;
if (features->type >= INTUOS4S && features->type <= INTUOS4L) { if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
input_report_key(input, BTN_0, (data[2] & 0x01)); buttons = (data[3] << 1) | (data[2] & 0x01);
input_report_key(input, BTN_1, (data[3] & 0x01)); ring1 = data[1];
input_report_key(input, BTN_2, (data[3] & 0x02));
input_report_key(input, BTN_3, (data[3] & 0x04));
input_report_key(input, BTN_4, (data[3] & 0x08));
input_report_key(input, BTN_5, (data[3] & 0x10));
input_report_key(input, BTN_6, (data[3] & 0x20));
if (data[1] & 0x80) {
input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f));
} else {
/* Out of proximity, clear wheel value. */
input_report_abs(input, ABS_WHEEL, 0);
}
if (features->type != INTUOS4S) {
input_report_key(input, BTN_7, (data[3] & 0x40));
input_report_key(input, BTN_8, (data[3] & 0x80));
}
if (data[1] | (data[2] & 0x01) | data[3]) {
input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
} else {
input_report_abs(input, ABS_MISC, 0);
}
} else if (features->type == DTK) { } else if (features->type == DTK) {
input_report_key(input, BTN_0, (data[6] & 0x01)); buttons = data[6];
input_report_key(input, BTN_1, (data[6] & 0x02));
input_report_key(input, BTN_2, (data[6] & 0x04));
input_report_key(input, BTN_3, (data[6] & 0x08));
input_report_key(input, BTN_4, (data[6] & 0x10));
input_report_key(input, BTN_5, (data[6] & 0x20));
if (data[6] & 0x3f) {
input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
} else {
input_report_abs(input, ABS_MISC, 0);
}
} else if (features->type == WACOM_13HD) { } else if (features->type == WACOM_13HD) {
input_report_key(input, BTN_0, (data[3] & 0x01)); buttons = (data[4] << 1) | (data[3] & 0x01);
input_report_key(input, BTN_1, (data[4] & 0x01));
input_report_key(input, BTN_2, (data[4] & 0x02));
input_report_key(input, BTN_3, (data[4] & 0x04));
input_report_key(input, BTN_4, (data[4] & 0x08));
input_report_key(input, BTN_5, (data[4] & 0x10));
input_report_key(input, BTN_6, (data[4] & 0x20));
input_report_key(input, BTN_7, (data[4] & 0x40));
input_report_key(input, BTN_8, (data[4] & 0x80));
if ((data[3] & 0x01) | data[4]) {
input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
} else {
input_report_abs(input, ABS_MISC, 0);
}
} else if (features->type == WACOM_24HD) { } else if (features->type == WACOM_24HD) {
input_report_key(input, BTN_0, (data[6] & 0x01)); buttons = (data[8] << 8) | data[6];
input_report_key(input, BTN_1, (data[6] & 0x02)); ring1 = data[1];
input_report_key(input, BTN_2, (data[6] & 0x04)); ring2 = data[2];
input_report_key(input, BTN_3, (data[6] & 0x08));
input_report_key(input, BTN_4, (data[6] & 0x10));
input_report_key(input, BTN_5, (data[6] & 0x20));
input_report_key(input, BTN_6, (data[6] & 0x40));
input_report_key(input, BTN_7, (data[6] & 0x80));
input_report_key(input, BTN_8, (data[8] & 0x01));
input_report_key(input, BTN_9, (data[8] & 0x02));
input_report_key(input, BTN_A, (data[8] & 0x04));
input_report_key(input, BTN_B, (data[8] & 0x08));
input_report_key(input, BTN_C, (data[8] & 0x10));
input_report_key(input, BTN_X, (data[8] & 0x20));
input_report_key(input, BTN_Y, (data[8] & 0x40));
input_report_key(input, BTN_Z, (data[8] & 0x80));
/* /*
* Three "buttons" are available on the 24HD which are * Three "buttons" are available on the 24HD which are
@ -532,160 +485,89 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
* The raw touchstrip bits are stored at: * The raw touchstrip bits are stored at:
* ((data[3] & 0x1f) << 8) | data[4]) * ((data[3] & 0x1f) << 8) | data[4])
*/ */
input_report_key(input, KEY_PROG1, data[4] & 0x07); nkeys = 3;
input_report_key(input, KEY_PROG2, data[4] & 0xE0); keys = ((data[3] & 0x1C) ? 1<<2 : 0) |
input_report_key(input, KEY_PROG3, data[3] & 0x1C); ((data[4] & 0xE0) ? 1<<1 : 0) |
((data[4] & 0x07) ? 1<<0 : 0);
if (data[1] & 0x80) {
input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f));
} else {
/* Out of proximity, clear wheel value. */
input_report_abs(input, ABS_WHEEL, 0);
}
if (data[2] & 0x80) {
input_report_abs(input, ABS_THROTTLE, (data[2] & 0x7f));
} else {
/* Out of proximity, clear second wheel value. */
input_report_abs(input, ABS_THROTTLE, 0);
}
if (data[1] | data[2] | (data[3] & 0x1f) | data[4] | data[6] | data[8]) {
input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
} else {
input_report_abs(input, ABS_MISC, 0);
}
} else if (features->type == WACOM_27QHD) { } else if (features->type == WACOM_27QHD) {
input_report_key(input, KEY_PROG1, data[2] & 0x01); nkeys = 3;
input_report_key(input, KEY_PROG2, data[2] & 0x02); keys = data[2] & 0x07;
input_report_key(input, KEY_PROG3, data[2] & 0x04);
input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4]));
input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6]));
input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8]));
if ((data[2] & 0x07) | data[4] | data[5] | data[6] | data[7] | data[8] | data[9]) {
input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
} else {
input_report_abs(input, ABS_MISC, 0);
}
} else if (features->type == CINTIQ_HYBRID) { } else if (features->type == CINTIQ_HYBRID) {
/* /*
* Do not send hardware buttons under Android. They * Do not send hardware buttons under Android. They
* are already sent to the system through GPIO (and * are already sent to the system through GPIO (and
* have different meaning). * have different meaning).
*
* d-pad right -> data[4] & 0x10
* d-pad up -> data[4] & 0x20
* d-pad left -> data[4] & 0x40
* d-pad down -> data[4] & 0x80
* d-pad center -> data[3] & 0x01
*/ */
input_report_key(input, BTN_1, (data[4] & 0x01)); buttons = (data[4] << 1) | (data[3] & 0x01);
input_report_key(input, BTN_2, (data[4] & 0x02));
input_report_key(input, BTN_3, (data[4] & 0x04));
input_report_key(input, BTN_4, (data[4] & 0x08));
input_report_key(input, BTN_5, (data[4] & 0x10)); /* Right */
input_report_key(input, BTN_6, (data[4] & 0x20)); /* Up */
input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */
input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */
input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */
if (data[4] | (data[3] & 0x01)) {
input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
} else {
input_report_abs(input, ABS_MISC, 0);
}
} else if (features->type == CINTIQ_COMPANION_2) { } else if (features->type == CINTIQ_COMPANION_2) {
input_report_key(input, BTN_1, (data[1] & 0x02)); /* d-pad right -> data[4] & 0x10
input_report_key(input, BTN_2, (data[2] & 0x01)); * d-pad up -> data[4] & 0x20
input_report_key(input, BTN_3, (data[2] & 0x02)); * d-pad left -> data[4] & 0x40
input_report_key(input, BTN_4, (data[2] & 0x04)); * d-pad down -> data[4] & 0x80
input_report_key(input, BTN_5, (data[2] & 0x08)); * d-pad center -> data[3] & 0x01
input_report_key(input, BTN_6, (data[1] & 0x04)); */
buttons = ((data[2] & 0xF0) << 7) |
input_report_key(input, BTN_7, (data[2] & 0x10)); /* Right */ ((data[1] & 0x04) << 6) |
input_report_key(input, BTN_8, (data[2] & 0x20)); /* Up */ ((data[2] & 0x0F) << 2) |
input_report_key(input, BTN_9, (data[2] & 0x40)); /* Left */ (data[1] & 0x03);
input_report_key(input, BTN_A, (data[2] & 0x80)); /* Down */
input_report_key(input, BTN_0, (data[1] & 0x01)); /* Center */
if (data[2] | (data[1] & 0x07)) {
input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
} else {
input_report_abs(input, ABS_MISC, 0);
}
} else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
int i;
/* Touch ring mode switch has no capacitive sensor */
input_report_key(input, BTN_0, (data[3] & 0x01));
/* /*
* ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in
* addition to the mechanical switch. Switch data is * addition to the mechanical switch. Switch data is
* stored in data[4], capacitive data in data[5]. * stored in data[4], capacitive data in data[5].
*
* Touch ring mode switch (data[3]) has no capacitive sensor
*/ */
for (i = 0; i < 8; i++) buttons = (data[4] << 1) | (data[3] & 0x01);
input_report_key(input, BTN_1 + i, data[4] & (1 << i)); ring1 = data[2];
if (data[2] & 0x80) {
input_report_abs(input, ABS_WHEEL, (data[2] & 0x7f));
} else {
/* Out of proximity, clear wheel value. */
input_report_abs(input, ABS_WHEEL, 0);
}
if (data[2] | (data[3] & 0x01) | data[4] | data[5]) {
input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
} else {
input_report_abs(input, ABS_MISC, 0);
}
} else { } else {
if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) { if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) {
input_report_key(input, BTN_0, (data[5] & 0x01)); buttons = (data[8] << 10) | ((data[7] & 0x01) << 9) |
input_report_key(input, BTN_1, (data[6] & 0x01)); (data[6] << 1) | (data[5] & 0x01);
input_report_key(input, BTN_2, (data[6] & 0x02));
input_report_key(input, BTN_3, (data[6] & 0x04));
input_report_key(input, BTN_4, (data[6] & 0x08));
input_report_key(input, BTN_5, (data[6] & 0x10));
input_report_key(input, BTN_6, (data[6] & 0x20));
input_report_key(input, BTN_7, (data[6] & 0x40));
input_report_key(input, BTN_8, (data[6] & 0x80));
input_report_key(input, BTN_9, (data[7] & 0x01));
input_report_key(input, BTN_A, (data[8] & 0x01));
input_report_key(input, BTN_B, (data[8] & 0x02));
input_report_key(input, BTN_C, (data[8] & 0x04));
input_report_key(input, BTN_X, (data[8] & 0x08));
input_report_key(input, BTN_Y, (data[8] & 0x10));
input_report_key(input, BTN_Z, (data[8] & 0x20));
input_report_key(input, BTN_BASE, (data[8] & 0x40));
input_report_key(input, BTN_BASE2, (data[8] & 0x80));
if (features->type == WACOM_22HD) { if (features->type == WACOM_22HD) {
input_report_key(input, KEY_PROG1, data[9] & 0x01); nkeys = 3;
input_report_key(input, KEY_PROG2, data[9] & 0x02); keys = data[9] & 0x07;
input_report_key(input, KEY_PROG3, data[9] & 0x04);
} }
} else { } else {
input_report_key(input, BTN_0, (data[5] & 0x01)); buttons = ((data[6] & 0x10) << 10) |
input_report_key(input, BTN_1, (data[5] & 0x02)); ((data[5] & 0x10) << 9) |
input_report_key(input, BTN_2, (data[5] & 0x04)); ((data[6] & 0x0F) << 4) |
input_report_key(input, BTN_3, (data[5] & 0x08)); (data[5] & 0x0F);
input_report_key(input, BTN_4, (data[6] & 0x01));
input_report_key(input, BTN_5, (data[6] & 0x02));
input_report_key(input, BTN_6, (data[6] & 0x04));
input_report_key(input, BTN_7, (data[6] & 0x08));
input_report_key(input, BTN_8, (data[5] & 0x10));
input_report_key(input, BTN_9, (data[6] & 0x10));
}
input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) |
data[2] | (data[3] & 0x1f) | data[4] | data[8] |
(data[7] & 0x01)) {
input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
} else {
input_report_abs(input, ABS_MISC, 0);
} }
strip1 = (data[1] << 8) || data[2];
strip2 = (data[3] << 8) || data[4];
} }
prox = (buttons & ~(~0 << nbuttons)) || (keys & ~(~0 << nkeys)) ||
(ring1 & 0x80) || (ring2 & 0x80) || strip1 || strip2;
wacom_report_numbered_buttons(input, nbuttons, buttons);
for (i = 0; i < nkeys; i++)
input_report_key(input, KEY_PROG1 + i, keys & (1 << i));
input_report_abs(input, ABS_RX, strip1);
input_report_abs(input, ABS_RX, strip2);
input_report_abs(input, ABS_WHEEL, ring1 & 0x7f ? ring1 : 0);
input_report_abs(input, ABS_THROTTLE, ring2 & 0x07 ? ring2 : 0);
input_report_key(input, wacom->tool[1], prox ? 1 : 0);
input_report_abs(input, ABS_MISC, prox ? PAD_DEVICE_ID : 0);
input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff);
return 1; return 1;
} }
@ -2818,6 +2700,19 @@ static void wacom_setup_numbered_buttons(struct input_dev *input_dev,
__set_bit(BTN_BASE + (i-16), input_dev->keybit); __set_bit(BTN_BASE + (i-16), input_dev->keybit);
} }
static void wacom_report_numbered_buttons(struct input_dev *input_dev,
int button_count, int mask)
{
int i;
for (i = 0; i < button_count && i < 10; i++)
input_report_key(input_dev, BTN_0 + i, mask & (1 << i));
for (i = 10; i < button_count && i < 16; i++)
input_report_key(input_dev, BTN_A + (i-10), mask & (1 << i));
for (i = 16; i < button_count && i < 18; i++)
input_report_key(input_dev, BTN_BASE + (i-16), mask & (1 << i));
}
int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
struct wacom_wac *wacom_wac) struct wacom_wac *wacom_wac)
{ {