diff options
Diffstat (limited to 'drivers/input/mouse/psmouse.h')
-rw-r--r-- | drivers/input/mouse/psmouse.h | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h new file mode 100644 index 0000000000..4d8acfe0d8 --- /dev/null +++ b/drivers/input/mouse/psmouse.h @@ -0,0 +1,251 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _PSMOUSE_H +#define _PSMOUSE_H + +#define PSMOUSE_OOB_NONE 0x00 +#define PSMOUSE_OOB_EXTRA_BTNS 0x01 + +#define PSMOUSE_CMD_SETSCALE11 0x00e6 +#define PSMOUSE_CMD_SETSCALE21 0x00e7 +#define PSMOUSE_CMD_SETRES 0x10e8 +#define PSMOUSE_CMD_GETINFO 0x03e9 +#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 +#define PSMOUSE_CMD_DISABLE 0x00f5 +#define PSMOUSE_CMD_RESET_DIS 0x00f6 +#define PSMOUSE_CMD_RESET_BAT 0x02ff + +#define PSMOUSE_RET_BAT 0xaa +#define PSMOUSE_RET_ID 0x00 +#define PSMOUSE_RET_ACK 0xfa +#define PSMOUSE_RET_NAK 0xfe + +enum psmouse_state { + PSMOUSE_IGNORE, + PSMOUSE_INITIALIZING, + PSMOUSE_RESYNCING, + PSMOUSE_CMD_MODE, + PSMOUSE_ACTIVATED, +}; + +/* psmouse protocol handler return codes */ +typedef enum { + PSMOUSE_BAD_DATA, + PSMOUSE_GOOD_DATA, + PSMOUSE_FULL_PACKET +} psmouse_ret_t; + +enum psmouse_scale { + PSMOUSE_SCALE11, + 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_SYNAPTICS_SMBUS, + PSMOUSE_ELANTECH_SMBUS, + 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 */ + bool smbus_companion; /* "Protocol" is a stub, device is on SMBus */ + 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; + 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 oob_data_type; + unsigned char extra_buttons; + bool acks_disable_command; + unsigned int model; + unsigned long last; + unsigned long out_of_sync_cnt; + unsigned long num_resyncs; + enum psmouse_state state; + char devname[64]; + char phys[32]; + + unsigned int rate; + unsigned int resolution; + unsigned int resetafter; + unsigned int resync_time; + bool smartscroll; /* Logitech only */ + + psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse); + void (*set_rate)(struct psmouse *psmouse, unsigned int rate); + void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution); + void (*set_scale)(struct psmouse *psmouse, enum psmouse_scale scale); + + int (*reconnect)(struct psmouse *psmouse); + int (*fast_reconnect)(struct psmouse *psmouse); + void (*disconnect)(struct psmouse *psmouse); + void (*cleanup)(struct psmouse *psmouse); + int (*poll)(struct psmouse *psmouse); + + void (*pt_activate)(struct psmouse *psmouse); + void (*pt_deactivate)(struct psmouse *psmouse); +}; + +struct psmouse *psmouse_from_serio(struct serio *serio); + +void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work, + unsigned long delay); +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); +int psmouse_activate(struct psmouse *psmouse); +int psmouse_deactivate(struct psmouse *psmouse); +bool psmouse_matches_pnp_id(struct psmouse *psmouse, const char * const ids[]); + +void psmouse_report_standard_buttons(struct input_dev *, u8 buttons); +void psmouse_report_standard_motion(struct input_dev *, u8 *packet); +void psmouse_report_standard_packet(struct input_dev *, u8 *packet); + +struct psmouse_attribute { + struct device_attribute dattr; + void *data; + ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf); + ssize_t (*set)(struct psmouse *psmouse, void *data, + const char *buf, size_t count); + bool protect; +}; +#define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr) + +ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *attr, + char *buf); +ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count); + +#define __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, _set, _protect) \ +static struct psmouse_attribute psmouse_attr_##_name = { \ + .dattr = { \ + .attr = { \ + .name = __stringify(_name), \ + .mode = _mode, \ + }, \ + .show = psmouse_attr_show_helper, \ + .store = psmouse_attr_set_helper, \ + }, \ + .data = _data, \ + .show = _show, \ + .set = _set, \ + .protect = _protect, \ +} + +#define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect) \ + static ssize_t _show(struct psmouse *, void *, char *); \ + static ssize_t _set(struct psmouse *, void *, const char *, size_t); \ + __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, _set, _protect) + +#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \ + __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, true) + +#define PSMOUSE_DEFINE_RO_ATTR(_name, _mode, _data, _show) \ + static ssize_t _show(struct psmouse *, void *, char *); \ + __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, NULL, true) + +#define PSMOUSE_DEFINE_WO_ATTR(_name, _mode, _data, _set) \ + static ssize_t _set(struct psmouse *, void *, const char *, size_t); \ + __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, NULL, _set, true) + +#ifndef psmouse_fmt +#define psmouse_fmt(fmt) KBUILD_BASENAME ": " fmt +#endif + +#define psmouse_dbg(psmouse, format, ...) \ + dev_dbg(&(psmouse)->ps2dev.serio->dev, \ + psmouse_fmt(format), ##__VA_ARGS__) +#define psmouse_info(psmouse, format, ...) \ + dev_info(&(psmouse)->ps2dev.serio->dev, \ + psmouse_fmt(format), ##__VA_ARGS__) +#define psmouse_warn(psmouse, format, ...) \ + dev_warn(&(psmouse)->ps2dev.serio->dev, \ + psmouse_fmt(format), ##__VA_ARGS__) +#define psmouse_err(psmouse, format, ...) \ + dev_err(&(psmouse)->ps2dev.serio->dev, \ + psmouse_fmt(format), ##__VA_ARGS__) +#define psmouse_notice(psmouse, format, ...) \ + dev_notice(&(psmouse)->ps2dev.serio->dev, \ + psmouse_fmt(format), ##__VA_ARGS__) +#define psmouse_printk(level, psmouse, format, ...) \ + dev_printk(level, \ + &(psmouse)->ps2dev.serio->dev, \ + psmouse_fmt(format), ##__VA_ARGS__) + +#ifdef CONFIG_MOUSE_PS2_SMBUS + +int psmouse_smbus_module_init(void); +void psmouse_smbus_module_exit(void); + +struct i2c_board_info; + +int psmouse_smbus_init(struct psmouse *psmouse, + const struct i2c_board_info *board, + const void *pdata, size_t pdata_size, + bool need_deactivate, + bool leave_breadcrumbs); +void psmouse_smbus_cleanup(struct psmouse *psmouse); + +#else /* !CONFIG_MOUSE_PS2_SMBUS */ + +static inline int psmouse_smbus_module_init(void) +{ + return 0; +} + +static inline void psmouse_smbus_module_exit(void) +{ +} + +static inline void psmouse_smbus_cleanup(struct psmouse *psmouse) +{ +} + +#endif /* CONFIG_MOUSE_PS2_SMBUS */ + +#endif /* _PSMOUSE_H */ |