aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorYunkang Tang <tommywill2011@gmail.com>2013-12-26 17:54:19 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2013-12-26 18:44:39 -0500
commitee65d4b36de8ddf4467f788faa5d8ddd1bfcdaa2 (patch)
treeb83ba964dff094e5d5cf7b0c66c0b334ef8fc900 /drivers/input
parent01d08185850c2eb5ce80722df3fdb5d7a291fb79 (diff)
Input: ALPS - add support for "Dolphin" devices
This adds support for another flavor of ALPS protocol used in newer "Dolphin" devices. Signed-off-by: Yunkang Tang <yunkang.tang@cn.alps.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/mouse/alps.c214
-rw-r--r--drivers/input/mouse/alps.h7
2 files changed, 179 insertions, 42 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 5cf62e315218..fb15c64ffb95 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -277,6 +277,57 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse)
277} 277}
278 278
279/* 279/*
280 * Process bitmap data for V5 protocols. Return value is null.
281 *
282 * The bitmaps don't have enough data to track fingers, so this function
283 * only generates points representing a bounding box of at most two contacts.
284 * These two points are returned in x1, y1, x2, and y2.
285 */
286static void alps_process_bitmap_dolphin(struct alps_data *priv,
287 struct alps_fields *fields,
288 int *x1, int *y1, int *x2, int *y2)
289{
290 int box_middle_x, box_middle_y;
291 unsigned int x_map, y_map;
292 unsigned char start_bit, end_bit;
293 unsigned char x_msb, x_lsb, y_msb, y_lsb;
294
295 x_map = fields->x_map;
296 y_map = fields->y_map;
297
298 if (!x_map || !y_map)
299 return;
300
301 /* Get Most-significant and Least-significant bit */
302 x_msb = fls(x_map);
303 x_lsb = ffs(x_map);
304 y_msb = fls(y_map);
305 y_lsb = ffs(y_map);
306
307 /* Most-significant bit should never exceed max sensor line number */
308 if (x_msb > priv->x_bits || y_msb > priv->y_bits)
309 return;
310
311 *x1 = *y1 = *x2 = *y2 = 0;
312
313 if (fields->fingers > 1) {
314 start_bit = priv->x_bits - x_msb;
315 end_bit = priv->x_bits - x_lsb;
316 box_middle_x = (priv->x_max * (start_bit + end_bit)) /
317 (2 * (priv->x_bits - 1));
318
319 start_bit = y_lsb - 1;
320 end_bit = y_msb - 1;
321 box_middle_y = (priv->y_max * (start_bit + end_bit)) /
322 (2 * (priv->y_bits - 1));
323 *x1 = fields->x;
324 *y1 = fields->y;
325 *x2 = 2 * box_middle_x - *x1;
326 *y2 = 2 * box_middle_y - *y1;
327 }
328}
329
330/*
280 * Process bitmap data from v3 and v4 protocols. Returns the number of 331 * Process bitmap data from v3 and v4 protocols. Returns the number of
281 * fingers detected. A return value of 0 means at least one of the 332 * fingers detected. A return value of 0 means at least one of the
282 * bitmaps was empty. 333 * bitmaps was empty.
@@ -481,7 +532,8 @@ static void alps_decode_buttons_v3(struct alps_fields *f, unsigned char *p)
481 f->ts_middle = !!(p[3] & 0x40); 532 f->ts_middle = !!(p[3] & 0x40);
482} 533}
483 534
484static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p) 535static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p,
536 struct psmouse *psmouse)
485{ 537{
486 f->first_mp = !!(p[4] & 0x40); 538 f->first_mp = !!(p[4] & 0x40);
487 f->is_mp = !!(p[0] & 0x40); 539 f->is_mp = !!(p[0] & 0x40);
@@ -502,48 +554,61 @@ static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p)
502 alps_decode_buttons_v3(f, p); 554 alps_decode_buttons_v3(f, p);
503} 555}
504 556
505static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p) 557static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p,
558 struct psmouse *psmouse)
506{ 559{
507 alps_decode_pinnacle(f, p); 560 alps_decode_pinnacle(f, p, psmouse);
508 561
509 f->x_map |= (p[5] & 0x10) << 11; 562 f->x_map |= (p[5] & 0x10) << 11;
510 f->y_map |= (p[5] & 0x20) << 6; 563 f->y_map |= (p[5] & 0x20) << 6;
511} 564}
512 565
513static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p) 566static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p,
567 struct psmouse *psmouse)
514{ 568{
569 u64 palm_data = 0;
570 struct alps_data *priv = psmouse->private;
571
515 f->first_mp = !!(p[0] & 0x02); 572 f->first_mp = !!(p[0] & 0x02);
516 f->is_mp = !!(p[0] & 0x20); 573 f->is_mp = !!(p[0] & 0x20);
517 574
518 f->fingers = ((p[0] & 0x6) >> 1 | 575 if (!f->is_mp) {
576 f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
577 f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
578 f->z = (p[0] & 4) ? 0 : p[5] & 0x7f;
579 alps_decode_buttons_v3(f, p);
580 } else {
581 f->fingers = ((p[0] & 0x6) >> 1 |
519 (p[0] & 0x10) >> 2); 582 (p[0] & 0x10) >> 2);
520 f->x_map = ((p[2] & 0x60) >> 5) |
521 ((p[4] & 0x7f) << 2) |
522 ((p[5] & 0x7f) << 9) |
523 ((p[3] & 0x07) << 16) |
524 ((p[3] & 0x70) << 15) |
525 ((p[0] & 0x01) << 22);
526 f->y_map = (p[1] & 0x7f) |
527 ((p[2] & 0x1f) << 7);
528
529 f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
530 f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
531 f->z = (p[0] & 4) ? 0 : p[5] & 0x7f;
532 583
533 alps_decode_buttons_v3(f, p); 584 palm_data = (p[1] & 0x7f) |
585 ((p[2] & 0x7f) << 7) |
586 ((p[4] & 0x7f) << 14) |
587 ((p[5] & 0x7f) << 21) |
588 ((p[3] & 0x07) << 28) |
589 (((u64)p[3] & 0x70) << 27) |
590 (((u64)p[0] & 0x01) << 34);
591
592 /* Y-profile is stored in P(0) to p(n-1), n = y_bits; */
593 f->y_map = palm_data & (BIT(priv->y_bits) - 1);
594
595 /* X-profile is stored in p(n) to p(n+m-1), m = x_bits; */
596 f->x_map = (palm_data >> priv->y_bits) &
597 (BIT(priv->x_bits) - 1);
598 }
534} 599}
535 600
536static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) 601static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
537{ 602{
538 struct alps_data *priv = psmouse->private; 603 struct alps_data *priv = psmouse->private;
539 unsigned char *packet = psmouse->packet; 604 unsigned char *packet = psmouse->packet;
540 struct input_dev *dev = psmouse->dev; 605 struct input_dev *dev = psmouse->dev;
541 struct input_dev *dev2 = priv->dev2; 606 struct input_dev *dev2 = priv->dev2;
542 int x1 = 0, y1 = 0, x2 = 0, y2 = 0; 607 int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
543 int fingers = 0, bmap_fingers; 608 int fingers = 0, bmap_fn;
544 struct alps_fields f; 609 struct alps_fields f = {0};
545 610
546 priv->decode_fields(&f, packet); 611 priv->decode_fields(&f, packet, psmouse);
547 612
548 /* 613 /*
549 * There's no single feature of touchpad position and bitmap packets 614 * There's no single feature of touchpad position and bitmap packets
@@ -560,19 +625,38 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
560 */ 625 */
561 if (f.is_mp) { 626 if (f.is_mp) {
562 fingers = f.fingers; 627 fingers = f.fingers;
563 bmap_fingers = alps_process_bitmap(priv, 628 if (priv->proto_version == ALPS_PROTO_V3) {
564 f.x_map, f.y_map, 629 bmap_fn = alps_process_bitmap(priv, f.x_map,
565 &x1, &y1, &x2, &y2); 630 f.y_map, &x1, &y1,
566 631 &x2, &y2);
567 /* 632
568 * We shouldn't report more than one finger if 633 /*
569 * we don't have two coordinates. 634 * We shouldn't report more than one finger if
570 */ 635 * we don't have two coordinates.
571 if (fingers > 1 && bmap_fingers < 2) 636 */
572 fingers = bmap_fingers; 637 if (fingers > 1 && bmap_fn < 2)
573 638 fingers = bmap_fn;
574 /* Now process position packet */ 639
575 priv->decode_fields(&f, priv->multi_data); 640 /* Now process position packet */
641 priv->decode_fields(&f, priv->multi_data,
642 psmouse);
643 } else {
644 /*
645 * Because Dolphin uses position packet's
646 * coordinate data as Pt1 and uses it to
647 * calculate Pt2, so we need to do position
648 * packet decode first.
649 */
650 priv->decode_fields(&f, priv->multi_data,
651 psmouse);
652
653 /*
654 * Since Dolphin's finger number is reliable,
655 * there is no need to compare with bmap_fn.
656 */
657 alps_process_bitmap_dolphin(priv, &f, &x1, &y1,
658 &x2, &y2);
659 }
576 } else { 660 } else {
577 priv->multi_packet = 0; 661 priv->multi_packet = 0;
578 } 662 }
@@ -662,7 +746,7 @@ static void alps_process_packet_v3(struct psmouse *psmouse)
662 return; 746 return;
663 } 747 }
664 748
665 alps_process_touchpad_packet_v3(psmouse); 749 alps_process_touchpad_packet_v3_v5(psmouse);
666} 750}
667 751
668static void alps_process_packet_v6(struct psmouse *psmouse) 752static void alps_process_packet_v6(struct psmouse *psmouse)
@@ -1709,6 +1793,52 @@ error:
1709 return -1; 1793 return -1;
1710} 1794}
1711 1795
1796static int alps_dolphin_get_device_area(struct psmouse *psmouse,
1797 struct alps_data *priv)
1798{
1799 struct ps2dev *ps2dev = &psmouse->ps2dev;
1800 unsigned char param[4] = {0};
1801 int num_x_electrode, num_y_electrode;
1802
1803 if (alps_enter_command_mode(psmouse))
1804 return -1;
1805
1806 param[0] = 0x0a;
1807 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
1808 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL) ||
1809 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL) ||
1810 ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
1811 ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE))
1812 return -1;
1813
1814 if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
1815 return -1;
1816
1817 /*
1818 * Dolphin's sensor line number is not fixed. It can be calculated
1819 * by adding the device's register value with DOLPHIN_PROFILE_X/YOFFSET.
1820 * Further more, we can get device's x_max and y_max by multiplying
1821 * sensor line number with DOLPHIN_COUNT_PER_ELECTRODE.
1822 *
1823 * e.g. When we get register's sensor_x = 11 & sensor_y = 8,
1824 * real sensor line number X = 11 + 8 = 19, and
1825 * real sensor line number Y = 8 + 1 = 9.
1826 * So, x_max = (19 - 1) * 64 = 1152, and
1827 * y_max = (9 - 1) * 64 = 512.
1828 */
1829 num_x_electrode = DOLPHIN_PROFILE_XOFFSET + (param[2] & 0x0F);
1830 num_y_electrode = DOLPHIN_PROFILE_YOFFSET + ((param[2] >> 4) & 0x0F);
1831 priv->x_bits = num_x_electrode;
1832 priv->y_bits = num_y_electrode;
1833 priv->x_max = (num_x_electrode - 1) * DOLPHIN_COUNT_PER_ELECTRODE;
1834 priv->y_max = (num_y_electrode - 1) * DOLPHIN_COUNT_PER_ELECTRODE;
1835
1836 if (alps_exit_command_mode(psmouse))
1837 return -1;
1838
1839 return 0;
1840}
1841
1712static int alps_hw_init_dolphin_v1(struct psmouse *psmouse) 1842static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
1713{ 1843{
1714 struct ps2dev *ps2dev = &psmouse->ps2dev; 1844 struct ps2dev *ps2dev = &psmouse->ps2dev;
@@ -1763,13 +1893,13 @@ static void alps_set_defaults(struct alps_data *priv)
1763 break; 1893 break;
1764 case ALPS_PROTO_V5: 1894 case ALPS_PROTO_V5:
1765 priv->hw_init = alps_hw_init_dolphin_v1; 1895 priv->hw_init = alps_hw_init_dolphin_v1;
1766 priv->process_packet = alps_process_packet_v3; 1896 priv->process_packet = alps_process_touchpad_packet_v3_v5;
1767 priv->decode_fields = alps_decode_dolphin; 1897 priv->decode_fields = alps_decode_dolphin;
1768 priv->set_abs_params = alps_set_abs_params_mt; 1898 priv->set_abs_params = alps_set_abs_params_mt;
1769 priv->nibble_commands = alps_v3_nibble_commands; 1899 priv->nibble_commands = alps_v3_nibble_commands;
1770 priv->addr_command = PSMOUSE_CMD_RESET_WRAP; 1900 priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
1771 priv->byte0 = 0xc8; 1901 priv->byte0 = 0xc8;
1772 priv->mask0 = 0xc8; 1902 priv->mask0 = 0xd8;
1773 priv->flags = 0; 1903 priv->flags = 0;
1774 priv->x_max = 1360; 1904 priv->x_max = 1360;
1775 priv->y_max = 660; 1905 priv->y_max = 660;
@@ -1845,11 +1975,13 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
1845 if (alps_match_table(psmouse, priv, e7, ec) == 0) { 1975 if (alps_match_table(psmouse, priv, e7, ec) == 0) {
1846 return 0; 1976 return 0;
1847 } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 && 1977 } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
1848 ec[0] == 0x73 && ec[1] == 0x01) { 1978 ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) {
1849 priv->proto_version = ALPS_PROTO_V5; 1979 priv->proto_version = ALPS_PROTO_V5;
1850 alps_set_defaults(priv); 1980 alps_set_defaults(priv);
1851 1981 if (alps_dolphin_get_device_area(psmouse, priv))
1852 return 0; 1982 return -EIO;
1983 else
1984 return 0;
1853 } else if (ec[0] == 0x88 && ec[1] == 0x08) { 1985 } else if (ec[0] == 0x88 && ec[1] == 0x08) {
1854 priv->proto_version = ALPS_PROTO_V3; 1986 priv->proto_version = ALPS_PROTO_V3;
1855 alps_set_defaults(priv); 1987 alps_set_defaults(priv);
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 704f0f924307..03f88b6940c7 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -19,6 +19,10 @@
19#define ALPS_PROTO_V5 5 19#define ALPS_PROTO_V5 5
20#define ALPS_PROTO_V6 6 20#define ALPS_PROTO_V6 6
21 21
22#define DOLPHIN_COUNT_PER_ELECTRODE 64
23#define DOLPHIN_PROFILE_XOFFSET 8 /* x-electrode offset */
24#define DOLPHIN_PROFILE_YOFFSET 1 /* y-electrode offset */
25
22/** 26/**
23 * struct alps_model_info - touchpad ID table 27 * struct alps_model_info - touchpad ID table
24 * @signature: E7 response string to match. 28 * @signature: E7 response string to match.
@@ -146,7 +150,8 @@ struct alps_data {
146 150
147 int (*hw_init)(struct psmouse *psmouse); 151 int (*hw_init)(struct psmouse *psmouse);
148 void (*process_packet)(struct psmouse *psmouse); 152 void (*process_packet)(struct psmouse *psmouse);
149 void (*decode_fields)(struct alps_fields *f, unsigned char *p); 153 void (*decode_fields)(struct alps_fields *f, unsigned char *p,
154 struct psmouse *psmouse);
150 void (*set_abs_params)(struct alps_data *priv, struct input_dev *dev1); 155 void (*set_abs_params)(struct alps_data *priv, struct input_dev *dev1);
151 156
152 int prev_fin; 157 int prev_fin;