|
@@ -30,6 +30,17 @@ static bool emulate_scroll_wheel = true;
|
|
module_param(emulate_scroll_wheel, bool, 0644);
|
|
module_param(emulate_scroll_wheel, bool, 0644);
|
|
MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel");
|
|
MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel");
|
|
|
|
|
|
|
|
+static unsigned int scroll_speed = 32;
|
|
|
|
+static int param_set_scroll_speed(const char *val, struct kernel_param *kp) {
|
|
|
|
+ unsigned long speed;
|
|
|
|
+ if (!val || strict_strtoul(val, 0, &speed) || speed > 63)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ scroll_speed = speed;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+module_param_call(scroll_speed, param_set_scroll_speed, param_get_uint, &scroll_speed, 0644);
|
|
|
|
+MODULE_PARM_DESC(scroll_speed, "Scroll speed, value from 0 (slow) to 63 (fast)");
|
|
|
|
+
|
|
static bool scroll_acceleration = false;
|
|
static bool scroll_acceleration = false;
|
|
module_param(scroll_acceleration, bool, 0644);
|
|
module_param(scroll_acceleration, bool, 0644);
|
|
MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events");
|
|
MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events");
|
|
@@ -54,6 +65,8 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
|
|
#define TOUCH_STATE_START 0x30
|
|
#define TOUCH_STATE_START 0x30
|
|
#define TOUCH_STATE_DRAG 0x40
|
|
#define TOUCH_STATE_DRAG 0x40
|
|
|
|
|
|
|
|
+#define SCROLL_ACCEL_DEFAULT 7
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* struct magicmouse_sc - Tracks Magic Mouse-specific data.
|
|
* struct magicmouse_sc - Tracks Magic Mouse-specific data.
|
|
* @input: Input device through which we report events.
|
|
* @input: Input device through which we report events.
|
|
@@ -145,7 +158,7 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
|
|
input_report_key(msc->input, BTN_RIGHT, state & 2);
|
|
input_report_key(msc->input, BTN_RIGHT, state & 2);
|
|
|
|
|
|
if (state != last_state)
|
|
if (state != last_state)
|
|
- msc->scroll_accel = 0;
|
|
|
|
|
|
+ msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
|
|
}
|
|
}
|
|
|
|
|
|
static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata)
|
|
static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata)
|
|
@@ -167,30 +180,28 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
|
|
* vertical touch motions.
|
|
* vertical touch motions.
|
|
*/
|
|
*/
|
|
if (emulate_scroll_wheel) {
|
|
if (emulate_scroll_wheel) {
|
|
- static const int accel_profile[] = {
|
|
|
|
- 256, 228, 192, 160, 128, 96, 64, 32,
|
|
|
|
- };
|
|
|
|
unsigned long now = jiffies;
|
|
unsigned long now = jiffies;
|
|
int step = msc->touches[id].scroll_y - y;
|
|
int step = msc->touches[id].scroll_y - y;
|
|
|
|
|
|
- /* Reset acceleration after half a second. */
|
|
|
|
- if (time_after(now, msc->scroll_jiffies + HZ / 2))
|
|
|
|
- msc->scroll_accel = 0;
|
|
|
|
-
|
|
|
|
/* Calculate and apply the scroll motion. */
|
|
/* Calculate and apply the scroll motion. */
|
|
switch (tdata[7] & TOUCH_STATE_MASK) {
|
|
switch (tdata[7] & TOUCH_STATE_MASK) {
|
|
case TOUCH_STATE_START:
|
|
case TOUCH_STATE_START:
|
|
msc->touches[id].scroll_y = y;
|
|
msc->touches[id].scroll_y = y;
|
|
- if (scroll_acceleration)
|
|
|
|
- msc->scroll_accel = min_t(int,
|
|
|
|
- msc->scroll_accel + 1,
|
|
|
|
- ARRAY_SIZE(accel_profile) - 1);
|
|
|
|
|
|
+
|
|
|
|
+ /* Reset acceleration after half a second. */
|
|
|
|
+ if (scroll_acceleration && time_before(now,
|
|
|
|
+ msc->scroll_jiffies + HZ / 2))
|
|
|
|
+ msc->scroll_accel = max_t(int,
|
|
|
|
+ msc->scroll_accel - 1, 1);
|
|
|
|
+ else
|
|
|
|
+ msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
|
|
|
|
+
|
|
break;
|
|
break;
|
|
case TOUCH_STATE_DRAG:
|
|
case TOUCH_STATE_DRAG:
|
|
- step = step / accel_profile[msc->scroll_accel];
|
|
|
|
|
|
+ step /= (64 - (int)scroll_speed) * msc->scroll_accel;
|
|
if (step != 0) {
|
|
if (step != 0) {
|
|
- msc->touches[id].scroll_y -=
|
|
|
|
- step * accel_profile[msc->scroll_accel];
|
|
|
|
|
|
+ msc->touches[id].scroll_y -= step *
|
|
|
|
+ (64 - scroll_speed) * msc->scroll_accel;
|
|
msc->scroll_jiffies = now;
|
|
msc->scroll_jiffies = now;
|
|
input_report_rel(input, REL_WHEEL, step);
|
|
input_report_rel(input, REL_WHEEL, step);
|
|
}
|
|
}
|
|
@@ -351,6 +362,8 @@ static int magicmouse_probe(struct hid_device *hdev,
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
|
|
|
|
+
|
|
msc->quirks = id->driver_data;
|
|
msc->quirks = id->driver_data;
|
|
hid_set_drvdata(hdev, msc);
|
|
hid_set_drvdata(hdev, msc);
|
|
|
|
|