|
@@ -157,9 +157,6 @@ MODULE_DEVICE_TABLE(usb, ati_remote_table);
|
|
|
static char init1[] = { 0x01, 0x00, 0x20, 0x14 };
|
|
|
static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 };
|
|
|
|
|
|
-/* Acceleration curve for directional control pad */
|
|
|
-static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
|
|
|
-
|
|
|
struct ati_remote {
|
|
|
struct input_dev *idev;
|
|
|
struct usb_device *udev;
|
|
@@ -416,6 +413,43 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2)
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * ati_remote_compute_accel
|
|
|
+ *
|
|
|
+ * Implements acceleration curve for directional control pad
|
|
|
+ * If elapsed time since last event is > 1/4 second, user "stopped",
|
|
|
+ * so reset acceleration. Otherwise, user is probably holding the control
|
|
|
+ * pad down, so we increase acceleration, ramping up over two seconds to
|
|
|
+ * a maximum speed.
|
|
|
+ */
|
|
|
+static int ati_remote_compute_accel(struct ati_remote *ati_remote)
|
|
|
+{
|
|
|
+ static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
|
|
|
+ unsigned long now = jiffies;
|
|
|
+ int acc;
|
|
|
+
|
|
|
+ if (time_after(now, ati_remote->old_jiffies + msecs_to_jiffies(250))) {
|
|
|
+ acc = 1;
|
|
|
+ ati_remote->acc_jiffies = now;
|
|
|
+ }
|
|
|
+ else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(125)))
|
|
|
+ acc = accel[0];
|
|
|
+ else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(250)))
|
|
|
+ acc = accel[1];
|
|
|
+ else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(500)))
|
|
|
+ acc = accel[2];
|
|
|
+ else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1000)))
|
|
|
+ acc = accel[3];
|
|
|
+ else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1500)))
|
|
|
+ acc = accel[4];
|
|
|
+ else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(2000)))
|
|
|
+ acc = accel[5];
|
|
|
+ else
|
|
|
+ acc = accel[6];
|
|
|
+
|
|
|
+ return acc;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* ati_remote_report_input
|
|
|
*/
|
|
@@ -494,63 +528,48 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
|
|
|
ati_remote_tbl[index].code, 0);
|
|
|
input_sync(dev);
|
|
|
|
|
|
- return;
|
|
|
- }
|
|
|
+ } else {
|
|
|
|
|
|
- /*
|
|
|
- * Other event kinds are from the directional control pad, and have an
|
|
|
- * acceleration factor applied to them. Without this acceleration, the
|
|
|
- * control pad is mostly unusable.
|
|
|
- *
|
|
|
- * If elapsed time since last event is > 1/4 second, user "stopped",
|
|
|
- * so reset acceleration. Otherwise, user is probably holding the control
|
|
|
- * pad down, so we increase acceleration, ramping up over two seconds to
|
|
|
- * a maximum speed. The acceleration curve is #defined above.
|
|
|
- */
|
|
|
- if (time_after(jiffies, ati_remote->old_jiffies + (HZ >> 2))) {
|
|
|
- acc = 1;
|
|
|
- ati_remote->acc_jiffies = jiffies;
|
|
|
- }
|
|
|
- else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 3))) acc = accel[0];
|
|
|
- else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 2))) acc = accel[1];
|
|
|
- else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 1))) acc = accel[2];
|
|
|
- else if (time_before(jiffies, ati_remote->acc_jiffies + HZ)) acc = accel[3];
|
|
|
- else if (time_before(jiffies, ati_remote->acc_jiffies + HZ+(HZ>>1))) acc = accel[4];
|
|
|
- else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ << 1))) acc = accel[5];
|
|
|
- else acc = accel[6];
|
|
|
-
|
|
|
- input_regs(dev, regs);
|
|
|
- switch (ati_remote_tbl[index].kind) {
|
|
|
- case KIND_ACCEL:
|
|
|
- input_event(dev, ati_remote_tbl[index].type,
|
|
|
- ati_remote_tbl[index].code,
|
|
|
- ati_remote_tbl[index].value * acc);
|
|
|
- break;
|
|
|
- case KIND_LU:
|
|
|
- input_report_rel(dev, REL_X, -acc);
|
|
|
- input_report_rel(dev, REL_Y, -acc);
|
|
|
- break;
|
|
|
- case KIND_RU:
|
|
|
- input_report_rel(dev, REL_X, acc);
|
|
|
- input_report_rel(dev, REL_Y, -acc);
|
|
|
- break;
|
|
|
- case KIND_LD:
|
|
|
- input_report_rel(dev, REL_X, -acc);
|
|
|
- input_report_rel(dev, REL_Y, acc);
|
|
|
- break;
|
|
|
- case KIND_RD:
|
|
|
- input_report_rel(dev, REL_X, acc);
|
|
|
- input_report_rel(dev, REL_Y, acc);
|
|
|
- break;
|
|
|
- default:
|
|
|
- dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
|
|
|
- ati_remote_tbl[index].kind);
|
|
|
- }
|
|
|
- input_sync(dev);
|
|
|
+ /*
|
|
|
+ * Other event kinds are from the directional control pad, and have an
|
|
|
+ * acceleration factor applied to them. Without this acceleration, the
|
|
|
+ * control pad is mostly unusable.
|
|
|
+ */
|
|
|
+ acc = ati_remote_compute_accel(ati_remote);
|
|
|
|
|
|
- ati_remote->old_jiffies = jiffies;
|
|
|
- ati_remote->old_data[0] = data[1];
|
|
|
- ati_remote->old_data[1] = data[2];
|
|
|
+ input_regs(dev, regs);
|
|
|
+ switch (ati_remote_tbl[index].kind) {
|
|
|
+ case KIND_ACCEL:
|
|
|
+ input_event(dev, ati_remote_tbl[index].type,
|
|
|
+ ati_remote_tbl[index].code,
|
|
|
+ ati_remote_tbl[index].value * acc);
|
|
|
+ break;
|
|
|
+ case KIND_LU:
|
|
|
+ input_report_rel(dev, REL_X, -acc);
|
|
|
+ input_report_rel(dev, REL_Y, -acc);
|
|
|
+ break;
|
|
|
+ case KIND_RU:
|
|
|
+ input_report_rel(dev, REL_X, acc);
|
|
|
+ input_report_rel(dev, REL_Y, -acc);
|
|
|
+ break;
|
|
|
+ case KIND_LD:
|
|
|
+ input_report_rel(dev, REL_X, -acc);
|
|
|
+ input_report_rel(dev, REL_Y, acc);
|
|
|
+ break;
|
|
|
+ case KIND_RD:
|
|
|
+ input_report_rel(dev, REL_X, acc);
|
|
|
+ input_report_rel(dev, REL_Y, acc);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
|
|
|
+ ati_remote_tbl[index].kind);
|
|
|
+ }
|
|
|
+ input_sync(dev);
|
|
|
+
|
|
|
+ ati_remote->old_jiffies = jiffies;
|
|
|
+ ati_remote->old_data[0] = data[1];
|
|
|
+ ati_remote->old_data[1] = data[2];
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/*
|