Commit df08ef27 authored by Andres Salomon's avatar Andres Salomon Committed by Dmitry Torokhov

Input: psmouse - add OLPC touchpad driver

This adds support for OLPC's touchpad.  It has lots of neat features,
none of which are enabled because the hardware is too buggy.  Instead,
we use it like a normal touchpad, but with a number of workarounds in
place to deal with the frequent hardware spasms.  Humidity changes,
sweat, tinfoil underwear, plugging in AC, drinks, evil felines.. All
tend to cause the touchpad to freak out.
Signed-off-by: default avatarAndres Salomon <dilinger@debian.org>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 68d48221
...@@ -96,6 +96,16 @@ config MOUSE_PS2_TOUCHKIT ...@@ -96,6 +96,16 @@ config MOUSE_PS2_TOUCHKIT
If unsure, say N. If unsure, say N.
config MOUSE_PS2_OLPC
bool "OLPC PS/2 mouse protocol extension"
depends on MOUSE_PS2 && OLPC
help
Say Y here if you have an OLPC XO-1 laptop (with built-in
PS/2 touchpad/tablet device). The manufacturer calls the
touchpad an HGPK.
If unsure, say N.
config MOUSE_SERIAL config MOUSE_SERIAL
tristate "Serial mouse" tristate "Serial mouse"
select SERIO select SERIO
......
...@@ -20,6 +20,7 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o ...@@ -20,6 +20,7 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
psmouse-objs := psmouse-base.o synaptics.o psmouse-objs := psmouse-base.o synaptics.o
psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.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_TRACKPOINT) += trackpoint.o psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
......
This diff is collapsed.
/*
* OLPC HGPK (XO-1) touchpad PS/2 mouse driver
*/
#ifndef _HGPK_H
#define _HGPK_H
enum hgpk_model_t {
HGPK_MODEL_PREA = 0x0a, /* pre-B1s */
HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */
HGPK_MODEL_B = 0x28, /* B2s, has capacitance issues */
HGPK_MODEL_C = 0x3c,
HGPK_MODEL_D = 0x50, /* C1, mass production */
};
struct hgpk_data {
struct psmouse *psmouse;
int powered;
int count, x_tally, y_tally; /* hardware workaround stuff */
unsigned long recalib_window;
struct delayed_work recalib_wq;
};
#define hgpk_dbg(psmouse, format, arg...) \
dev_dbg(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#define hgpk_err(psmouse, format, arg...) \
dev_err(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#define hgpk_info(psmouse, format, arg...) \
dev_info(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#define hgpk_warn(psmouse, format, arg...) \
dev_warn(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#define hgpk_notice(psmouse, format, arg...) \
dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)
#ifdef CONFIG_MOUSE_PS2_OLPC
int hgpk_detect(struct psmouse *psmouse, int set_properties);
int hgpk_init(struct psmouse *psmouse);
#else
static inline int hgpk_detect(struct psmouse *psmouse, int set_properties)
{
return -ENODEV;
}
static inline int hgpk_init(struct psmouse *psmouse)
{
return -ENODEV;
}
#endif
#endif
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "synaptics.h" #include "synaptics.h"
#include "logips2pp.h" #include "logips2pp.h"
#include "alps.h" #include "alps.h"
#include "hgpk.h"
#include "lifebook.h" #include "lifebook.h"
#include "trackpoint.h" #include "trackpoint.h"
#include "touchkit_ps2.h" #include "touchkit_ps2.h"
...@@ -636,8 +637,20 @@ static int psmouse_extensions(struct psmouse *psmouse, ...@@ -636,8 +637,20 @@ static int psmouse_extensions(struct psmouse *psmouse,
} }
} }
if (max_proto > PSMOUSE_IMEX) { /*
* Try OLPC HGPK touchpad.
*/
if (max_proto > PSMOUSE_IMEX &&
hgpk_detect(psmouse, set_properties) == 0) {
if (!set_properties || hgpk_init(psmouse) == 0)
return PSMOUSE_HGPK;
/*
* Init failed, try basic relative protocols
*/
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;
...@@ -767,6 +780,14 @@ static const struct psmouse_protocol psmouse_protocols[] = { ...@@ -767,6 +780,14 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.alias = "touchkit", .alias = "touchkit",
.detect = touchkit_ps2_detect, .detect = touchkit_ps2_detect,
}, },
#endif
#ifdef CONFIG_MOUSE_PS2_OLPC
{
.type = PSMOUSE_HGPK,
.name = "OLPC HGPK",
.alias = "hgpk",
.detect = hgpk_detect,
},
#endif #endif
{ {
.type = PSMOUSE_CORTRON, .type = PSMOUSE_CORTRON,
......
...@@ -89,6 +89,7 @@ enum psmouse_type { ...@@ -89,6 +89,7 @@ enum psmouse_type {
PSMOUSE_TRACKPOINT, PSMOUSE_TRACKPOINT,
PSMOUSE_TOUCHKIT_PS2, PSMOUSE_TOUCHKIT_PS2,
PSMOUSE_CORTRON, PSMOUSE_CORTRON,
PSMOUSE_HGPK,
PSMOUSE_AUTO /* This one should always be last */ PSMOUSE_AUTO /* This one should always be last */
}; };
...@@ -99,7 +100,6 @@ int psmouse_reset(struct psmouse *psmouse); ...@@ -99,7 +100,6 @@ int psmouse_reset(struct psmouse *psmouse);
void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state); void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state);
void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution); void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution);
struct psmouse_attribute { struct psmouse_attribute {
struct device_attribute dattr; struct device_attribute dattr;
void *data; void *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