[PATCH v2] Input: trackpoint - Optimize trackpoint init to use power-on reset

2013-04-09 Thread Shawn Nematbakhsh
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

2013-04-09 Thread Shawn Nematbakhsh
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);