static struct workqueue_struct *kpsmoused_wq;
-struct psmouse_protocol {
- enum psmouse_type type;
- bool maxproto;
- bool ignore_parity; /* Protocol should ignore parity errors from KBC */
- bool try_passthru; /* Try protocol also on passthrough ports */
- const char *name;
- const char *alias;
- int (*detect)(struct psmouse *, bool);
- int (*init)(struct psmouse *);
-};
-
static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
{
input_report_key(dev, BTN_LEFT, buttons & BIT(0));
/* Full packet accumulated, process it */
- switch (psmouse->type) {
+ switch (psmouse->protocol->type) {
case PSMOUSE_IMPS:
/* IntelliMouse has scroll wheel */
input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]);
goto out;
if (unlikely((flags & SERIO_TIMEOUT) ||
- ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) {
+ ((flags & SERIO_PARITY) &&
+ !psmouse->protocol->ignore_parity))) {
if (psmouse->state == PSMOUSE_ACTIVATED)
psmouse_warn(psmouse,
}
if (psmouse->packet[1] == PSMOUSE_RET_ID ||
- (psmouse->type == PSMOUSE_HGPK &&
+ (psmouse->protocol->type == PSMOUSE_HGPK &&
psmouse->packet[1] == PSMOUSE_RET_BAT)) {
__psmouse_set_state(psmouse, PSMOUSE_IGNORE);
serio_reconnect(serio);
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+ psmouse->protocol = &psmouse_protocols[0];
+
psmouse->set_rate = psmouse_set_rate;
psmouse->set_resolution = psmouse_set_resolution;
psmouse->set_scale = psmouse_set_scale;
{
const struct psmouse_protocol *selected_proto;
struct input_dev *input_dev = psmouse->dev;
+ enum psmouse_type type;
input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
if (proto->init && proto->init(psmouse) < 0)
return -1;
- psmouse->type = proto->type;
selected_proto = proto;
} else {
- psmouse->type = psmouse_extensions(psmouse,
- psmouse_max_proto, true);
- selected_proto = psmouse_protocol_by_type(psmouse->type);
+ type = psmouse_extensions(psmouse, psmouse_max_proto, true);
+ selected_proto = psmouse_protocol_by_type(type);
}
- psmouse->ignore_parity = selected_proto->ignore_parity;
+ psmouse->protocol = selected_proto;
/*
* If mouse's packet size is 3 there is no point in polling the
input_dev->phys = psmouse->phys;
input_dev->id.bustype = BUS_I8042;
input_dev->id.vendor = 0x0002;
- input_dev->id.product = psmouse->type;
+ input_dev->id.product = psmouse->protocol->type;
input_dev->id.version = psmouse->model;
return 0;
struct psmouse *psmouse = serio_get_drvdata(serio);
struct psmouse *parent = NULL;
int (*reconnect_handler)(struct psmouse *);
- unsigned char type;
+ enum psmouse_type type;
int rc = -1;
mutex_lock(&psmouse_mutex);
goto out;
type = psmouse_extensions(psmouse, psmouse_max_proto, false);
- if (psmouse->type != type)
+ if (psmouse->protocol->type != type)
goto out;
}
static ssize_t psmouse_attr_show_protocol(struct psmouse *psmouse, void *data, char *buf)
{
- return sprintf(buf, "%s\n", psmouse_protocol_by_type(psmouse->type)->name);
+ return sprintf(buf, "%s\n", psmouse->protocol->name);
}
static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, const char *buf, size_t count)
if (!proto)
return -EINVAL;
- if (psmouse->type == proto->type)
+ if (psmouse->protocol == proto)
return count;
new_dev = input_allocate_device();
return -ENODEV;
}
- if (psmouse->type == proto->type) {
+ if (psmouse->protocol == proto) {
input_free_device(new_dev);
return count; /* switched by other thread */
}
}
old_dev = psmouse->dev;
- old_proto = psmouse_protocol_by_type(psmouse->type);
+ old_proto = psmouse->protocol;
if (psmouse->disconnect)
psmouse->disconnect(psmouse);
PSMOUSE_SCALE21
};
+enum psmouse_type {
+ PSMOUSE_NONE,
+ PSMOUSE_PS2,
+ PSMOUSE_PS2PP,
+ PSMOUSE_THINKPS,
+ PSMOUSE_GENPS,
+ PSMOUSE_IMPS,
+ PSMOUSE_IMEX,
+ PSMOUSE_SYNAPTICS,
+ PSMOUSE_ALPS,
+ PSMOUSE_LIFEBOOK,
+ PSMOUSE_TRACKPOINT,
+ PSMOUSE_TOUCHKIT_PS2,
+ PSMOUSE_CORTRON,
+ PSMOUSE_HGPK,
+ PSMOUSE_ELANTECH,
+ PSMOUSE_FSP,
+ PSMOUSE_SYNAPTICS_RELATIVE,
+ PSMOUSE_CYPRESS,
+ PSMOUSE_FOCALTECH,
+ PSMOUSE_VMMOUSE,
+ PSMOUSE_BYD,
+ PSMOUSE_AUTO /* This one should always be last */
+};
+
+struct psmouse;
+
+struct psmouse_protocol {
+ enum psmouse_type type;
+ bool maxproto;
+ bool ignore_parity; /* Protocol should ignore parity errors from KBC */
+ bool try_passthru; /* Try protocol also on passthrough ports */
+ const char *name;
+ const char *alias;
+ int (*detect)(struct psmouse *, bool);
+ int (*init)(struct psmouse *);
+};
+
struct psmouse {
void *private;
struct input_dev *dev;
struct ps2dev ps2dev;
struct delayed_work resync_work;
- char *vendor;
- char *name;
+ const char *vendor;
+ const char *name;
+ const struct psmouse_protocol *protocol;
unsigned char packet[8];
unsigned char badbyte;
unsigned char pktcnt;
unsigned char pktsize;
- unsigned char type;
unsigned char oob_data_type;
unsigned char extra_buttons;
- bool ignore_parity;
bool acks_disable_command;
unsigned int model;
unsigned long last;
void (*pt_deactivate)(struct psmouse *psmouse);
};
-enum psmouse_type {
- PSMOUSE_NONE,
- PSMOUSE_PS2,
- PSMOUSE_PS2PP,
- PSMOUSE_THINKPS,
- PSMOUSE_GENPS,
- PSMOUSE_IMPS,
- PSMOUSE_IMEX,
- PSMOUSE_SYNAPTICS,
- PSMOUSE_ALPS,
- PSMOUSE_LIFEBOOK,
- PSMOUSE_TRACKPOINT,
- PSMOUSE_TOUCHKIT_PS2,
- PSMOUSE_CORTRON,
- PSMOUSE_HGPK,
- PSMOUSE_ELANTECH,
- PSMOUSE_FSP,
- PSMOUSE_SYNAPTICS_RELATIVE,
- PSMOUSE_CYPRESS,
- PSMOUSE_FOCALTECH,
- PSMOUSE_VMMOUSE,
- PSMOUSE_BYD,
- PSMOUSE_AUTO /* This one should always be last */
-};
-
void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
unsigned long delay);
int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);