Input: ALPS - add touchstick support for SS5 hardware
Add touchstick support for the so-called SS5 hardware, which uses a variant of the SS4 protocol. Reviewed-by: Pali Rohár <pali.rohar@gmail.com> Tested-by: Michal Hocko <mhocko@suse.com> Signed-off-by: Ben Gamari <ben@smart-cactus.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
parent
f9a703a54d
commit
4777ac220c
2 changed files with 56 additions and 11 deletions
|
@ -1156,15 +1156,28 @@ static unsigned char alps_get_pkt_id_ss4_v2(unsigned char *byte)
|
|||
{
|
||||
unsigned char pkt_id = SS4_PACKET_ID_IDLE;
|
||||
|
||||
if (byte[0] == 0x18 && byte[1] == 0x10 && byte[2] == 0x00 &&
|
||||
(byte[3] & 0x88) == 0x08 && byte[4] == 0x10 && byte[5] == 0x00) {
|
||||
pkt_id = SS4_PACKET_ID_IDLE;
|
||||
} else if (!(byte[3] & 0x10)) {
|
||||
pkt_id = SS4_PACKET_ID_ONE;
|
||||
} else if (!(byte[3] & 0x20)) {
|
||||
switch (byte[3] & 0x30) {
|
||||
case 0x00:
|
||||
if (byte[0] == 0x18 && byte[1] == 0x10 && byte[2] == 0x00 &&
|
||||
(byte[3] & 0x88) == 0x08 && byte[4] == 0x10 &&
|
||||
byte[5] == 0x00) {
|
||||
pkt_id = SS4_PACKET_ID_IDLE;
|
||||
} else {
|
||||
pkt_id = SS4_PACKET_ID_ONE;
|
||||
}
|
||||
break;
|
||||
case 0x10:
|
||||
/* two-finger finger positions */
|
||||
pkt_id = SS4_PACKET_ID_TWO;
|
||||
} else {
|
||||
break;
|
||||
case 0x20:
|
||||
/* stick pointer */
|
||||
pkt_id = SS4_PACKET_ID_STICK;
|
||||
break;
|
||||
case 0x30:
|
||||
/* third and fourth finger positions */
|
||||
pkt_id = SS4_PACKET_ID_MULTI;
|
||||
break;
|
||||
}
|
||||
|
||||
return pkt_id;
|
||||
|
@ -1246,16 +1259,38 @@ static int alps_decode_ss4_v2(struct alps_fields *f,
|
|||
}
|
||||
break;
|
||||
|
||||
case SS4_PACKET_ID_STICK:
|
||||
if (!(priv->flags & ALPS_DUALPOINT)) {
|
||||
psmouse_warn(psmouse,
|
||||
"Rejected trackstick packet from non DualPoint device");
|
||||
} else {
|
||||
int x = (s8)(((p[0] & 1) << 7) | (p[1] & 0x7f));
|
||||
int y = (s8)(((p[3] & 1) << 7) | (p[2] & 0x7f));
|
||||
|
||||
input_report_rel(priv->dev2, REL_X, x);
|
||||
input_report_rel(priv->dev2, REL_Y, -y);
|
||||
}
|
||||
break;
|
||||
|
||||
case SS4_PACKET_ID_IDLE:
|
||||
default:
|
||||
memset(f, 0, sizeof(struct alps_fields));
|
||||
break;
|
||||
}
|
||||
|
||||
f->left = !!(SS4_BTN_V2(p) & 0x01);
|
||||
if (!(priv->flags & ALPS_BUTTONPAD)) {
|
||||
f->right = !!(SS4_BTN_V2(p) & 0x02);
|
||||
f->middle = !!(SS4_BTN_V2(p) & 0x04);
|
||||
/* handle buttons */
|
||||
if (pkt_id == SS4_PACKET_ID_STICK) {
|
||||
f->ts_left = !!(SS4_BTN_V2(p) & 0x01);
|
||||
if (!(priv->flags & ALPS_BUTTONPAD)) {
|
||||
f->ts_right = !!(SS4_BTN_V2(p) & 0x02);
|
||||
f->ts_middle = !!(SS4_BTN_V2(p) & 0x04);
|
||||
}
|
||||
} else {
|
||||
f->left = !!(SS4_BTN_V2(p) & 0x01);
|
||||
if (!(priv->flags & ALPS_BUTTONPAD)) {
|
||||
f->right = !!(SS4_BTN_V2(p) & 0x02);
|
||||
f->middle = !!(SS4_BTN_V2(p) & 0x04);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1266,6 +1301,7 @@ static void alps_process_packet_ss4_v2(struct psmouse *psmouse)
|
|||
struct alps_data *priv = psmouse->private;
|
||||
unsigned char *packet = psmouse->packet;
|
||||
struct input_dev *dev = psmouse->dev;
|
||||
struct input_dev *dev2 = priv->dev2;
|
||||
struct alps_fields *f = &priv->f;
|
||||
|
||||
memset(f, 0, sizeof(struct alps_fields));
|
||||
|
@ -1311,6 +1347,13 @@ static void alps_process_packet_ss4_v2(struct psmouse *psmouse)
|
|||
|
||||
input_report_abs(dev, ABS_PRESSURE, f->pressure);
|
||||
input_sync(dev);
|
||||
|
||||
if (priv->flags & ALPS_DUALPOINT) {
|
||||
input_report_key(dev2, BTN_LEFT, f->ts_left);
|
||||
input_report_key(dev2, BTN_RIGHT, f->ts_right);
|
||||
input_report_key(dev2, BTN_MIDDLE, f->ts_middle);
|
||||
input_sync(dev2);
|
||||
}
|
||||
}
|
||||
|
||||
static bool alps_is_valid_package_ss4_v2(struct psmouse *psmouse)
|
||||
|
|
|
@ -37,12 +37,14 @@
|
|||
* or there's button activities.
|
||||
* SS4_PACKET_ID_TWO: There's two or more fingers on touchpad
|
||||
* SS4_PACKET_ID_MULTI: There's three or more fingers on touchpad
|
||||
* SS4_PACKET_ID_STICK: A stick pointer packet
|
||||
*/
|
||||
enum SS4_PACKET_ID {
|
||||
SS4_PACKET_ID_IDLE = 0,
|
||||
SS4_PACKET_ID_ONE,
|
||||
SS4_PACKET_ID_TWO,
|
||||
SS4_PACKET_ID_MULTI,
|
||||
SS4_PACKET_ID_STICK,
|
||||
};
|
||||
|
||||
#define SS4_COUNT_PER_ELECTRODE 256
|
||||
|
|
Loading…
Reference in a new issue