summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/input/ati_remote.c135
1 files changed, 77 insertions, 58 deletions
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
index 5a56f6cb36a..3719fcb04b8 100644
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -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;
@@ -417,6 +414,43 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2)
}
/*
+ * 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
*/
static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
@@ -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];
+ }
}
/*