[PATCH v2] Input: trackpoint - Optimize trackpoint init to use power-on reset
From: Shawn Nematbakhsh The trackpoint driver sets various parameter default values, all of which happen to be power-on defaults (Source: IBM TrackPoint Engineering Specification, Version 4.0. Also confirmed by empirical data). By sending the power-on reset command to reset all parameters to power-on state, we can skip the lengthy process of programming all parameters. In testing, ~2.5 secs of time writing parameters was reduced to .35 seconds waiting for power-on reset to complete. Signed-off-by: Shawn Nematbakhsh --- Changes since v1: - Changed handling of 0xfc00 reply to POR. --- drivers/input/mouse/trackpoint.c | 224 +-- drivers/input/mouse/trackpoint.h | 7 +- 2 files changed, 150 insertions(+), 81 deletions(-) diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index f310249..42964d4 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c @@ -20,6 +20,30 @@ #include "trackpoint.h" /* + * Power-on Reset: Resets all trackpoint parameters, including RAM values, + * to defaults. + * Returns zero on success, non-zero on failure. + */ +static int trackpoint_power_on_reset(struct ps2dev *ps2dev) +{ + unsigned char results[2]; + int tries = 0; + + /* Issue POR command, and repeat up to once if 0xFC00 received */ + do { + if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || + ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 2, TP_POR))) + return -1; + } while (results[0] == 0xFC && results[1] == 0x00 && ++tries < 2); + + /* Check for success response -- 0xAA00 */ + if (results[0] != 0xAA || results[1] != 0x00) + return -1; + + return 0; +} + +/* * Device IO: read, write and toggle bit */ static int trackpoint_read(struct ps2dev *ps2dev, unsigned char loc, unsigned char *results) @@ -69,6 +93,7 @@ struct trackpoint_attr_data { unsigned char command; unsigned char mask; unsigned char inverted; + unsigned char power_on_default; }; static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, void *data, char *buf) @@ -102,10 +127,11 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data, return count; } -#define TRACKPOINT_INT_ATTR(_name, _command) \ +#define TRACKPOINT_INT_ATTR(_name, _command, _default) \ static struct trackpoint_attr_data trackpoint_attr_##_name = { \ .field_offset = offsetof(struct trackpoint_data, _name), \ .command = _command, \ + .power_on_default = _default, \ }; \ PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \ _attr_##_name, \ @@ -139,31 +165,68 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data, } -#define TRACKPOINT_BIT_ATTR(_name, _command, _mask, _inv) \ +#define TRACKPOINT_BIT_ATTR(_name, _command, _mask, _inv, _default) \ static struct trackpoint_attr_data trackpoint_attr_##_name = { \ - .field_offset = offsetof(struct trackpoint_data, _name), \ - .command= _command, \ - .mask = _mask, \ - .inverted = _inv, \ + .field_offset = offsetof(struct trackpoint_data, \ + _name), \ + .command= _command, \ + .mask = _mask, \ + .inverted = _inv, \ + .power_on_default = _default, \ }; \ PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \ _attr_##_name, \ trackpoint_show_int_attr, trackpoint_set_bit_attr) -TRACKPOINT_INT_ATTR(sensitivity, TP_SENS); -TRACKPOINT_INT_ATTR(speed, TP_SPEED); -TRACKPOINT_INT_ATTR(inertia, TP_INERTIA); -TRACKPOINT_INT_ATTR(reach, TP_REACH); -TRACKPOINT_INT_ATTR(draghys, TP_DRAGHYS); -TRACKPOINT_INT_ATTR(mindrag, TP_MINDRAG); -TRACKPOINT_INT_ATTR(thresh, TP_THRESH); -TRACKPOINT_INT_ATTR(upthresh, TP_UP_THRESH); -TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME); -TRACKPOINT_INT_ATTR(jenks,
[PATCH v2] Input: trackpoint - Optimize trackpoint init to use power-on reset
From: Shawn Nematbakhsh sha...@chromium.org The trackpoint driver sets various parameter default values, all of which happen to be power-on defaults (Source: IBM TrackPoint Engineering Specification, Version 4.0. Also confirmed by empirical data). By sending the power-on reset command to reset all parameters to power-on state, we can skip the lengthy process of programming all parameters. In testing, ~2.5 secs of time writing parameters was reduced to .35 seconds waiting for power-on reset to complete. Signed-off-by: Shawn Nematbakhsh sha...@chromium.org --- Changes since v1: - Changed handling of 0xfc00 reply to POR. --- drivers/input/mouse/trackpoint.c | 224 +-- drivers/input/mouse/trackpoint.h | 7 +- 2 files changed, 150 insertions(+), 81 deletions(-) diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index f310249..42964d4 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c @@ -20,6 +20,30 @@ #include trackpoint.h /* + * Power-on Reset: Resets all trackpoint parameters, including RAM values, + * to defaults. + * Returns zero on success, non-zero on failure. + */ +static int trackpoint_power_on_reset(struct ps2dev *ps2dev) +{ + unsigned char results[2]; + int tries = 0; + + /* Issue POR command, and repeat up to once if 0xFC00 received */ + do { + if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || + ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 2, TP_POR))) + return -1; + } while (results[0] == 0xFC results[1] == 0x00 ++tries 2); + + /* Check for success response -- 0xAA00 */ + if (results[0] != 0xAA || results[1] != 0x00) + return -1; + + return 0; +} + +/* * Device IO: read, write and toggle bit */ static int trackpoint_read(struct ps2dev *ps2dev, unsigned char loc, unsigned char *results) @@ -69,6 +93,7 @@ struct trackpoint_attr_data { unsigned char command; unsigned char mask; unsigned char inverted; + unsigned char power_on_default; }; static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, void *data, char *buf) @@ -102,10 +127,11 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data, return count; } -#define TRACKPOINT_INT_ATTR(_name, _command) \ +#define TRACKPOINT_INT_ATTR(_name, _command, _default) \ static struct trackpoint_attr_data trackpoint_attr_##_name = { \ .field_offset = offsetof(struct trackpoint_data, _name), \ .command = _command, \ + .power_on_default = _default, \ }; \ PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \ trackpoint_attr_##_name, \ @@ -139,31 +165,68 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data, } -#define TRACKPOINT_BIT_ATTR(_name, _command, _mask, _inv) \ +#define TRACKPOINT_BIT_ATTR(_name, _command, _mask, _inv, _default) \ static struct trackpoint_attr_data trackpoint_attr_##_name = { \ - .field_offset = offsetof(struct trackpoint_data, _name), \ - .command= _command, \ - .mask = _mask, \ - .inverted = _inv, \ + .field_offset = offsetof(struct trackpoint_data, \ + _name), \ + .command= _command, \ + .mask = _mask, \ + .inverted = _inv, \ + .power_on_default = _default, \ }; \ PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \ trackpoint_attr_##_name, \ trackpoint_show_int_attr, trackpoint_set_bit_attr) -TRACKPOINT_INT_ATTR(sensitivity, TP_SENS); -TRACKPOINT_INT_ATTR(speed, TP_SPEED); -TRACKPOINT_INT_ATTR(inertia, TP_INERTIA); -TRACKPOINT_INT_ATTR(reach, TP_REACH); -TRACKPOINT_INT_ATTR(draghys, TP_DRAGHYS); -TRACKPOINT_INT_ATTR(mindrag, TP_MINDRAG); -TRACKPOINT_INT_ATTR(thresh, TP_THRESH); -TRACKPOINT_INT_ATTR(upthresh, TP_UP_THRESH);