aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
authorTai-hwa Liang <avatar@sentelic.com>2012-03-25 20:16:36 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-03-25 20:18:10 -0400
commita4c85075f00d56b38f5c277ab89f9aaad69eb17b (patch)
tree572cf90d91ec2315d10a5504191b4f8528bef2ce /drivers/input/mouse
parent3ac1780f9e6ed212e56d4132e997551297a97112 (diff)
Input: sentelic - enabling absolute coordinates output for newer hardware
- Hooking multi-finger coordinates output with kernel multitouch library; - Enabling absolute coordinates output for Cx+ hardware. The older hardware performs much better in relative mode; thus relative mode related code are preserved. Part of the code is based on the work done by Oskari Saarenmaa <os@ohmu.fi>, which was used to support the clickpad found on ASUS UX21/31 Ultrabook. On the other hand, the FSP found on UX21/31 doesn't have hardware capability register other than PnP ID, which means that we'll have to figure out an alternative approach to identify such pad correctly; otherwise, blindly adding INPUT_PROP_BUTTONPAD property may compatability issues amongst existing FSPs. Signed-off-by: Tai-hwa Liang <avatar@sentelic.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/sentelic.c114
-rw-r--r--drivers/input/mouse/sentelic.h22
2 files changed, 132 insertions, 4 deletions
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c
index 62fa69825671..5ea5c689d262 100644
--- a/drivers/input/mouse/sentelic.c
+++ b/drivers/input/mouse/sentelic.c
@@ -2,7 +2,7 @@
2 * Finger Sensing Pad PS/2 mouse driver. 2 * Finger Sensing Pad PS/2 mouse driver.
3 * 3 *
4 * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. 4 * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
5 * Copyright (C) 2005-2011 Tai-hwa Liang, Sentelic Corporation. 5 * Copyright (C) 2005-2012 Tai-hwa Liang, Sentelic Corporation.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -21,6 +21,7 @@
21 21
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/input.h> 23#include <linux/input.h>
24#include <linux/input/mt.h>
24#include <linux/ctype.h> 25#include <linux/ctype.h>
25#include <linux/libps2.h> 26#include <linux/libps2.h>
26#include <linux/serio.h> 27#include <linux/serio.h>
@@ -643,12 +644,24 @@ static void fsp_packet_debug(unsigned char packet[])
643} 644}
644#endif 645#endif
645 646
647static void fsp_set_slot(struct input_dev *dev, int slot, bool active,
648 unsigned int x, unsigned int y)
649{
650 input_mt_slot(dev, slot);
651 input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
652 if (active) {
653 input_report_abs(dev, ABS_MT_POSITION_X, x);
654 input_report_abs(dev, ABS_MT_POSITION_Y, y);
655 }
656}
657
646static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) 658static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
647{ 659{
648 struct input_dev *dev = psmouse->dev; 660 struct input_dev *dev = psmouse->dev;
649 struct fsp_data *ad = psmouse->private; 661 struct fsp_data *ad = psmouse->private;
650 unsigned char *packet = psmouse->packet; 662 unsigned char *packet = psmouse->packet;
651 unsigned char button_status = 0, lscroll = 0, rscroll = 0; 663 unsigned char button_status = 0, lscroll = 0, rscroll = 0;
664 unsigned short abs_x, abs_y, fgrs = 0;
652 int rel_x, rel_y; 665 int rel_x, rel_y;
653 666
654 if (psmouse->pktcnt < 4) 667 if (psmouse->pktcnt < 4)
@@ -660,8 +673,66 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
660 673
661 switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { 674 switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
662 case FSP_PKT_TYPE_ABS: 675 case FSP_PKT_TYPE_ABS:
663 psmouse_warn(psmouse, 676 abs_x = (packet[1] << 2) | ((packet[3] >> 2) & 0x03);
664 "Unexpected absolute mode packet, ignored.\n"); 677 abs_y = (packet[2] << 2) | (packet[3] & 0x03);
678
679 if (packet[0] & FSP_PB0_MFMC) {
680 /*
681 * MFMC packet: assume that there are two fingers on
682 * pad
683 */
684 fgrs = 2;
685
686 /* MFMC packet */
687 if (packet[0] & FSP_PB0_MFMC_FGR2) {
688 /* 2nd finger */
689 if (ad->last_mt_fgr == 2) {
690 /*
691 * workaround for buggy firmware
692 * which doesn't clear MFMC bit if
693 * the 1st finger is up
694 */
695 fgrs = 1;
696 fsp_set_slot(dev, 0, false, 0, 0);
697 }
698 ad->last_mt_fgr = 2;
699
700 fsp_set_slot(dev, 1, fgrs == 2, abs_x, abs_y);
701 } else {
702 /* 1st finger */
703 if (ad->last_mt_fgr == 1) {
704 /*
705 * workaround for buggy firmware
706 * which doesn't clear MFMC bit if
707 * the 2nd finger is up
708 */
709 fgrs = 1;
710 fsp_set_slot(dev, 1, false, 0, 0);
711 }
712 ad->last_mt_fgr = 1;
713 fsp_set_slot(dev, 0, fgrs != 0, abs_x, abs_y);
714 }
715 } else {
716 /* SFAC packet */
717
718 /* no multi-finger information */
719 ad->last_mt_fgr = 0;
720
721 if (abs_x != 0 && abs_y != 0)
722 fgrs = 1;
723
724 fsp_set_slot(dev, 0, fgrs > 0, abs_x, abs_y);
725 fsp_set_slot(dev, 1, false, 0, 0);
726 }
727 if (fgrs > 0) {
728 input_report_abs(dev, ABS_X, abs_x);
729 input_report_abs(dev, ABS_Y, abs_y);
730 }
731 input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
732 input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
733 input_report_key(dev, BTN_TOUCH, fgrs);
734 input_report_key(dev, BTN_TOOL_FINGER, fgrs == 1);
735 input_report_key(dev, BTN_TOOL_DOUBLETAP, fgrs == 2);
665 break; 736 break;
666 737
667 case FSP_PKT_TYPE_NORMAL_OPC: 738 case FSP_PKT_TYPE_NORMAL_OPC:
@@ -785,6 +856,17 @@ static int fsp_activate_protocol(struct psmouse *psmouse)
785 /* Enable on-pad vertical and horizontal scrolling */ 856 /* Enable on-pad vertical and horizontal scrolling */
786 fsp_onpad_vscr(psmouse, true); 857 fsp_onpad_vscr(psmouse, true);
787 fsp_onpad_hscr(psmouse, true); 858 fsp_onpad_hscr(psmouse, true);
859 } else {
860 /* Enable absolute coordinates output for Cx/Dx hardware */
861 if (fsp_reg_write(psmouse, FSP_REG_SWC1,
862 FSP_BIT_SWC1_EN_ABS_1F |
863 FSP_BIT_SWC1_EN_ABS_2F |
864 FSP_BIT_SWC1_EN_FUP_OUT |
865 FSP_BIT_SWC1_EN_ABS_CON)) {
866 psmouse_err(psmouse,
867 "Unable to enable absolute coordinates output.\n");
868 return -EIO;
869 }
788 } 870 }
789 871
790 return 0; 872 return 0;
@@ -801,6 +883,32 @@ static int fsp_set_input_params(struct psmouse *psmouse)
801 __set_bit(BTN_FORWARD, dev->keybit); 883 __set_bit(BTN_FORWARD, dev->keybit);
802 __set_bit(REL_WHEEL, dev->relbit); 884 __set_bit(REL_WHEEL, dev->relbit);
803 __set_bit(REL_HWHEEL, dev->relbit); 885 __set_bit(REL_HWHEEL, dev->relbit);
886 } else {
887 /*
888 * Hardware prior to Cx performs much better in relative mode;
889 * hence, only enable absolute coordinates output as well as
890 * multi-touch output for the newer hardware.
891 *
892 * Maximum coordinates can be computed as:
893 *
894 * number of scanlines * 64 - 57
895 *
896 * where number of X/Y scanline lines are 16/12.
897 */
898 int abs_x = 967, abs_y = 711;
899
900 __set_bit(EV_ABS, dev->evbit);
901 __clear_bit(EV_REL, dev->evbit);
902 __set_bit(BTN_TOUCH, dev->keybit);
903 __set_bit(BTN_TOOL_FINGER, dev->keybit);
904 __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
905 __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
906
907 input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0);
908 input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0);
909 input_mt_init_slots(dev, 2);
910 input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0);
911 input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0);
804 } 912 }
805 913
806 return 0; 914 return 0;
diff --git a/drivers/input/mouse/sentelic.h b/drivers/input/mouse/sentelic.h
index 23bd25e539ba..334de19e5ddb 100644
--- a/drivers/input/mouse/sentelic.h
+++ b/drivers/input/mouse/sentelic.h
@@ -2,7 +2,7 @@
2 * Finger Sensing Pad PS/2 mouse driver. 2 * Finger Sensing Pad PS/2 mouse driver.
3 * 3 *
4 * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd. 4 * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
5 * Copyright (C) 2005-2011 Tai-hwa Liang, Sentelic Corporation. 5 * Copyright (C) 2005-2012 Tai-hwa Liang, Sentelic Corporation.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -55,6 +55,16 @@
55#define FSP_BIT_FIX_HSCR BIT(5) 55#define FSP_BIT_FIX_HSCR BIT(5)
56#define FSP_BIT_DRAG_LOCK BIT(6) 56#define FSP_BIT_DRAG_LOCK BIT(6)
57 57
58#define FSP_REG_SWC1 (0x90)
59#define FSP_BIT_SWC1_EN_ABS_1F BIT(0)
60#define FSP_BIT_SWC1_EN_GID BIT(1)
61#define FSP_BIT_SWC1_EN_ABS_2F BIT(2)
62#define FSP_BIT_SWC1_EN_FUP_OUT BIT(3)
63#define FSP_BIT_SWC1_EN_ABS_CON BIT(4)
64#define FSP_BIT_SWC1_GST_GRP0 BIT(5)
65#define FSP_BIT_SWC1_GST_GRP1 BIT(6)
66#define FSP_BIT_SWC1_BX_COMPAT BIT(7)
67
58/* Finger-sensing Pad packet formating related definitions */ 68/* Finger-sensing Pad packet formating related definitions */
59 69
60/* absolute packet type */ 70/* absolute packet type */
@@ -64,6 +74,15 @@
64#define FSP_PKT_TYPE_NORMAL_OPC (0x03) 74#define FSP_PKT_TYPE_NORMAL_OPC (0x03)
65#define FSP_PKT_TYPE_SHIFT (6) 75#define FSP_PKT_TYPE_SHIFT (6)
66 76
77/* bit definitions for the first byte of report packet */
78#define FSP_PB0_LBTN BIT(0)
79#define FSP_PB0_RBTN BIT(1)
80#define FSP_PB0_MBTN BIT(2)
81#define FSP_PB0_MFMC_FGR2 FSP_PB0_MBTN
82#define FSP_PB0_MUST_SET BIT(3)
83#define FSP_PB0_PHY_BTN BIT(4)
84#define FSP_PB0_MFMC BIT(5)
85
67/* hardware revisions */ 86/* hardware revisions */
68#define FSP_VER_STL3888_A4 (0xC1) 87#define FSP_VER_STL3888_A4 (0xC1)
69#define FSP_VER_STL3888_B0 (0xD0) 88#define FSP_VER_STL3888_B0 (0xD0)
@@ -89,6 +108,7 @@ struct fsp_data {
89 108
90 unsigned char last_reg; /* Last register we requested read from */ 109 unsigned char last_reg; /* Last register we requested read from */
91 unsigned char last_val; 110 unsigned char last_val;
111 unsigned int last_mt_fgr; /* Last seen finger(multitouch) */
92}; 112};
93 113
94#ifdef CONFIG_MOUSE_PS2_SENTELIC 114#ifdef CONFIG_MOUSE_PS2_SENTELIC