Commit fc69f4a6 authored by Tai-hwa Liang's avatar Tai-hwa Liang Committed by Dmitry Torokhov

Input: add new driver for Sentelic Finger Sensing Pad

This is the driver for Sentelic Finger Sensing Pad which can be found
on MSI WIND Netbook.
Signed-off-by: default avatarTai-hwa Liang <avatar@sentelic.com>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 3b720944
This diff is collapsed.
...@@ -107,6 +107,14 @@ config MOUSE_PS2_ELANTECH ...@@ -107,6 +107,14 @@ config MOUSE_PS2_ELANTECH
entries. For further information, entries. For further information,
see <file:Documentation/input/elantech.txt>. see <file:Documentation/input/elantech.txt>.
config MOUSE_PS2_SENTELIC
bool "Sentelic Finger Sensing Pad PS/2 protocol extension"
depends on MOUSE_PS2
help
Say Y here if you have a laptop (such as MSI WIND Netbook)
with Sentelic Finger Sensing Pad touchpad.
If unsure, say N.
config MOUSE_PS2_TOUCHKIT config MOUSE_PS2_TOUCHKIT
bool "eGalax TouchKit PS/2 protocol extension" bool "eGalax TouchKit PS/2 protocol extension"
......
...@@ -27,5 +27,6 @@ psmouse-$(CONFIG_MOUSE_PS2_ELANTECH) += elantech.o ...@@ -27,5 +27,6 @@ psmouse-$(CONFIG_MOUSE_PS2_ELANTECH) += elantech.o
psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o
psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o
psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o
psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o
psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "trackpoint.h" #include "trackpoint.h"
#include "touchkit_ps2.h" #include "touchkit_ps2.h"
#include "elantech.h" #include "elantech.h"
#include "sentelic.h"
#define DRIVER_DESC "PS/2 mouse driver" #define DRIVER_DESC "PS/2 mouse driver"
...@@ -666,6 +667,20 @@ static int psmouse_extensions(struct psmouse *psmouse, ...@@ -666,6 +667,20 @@ static int psmouse_extensions(struct psmouse *psmouse,
max_proto = PSMOUSE_IMEX; max_proto = PSMOUSE_IMEX;
} }
/*
* Try Finger Sensing Pad
*/
if (max_proto > PSMOUSE_IMEX) {
if (fsp_detect(psmouse, set_properties) == 0) {
if (!set_properties || fsp_init(psmouse) == 0)
return PSMOUSE_FSP;
/*
* Init failed, try basic relative protocols
*/
max_proto = PSMOUSE_IMEX;
}
}
if (max_proto > PSMOUSE_IMEX) { if (max_proto > PSMOUSE_IMEX) {
if (genius_detect(psmouse, set_properties) == 0) if (genius_detect(psmouse, set_properties) == 0)
return PSMOUSE_GENPS; return PSMOUSE_GENPS;
...@@ -813,7 +828,16 @@ static const struct psmouse_protocol psmouse_protocols[] = { ...@@ -813,7 +828,16 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.detect = elantech_detect, .detect = elantech_detect,
.init = elantech_init, .init = elantech_init,
}, },
#endif #endif
#ifdef CONFIG_MOUSE_PS2_SENTELIC
{
.type = PSMOUSE_FSP,
.name = "FSPPS/2",
.alias = "fsp",
.detect = fsp_detect,
.init = fsp_init,
},
#endif
{ {
.type = PSMOUSE_CORTRON, .type = PSMOUSE_CORTRON,
.name = "CortronPS/2", .name = "CortronPS/2",
......
...@@ -91,6 +91,7 @@ enum psmouse_type { ...@@ -91,6 +91,7 @@ enum psmouse_type {
PSMOUSE_CORTRON, PSMOUSE_CORTRON,
PSMOUSE_HGPK, PSMOUSE_HGPK,
PSMOUSE_ELANTECH, PSMOUSE_ELANTECH,
PSMOUSE_FSP,
PSMOUSE_AUTO /* This one should always be last */ PSMOUSE_AUTO /* This one should always be last */
}; };
......
This diff is collapsed.
/*-
* Finger Sensing Pad PS/2 mouse driver.
*
* Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
* Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __SENTELIC_H
#define __SENTELIC_H
/* Finger-sensing Pad information registers */
#define FSP_REG_DEVICE_ID 0x00
#define FSP_REG_VERSION 0x01
#define FSP_REG_REVISION 0x04
#define FSP_REG_TMOD_STATUS1 0x0B
#define FSP_BIT_NO_ROTATION BIT(3)
#define FSP_REG_PAGE_CTRL 0x0F
/* Finger-sensing Pad control registers */
#define FSP_REG_SYSCTL1 0x10
#define FSP_BIT_EN_REG_CLK BIT(5)
#define FSP_REG_OPC_QDOWN 0x31
#define FSP_BIT_EN_OPC_TAG BIT(7)
#define FSP_REG_OPTZ_XLO 0x34
#define FSP_REG_OPTZ_XHI 0x35
#define FSP_REG_OPTZ_YLO 0x36
#define FSP_REG_OPTZ_YHI 0x37
#define FSP_REG_SYSCTL5 0x40
#define FSP_BIT_90_DEGREE BIT(0)
#define FSP_BIT_EN_MSID6 BIT(1)
#define FSP_BIT_EN_MSID7 BIT(2)
#define FSP_BIT_EN_MSID8 BIT(3)
#define FSP_BIT_EN_AUTO_MSID8 BIT(5)
#define FSP_BIT_EN_PKT_G0 BIT(6)
#define FSP_REG_ONPAD_CTL 0x43
#define FSP_BIT_ONPAD_ENABLE BIT(0)
#define FSP_BIT_ONPAD_FBBB BIT(1)
#define FSP_BIT_FIX_VSCR BIT(3)
#define FSP_BIT_FIX_HSCR BIT(5)
#define FSP_BIT_DRAG_LOCK BIT(6)
/* Finger-sensing Pad packet formating related definitions */
/* absolute packet type */
#define FSP_PKT_TYPE_NORMAL (0x00)
#define FSP_PKT_TYPE_ABS (0x01)
#define FSP_PKT_TYPE_NOTIFY (0x02)
#define FSP_PKT_TYPE_NORMAL_OPC (0x03)
#define FSP_PKT_TYPE_SHIFT (6)
#ifdef __KERNEL__
struct fsp_data {
unsigned char ver; /* hardware version */
unsigned char rev; /* hardware revison */
unsigned char buttons; /* Number of buttons */
unsigned int flags;
#define FSPDRV_FLAG_EN_OPC (0x001) /* enable on-pad clicking */
bool vscroll; /* Vertical scroll zone enabled */
bool hscroll; /* Horizontal scroll zone enabled */
unsigned char last_reg; /* Last register we requested read from */
unsigned char last_val;
};
#ifdef CONFIG_MOUSE_PS2_SENTELIC
extern int fsp_detect(struct psmouse *psmouse, int set_properties);
extern int fsp_init(struct psmouse *psmouse);
#else
inline int fsp_detect(struct psmouse *psmouse, int set_properties)
{
return -ENOSYS;
}
inline int fsp_init(struct psmouse *psmouse)
{
return -ENOSYS;
}
#endif
#endif /* __KERNEL__ */
#endif /* !__SENTELIC_H */
...@@ -161,7 +161,7 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout) ...@@ -161,7 +161,7 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout)
* ps2_command() can only be called from a process context * ps2_command() can only be called from a process context
*/ */
int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
{ {
int timeout; int timeout;
int send = (command >> 12) & 0xf; int send = (command >> 12) & 0xf;
...@@ -179,8 +179,6 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) ...@@ -179,8 +179,6 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
return -1; return -1;
} }
mutex_lock(&ps2dev->cmd_mutex);
serio_pause_rx(ps2dev->serio); serio_pause_rx(ps2dev->serio);
ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
ps2dev->cmdcnt = receive; ps2dev->cmdcnt = receive;
...@@ -231,7 +229,18 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) ...@@ -231,7 +229,18 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
ps2dev->flags = 0; ps2dev->flags = 0;
serio_continue_rx(ps2dev->serio); serio_continue_rx(ps2dev->serio);
return rc;
}
EXPORT_SYMBOL(__ps2_command);
int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
{
int rc;
mutex_lock(&ps2dev->cmd_mutex);
rc = __ps2_command(ps2dev, param, command);
mutex_unlock(&ps2dev->cmd_mutex); mutex_unlock(&ps2dev->cmd_mutex);
return rc; return rc;
} }
EXPORT_SYMBOL(ps2_command); EXPORT_SYMBOL(ps2_command);
......
...@@ -44,6 +44,7 @@ struct ps2dev { ...@@ -44,6 +44,7 @@ struct ps2dev {
void ps2_init(struct ps2dev *ps2dev, struct serio *serio); void ps2_init(struct ps2dev *ps2dev, struct serio *serio);
int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout); int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout);
void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout); void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout);
int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data); int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);
int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data); int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment