aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
authorDave Turvene <dturvene@dahetral.com>2013-02-22 01:58:28 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2013-02-22 03:10:30 -0500
commit75af9e56c1e309a4132d15120d7061656609b84e (patch)
tree0ff39fe6344c0dffb4df7492b47ea5e349961e92 /drivers/input/mouse
parentd18e53fce2f6e42bfb8ac157547dd3f804385749 (diff)
Input: ALPS - add "Dolphin V1" touchpad support
These touchpads use a different protocol; they have been seen on Dell N5110, Dell 17R SE, and others. The official ALPS driver identifies them by looking for an exact match on the E7 report: 73 03 50. Dolphin V1 returns an EC report of 73 01 xx (02 and 0d have been seen); Dolphin V2 returns an EC report of 73 02 xx (02 has been seen). Dolphin V2 probably needs a different initialization sequence and/or report parser, so it is left for a future commit. Signed-off-by: Dave Turvene <dturvene@dahetral.com> Signed-off-by: Kevin Cernekee <cernekee@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/alps.c67
-rw-r--r--drivers/input/mouse/alps.h1
2 files changed, 66 insertions, 2 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 9c97531bd2cd..0238e0e14335 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -490,6 +490,29 @@ static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p)
490 f->y_map |= (p[5] & 0x20) << 6; 490 f->y_map |= (p[5] & 0x20) << 6;
491} 491}
492 492
493static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p)
494{
495 f->first_mp = !!(p[0] & 0x02);
496 f->is_mp = !!(p[0] & 0x20);
497
498 f->fingers = ((p[0] & 0x6) >> 1 |
499 (p[0] & 0x10) >> 2);
500 f->x_map = ((p[2] & 0x60) >> 5) |
501 ((p[4] & 0x7f) << 2) |
502 ((p[5] & 0x7f) << 9) |
503 ((p[3] & 0x07) << 16) |
504 ((p[3] & 0x70) << 15) |
505 ((p[0] & 0x01) << 22);
506 f->y_map = (p[1] & 0x7f) |
507 ((p[2] & 0x1f) << 7);
508
509 f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
510 f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
511 f->z = (p[0] & 4) ? 0 : p[5] & 0x7f;
512
513 alps_decode_buttons_v3(f, p);
514}
515
493static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) 516static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
494{ 517{
495 struct alps_data *priv = psmouse->private; 518 struct alps_data *priv = psmouse->private;
@@ -874,7 +897,8 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
874 } 897 }
875 898
876 /* Bytes 2 - pktsize should have 0 in the highest bit */ 899 /* Bytes 2 - pktsize should have 0 in the highest bit */
877 if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize && 900 if (priv->proto_version != ALPS_PROTO_V5 &&
901 psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
878 (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { 902 (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
879 psmouse_dbg(psmouse, "refusing packet[%i] = %x\n", 903 psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
880 psmouse->pktcnt - 1, 904 psmouse->pktcnt - 1,
@@ -1003,7 +1027,8 @@ static int alps_enter_command_mode(struct psmouse *psmouse)
1003 return -1; 1027 return -1;
1004 } 1028 }
1005 1029
1006 if (param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) { 1030 if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) &&
1031 param[0] != 0x73) {
1007 psmouse_dbg(psmouse, 1032 psmouse_dbg(psmouse,
1008 "unknown response while entering command mode\n"); 1033 "unknown response while entering command mode\n");
1009 return -1; 1034 return -1;
@@ -1495,6 +1520,23 @@ error:
1495 return -1; 1520 return -1;
1496} 1521}
1497 1522
1523static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
1524{
1525 struct ps2dev *ps2dev = &psmouse->ps2dev;
1526 unsigned char param[2];
1527
1528 /* This is dolphin "v1" as empirically defined by florin9doi */
1529 param[0] = 0x64;
1530 param[1] = 0x28;
1531
1532 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
1533 ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
1534 ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE))
1535 return -1;
1536
1537 return 0;
1538}
1539
1498static void alps_set_defaults(struct alps_data *priv) 1540static void alps_set_defaults(struct alps_data *priv)
1499{ 1541{
1500 priv->byte0 = 0x8f; 1542 priv->byte0 = 0x8f;
@@ -1528,6 +1570,21 @@ static void alps_set_defaults(struct alps_data *priv)
1528 priv->nibble_commands = alps_v4_nibble_commands; 1570 priv->nibble_commands = alps_v4_nibble_commands;
1529 priv->addr_command = PSMOUSE_CMD_DISABLE; 1571 priv->addr_command = PSMOUSE_CMD_DISABLE;
1530 break; 1572 break;
1573 case ALPS_PROTO_V5:
1574 priv->hw_init = alps_hw_init_dolphin_v1;
1575 priv->process_packet = alps_process_packet_v3;
1576 priv->decode_fields = alps_decode_dolphin;
1577 priv->set_abs_params = alps_set_abs_params_mt;
1578 priv->nibble_commands = alps_v3_nibble_commands;
1579 priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
1580 priv->byte0 = 0xc8;
1581 priv->mask0 = 0xc8;
1582 priv->flags = 0;
1583 priv->x_max = 1360;
1584 priv->y_max = 660;
1585 priv->x_bits = 23;
1586 priv->y_bits = 12;
1587 break;
1531 } 1588 }
1532} 1589}
1533 1590
@@ -1588,6 +1645,12 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
1588 1645
1589 if (alps_match_table(psmouse, priv, e7, ec) == 0) { 1646 if (alps_match_table(psmouse, priv, e7, ec) == 0) {
1590 return 0; 1647 return 0;
1648 } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
1649 ec[0] == 0x73 && ec[1] == 0x01) {
1650 priv->proto_version = ALPS_PROTO_V5;
1651 alps_set_defaults(priv);
1652
1653 return 0;
1591 } else if (ec[0] == 0x88 && ec[1] == 0x08) { 1654 } else if (ec[0] == 0x88 && ec[1] == 0x08) {
1592 priv->proto_version = ALPS_PROTO_V3; 1655 priv->proto_version = ALPS_PROTO_V3;
1593 alps_set_defaults(priv); 1656 alps_set_defaults(priv);
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 970480551b6e..eee59853b9ce 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -16,6 +16,7 @@
16#define ALPS_PROTO_V2 2 16#define ALPS_PROTO_V2 2
17#define ALPS_PROTO_V3 3 17#define ALPS_PROTO_V3 3
18#define ALPS_PROTO_V4 4 18#define ALPS_PROTO_V4 4
19#define ALPS_PROTO_V5 5
19 20
20/** 21/**
21 * struct alps_model_info - touchpad ID table 22 * struct alps_model_info - touchpad ID table