Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (64 commits) Input: tc3589x-keypad - add missing kerneldoc Input: ucb1400-ts - switch to using dev_xxx() for diagnostic messages Input: ucb1400_ts - convert to threaded IRQ Input: ucb1400_ts - drop inline annotations Input: usb1400_ts - add __devinit/__devexit section annotations Input: ucb1400_ts - set driver owner Input: ucb1400_ts - convert to use dev_pm_ops Input: psmouse - make sure we do not use stale methods Input: evdev - do not block waiting for an event if fd is nonblock Input: evdev - if no events and non-block, return EAGAIN not 0 Input: evdev - only allow reading events if a full packet is present Input: add driver for pixcir i2c touchscreens Input: samsung-keypad - implement runtime power management support Input: tegra-kbc - report wakeup key for some platforms Input: tegra-kbc - add device tree bindings Input: add driver for AUO In-Cell touchscreens using pixcir ICs Input: mpu3050 - configure the sampling method Input: mpu3050 - ensure we enable interrupts Input: mpu3050 - add of_match table for device-tree probing Input: sentelic - document the latest hardware ... Fix up fairly trivial conflicts (device tree matching conflicting with some independent cleanups) in drivers/input/keyboard/samsung-keypad.c
This commit is contained in:
commit
dbe950f201
132 changed files with 5550 additions and 1645 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -12,20 +12,39 @@
|
|||
#ifndef _ALPS_H
|
||||
#define _ALPS_H
|
||||
|
||||
#define ALPS_PROTO_V1 0
|
||||
#define ALPS_PROTO_V2 1
|
||||
#define ALPS_PROTO_V3 2
|
||||
#define ALPS_PROTO_V4 3
|
||||
|
||||
struct alps_model_info {
|
||||
unsigned char signature[3];
|
||||
unsigned char command_mode_resp; /* v3/v4 only */
|
||||
unsigned char proto_version;
|
||||
unsigned char byte0, mask0;
|
||||
unsigned char flags;
|
||||
};
|
||||
|
||||
struct alps_nibble_commands {
|
||||
int command;
|
||||
unsigned char data;
|
||||
};
|
||||
|
||||
struct alps_data {
|
||||
struct input_dev *dev2; /* Relative device */
|
||||
char phys[32]; /* Phys */
|
||||
const struct alps_model_info *i;/* Info */
|
||||
const struct alps_nibble_commands *nibble_commands;
|
||||
int addr_command; /* Command to set register address */
|
||||
int prev_fin; /* Finger bit from previous packet */
|
||||
int multi_packet; /* Multi-packet data in progress */
|
||||
unsigned char multi_data[6]; /* Saved multi-packet data */
|
||||
u8 quirks;
|
||||
struct timer_list timer;
|
||||
};
|
||||
|
||||
#define ALPS_QUIRK_TRACKSTICK_BUTTONS 1 /* trakcstick buttons in trackstick packet */
|
||||
|
||||
#ifdef CONFIG_MOUSE_PS2_ALPS
|
||||
int alps_detect(struct psmouse *psmouse, bool set_properties);
|
||||
int alps_init(struct psmouse *psmouse);
|
||||
|
|
|
|||
|
|
@ -140,25 +140,13 @@ static int __exit amimouse_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static struct platform_driver amimouse_driver = {
|
||||
.probe = amimouse_probe,
|
||||
.remove = __exit_p(amimouse_remove),
|
||||
.driver = {
|
||||
.name = "amiga-mouse",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init amimouse_init(void)
|
||||
{
|
||||
return platform_driver_probe(&amimouse_driver, amimouse_probe);
|
||||
}
|
||||
|
||||
module_init(amimouse_init);
|
||||
|
||||
static void __exit amimouse_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&amimouse_driver);
|
||||
}
|
||||
|
||||
module_exit(amimouse_exit);
|
||||
module_platform_driver(amimouse_driver);
|
||||
|
||||
MODULE_ALIAS("platform:amiga-mouse");
|
||||
|
|
|
|||
|
|
@ -42,6 +42,24 @@ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* V3 and later support this fast command
|
||||
*/
|
||||
static int elantech_send_cmd(struct psmouse *psmouse, unsigned char c,
|
||||
unsigned char *param)
|
||||
{
|
||||
struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
|
||||
if (ps2_command(ps2dev, NULL, ETP_PS2_CUSTOM_COMMAND) ||
|
||||
ps2_command(ps2dev, NULL, c) ||
|
||||
ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
|
||||
psmouse_err(psmouse, "%s query 0x%02x failed.\n", __func__, c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A retrying version of ps2_command
|
||||
*/
|
||||
|
|
@ -863,13 +881,13 @@ static int elantech_set_range(struct psmouse *psmouse,
|
|||
i = (etd->fw_version > 0x020800 &&
|
||||
etd->fw_version < 0x020900) ? 1 : 2;
|
||||
|
||||
if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
|
||||
if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
|
||||
return -1;
|
||||
|
||||
fixed_dpi = param[1] & 0x10;
|
||||
|
||||
if (((etd->fw_version >> 16) == 0x14) && fixed_dpi) {
|
||||
if (synaptics_send_cmd(psmouse, ETP_SAMPLE_QUERY, param))
|
||||
if (etd->send_cmd(psmouse, ETP_SAMPLE_QUERY, param))
|
||||
return -1;
|
||||
|
||||
*x_max = (etd->capabilities[1] - i) * param[1] / 2;
|
||||
|
|
@ -888,7 +906,7 @@ static int elantech_set_range(struct psmouse *psmouse,
|
|||
break;
|
||||
|
||||
case 3:
|
||||
if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
|
||||
if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
|
||||
return -1;
|
||||
|
||||
*x_max = (0x0f & param[0]) << 8 | param[1];
|
||||
|
|
@ -896,7 +914,7 @@ static int elantech_set_range(struct psmouse *psmouse,
|
|||
break;
|
||||
|
||||
case 4:
|
||||
if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
|
||||
if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param))
|
||||
return -1;
|
||||
|
||||
*x_max = (0x0f & param[0]) << 8 | param[1];
|
||||
|
|
@ -912,6 +930,30 @@ static int elantech_set_range(struct psmouse *psmouse,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* (value from firmware) * 10 + 790 = dpi
|
||||
* we also have to convert dpi to dots/mm (*10/254 to avoid floating point)
|
||||
*/
|
||||
static unsigned int elantech_convert_res(unsigned int val)
|
||||
{
|
||||
return (val * 10 + 790) * 10 / 254;
|
||||
}
|
||||
|
||||
static int elantech_get_resolution_v4(struct psmouse *psmouse,
|
||||
unsigned int *x_res,
|
||||
unsigned int *y_res)
|
||||
{
|
||||
unsigned char param[3];
|
||||
|
||||
if (elantech_send_cmd(psmouse, ETP_RESOLUTION_QUERY, param))
|
||||
return -1;
|
||||
|
||||
*x_res = elantech_convert_res(param[1] & 0x0f);
|
||||
*y_res = elantech_convert_res((param[1] & 0xf0) >> 4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the appropriate event bits for the input subsystem
|
||||
*/
|
||||
|
|
@ -920,6 +962,7 @@ static int elantech_set_input_params(struct psmouse *psmouse)
|
|||
struct input_dev *dev = psmouse->dev;
|
||||
struct elantech_data *etd = psmouse->private;
|
||||
unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, width = 0;
|
||||
unsigned int x_res = 0, y_res = 0;
|
||||
|
||||
if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width))
|
||||
return -1;
|
||||
|
|
@ -967,10 +1010,20 @@ static int elantech_set_input_params(struct psmouse *psmouse)
|
|||
break;
|
||||
|
||||
case 4:
|
||||
if (elantech_get_resolution_v4(psmouse, &x_res, &y_res)) {
|
||||
/*
|
||||
* if query failed, print a warning and leave the values
|
||||
* zero to resemble synaptics.c behavior.
|
||||
*/
|
||||
psmouse_warn(psmouse, "couldn't query resolution data.\n");
|
||||
}
|
||||
|
||||
__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
|
||||
/* For X to recognize me as touchpad. */
|
||||
input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
|
||||
input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0);
|
||||
input_abs_set_res(dev, ABS_X, x_res);
|
||||
input_abs_set_res(dev, ABS_Y, y_res);
|
||||
/*
|
||||
* range of pressure and width is the same as v2,
|
||||
* report ABS_PRESSURE, ABS_TOOL_WIDTH for compatibility.
|
||||
|
|
@ -983,6 +1036,8 @@ static int elantech_set_input_params(struct psmouse *psmouse)
|
|||
input_mt_init_slots(dev, ETP_MAX_FINGERS);
|
||||
input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0);
|
||||
input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0);
|
||||
input_abs_set_res(dev, ABS_MT_POSITION_X, x_res);
|
||||
input_abs_set_res(dev, ABS_MT_POSITION_Y, y_res);
|
||||
input_set_abs_params(dev, ABS_MT_PRESSURE, ETP_PMIN_V2,
|
||||
ETP_PMAX_V2, 0, 0);
|
||||
/*
|
||||
|
|
@ -1031,16 +1086,13 @@ static ssize_t elantech_set_int_attr(struct psmouse *psmouse,
|
|||
struct elantech_data *etd = psmouse->private;
|
||||
struct elantech_attr_data *attr = data;
|
||||
unsigned char *reg = (unsigned char *) etd + attr->field_offset;
|
||||
unsigned long value;
|
||||
unsigned char value;
|
||||
int err;
|
||||
|
||||
err = strict_strtoul(buf, 16, &value);
|
||||
err = kstrtou8(buf, 16, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (value > 0xff)
|
||||
return -EINVAL;
|
||||
|
||||
/* Do we need to preserve some bits for version 2 hardware too? */
|
||||
if (etd->hw_version == 1) {
|
||||
if (attr->reg == 0x10)
|
||||
|
|
@ -1233,9 +1285,11 @@ static int elantech_set_properties(struct elantech_data *etd)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn on packet checking by default.
|
||||
*/
|
||||
/* decide which send_cmd we're gonna use early */
|
||||
etd->send_cmd = etd->hw_version >= 3 ? elantech_send_cmd :
|
||||
synaptics_send_cmd;
|
||||
|
||||
/* Turn on packet checking by default */
|
||||
etd->paritycheck = 1;
|
||||
|
||||
/*
|
||||
|
|
@ -1291,7 +1345,7 @@ int elantech_init(struct psmouse *psmouse)
|
|||
"assuming hardware version %d (with firmware version 0x%02x%02x%02x)\n",
|
||||
etd->hw_version, param[0], param[1], param[2]);
|
||||
|
||||
if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY,
|
||||
if (etd->send_cmd(psmouse, ETP_CAPABILITIES_QUERY,
|
||||
etd->capabilities)) {
|
||||
psmouse_err(psmouse, "failed to query capabilities.\n");
|
||||
goto init_fail;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#define ETP_FW_VERSION_QUERY 0x01
|
||||
#define ETP_CAPABILITIES_QUERY 0x02
|
||||
#define ETP_SAMPLE_QUERY 0x03
|
||||
#define ETP_RESOLUTION_QUERY 0x04
|
||||
|
||||
/*
|
||||
* Command values for register reading or writing
|
||||
|
|
@ -135,6 +136,7 @@ struct elantech_data {
|
|||
unsigned int width;
|
||||
struct finger_pos mt[ETP_MAX_FINGERS];
|
||||
unsigned char parity[256];
|
||||
int (*send_cmd)(struct psmouse *psmouse, unsigned char c, unsigned char *param);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MOUSE_PS2_ELANTECH
|
||||
|
|
|
|||
|
|
@ -178,18 +178,7 @@ static struct platform_driver gpio_mouse_device_driver = {
|
|||
.owner = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init gpio_mouse_init(void)
|
||||
{
|
||||
return platform_driver_register(&gpio_mouse_device_driver);
|
||||
}
|
||||
module_init(gpio_mouse_init);
|
||||
|
||||
static void __exit gpio_mouse_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&gpio_mouse_device_driver);
|
||||
}
|
||||
module_exit(gpio_mouse_exit);
|
||||
module_platform_driver(gpio_mouse_device_driver);
|
||||
|
||||
MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
|
||||
MODULE_DESCRIPTION("GPIO mouse driver");
|
||||
|
|
|
|||
|
|
@ -789,11 +789,14 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
|
|||
const char *buf, size_t count)
|
||||
{
|
||||
struct hgpk_data *priv = psmouse->private;
|
||||
unsigned long value;
|
||||
unsigned int value;
|
||||
int err;
|
||||
|
||||
err = strict_strtoul(buf, 10, &value);
|
||||
if (err || value > 1)
|
||||
err = kstrtouint(buf, 10, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (value > 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (value != priv->powered) {
|
||||
|
|
@ -881,11 +884,14 @@ static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data,
|
|||
const char *buf, size_t count)
|
||||
{
|
||||
struct hgpk_data *priv = psmouse->private;
|
||||
unsigned long value;
|
||||
unsigned int value;
|
||||
int err;
|
||||
|
||||
err = strict_strtoul(buf, 10, &value);
|
||||
if (err || value != 1)
|
||||
err = kstrtouint(buf, 10, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (value != 1)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -155,9 +155,14 @@ static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse,
|
|||
static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long value;
|
||||
unsigned int value;
|
||||
int err;
|
||||
|
||||
if (strict_strtoul(buf, 10, &value) || value > 1)
|
||||
err = kstrtouint(buf, 10, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (value > 1)
|
||||
return -EINVAL;
|
||||
|
||||
ps2pp_set_smartscroll(psmouse, value);
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ struct psmouse_protocol {
|
|||
* relevant events to the input module once full packet has arrived.
|
||||
*/
|
||||
|
||||
static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
|
||||
psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
|
||||
{
|
||||
struct input_dev *dev = psmouse->dev;
|
||||
unsigned char *packet = psmouse->packet;
|
||||
|
|
@ -418,6 +418,49 @@ int psmouse_reset(struct psmouse *psmouse)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we set the mouse resolution.
|
||||
*/
|
||||
|
||||
void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
|
||||
{
|
||||
static const unsigned char params[] = { 0, 1, 2, 2, 3 };
|
||||
unsigned char p;
|
||||
|
||||
if (resolution == 0 || resolution > 200)
|
||||
resolution = 200;
|
||||
|
||||
p = params[resolution / 50];
|
||||
ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
|
||||
psmouse->resolution = 25 << p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we set the mouse report rate.
|
||||
*/
|
||||
|
||||
static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
|
||||
{
|
||||
static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
|
||||
unsigned char r;
|
||||
int i = 0;
|
||||
|
||||
while (rates[i] > rate) i++;
|
||||
r = rates[i];
|
||||
ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE);
|
||||
psmouse->rate = r;
|
||||
}
|
||||
|
||||
/*
|
||||
* psmouse_poll() - default poll handler. Everyone except for ALPS uses it.
|
||||
*/
|
||||
|
||||
static int psmouse_poll(struct psmouse *psmouse)
|
||||
{
|
||||
return ps2_command(&psmouse->ps2dev, psmouse->packet,
|
||||
PSMOUSE_CMD_POLL | (psmouse->pktsize << 8));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Genius NetMouse magic init.
|
||||
|
|
@ -602,6 +645,56 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply default settings to the psmouse structure. Most of them will
|
||||
* be overridden by individual protocol initialization routines.
|
||||
*/
|
||||
|
||||
static void psmouse_apply_defaults(struct psmouse *psmouse)
|
||||
{
|
||||
struct input_dev *input_dev = psmouse->dev;
|
||||
|
||||
memset(input_dev->evbit, 0, sizeof(input_dev->evbit));
|
||||
memset(input_dev->keybit, 0, sizeof(input_dev->keybit));
|
||||
memset(input_dev->relbit, 0, sizeof(input_dev->relbit));
|
||||
memset(input_dev->absbit, 0, sizeof(input_dev->absbit));
|
||||
memset(input_dev->mscbit, 0, sizeof(input_dev->mscbit));
|
||||
|
||||
__set_bit(EV_KEY, input_dev->evbit);
|
||||
__set_bit(EV_REL, input_dev->evbit);
|
||||
|
||||
__set_bit(BTN_LEFT, input_dev->keybit);
|
||||
__set_bit(BTN_RIGHT, input_dev->keybit);
|
||||
|
||||
__set_bit(REL_X, input_dev->relbit);
|
||||
__set_bit(REL_Y, input_dev->relbit);
|
||||
|
||||
psmouse->set_rate = psmouse_set_rate;
|
||||
psmouse->set_resolution = psmouse_set_resolution;
|
||||
psmouse->poll = psmouse_poll;
|
||||
psmouse->protocol_handler = psmouse_process_byte;
|
||||
psmouse->pktsize = 3;
|
||||
psmouse->reconnect = NULL;
|
||||
psmouse->disconnect = NULL;
|
||||
psmouse->cleanup = NULL;
|
||||
psmouse->pt_activate = NULL;
|
||||
psmouse->pt_deactivate = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply default settings to the psmouse structure and call specified
|
||||
* protocol detection or initialization routine.
|
||||
*/
|
||||
static int psmouse_do_detect(int (*detect)(struct psmouse *psmouse,
|
||||
bool set_properties),
|
||||
struct psmouse *psmouse, bool set_properties)
|
||||
{
|
||||
if (set_properties)
|
||||
psmouse_apply_defaults(psmouse);
|
||||
|
||||
return detect(psmouse, set_properties);
|
||||
}
|
||||
|
||||
/*
|
||||
* psmouse_extensions() probes for any extensions to the basic PS/2 protocol
|
||||
* the mouse may have.
|
||||
|
|
@ -616,7 +709,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|||
* We always check for lifebook because it does not disturb mouse
|
||||
* (it only checks DMI information).
|
||||
*/
|
||||
if (lifebook_detect(psmouse, set_properties) == 0) {
|
||||
if (psmouse_do_detect(lifebook_detect, psmouse, set_properties) == 0) {
|
||||
if (max_proto > PSMOUSE_IMEX) {
|
||||
if (!set_properties || lifebook_init(psmouse) == 0)
|
||||
return PSMOUSE_LIFEBOOK;
|
||||
|
|
@ -628,15 +721,18 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|||
* upsets the thinkingmouse).
|
||||
*/
|
||||
|
||||
if (max_proto > PSMOUSE_IMEX && thinking_detect(psmouse, set_properties) == 0)
|
||||
if (max_proto > PSMOUSE_IMEX &&
|
||||
psmouse_do_detect(thinking_detect, psmouse, set_properties) == 0) {
|
||||
return PSMOUSE_THINKPS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol
|
||||
* support is disabled in config - we need to know if it is synaptics so we
|
||||
* can reset it properly after probing for intellimouse.
|
||||
*/
|
||||
if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) {
|
||||
if (max_proto > PSMOUSE_PS2 &&
|
||||
psmouse_do_detect(synaptics_detect, psmouse, set_properties) == 0) {
|
||||
synaptics_hardware = true;
|
||||
|
||||
if (max_proto > PSMOUSE_IMEX) {
|
||||
|
|
@ -667,7 +763,8 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|||
*/
|
||||
if (max_proto > PSMOUSE_IMEX) {
|
||||
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
|
||||
if (alps_detect(psmouse, set_properties) == 0) {
|
||||
if (psmouse_do_detect(alps_detect,
|
||||
psmouse, set_properties) == 0) {
|
||||
if (!set_properties || alps_init(psmouse) == 0)
|
||||
return PSMOUSE_ALPS;
|
||||
/*
|
||||
|
|
@ -681,7 +778,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|||
* Try OLPC HGPK touchpad.
|
||||
*/
|
||||
if (max_proto > PSMOUSE_IMEX &&
|
||||
hgpk_detect(psmouse, set_properties) == 0) {
|
||||
psmouse_do_detect(hgpk_detect, psmouse, set_properties) == 0) {
|
||||
if (!set_properties || hgpk_init(psmouse) == 0)
|
||||
return PSMOUSE_HGPK;
|
||||
/*
|
||||
|
|
@ -694,7 +791,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|||
* Try Elantech touchpad.
|
||||
*/
|
||||
if (max_proto > PSMOUSE_IMEX &&
|
||||
elantech_detect(psmouse, set_properties) == 0) {
|
||||
psmouse_do_detect(elantech_detect, psmouse, set_properties) == 0) {
|
||||
if (!set_properties || elantech_init(psmouse) == 0)
|
||||
return PSMOUSE_ELANTECH;
|
||||
/*
|
||||
|
|
@ -703,18 +800,21 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|||
max_proto = PSMOUSE_IMEX;
|
||||
}
|
||||
|
||||
|
||||
if (max_proto > PSMOUSE_IMEX) {
|
||||
if (genius_detect(psmouse, set_properties) == 0)
|
||||
if (psmouse_do_detect(genius_detect,
|
||||
psmouse, set_properties) == 0)
|
||||
return PSMOUSE_GENPS;
|
||||
|
||||
if (ps2pp_init(psmouse, set_properties) == 0)
|
||||
if (psmouse_do_detect(ps2pp_init,
|
||||
psmouse, set_properties) == 0)
|
||||
return PSMOUSE_PS2PP;
|
||||
|
||||
if (trackpoint_detect(psmouse, set_properties) == 0)
|
||||
if (psmouse_do_detect(trackpoint_detect,
|
||||
psmouse, set_properties) == 0)
|
||||
return PSMOUSE_TRACKPOINT;
|
||||
|
||||
if (touchkit_ps2_detect(psmouse, set_properties) == 0)
|
||||
if (psmouse_do_detect(touchkit_ps2_detect,
|
||||
psmouse, set_properties) == 0)
|
||||
return PSMOUSE_TOUCHKIT_PS2;
|
||||
}
|
||||
|
||||
|
|
@ -723,7 +823,8 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|||
* Trackpoint devices (causing TP_READ_ID command to time out).
|
||||
*/
|
||||
if (max_proto > PSMOUSE_IMEX) {
|
||||
if (fsp_detect(psmouse, set_properties) == 0) {
|
||||
if (psmouse_do_detect(fsp_detect,
|
||||
psmouse, set_properties) == 0) {
|
||||
if (!set_properties || fsp_init(psmouse) == 0)
|
||||
return PSMOUSE_FSP;
|
||||
/*
|
||||
|
|
@ -741,17 +842,23 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|||
ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
|
||||
psmouse_reset(psmouse);
|
||||
|
||||
if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0)
|
||||
if (max_proto >= PSMOUSE_IMEX &&
|
||||
psmouse_do_detect(im_explorer_detect,
|
||||
psmouse, set_properties) == 0) {
|
||||
return PSMOUSE_IMEX;
|
||||
}
|
||||
|
||||
if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse, set_properties) == 0)
|
||||
if (max_proto >= PSMOUSE_IMPS &&
|
||||
psmouse_do_detect(intellimouse_detect,
|
||||
psmouse, set_properties) == 0) {
|
||||
return PSMOUSE_IMPS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Okay, all failed, we have a standard mouse here. The number of the buttons
|
||||
* is still a question, though. We assume 3.
|
||||
*/
|
||||
ps2bare_detect(psmouse, set_properties);
|
||||
psmouse_do_detect(ps2bare_detect, psmouse, set_properties);
|
||||
|
||||
if (synaptics_hardware) {
|
||||
/*
|
||||
|
|
@ -819,6 +926,13 @@ static const struct psmouse_protocol psmouse_protocols[] = {
|
|||
.detect = synaptics_detect,
|
||||
.init = synaptics_init,
|
||||
},
|
||||
{
|
||||
.type = PSMOUSE_SYNAPTICS_RELATIVE,
|
||||
.name = "SynRelPS/2",
|
||||
.alias = "synaptics-relative",
|
||||
.detect = synaptics_detect,
|
||||
.init = synaptics_init_relative,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_MOUSE_PS2_ALPS
|
||||
{
|
||||
|
|
@ -957,39 +1071,6 @@ static int psmouse_probe(struct psmouse *psmouse)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we set the mouse resolution.
|
||||
*/
|
||||
|
||||
void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution)
|
||||
{
|
||||
static const unsigned char params[] = { 0, 1, 2, 2, 3 };
|
||||
unsigned char p;
|
||||
|
||||
if (resolution == 0 || resolution > 200)
|
||||
resolution = 200;
|
||||
|
||||
p = params[resolution / 50];
|
||||
ps2_command(&psmouse->ps2dev, &p, PSMOUSE_CMD_SETRES);
|
||||
psmouse->resolution = 25 << p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we set the mouse report rate.
|
||||
*/
|
||||
|
||||
static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
|
||||
{
|
||||
static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 };
|
||||
unsigned char r;
|
||||
int i = 0;
|
||||
|
||||
while (rates[i] > rate) i++;
|
||||
r = rates[i];
|
||||
ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE);
|
||||
psmouse->rate = r;
|
||||
}
|
||||
|
||||
/*
|
||||
* psmouse_initialize() initializes the mouse to a sane state.
|
||||
*/
|
||||
|
|
@ -1035,16 +1116,6 @@ static void psmouse_deactivate(struct psmouse *psmouse)
|
|||
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
|
||||
}
|
||||
|
||||
/*
|
||||
* psmouse_poll() - default poll handler. Everyone except for ALPS uses it.
|
||||
*/
|
||||
|
||||
static int psmouse_poll(struct psmouse *psmouse)
|
||||
{
|
||||
return ps2_command(&psmouse->ps2dev, psmouse->packet,
|
||||
PSMOUSE_CMD_POLL | (psmouse->pktsize << 8));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* psmouse_resync() attempts to re-validate current protocol.
|
||||
|
|
@ -1245,18 +1316,9 @@ static int psmouse_switch_protocol(struct psmouse *psmouse,
|
|||
|
||||
input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
|
||||
|
||||
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
|
||||
input_dev->keybit[BIT_WORD(BTN_MOUSE)] =
|
||||
BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
|
||||
input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
|
||||
|
||||
psmouse->set_rate = psmouse_set_rate;
|
||||
psmouse->set_resolution = psmouse_set_resolution;
|
||||
psmouse->poll = psmouse_poll;
|
||||
psmouse->protocol_handler = psmouse_process_byte;
|
||||
psmouse->pktsize = 3;
|
||||
|
||||
if (proto && (proto->detect || proto->init)) {
|
||||
psmouse_apply_defaults(psmouse);
|
||||
|
||||
if (proto->detect && proto->detect(psmouse, true) < 0)
|
||||
return -1;
|
||||
|
||||
|
|
@ -1558,13 +1620,12 @@ static ssize_t psmouse_show_int_attr(struct psmouse *psmouse, void *offset, char
|
|||
static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const char *buf, size_t count)
|
||||
{
|
||||
unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset);
|
||||
unsigned long value;
|
||||
unsigned int value;
|
||||
int err;
|
||||
|
||||
if (strict_strtoul(buf, 10, &value))
|
||||
return -EINVAL;
|
||||
|
||||
if ((unsigned int)value != value)
|
||||
return -EINVAL;
|
||||
err = kstrtouint(buf, 10, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*field = value;
|
||||
|
||||
|
|
@ -1671,10 +1732,12 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
|
|||
|
||||
static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count)
|
||||
{
|
||||
unsigned long value;
|
||||
unsigned int value;
|
||||
int err;
|
||||
|
||||
if (strict_strtoul(buf, 10, &value))
|
||||
return -EINVAL;
|
||||
err = kstrtouint(buf, 10, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
psmouse->set_rate(psmouse, value);
|
||||
return count;
|
||||
|
|
@ -1682,10 +1745,12 @@ static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const
|
|||
|
||||
static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count)
|
||||
{
|
||||
unsigned long value;
|
||||
unsigned int value;
|
||||
int err;
|
||||
|
||||
if (strict_strtoul(buf, 10, &value))
|
||||
return -EINVAL;
|
||||
err = kstrtouint(buf, 10, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
psmouse->set_resolution(psmouse, value);
|
||||
return count;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#define PSMOUSE_CMD_SETSTREAM 0x00ea
|
||||
#define PSMOUSE_CMD_SETPOLL 0x00f0
|
||||
#define PSMOUSE_CMD_POLL 0x00eb /* caller sets number of bytes to receive */
|
||||
#define PSMOUSE_CMD_RESET_WRAP 0x00ec
|
||||
#define PSMOUSE_CMD_GETID 0x02f2
|
||||
#define PSMOUSE_CMD_SETRATE 0x10f3
|
||||
#define PSMOUSE_CMD_ENABLE 0x00f4
|
||||
|
|
@ -93,6 +94,7 @@ enum psmouse_type {
|
|||
PSMOUSE_HGPK,
|
||||
PSMOUSE_ELANTECH,
|
||||
PSMOUSE_FSP,
|
||||
PSMOUSE_SYNAPTICS_RELATIVE,
|
||||
PSMOUSE_AUTO /* This one should always be last */
|
||||
};
|
||||
|
||||
|
|
@ -102,6 +104,7 @@ int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
|
|||
int psmouse_reset(struct psmouse *psmouse);
|
||||
void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state);
|
||||
void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution);
|
||||
psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse);
|
||||
|
||||
struct psmouse_attribute {
|
||||
struct device_attribute dattr;
|
||||
|
|
|
|||
|
|
@ -250,19 +250,7 @@ static struct platform_driver pxa930_trkball_driver = {
|
|||
.probe = pxa930_trkball_probe,
|
||||
.remove = __devexit_p(pxa930_trkball_remove),
|
||||
};
|
||||
|
||||
static int __init pxa930_trkball_init(void)
|
||||
{
|
||||
return platform_driver_register(&pxa930_trkball_driver);
|
||||
}
|
||||
|
||||
static void __exit pxa930_trkball_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&pxa930_trkball_driver);
|
||||
}
|
||||
|
||||
module_init(pxa930_trkball_init);
|
||||
module_exit(pxa930_trkball_exit);
|
||||
module_platform_driver(pxa930_trkball_driver);
|
||||
|
||||
MODULE_AUTHOR("Yong Yao <yaoyong@marvell.com>");
|
||||
MODULE_DESCRIPTION("PXA930 Trackball Mouse Driver");
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable)
|
|||
static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long reg, val;
|
||||
int reg, val;
|
||||
char *rest;
|
||||
ssize_t retval;
|
||||
|
||||
|
|
@ -416,7 +416,11 @@ static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data,
|
|||
if (rest == buf || *rest != ' ' || reg > 0xff)
|
||||
return -EINVAL;
|
||||
|
||||
if (strict_strtoul(rest + 1, 16, &val) || val > 0xff)
|
||||
retval = kstrtoint(rest + 1, 16, &val);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
if (val > 0xff)
|
||||
return -EINVAL;
|
||||
|
||||
if (fsp_reg_write_enable(psmouse, true))
|
||||
|
|
@ -448,10 +452,13 @@ static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data,
|
|||
const char *buf, size_t count)
|
||||
{
|
||||
struct fsp_data *pad = psmouse->private;
|
||||
unsigned long reg;
|
||||
int val;
|
||||
int reg, val, err;
|
||||
|
||||
if (strict_strtoul(buf, 16, ®) || reg > 0xff)
|
||||
err = kstrtoint(buf, 16, ®);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (reg > 0xff)
|
||||
return -EINVAL;
|
||||
|
||||
if (fsp_reg_read(psmouse, reg, &val))
|
||||
|
|
@ -480,9 +487,13 @@ static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse,
|
|||
static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long val;
|
||||
int val, err;
|
||||
|
||||
if (strict_strtoul(buf, 16, &val) || val > 0xff)
|
||||
err = kstrtoint(buf, 16, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (val > 0xff)
|
||||
return -EINVAL;
|
||||
|
||||
if (fsp_page_reg_write(psmouse, val))
|
||||
|
|
@ -505,9 +516,14 @@ static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse,
|
|||
static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long val;
|
||||
unsigned int val;
|
||||
int err;
|
||||
|
||||
if (strict_strtoul(buf, 10, &val) || val > 1)
|
||||
err = kstrtouint(buf, 10, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (val > 1)
|
||||
return -EINVAL;
|
||||
|
||||
fsp_onpad_vscr(psmouse, val);
|
||||
|
|
@ -529,9 +545,14 @@ static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse,
|
|||
static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long val;
|
||||
unsigned int val;
|
||||
int err;
|
||||
|
||||
if (strict_strtoul(buf, 10, &val) || val > 1)
|
||||
err = kstrtouint(buf, 10, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (val > 1)
|
||||
return -EINVAL;
|
||||
|
||||
fsp_onpad_hscr(psmouse, val);
|
||||
|
|
|
|||
|
|
@ -269,19 +269,49 @@ static int synaptics_query_hardware(struct psmouse *psmouse)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int synaptics_set_absolute_mode(struct psmouse *psmouse)
|
||||
static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
|
||||
{
|
||||
static unsigned char param = 0xc8;
|
||||
struct synaptics_data *priv = psmouse->private;
|
||||
|
||||
if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))
|
||||
return 0;
|
||||
|
||||
if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL))
|
||||
return -1;
|
||||
|
||||
if (ps2_command(&psmouse->ps2dev, ¶m, PSMOUSE_CMD_SETRATE))
|
||||
return -1;
|
||||
|
||||
/* Advanced gesture mode also sends multi finger data */
|
||||
priv->capabilities |= BIT(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int synaptics_set_mode(struct psmouse *psmouse)
|
||||
{
|
||||
struct synaptics_data *priv = psmouse->private;
|
||||
|
||||
priv->mode = SYN_BIT_ABSOLUTE_MODE;
|
||||
if (SYN_ID_MAJOR(priv->identity) >= 4)
|
||||
priv->mode = 0;
|
||||
if (priv->absolute_mode)
|
||||
priv->mode |= SYN_BIT_ABSOLUTE_MODE;
|
||||
if (priv->disable_gesture)
|
||||
priv->mode |= SYN_BIT_DISABLE_GESTURE;
|
||||
if (psmouse->rate >= 80)
|
||||
priv->mode |= SYN_BIT_HIGH_RATE;
|
||||
if (SYN_CAP_EXTENDED(priv->capabilities))
|
||||
priv->mode |= SYN_BIT_W_MODE;
|
||||
|
||||
if (synaptics_mode_cmd(psmouse, priv->mode))
|
||||
return -1;
|
||||
|
||||
if (priv->absolute_mode &&
|
||||
synaptics_set_advanced_gesture_mode(psmouse)) {
|
||||
psmouse_err(psmouse, "Advanced gesture mode init failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -300,26 +330,6 @@ static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate)
|
|||
synaptics_mode_cmd(psmouse, priv->mode);
|
||||
}
|
||||
|
||||
static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
|
||||
{
|
||||
static unsigned char param = 0xc8;
|
||||
struct synaptics_data *priv = psmouse->private;
|
||||
|
||||
if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) ||
|
||||
SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)))
|
||||
return 0;
|
||||
|
||||
if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL))
|
||||
return -1;
|
||||
if (ps2_command(&psmouse->ps2dev, ¶m, PSMOUSE_CMD_SETRATE))
|
||||
return -1;
|
||||
|
||||
/* Advanced gesture mode also sends multi finger data */
|
||||
priv->capabilities |= BIT(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Synaptics pass-through PS/2 port support
|
||||
****************************************************************************/
|
||||
|
|
@ -1143,8 +1153,24 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
|
|||
{
|
||||
int i;
|
||||
|
||||
/* Things that apply to both modes */
|
||||
__set_bit(INPUT_PROP_POINTER, dev->propbit);
|
||||
__set_bit(EV_KEY, dev->evbit);
|
||||
__set_bit(BTN_LEFT, dev->keybit);
|
||||
__set_bit(BTN_RIGHT, dev->keybit);
|
||||
|
||||
if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
|
||||
__set_bit(BTN_MIDDLE, dev->keybit);
|
||||
|
||||
if (!priv->absolute_mode) {
|
||||
/* Relative mode */
|
||||
__set_bit(EV_REL, dev->evbit);
|
||||
__set_bit(REL_X, dev->relbit);
|
||||
__set_bit(REL_Y, dev->relbit);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Absolute mode */
|
||||
__set_bit(EV_ABS, dev->evbit);
|
||||
set_abs_position_params(dev, priv, ABS_X, ABS_Y);
|
||||
input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
|
||||
|
|
@ -1170,20 +1196,14 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
|
|||
if (SYN_CAP_PALMDETECT(priv->capabilities))
|
||||
input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
|
||||
|
||||
__set_bit(EV_KEY, dev->evbit);
|
||||
__set_bit(BTN_TOUCH, dev->keybit);
|
||||
__set_bit(BTN_TOOL_FINGER, dev->keybit);
|
||||
__set_bit(BTN_LEFT, dev->keybit);
|
||||
__set_bit(BTN_RIGHT, dev->keybit);
|
||||
|
||||
if (SYN_CAP_MULTIFINGER(priv->capabilities)) {
|
||||
__set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
|
||||
__set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
|
||||
}
|
||||
|
||||
if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
|
||||
__set_bit(BTN_MIDDLE, dev->keybit);
|
||||
|
||||
if (SYN_CAP_FOUR_BUTTON(priv->capabilities) ||
|
||||
SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
|
||||
__set_bit(BTN_FORWARD, dev->keybit);
|
||||
|
|
@ -1205,10 +1225,58 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
|
|||
}
|
||||
}
|
||||
|
||||
static ssize_t synaptics_show_disable_gesture(struct psmouse *psmouse,
|
||||
void *data, char *buf)
|
||||
{
|
||||
struct synaptics_data *priv = psmouse->private;
|
||||
|
||||
return sprintf(buf, "%c\n", priv->disable_gesture ? '1' : '0');
|
||||
}
|
||||
|
||||
static ssize_t synaptics_set_disable_gesture(struct psmouse *psmouse,
|
||||
void *data, const char *buf,
|
||||
size_t len)
|
||||
{
|
||||
struct synaptics_data *priv = psmouse->private;
|
||||
unsigned int value;
|
||||
int err;
|
||||
|
||||
err = kstrtouint(buf, 10, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (value > 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (value == priv->disable_gesture)
|
||||
return len;
|
||||
|
||||
priv->disable_gesture = value;
|
||||
if (value)
|
||||
priv->mode |= SYN_BIT_DISABLE_GESTURE;
|
||||
else
|
||||
priv->mode &= ~SYN_BIT_DISABLE_GESTURE;
|
||||
|
||||
if (synaptics_mode_cmd(psmouse, priv->mode))
|
||||
return -EIO;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
PSMOUSE_DEFINE_ATTR(disable_gesture, S_IWUSR | S_IRUGO, NULL,
|
||||
synaptics_show_disable_gesture,
|
||||
synaptics_set_disable_gesture);
|
||||
|
||||
static void synaptics_disconnect(struct psmouse *psmouse)
|
||||
{
|
||||
struct synaptics_data *priv = psmouse->private;
|
||||
|
||||
if (!priv->absolute_mode && SYN_ID_DISGEST_SUPPORTED(priv->identity))
|
||||
device_remove_file(&psmouse->ps2dev.serio->dev,
|
||||
&psmouse_attr_disable_gesture.dattr);
|
||||
|
||||
synaptics_reset(psmouse);
|
||||
kfree(psmouse->private);
|
||||
kfree(priv);
|
||||
psmouse->private = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1245,17 +1313,11 @@ static int synaptics_reconnect(struct psmouse *psmouse)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (synaptics_set_absolute_mode(psmouse)) {
|
||||
if (synaptics_set_mode(psmouse)) {
|
||||
psmouse_err(psmouse, "Unable to initialize device.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (synaptics_set_advanced_gesture_mode(psmouse)) {
|
||||
psmouse_err(psmouse,
|
||||
"Advanced gesture mode reconnect failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (old_priv.identity != priv->identity ||
|
||||
old_priv.model_id != priv->model_id ||
|
||||
old_priv.capabilities != priv->capabilities ||
|
||||
|
|
@ -1332,20 +1394,18 @@ void __init synaptics_module_init(void)
|
|||
broken_olpc_ec = dmi_check_system(olpc_dmi_table);
|
||||
}
|
||||
|
||||
int synaptics_init(struct psmouse *psmouse)
|
||||
static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
|
||||
{
|
||||
struct synaptics_data *priv;
|
||||
int err = -1;
|
||||
|
||||
/*
|
||||
* The OLPC XO has issues with Synaptics' absolute mode; similarly to
|
||||
* the HGPK, it quickly degrades and the hardware becomes jumpy and
|
||||
* overly sensitive. Not only that, but the constant packet spew
|
||||
* (even at a lowered 40pps rate) overloads the EC such that key
|
||||
* presses on the keyboard are missed. Given all of that, don't
|
||||
* even attempt to use Synaptics mode. Relative mode seems to work
|
||||
* just fine.
|
||||
* The OLPC XO has issues with Synaptics' absolute mode; the constant
|
||||
* packet spew overloads the EC such that key presses on the keyboard
|
||||
* are missed. Given that, don't even attempt to use Absolute mode.
|
||||
* Relative mode seems to work just fine.
|
||||
*/
|
||||
if (broken_olpc_ec) {
|
||||
if (absolute_mode && broken_olpc_ec) {
|
||||
psmouse_info(psmouse,
|
||||
"OLPC XO detected, not enabling Synaptics protocol.\n");
|
||||
return -ENODEV;
|
||||
|
|
@ -1362,13 +1422,12 @@ int synaptics_init(struct psmouse *psmouse)
|
|||
goto init_fail;
|
||||
}
|
||||
|
||||
if (synaptics_set_absolute_mode(psmouse)) {
|
||||
psmouse_err(psmouse, "Unable to initialize device.\n");
|
||||
goto init_fail;
|
||||
}
|
||||
priv->absolute_mode = absolute_mode;
|
||||
if (SYN_ID_DISGEST_SUPPORTED(priv->identity))
|
||||
priv->disable_gesture = true;
|
||||
|
||||
if (synaptics_set_advanced_gesture_mode(psmouse)) {
|
||||
psmouse_err(psmouse, "Advanced gesture mode init failed.\n");
|
||||
if (synaptics_set_mode(psmouse)) {
|
||||
psmouse_err(psmouse, "Unable to initialize device.\n");
|
||||
goto init_fail;
|
||||
}
|
||||
|
||||
|
|
@ -1393,12 +1452,19 @@ int synaptics_init(struct psmouse *psmouse)
|
|||
psmouse->model = ((priv->model_id & 0x00ff0000) >> 8) |
|
||||
(priv->model_id & 0x000000ff);
|
||||
|
||||
psmouse->protocol_handler = synaptics_process_byte;
|
||||
if (absolute_mode) {
|
||||
psmouse->protocol_handler = synaptics_process_byte;
|
||||
psmouse->pktsize = 6;
|
||||
} else {
|
||||
/* Relative mode follows standard PS/2 mouse protocol */
|
||||
psmouse->protocol_handler = psmouse_process_byte;
|
||||
psmouse->pktsize = 3;
|
||||
}
|
||||
|
||||
psmouse->set_rate = synaptics_set_rate;
|
||||
psmouse->disconnect = synaptics_disconnect;
|
||||
psmouse->reconnect = synaptics_reconnect;
|
||||
psmouse->cleanup = synaptics_reset;
|
||||
psmouse->pktsize = 6;
|
||||
/* Synaptics can usually stay in sync without extra help */
|
||||
psmouse->resync_time = 0;
|
||||
|
||||
|
|
@ -1417,11 +1483,32 @@ int synaptics_init(struct psmouse *psmouse)
|
|||
psmouse->rate = 40;
|
||||
}
|
||||
|
||||
if (!priv->absolute_mode && SYN_ID_DISGEST_SUPPORTED(priv->identity)) {
|
||||
err = device_create_file(&psmouse->ps2dev.serio->dev,
|
||||
&psmouse_attr_disable_gesture.dattr);
|
||||
if (err) {
|
||||
psmouse_err(psmouse,
|
||||
"Failed to create disable_gesture attribute (%d)",
|
||||
err);
|
||||
goto init_fail;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
init_fail:
|
||||
kfree(priv);
|
||||
return -1;
|
||||
return err;
|
||||
}
|
||||
|
||||
int synaptics_init(struct psmouse *psmouse)
|
||||
{
|
||||
return __synaptics_init(psmouse, true);
|
||||
}
|
||||
|
||||
int synaptics_init_relative(struct psmouse *psmouse)
|
||||
{
|
||||
return __synaptics_init(psmouse, false);
|
||||
}
|
||||
|
||||
bool synaptics_supported(void)
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@
|
|||
#define SYN_ID_MINOR(i) (((i) >> 16) & 0xff)
|
||||
#define SYN_ID_FULL(i) ((SYN_ID_MAJOR(i) << 8) | SYN_ID_MINOR(i))
|
||||
#define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47)
|
||||
#define SYN_ID_DISGEST_SUPPORTED(i) (SYN_ID_MAJOR(i) >= 4)
|
||||
|
||||
/* synaptics special commands */
|
||||
#define SYN_PS_SET_MODE2 0x14
|
||||
|
|
@ -159,6 +160,9 @@ struct synaptics_data {
|
|||
unsigned char mode; /* current mode byte */
|
||||
int scroll;
|
||||
|
||||
bool absolute_mode; /* run in Absolute mode */
|
||||
bool disable_gesture; /* disable gestures */
|
||||
|
||||
struct serio *pt_port; /* Pass-through serio port */
|
||||
|
||||
struct synaptics_mt_state mt_state; /* Current mt finger state */
|
||||
|
|
@ -175,6 +179,7 @@ struct synaptics_data {
|
|||
void synaptics_module_init(void);
|
||||
int synaptics_detect(struct psmouse *psmouse, bool set_properties);
|
||||
int synaptics_init(struct psmouse *psmouse);
|
||||
int synaptics_init_relative(struct psmouse *psmouse);
|
||||
void synaptics_reset(struct psmouse *psmouse);
|
||||
bool synaptics_supported(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -89,10 +89,12 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data,
|
|||
struct trackpoint_data *tp = psmouse->private;
|
||||
struct trackpoint_attr_data *attr = data;
|
||||
unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
|
||||
unsigned long value;
|
||||
unsigned char value;
|
||||
int err;
|
||||
|
||||
if (strict_strtoul(buf, 10, &value) || value > 255)
|
||||
return -EINVAL;
|
||||
err = kstrtou8(buf, 10, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*field = value;
|
||||
trackpoint_write(&psmouse->ps2dev, attr->command, value);
|
||||
|
|
@ -115,9 +117,14 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
|
|||
struct trackpoint_data *tp = psmouse->private;
|
||||
struct trackpoint_attr_data *attr = data;
|
||||
unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
|
||||
unsigned long value;
|
||||
unsigned int value;
|
||||
int err;
|
||||
|
||||
if (strict_strtoul(buf, 10, &value) || value > 1)
|
||||
err = kstrtouint(buf, 10, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (value > 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (attr->inverted)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue