Input: ati_remote - use msec instead of jiffies

By using milliseconds instead of jiffies to calculate acceleration
factor we make the code immune to changes in HZ.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
Dmitry Torokhov 2006-08-04 22:53:37 -04:00
parent c3c38fbd0c
commit 2ffc1ccad8

View file

@ -157,9 +157,6 @@ MODULE_DEVICE_TABLE(usb, ati_remote_table);
static char init1[] = { 0x01, 0x00, 0x20, 0x14 }; static char init1[] = { 0x01, 0x00, 0x20, 0x14 };
static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; 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 ati_remote {
struct input_dev *idev; struct input_dev *idev;
struct usb_device *udev; struct usb_device *udev;
@ -416,6 +413,43 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2)
return -1; 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 * 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); ati_remote_tbl[index].code, 0);
input_sync(dev); input_sync(dev);
return; } else {
}
/* /*
* Other event kinds are from the directional control pad, and have an * Other event kinds are from the directional control pad, and have an
* acceleration factor applied to them. Without this acceleration, the * acceleration factor applied to them. Without this acceleration, the
* control pad is mostly unusable. * control pad is mostly unusable.
* */
* If elapsed time since last event is > 1/4 second, user "stopped", acc = ati_remote_compute_accel(ati_remote);
* 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); input_regs(dev, regs);
switch (ati_remote_tbl[index].kind) { switch (ati_remote_tbl[index].kind) {
case KIND_ACCEL: case KIND_ACCEL:
input_event(dev, ati_remote_tbl[index].type, input_event(dev, ati_remote_tbl[index].type,
ati_remote_tbl[index].code, ati_remote_tbl[index].code,
ati_remote_tbl[index].value * acc); ati_remote_tbl[index].value * acc);
break; break;
case KIND_LU: case KIND_LU:
input_report_rel(dev, REL_X, -acc); input_report_rel(dev, REL_X, -acc);
input_report_rel(dev, REL_Y, -acc); input_report_rel(dev, REL_Y, -acc);
break; break;
case KIND_RU: case KIND_RU:
input_report_rel(dev, REL_X, acc); input_report_rel(dev, REL_X, acc);
input_report_rel(dev, REL_Y, -acc); input_report_rel(dev, REL_Y, -acc);
break; break;
case KIND_LD: case KIND_LD:
input_report_rel(dev, REL_X, -acc); input_report_rel(dev, REL_X, -acc);
input_report_rel(dev, REL_Y, acc); input_report_rel(dev, REL_Y, acc);
break; break;
case KIND_RD: case KIND_RD:
input_report_rel(dev, REL_X, acc); input_report_rel(dev, REL_X, acc);
input_report_rel(dev, REL_Y, acc); input_report_rel(dev, REL_Y, acc);
break; break;
default: default:
dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n", dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
ati_remote_tbl[index].kind); ati_remote_tbl[index].kind);
} }
input_sync(dev); input_sync(dev);
ati_remote->old_jiffies = jiffies; ati_remote->old_jiffies = jiffies;
ati_remote->old_data[0] = data[1]; ati_remote->old_data[0] = data[1];
ati_remote->old_data[1] = data[2]; ati_remote->old_data[1] = data[2];
}
} }
/* /*