Updates from Zephaniah
Andres Salomon
dilinger at debian.unroutableorg
Wed Jan 3 03:36:24 EST 2007
Commit: 4ad40f5258f1bdf3250a191f08811a10e15c4f64
Parent: 91a1b86bf57adeb44b0c9415da8983a74d2b5b60
commit 4ad40f5258f1bdf3250a191f08811a10e15c4f64
Author: Andres Salomon <dilinger at debian.org>
AuthorDate: Mon Dec 18 16:10:07 2006 -0500
Commit: Andres Salomon <dilinger at debian.org>
CommitDate: Mon Dec 18 16:10:07 2006 -0500
Updates from Zephaniah
New driver from zephaniah, as of 12/17.
---
drivers/input/mouse/olpc.c | 437 ++++++++++++++++++++++++--------------------
drivers/input/mouse/olpc.h | 7 +
2 files changed, 245 insertions(+), 199 deletions(-)
diff --git a/drivers/input/mouse/olpc.c b/drivers/input/mouse/olpc.c
index 087dc64..9282470 100644
--- a/drivers/input/mouse/olpc.c
+++ b/drivers/input/mouse/olpc.c
@@ -42,83 +42,19 @@ module_param(tpmode, int, 0644);
static int tpdebug;
module_param(tpdebug, int, 0644);
-static const struct olpc_model_info olpc_model_data[] = {
- { { 0x67, 0x00, 0x0a }, 0 }, /* v1 in PT+GS mode. */
- { { 0x67, 0x00, 0x14 }, 0 }, /* v2 in PT+GS mode. */
- { { 0x67, 0x00, 0x28 }, 1 }, /* v3, single-mode. */
+#define OLPC_GS 1 /* The GS sensor. */
+#define OLPC_PT 2 /* The PT sensor. */
+
+static struct olpc_model_info olpc_model_data[] = {
+ { { 0x67, 0x00, 0x0a }, OLPC_GS | OLPC_PT }, /* 1st gen. */
+ { { 0x67, 0x00, 0x14 }, OLPC_GS }, /* 2nd gen. */
+ { { 0x67, 0x00, 0x28 }, OLPC_GS | OLPC_PT }, /* 3nd gen. */
};
-#define OLPC_PKT_SIM 0xeb
#define OLPC_PKT_PT 0xcf
#define OLPC_PKT_GS 0xff
-/*
- * OLPC absolute Mode - simultaneous format
- *
- * byte 0: 1 1 1 0 1 0 1 1
- * byte 1: 0 gx6 gx5 gx4 gx3 gx2 gx1 gx0
- * byte 2: 0 gx10 gx9 gx8 gx7 px9 px8 px7
- * byte 3: 0 gy9 gy8 gy7 1 ? pt-dsw gs-dsw
- * byte 4: 0 gy6 gy5 gy4 gy3 gy2 gy1 gy0
- * byte 5: 0 gz6 gz5 gz4 gz3 gz2 gz1 gz0
- * byte 6: 0 py9 py8 py7 1 ? swr swl
- * byte 7: 0 py6 py5 py4 py3 py2 py1 py0
- * byte 8: 0 px6 px5 px4 px3 px2 px1 px0
- *
- * ?'s are not defined in the protocol spec, may vary between models.
- *
- * gx/gy/gz is for the GlideSensor.
- * px/py is for the PenTablet sensor.
- *
- * swr/swl are the left/right buttons.
- *
- * pt-dsw/gs-dsw indicate that the pt/gs sensor is detecting a
- * pen/finger and is thus sending data this packet.
- */
-
-static void olpc_process_packet(struct psmouse *psmouse)
-{
- struct olpc_data *priv = psmouse->private;
- unsigned char *packet = psmouse->packet;
- struct input_dev *dev = psmouse->dev;
- struct input_dev *dev2 = priv->dev2;
- int px, py, gx, gy, gz, gs_down, pt_down, left, right;
-
- left = packet[6] & 1;
- right = packet[6] & 2;
- gx = packet[1] | ((packet[2] & 0x78) << (7 - 3));
- gy = packet[4] | ((packet[3] & 0x70) << (7 - 4));
- gz = packet[5];
- px = packet[8] | ((packet[2] & 0x7) << 7);
- py = packet[7] | ((packet[6] & 0x70) << (7 - 4));
-
- pt_down = packet[3] & 1;
- gs_down = packet[3] & 2;
-
- input_report_key(dev, BTN_LEFT, left);
- input_report_key(dev2, BTN_LEFT, left);
- input_report_key(dev, BTN_RIGHT, right);
- input_report_key(dev2, BTN_RIGHT, right);
-
- input_report_key(dev, BTN_TOUCH, pt_down);
- input_report_key(dev, BTN_TOOL_PEN, pt_down);
- input_report_key(dev2, BTN_TOUCH, gs_down);
- input_report_key(dev2, BTN_TOOL_FINGER, gs_down);
-
- if (gs_down) {
- input_report_abs(dev2, ABS_X, gx);
- input_report_abs(dev2, ABS_Y, gy);
- }
- input_report_abs(dev2, ABS_PRESSURE, gz);
-
- if (pt_down) {
- input_report_abs(dev, ABS_X, px);
- input_report_abs(dev, ABS_Y, py);
- }
-
- input_sync(dev);
- input_sync(dev2);
-}
+static int olpc_absolute_mode(struct psmouse *psmouse, int mode);
/*
* OLPC absolute Mode - single-mode format
@@ -139,13 +75,13 @@ static void olpc_process_packet(struct p
* pen/finger
*/
-static void olpc_process_pt_packet(struct psmouse *psmouse)
+static void olpc_process_packet_gspt(struct psmouse *psmouse)
{
struct olpc_data *priv = psmouse->private;
unsigned char *packet = psmouse->packet;
struct input_dev *dev = psmouse->dev;
struct input_dev *dev2 = priv->dev2;
- int x, y, z, gs_down, pt_down, left, right;
+ int x, y, z, gs_down = 0, pt_down = 0, left, right;
left = packet[3] & 1;
right = packet[3] & 2;
@@ -153,8 +89,13 @@ static void olpc_process_pt_packet(struc
y = packet[4] | ((packet[3] & 0x70) << (7 - 4));
z = packet[5];
- pt_down = packet[2] & 2;
- gs_down = packet[2] & 1;
+ if (psmouse->packet[0] == OLPC_PKT_GS) {
+ pt_down = !!(packet[2] & 1);
+ gs_down = !!(packet[2] & 2);
+ } else if (psmouse->packet[0] == OLPC_PKT_PT) {
+ gs_down = !!(packet[2] & 1);
+ pt_down = !!(packet[2] & 2);
+ }
if (tpdebug) {
printk(KERN_DEBUG "%s %02x %02x %02x %02x %02x %02x\n",
@@ -165,10 +106,15 @@ static void olpc_process_pt_packet(struc
left, right, pt_down, gs_down, x, y, z);
}
- input_report_key(dev, BTN_LEFT, left);
- input_report_key(dev2, BTN_LEFT, left);
- input_report_key(dev, BTN_RIGHT, right);
- input_report_key(dev2, BTN_RIGHT, right);
+ if (psmouse->packet[0] == OLPC_PKT_PT) {
+ input_report_key(dev, BTN_LEFT, left);
+ input_report_key(dev, BTN_RIGHT, right);
+ } else if (psmouse->packet[0] == OLPC_PKT_GS) {
+ input_report_key(dev, BTN_LEFT, left);
+ input_report_key(dev, BTN_RIGHT, right);
+ input_report_key(dev2, BTN_LEFT, left);
+ input_report_key(dev2, BTN_RIGHT, right);
+ }
input_report_key(dev, BTN_TOUCH, pt_down);
input_report_key(dev, BTN_TOOL_PEN, pt_down);
@@ -177,68 +123,46 @@ static void olpc_process_pt_packet(struc
input_report_abs(dev2, ABS_PRESSURE, z);
- if (pt_down) {
+ if (psmouse->packet[0] == OLPC_PKT_PT && pt_down) {
input_report_abs(dev, ABS_X, x);
input_report_abs(dev, ABS_Y, y);
+ } else if (psmouse->packet[0] == OLPC_PKT_GS && gs_down) {
+ input_report_abs(dev2, ABS_X, x);
+ input_report_abs(dev2, ABS_Y, y);
}
input_sync(dev);
input_sync(dev2);
-}
-
-static void olpc_process_gs_packet(struct psmouse *psmouse)
-{
- struct olpc_data *priv = psmouse->private;
- unsigned char *packet = psmouse->packet;
- struct input_dev *dev = psmouse->dev;
- struct input_dev *dev2 = priv->dev2;
- int x, y, z, gs_down, pt_down, left, right;
-
- left = packet[3] & 1;
- right = packet[3] & 2;
- x = packet[1] | ((packet[2] & 0x78) << (7 - 3));
- y = packet[4] | ((packet[3] & 0x70) << (7 - 4));
- z = packet[5];
- gs_down = packet[2] & 2;
- pt_down = packet[2] & 1;
+ if (!priv->pending_mode)
+ goto switch_mode;
- if (tpdebug) {
- printk(KERN_DEBUG "%s %02x %02x %02x %02x %02x %02x\n",
- __func__, psmouse->packet[0], psmouse->packet[1],
- psmouse->packet[2], psmouse->packet[3], psmouse->packet[4],
- psmouse->packet[5]);
- printk(KERN_DEBUG "l=%d r=%d p=%d g=%d x=%d y=%d z=%d\n",
- left, right, pt_down, gs_down, x, y, z);
+ if (priv->pending_mode == OLPC_GS && pt_down) {
+ priv->pending_mode = 0;
+ cancel_delayed_work(&priv->modeswitch_work_0);
}
- input_report_key(dev, BTN_LEFT, left);
- input_report_key(dev2, BTN_LEFT, left);
- input_report_key(dev, BTN_RIGHT, right);
- input_report_key(dev2, BTN_RIGHT, right);
-
- input_report_key(dev, BTN_TOUCH, pt_down);
- input_report_key(dev, BTN_TOOL_PEN, pt_down);
- input_report_key(dev2, BTN_TOUCH, gs_down);
- input_report_key(dev2, BTN_TOOL_FINGER, gs_down);
-
- input_report_abs(dev2, ABS_PRESSURE, z);
-
- if (gs_down) {
- input_report_abs(dev2, ABS_X, x);
- input_report_abs(dev2, ABS_Y, y);
+ return;
+
+switch_mode:
+ if (priv->i->flags & OLPC_PT && priv->i->flags & OLPC_GS) {
+ if (psmouse->packet[0] == OLPC_PKT_PT && !pt_down) {
+ printk(KERN_WARNING "Scheduling switch to GS.\n");
+ priv->pending_mode = OLPC_GS;
+ queue_work(kpsmoused_wq, &priv->modeswitch_work_0);
+ } else if (psmouse->packet[0] == OLPC_PKT_GS && pt_down) {
+ printk(KERN_WARNING "Scheduling switch to PT.\n");
+ priv->pending_mode = OLPC_PT;
+ queue_work(kpsmoused_wq, &priv->modeswitch_work_0);
+ }
}
-
- input_sync(dev);
- input_sync(dev2);
}
static psmouse_ret_t olpc_process_byte(struct psmouse *psmouse)
{
psmouse_ret_t ret = PSMOUSE_BAD_DATA;
- if (psmouse->packet[0] != OLPC_PKT_SIM &&
- psmouse->packet[0] != OLPC_PKT_PT &&
+ if (psmouse->packet[0] != OLPC_PKT_PT &&
psmouse->packet[0] != OLPC_PKT_GS)
goto out;
@@ -247,55 +171,24 @@ static psmouse_ret_t olpc_process_byte(s
(psmouse->packet[psmouse->pktcnt - 1] & 0x80))
goto out;
- /*
- * For simultaneous mode, bytes 4 and 7 should have 1 in the 4th bit,
- * and the high bit unset.
- */
- if (psmouse->packet[0] == OLPC_PKT_SIM &&
- (psmouse->pktcnt == 4 || psmouse->pktcnt == 7) &&
- ((psmouse->packet[psmouse->pktcnt - 1] & 0x88) != 8))
- goto out;
-
- /*
- * For single mode, byte 4 should have bit 3 set and bit 2 clear
- */
- if (psmouse->packet[0] != OLPC_PKT_SIM &&
- psmouse->pktcnt == 4 &&
- ((psmouse->packet[psmouse->pktcnt - 1] & 0xc) != 0x8))
- goto out;
-
- if (psmouse->packet[0] == OLPC_PKT_PT &&
- psmouse->pktcnt == 6) {
- olpc_process_pt_packet(psmouse);
- ret = PSMOUSE_FULL_PACKET;
- goto out;
- } else if (psmouse->packet[0] == OLPC_PKT_GS &&
- psmouse->pktcnt == 6) {
- olpc_process_gs_packet(psmouse);
- ret = PSMOUSE_FULL_PACKET;
- goto out;
- } else if (psmouse->pktcnt == 9) {
- olpc_process_packet(psmouse);
-
+ if (psmouse->pktcnt == 6) {
+ olpc_process_packet_gspt(psmouse);
ret = PSMOUSE_FULL_PACKET;
goto out;
}
ret = PSMOUSE_GOOD_DATA;
out:
- if (ret != PSMOUSE_GOOD_DATA)
- dev_dbg(psmouse->dev->cdev.dev, "olpc.c(%d): ret: %d, len: %u,"
- "data: %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x",
- __LINE__, ret, psmouse->pktcnt,
- psmouse->packet[0], psmouse->packet[1],
- psmouse->packet[2], psmouse->packet[3],
- psmouse->packet[4], psmouse->packet[5],
- psmouse->packet[6], psmouse->packet[7],
- psmouse->packet[8]);
+ if (ret != PSMOUSE_GOOD_DATA && ret != PSMOUSE_FULL_PACKET)
+ printk(KERN_DEBUG "%s: (%d) %02x %02x %02x %02x %02x %02x\n",
+ __func__, psmouse->pktcnt, psmouse->packet[0],
+ psmouse->packet[1], psmouse->packet[2],
+ psmouse->packet[3], psmouse->packet[4],
+ psmouse->packet[5]);
return ret;
}
-static const struct olpc_model_info *olpc_get_model(struct psmouse *psmouse)
+static struct olpc_model_info *olpc_get_model(struct psmouse *psmouse)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param[4];
@@ -325,42 +218,63 @@ static const struct olpc_model_info *olp
return NULL;
}
-static int olpc_absolute_mode(struct psmouse *psmouse)
+static int olpc_find_mode (struct psmouse *psmouse)
+{
+ struct olpc_data *priv = psmouse->private;
+ int mode;
+
+ if (tpmode < -1 || tpmode > 4)
+ return -1;
+
+ if (tpmode)
+ priv->i->flags = tpmode;
+
+ mode = priv->i->flags;
+
+ if (mode & OLPC_GS) {
+ priv->initial = OLPC_GS;
+ } else if (mode & OLPC_PT) {
+ priv->initial = OLPC_PT;
+ } else
+ return -1;
+
+ return priv->initial;
+}
+
+static int olpc_absolute_mode(struct psmouse *psmouse, int mode)
{
struct ps2dev *ps2dev = &psmouse->ps2dev;
unsigned char param;
/* Switch to 'Advanced mode.', four disables in a row. */
if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
- ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
- ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
- ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE))
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE))
return -1;
- /*
- * Switch to simultaneous mode, F2 (GETID) three times with no
- * arguments or reply, followed by SETRES with an argument of 2.
- */
- ps2_command(ps2dev, NULL, 0xF2);
- ps2_command(ps2dev, NULL, 0xF2);
- ps2_command(ps2dev, NULL, 0xF2);
- switch(tpmode) {
+ if (ps2_command(ps2dev, ¶m, 0x01F2))
+ return -3;
+ if (ps2_command(ps2dev, ¶m, 0x01F2))
+ return -4;
+ if (ps2_command(ps2dev, ¶m, 0x01F2))
+ return -5;
+
+ switch(mode) {
default:
- printk(KERN_WARNING "Invalid tpmode %d. Default to simultaneous mode\n", tpmode);
- case 0: /* Dual mode */
- param = 0x02;
- ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES);
- ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
+ printk(KERN_WARNING __FILE__ ": Invalid tpmode %d. Default to GS mode\n", tpmode);
+ case OLPC_GS: /* GS only */
+ if (ps2_command(ps2dev, NULL, 0xE6))
+ return -8;
break;
- case 1: /* GS only */
- ps2_command(ps2dev, NULL, 0xe6);
- break;
- case 2: /* PT only */
- ps2_command(ps2dev, NULL, 0xe7);
+ case OLPC_PT: /* PT only */
+ if (ps2_command(ps2dev, NULL, 0xE7))
+ return -9;
break;
}
- param = 100;
- ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES);
+
+ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))
+ return -10;
return 0;
}
@@ -384,8 +298,11 @@ static int olpc_reconnect(struct psmouse
if (!(priv->i = olpc_get_model(psmouse)))
return -1;
- if (olpc_absolute_mode(psmouse)) {
- printk(KERN_ERR "olpc.c: Failed to reenable absolute mode.\n");
+ if (olpc_find_mode (psmouse) < 0)
+ return -1;
+
+ if (olpc_absolute_mode(psmouse, priv->initial)) {
+ printk(KERN_ERR __FILE__ ": Failed to reenable absolute mode.\n");
return -1;
}
@@ -401,6 +318,122 @@ static void olpc_disconnect(struct psmou
kfree(priv);
}
+static void olpc_switch_mode_0 (void *p)
+{
+ struct psmouse *psmouse = p;
+ struct olpc_data *priv = psmouse->private;
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ int pending_mode, ret, count;
+ unsigned char param[3];
+
+ pending_mode = priv->pending_mode;
+ if (!pending_mode) {
+ printk (KERN_WARNING __FILE__ ": In switch_mode, no target mode.\n");
+ return;
+ }
+ if (pending_mode == priv->current_mode && 0) {
+ printk (KERN_WARNING __FILE__ ": In switch_mode, pending == current.\n");
+ return;
+ }
+
+ if (tpdebug)
+ printk(KERN_WARNING __FILE__ ": Disable for switch to %d. [%lu]\n", pending_mode, jiffies);
+
+ /* XXX: This is a bit hacky, make sure this isn't screwing stuff up. */
+ psmouse->state = PSMOUSE_INITIALIZING;
+
+ ret = ps2_command(ps2dev, NULL, 0xF5);
+ if (ret) {
+ /* Wait 100ms, then continue. */
+ queue_delayed_work(kpsmoused_wq, &priv->modeswitch_work_1, msecs_to_jiffies(100));
+ return;
+ }
+ printk(KERN_WARNING __FILE__ ": Disable failed for switch to %d. (%d) [%lu]\n", pending_mode, ret, jiffies);
+ }
+}
+
+static void olpc_switch_mode_1 (void *p)
+{
+ struct psmouse *psmouse = p;
+ struct olpc_data *priv = psmouse->private;
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ unsigned char param[3];
+ int ret = 0, pending_mode, count;
+
+ pending_mode = priv->pending_mode;
+ if (!pending_mode) {
+ printk (KERN_WARNING __FILE__ ": In switch_mode, no target mode.\n");
+ return;
+ }
+ if (pending_mode == priv->current_mode && 0) {
+ printk (KERN_WARNING __FILE__ ": In switch_mode, pending == current.\n");
+ return;
+ }
+
+ if (tpdebug)
+ printk(KERN_WARNING __FILE__ ": Switching to %d. [%lu]\n", pending_mode, jiffies);
+
+ if (ps2_command(ps2dev, param, 0x01F2)) {
+ ret = 3;
+ goto bad;
+ }
+ if (ps2_command(ps2dev, param, 0x01F2)) {
+ ret = 4;
+ goto bad;
+ }
+ if (ps2_command(ps2dev, param, 0x01F2)) {
+ ret = 5;
+ goto bad;
+ }
+
+ switch(pending_mode) {
+ default:
+ printk(KERN_WARNING __FILE__ ": Invalid tpmode %d. Default to simultaneous mode\n", tpmode);
+ case OLPC_GS: /* GS only */
+ if (ps2_command(ps2dev, NULL, 0xE6)) {
+ ret = -20;
+ goto bad;
+ }
+ break;
+ case OLPC_PT: /* PT only */
+ if (ps2_command(ps2dev, NULL, 0xE7)) {
+ ret = -30;
+ goto bad;
+ }
+ break;
+ }
+
+ count = 0;
+ while (count++ < 5) {
+ /* XXX: This is a bit hacky, make sure this isn't screwing stuff up. */
+ psmouse->pktcnt = psmouse->out_of_sync = 0;
+ psmouse->last = jiffies;
+ psmouse->state = PSMOUSE_ACTIVATED;
+
+ ret = ps2_sendbyte(ps2dev, 0xF4, 500);
+ if (!ret) {
+ break;
+ } else if (tpdebug) {
+ printk(KERN_WARNING __FILE__ ": Enable failed for switch to %d. (%d) [%lu]\n", pending_mode, ret, jiffies);
+ }
+ ps2_command(ps2dev, param, 0x03E9);
+ }
+
+ if (tpdebug)
+ printk(KERN_WARNING __FILE__ ": Switched to %d: %d.\n", pending_mode, ret);
+
+ if (!ret)
+ priv->current_mode = pending_mode;
+ priv->pending_mode = 0;
+
+ return;
+
+bad:
+ printk(KERN_WARNING __FILE__ ": Failure in switching to %d. (%d) Retrying..\n", pending_mode, ret);
+ /* Delay, restart. */
+ queue_delayed_work(kpsmoused_wq, &priv->modeswitch_work_1, HZ/10);
+}
+
int olpc_init(struct psmouse *psmouse)
{
struct olpc_data *priv;
@@ -418,12 +451,13 @@ int olpc_init(struct psmouse *psmouse)
if (!(priv->i = olpc_get_model(psmouse)))
goto init_fail;
- if (!tpmode && (priv->i->flags & 1)) {
- /* Can't do dual-mode on newest device; use GS mode to start */
- tpmode = 1;
+ if (olpc_find_mode (psmouse) < 0) {
+ printk(KERN_ERR __FILE__ ": Failed to identify proper mode\n");
+ goto init_fail;
}
- if (olpc_absolute_mode(psmouse)) {
- printk(KERN_ERR "olpc.c: Failed to enable absolute mode\n");
+
+ if (olpc_absolute_mode(psmouse, priv->initial)) {
+ printk(KERN_ERR __FILE__ ": Failed to enable absolute mode\n");
goto init_fail;
}
@@ -462,17 +496,24 @@ int olpc_init(struct psmouse *psmouse)
input_set_abs_params(dev2, ABS_Y, 70, 325, 0, 0);
input_set_abs_params(dev2, ABS_PRESSURE, 0, 63, 0, 0);
- if (input_register_device(dev2))
+ if (input_register_device(dev2)) {
+ printk(KERN_ERR __FILE__ ": Failed to register GlideSensor\n");
goto init_fail;
+ }
psmouse->protocol_handler = olpc_process_byte;
psmouse->poll = olpc_poll;
psmouse->disconnect = olpc_disconnect;
psmouse->reconnect = olpc_reconnect;
- psmouse->pktsize = 9;
+ psmouse->pktsize = 6;
/* Disable the idle resync. */
psmouse->resync_time = 0;
+ /* Reset after a lot of bad bytes. */
+ psmouse->resetafter = 1024;
+
+ INIT_WORK(&priv->modeswitch_work_0, olpc_switch_mode_0, psmouse);
+ INIT_WORK(&priv->modeswitch_work_1, olpc_switch_mode_1, psmouse);
return 0;
diff --git a/drivers/input/mouse/olpc.h b/drivers/input/mouse/olpc.h
index 4e7c76a..3b147e8 100644
--- a/drivers/input/mouse/olpc.h
+++ b/drivers/input/mouse/olpc.h
@@ -27,7 +27,12 @@ struct olpc_data {
struct input_dev *dev2; /* Relative device */
char name[32]; /* Name */
char phys[32]; /* Phys */
- const struct olpc_model_info *i;/* Info */
+ struct olpc_model_info *i; /* Info */
+ int initial;
+ int pending_mode;
+ int current_mode;
+ struct work_struct modeswitch_work_0;
+ struct work_struct modeswitch_work_1;
};
More information about the Commits-kernel
mailing list