|
@@ -189,7 +189,7 @@ struct ati_remote {
|
|
|
dma_addr_t inbuf_dma;
|
|
|
dma_addr_t outbuf_dma;
|
|
|
|
|
|
- unsigned char old_data[2]; /* Detect duplicate events */
|
|
|
+ unsigned char old_data; /* Detect duplicate events */
|
|
|
unsigned long old_jiffies;
|
|
|
unsigned long acc_jiffies; /* handle acceleration */
|
|
|
unsigned long first_jiffies;
|
|
@@ -221,35 +221,35 @@ struct ati_remote {
|
|
|
/* Translation table from hardware messages to input events. */
|
|
|
static const struct {
|
|
|
short kind;
|
|
|
- unsigned char data1, data2;
|
|
|
+ unsigned char data;
|
|
|
int type;
|
|
|
unsigned int code;
|
|
|
int value;
|
|
|
} ati_remote_tbl[] = {
|
|
|
/* Directional control pad axes */
|
|
|
- {KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */
|
|
|
- {KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */
|
|
|
- {KIND_ACCEL, 0x37, 0x72, EV_REL, REL_Y, -1}, /* up */
|
|
|
- {KIND_ACCEL, 0x38, 0x73, EV_REL, REL_Y, 1}, /* down */
|
|
|
+ {KIND_ACCEL, 0x70, EV_REL, REL_X, -1}, /* left */
|
|
|
+ {KIND_ACCEL, 0x71, EV_REL, REL_X, 1}, /* right */
|
|
|
+ {KIND_ACCEL, 0x72, EV_REL, REL_Y, -1}, /* up */
|
|
|
+ {KIND_ACCEL, 0x73, EV_REL, REL_Y, 1}, /* down */
|
|
|
/* Directional control pad diagonals */
|
|
|
- {KIND_LU, 0x39, 0x74, EV_REL, 0, 0}, /* left up */
|
|
|
- {KIND_RU, 0x3a, 0x75, EV_REL, 0, 0}, /* right up */
|
|
|
- {KIND_LD, 0x3c, 0x77, EV_REL, 0, 0}, /* left down */
|
|
|
- {KIND_RD, 0x3b, 0x76, EV_REL, 0, 0}, /* right down */
|
|
|
+ {KIND_LU, 0x74, EV_REL, 0, 0}, /* left up */
|
|
|
+ {KIND_RU, 0x75, EV_REL, 0, 0}, /* right up */
|
|
|
+ {KIND_LD, 0x77, EV_REL, 0, 0}, /* left down */
|
|
|
+ {KIND_RD, 0x76, EV_REL, 0, 0}, /* right down */
|
|
|
|
|
|
/* "Mouse button" buttons */
|
|
|
- {KIND_LITERAL, 0x3d, 0x78, EV_KEY, BTN_LEFT, 1}, /* left btn down */
|
|
|
- {KIND_LITERAL, 0x3e, 0x79, EV_KEY, BTN_LEFT, 0}, /* left btn up */
|
|
|
- {KIND_LITERAL, 0x41, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */
|
|
|
- {KIND_LITERAL, 0x42, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */
|
|
|
+ {KIND_LITERAL, 0x78, EV_KEY, BTN_LEFT, 1}, /* left btn down */
|
|
|
+ {KIND_LITERAL, 0x79, EV_KEY, BTN_LEFT, 0}, /* left btn up */
|
|
|
+ {KIND_LITERAL, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */
|
|
|
+ {KIND_LITERAL, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */
|
|
|
|
|
|
/* Artificial "doubleclick" events are generated by the hardware.
|
|
|
* They are mapped to the "side" and "extra" mouse buttons here. */
|
|
|
- {KIND_FILTERED, 0x3f, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */
|
|
|
- {KIND_FILTERED, 0x43, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */
|
|
|
+ {KIND_FILTERED, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */
|
|
|
+ {KIND_FILTERED, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */
|
|
|
|
|
|
/* Non-mouse events are handled by rc-core */
|
|
|
- {KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0}
|
|
|
+ {KIND_END, 0x00, EV_MAX + 1, 0, 0}
|
|
|
};
|
|
|
|
|
|
/* Local function prototypes */
|
|
@@ -396,25 +396,6 @@ static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd, unsigne
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * ati_remote_event_lookup
|
|
|
- */
|
|
|
-static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2)
|
|
|
-{
|
|
|
- int i;
|
|
|
-
|
|
|
- for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) {
|
|
|
- /*
|
|
|
- * Decide if the table entry matches the remote input.
|
|
|
- */
|
|
|
- if (ati_remote_tbl[i].data1 == d1 &&
|
|
|
- ati_remote_tbl[i].data2 == d2)
|
|
|
- return i;
|
|
|
-
|
|
|
- }
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* ati_remote_compute_accel
|
|
|
*
|
|
@@ -463,7 +444,15 @@ static void ati_remote_input_report(struct urb *urb)
|
|
|
int index = -1;
|
|
|
int acc;
|
|
|
int remote_num;
|
|
|
- unsigned char scancode[2];
|
|
|
+ unsigned char scancode;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * data[0] = 0x14
|
|
|
+ * data[1] = data[2] + data[3] + 0xd5 (a checksum byte)
|
|
|
+ * data[2] = the key code (with toggle bit in MSB with some models)
|
|
|
+ * data[3] = channel << 4 (the low 4 bits must be zero)
|
|
|
+ */
|
|
|
|
|
|
/* Deal with strange looking inputs */
|
|
|
if ( (urb->actual_length != 4) || (data[0] != 0x14) ||
|
|
@@ -472,6 +461,13 @@ static void ati_remote_input_report(struct urb *urb)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ if (data[1] != ((data[2] + data[3] + 0xd5) & 0xff)) {
|
|
|
+ dbginfo(&ati_remote->interface->dev,
|
|
|
+ "wrong checksum in input: %02x %02x %02x %02x\n",
|
|
|
+ data[0], data[1], data[2], data[3]);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
/* Mask unwanted remote channels. */
|
|
|
/* note: remote_num is 0-based, channel 1 on remote == 0 here */
|
|
|
remote_num = (data[3] >> 4) & 0x0f;
|
|
@@ -482,31 +478,30 @@ static void ati_remote_input_report(struct urb *urb)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- scancode[0] = (((data[1] - ((remote_num + 1) << 4)) & 0xf0) | (data[1] & 0x0f));
|
|
|
-
|
|
|
/*
|
|
|
- * Some devices (e.g. SnapStream Firefly) use 8080 as toggle code,
|
|
|
- * so we have to clear them. The first bit is a bit tricky as the
|
|
|
- * "non-toggled" state depends on remote_num, so we xor it with the
|
|
|
- * second bit which is only used for toggle.
|
|
|
+ * MSB is a toggle code, though only used by some devices
|
|
|
+ * (e.g. SnapStream Firefly)
|
|
|
*/
|
|
|
- scancode[0] ^= (data[2] & 0x80);
|
|
|
-
|
|
|
- scancode[1] = data[2] & ~0x80;
|
|
|
+ scancode = data[2] & 0x7f;
|
|
|
|
|
|
- /* Look up event code index in mouse translation table. */
|
|
|
- index = ati_remote_event_lookup(remote_num, scancode[0], scancode[1]);
|
|
|
+ /* Look up event code index in the mouse translation table. */
|
|
|
+ for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) {
|
|
|
+ if (scancode == ati_remote_tbl[i].data) {
|
|
|
+ index = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
if (index >= 0) {
|
|
|
dbginfo(&ati_remote->interface->dev,
|
|
|
- "channel 0x%02x; mouse data %02x,%02x; index %d; keycode %d\n",
|
|
|
- remote_num, data[1], data[2], index, ati_remote_tbl[index].code);
|
|
|
+ "channel 0x%02x; mouse data %02x; index %d; keycode %d\n",
|
|
|
+ remote_num, data[2], index, ati_remote_tbl[index].code);
|
|
|
if (!dev)
|
|
|
return; /* no mouse device */
|
|
|
} else
|
|
|
dbginfo(&ati_remote->interface->dev,
|
|
|
- "channel 0x%02x; key data %02x,%02x, scancode %02x,%02x\n",
|
|
|
- remote_num, data[1], data[2], scancode[0], scancode[1]);
|
|
|
+ "channel 0x%02x; key data %02x, scancode %02x\n",
|
|
|
+ remote_num, data[2], scancode);
|
|
|
|
|
|
|
|
|
if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) {
|
|
@@ -523,8 +518,7 @@ static void ati_remote_input_report(struct urb *urb)
|
|
|
unsigned long now = jiffies;
|
|
|
|
|
|
/* Filter duplicate events which happen "too close" together. */
|
|
|
- if (ati_remote->old_data[0] == data[1] &&
|
|
|
- ati_remote->old_data[1] == data[2] &&
|
|
|
+ if (ati_remote->old_data == data[2] &&
|
|
|
time_before(now, ati_remote->old_jiffies +
|
|
|
msecs_to_jiffies(repeat_filter))) {
|
|
|
ati_remote->repeat_count++;
|
|
@@ -533,8 +527,7 @@ static void ati_remote_input_report(struct urb *urb)
|
|
|
ati_remote->first_jiffies = now;
|
|
|
}
|
|
|
|
|
|
- ati_remote->old_data[0] = data[1];
|
|
|
- ati_remote->old_data[1] = data[2];
|
|
|
+ ati_remote->old_data = data[2];
|
|
|
ati_remote->old_jiffies = now;
|
|
|
|
|
|
/* Ensure we skip at least the 4 first duplicate events (generated
|
|
@@ -549,14 +542,13 @@ static void ati_remote_input_report(struct urb *urb)
|
|
|
|
|
|
if (index < 0) {
|
|
|
/* Not a mouse event, hand it to rc-core. */
|
|
|
- u32 rc_code = (scancode[0] << 8) | scancode[1];
|
|
|
|
|
|
/*
|
|
|
* We don't use the rc-core repeat handling yet as
|
|
|
* it would cause ghost repeats which would be a
|
|
|
* regression for this driver.
|
|
|
*/
|
|
|
- rc_keydown_notimeout(ati_remote->rdev, rc_code,
|
|
|
+ rc_keydown_notimeout(ati_remote->rdev, scancode,
|
|
|
data[2]);
|
|
|
rc_keyup(ati_remote->rdev);
|
|
|
return;
|
|
@@ -607,8 +599,7 @@ static void ati_remote_input_report(struct urb *urb)
|
|
|
input_sync(dev);
|
|
|
|
|
|
ati_remote->old_jiffies = jiffies;
|
|
|
- ati_remote->old_data[0] = data[1];
|
|
|
- ati_remote->old_data[1] = data[2];
|
|
|
+ ati_remote->old_data = data[2];
|
|
|
}
|
|
|
}
|
|
|
|