From 597b49ec6f19b6df975e2101c42b7b1cfe168280 Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Wed, 26 May 2010 20:50:50 +0200 Subject: HID: roccat: remove obsolete comment Removed comment that is obsolete since roccat char device is implemented Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat-kone.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 17f2dc0..3e5b553 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -22,11 +22,6 @@ * Is it possible to remove and reinstall the urb in raw-event- or any * other handler, or to defer this action to be executed somewhere else? * - * TODO implement notification mechanism for overlong macro execution - * If user wants to execute an overlong macro only the names of macroset - * and macro are given. Should userland tap hidraw or is there an - * additional streaming mechanism? - * * TODO is it possible to overwrite group for sysfs attributes via udev? */ -- cgit v1.1 From 22d515723ff1d92eea4d7537a3f8d7674080422b Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Wed, 26 May 2010 20:51:28 +0200 Subject: HID: roccat: fix whitespace warning from checkpatch.pl Fixed the following warning of checkpatch.pl: WARNING: space prohibited between function name and open parenthesis '(' Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-roccat.h b/drivers/hid/hid-roccat.h index d8aae0c..09e864e 100644 --- a/drivers/hid/hid-roccat.h +++ b/drivers/hid/hid-roccat.h @@ -15,7 +15,7 @@ #include #include -#if defined(CONFIG_HID_ROCCAT) || defined (CONFIG_HID_ROCCAT_MODULE) +#if defined(CONFIG_HID_ROCCAT) || defined(CONFIG_HID_ROCCAT_MODULE) int roccat_connect(struct hid_device *hid); void roccat_disconnect(int minor); int roccat_report_event(int minor, u8 const *data, int len); -- cgit v1.1 From 33ccbc320fc38094128c68b2ee0b305884965bd4 Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Wed, 26 May 2010 20:52:43 +0200 Subject: HID: roccat: change kone_driver_version to kone_abi_version Renamed the sysfs attribute kone_driver_version to kone_abi_version and simplified returned data to integer. Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat-kone.c | 12 ++++++------ drivers/hid/hid-roccat-kone.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 3e5b553..0ab1df9 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -621,12 +621,12 @@ static ssize_t kone_sysfs_set_startup_profile(struct device *dev, * This file is used by userland software to find devices that are handled by * this driver. This provides a consistent way for actual and older kernels * where this driver replaced usbhid instead of generic-usb. - * Driver capabilities are determined by version number. + * Driver capabilities are determined by returned number. */ -static ssize_t kone_sysfs_show_driver_version(struct device *dev, +static ssize_t kone_sysfs_show_abi_version(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, ROCCAT_KONE_DRIVER_VERSION "\n"); + return snprintf(buf, PAGE_SIZE, ROCCAT_KONE_ABI_VERSION "\n"); } /* @@ -666,8 +666,8 @@ static DEVICE_ATTR(startup_profile, 0660, kone_sysfs_show_startup_profile, kone_sysfs_set_startup_profile); -static DEVICE_ATTR(kone_driver_version, 0440, - kone_sysfs_show_driver_version, NULL); +static DEVICE_ATTR(kone_abi_version, 0440, + kone_sysfs_show_abi_version, NULL); static struct attribute *kone_attributes[] = { &dev_attr_actual_dpi.attr, @@ -676,7 +676,7 @@ static struct attribute *kone_attributes[] = { &dev_attr_firmware_version.attr, &dev_attr_tcu.attr, &dev_attr_startup_profile.attr, - &dev_attr_kone_driver_version.attr, + &dev_attr_kone_abi_version.attr, NULL }; diff --git a/drivers/hid/hid-roccat-kone.h b/drivers/hid/hid-roccat-kone.h index 003e6f8..71b14fa 100644 --- a/drivers/hid/hid-roccat-kone.h +++ b/drivers/hid/hid-roccat-kone.h @@ -14,7 +14,7 @@ #include -#define ROCCAT_KONE_DRIVER_VERSION "v0.3.1" +#define ROCCAT_KONE_ABI_VERSION "1" #pragma pack(push) #pragma pack(1) -- cgit v1.1 From dfe5c7b7e710d8ed885068b0fcfa6f66ab685592 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 1 Jun 2010 16:35:15 +0200 Subject: HID: roccat: introduce missing kfree Error handling code following a kmalloc should free the allocated data. The semantic match that finds the problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @r exists@ local idexpression x; statement S; expression E; identifier f,f1,l; position p1,p2; expression *ptr != NULL; @@ x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); ... if (x == NULL) S <... when != x when != if (...) { <+...x...+> } ( x->f1 = E | (x->f1 == NULL || ...) | f(...,x->f1,...) ) ...> ( return \(0\|<+...x...+>\|ptr\); | return@p2 ...; ) @script:python@ p1 << r.p1; p2 << r.p2; @@ print "* file: %s kmalloc %s return %s" % (p1[0].file,p1[0].line,p2[0].line) // Signed-off-by: Julia Lawall Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index e05d48e..f6e80c7 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c @@ -168,7 +168,7 @@ static int roccat_open(struct inode *inode, struct file *file) printk(KERN_EMERG "roccat device with minor %d doesn't exist\n", minor); error = -ENODEV; - goto exit_unlock; + goto exit_err; } if (!device->open++) { @@ -178,7 +178,7 @@ static int roccat_open(struct inode *inode, struct file *file) PM_HINT_FULLON); if (error < 0) { --device->open; - goto exit_unlock; + goto exit_err; } } error = device->hid->ll_driver->open(device->hid); @@ -187,7 +187,7 @@ static int roccat_open(struct inode *inode, struct file *file) device->hid->ll_driver->power(device->hid, PM_HINT_NORMAL); --device->open; - goto exit_unlock; + goto exit_err; } } @@ -202,6 +202,9 @@ exit_unlock: mutex_unlock(&device->readers_lock); mutex_unlock(&devices_lock); return error; +exit_err: + kfree(reader); + goto exit_unlock; } static int roccat_release(struct inode *inode, struct file *file) -- cgit v1.1 From ef566d30a702cc9b49d24edc4ad45c62208a4f5d Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Wed, 2 Jun 2010 10:28:25 -0400 Subject: HID: magicmouse: scroll on entire surface, not just middle of mouse Previously, scroll events only occurred when the user moved a touch along the middle of the touch surface. This is unintuitive for a normal user who is not aware of this. The device has a uniform surface, so the distinction is artificial. This change removes the touch area check for a scroll event, which replicates the OS X behavior. Signed-off-by: Chase Douglas Acked-by: Michael Poole Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index f10d56a..cd70635 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -160,10 +160,9 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda msc->touches[id].size = misc & 63; /* If requested, emulate a scroll wheel by detecting small - * vertical touch motions along the middle of the mouse. + * vertical touch motions. */ - if (emulate_scroll_wheel && - middle_button_start < x && x < middle_button_stop) { + if (emulate_scroll_wheel) { static const int accel_profile[] = { 256, 228, 192, 160, 128, 96, 64, 32, }; -- cgit v1.1 From 9846f350ef4d4108c1154acfc125fe8d8630ef84 Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Wed, 2 Jun 2010 10:28:27 -0400 Subject: HID: magicmouse: disable and add module param for scroll acceleration Scroll acceleration is unique to the magicmouse driver, and is unintuitive to a user who is unaware of the functionality. Thus, disable it by default, but add a module parameter to enable it for power users who want it. Signed-off-by: Chase Douglas Acked-by: Michael Poole Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index cd70635..4c4a79c 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -30,6 +30,10 @@ static bool emulate_scroll_wheel = true; module_param(emulate_scroll_wheel, bool, 0644); MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel"); +static bool scroll_acceleration = false; +module_param(scroll_acceleration, bool, 0644); +MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events"); + static bool report_touches = true; module_param(report_touches, bool, 0644); MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)"); @@ -177,7 +181,9 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda switch (tdata[7] & TOUCH_STATE_MASK) { case TOUCH_STATE_START: msc->touches[id].scroll_y = y; - msc->scroll_accel = min_t(int, msc->scroll_accel + 1, + if (scroll_acceleration) + msc->scroll_accel = min_t(int, + msc->scroll_accel + 1, ARRAY_SIZE(accel_profile) - 1); break; case TOUCH_STATE_DRAG: -- cgit v1.1 From cab6b16aca4ac12f731a523fe14770add2f9394a Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Sun, 20 Jun 2010 19:19:06 +0200 Subject: HID: roccat: fix offset errors in bin_attribute read Fixing wrong calculated offsets in bin_attribute read functions. Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat-kone.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 0ab1df9..2aef6e4 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -272,7 +272,7 @@ static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj, count = sizeof(struct kone_settings) - off; mutex_lock(&kone->kone_lock); - memcpy(buf, &kone->settings + off, count); + memcpy(buf, ((char const *)&kone->settings) + off, count); mutex_unlock(&kone->kone_lock); return count; @@ -332,7 +332,7 @@ static ssize_t kone_sysfs_read_profilex(struct kobject *kobj, count = sizeof(struct kone_profile) - off; mutex_lock(&kone->kone_lock); - memcpy(buf, &kone->profiles[number - 1], sizeof(struct kone_profile)); + memcpy(buf, ((char const *)&kone->profiles[number - 1]) + off, count); mutex_unlock(&kone->kone_lock); return count; -- cgit v1.1 From 0b3fa399bef02f3658295f8dd334fc26a59c3a95 Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Fri, 18 Jun 2010 16:42:25 +0200 Subject: HID: roccat: remove obsolete kone_abi_version sysfs attribute The newest version of the accompanying userland tools cuts backward compatibility and uses libudev to find its devices superseding the quirky kone_abi_version sysfs attribute. Therefore it should be removed. Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat-kone.c | 16 ---------------- drivers/hid/hid-roccat-kone.h | 2 -- 2 files changed, 18 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 2aef6e4..f776957 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -618,18 +618,6 @@ static ssize_t kone_sysfs_set_startup_profile(struct device *dev, } /* - * This file is used by userland software to find devices that are handled by - * this driver. This provides a consistent way for actual and older kernels - * where this driver replaced usbhid instead of generic-usb. - * Driver capabilities are determined by returned number. - */ -static ssize_t kone_sysfs_show_abi_version(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, ROCCAT_KONE_ABI_VERSION "\n"); -} - -/* * Read actual dpi settings. * Returns raw value for further processing. Refer to enum kone_polling_rates to * get real value. @@ -666,9 +654,6 @@ static DEVICE_ATTR(startup_profile, 0660, kone_sysfs_show_startup_profile, kone_sysfs_set_startup_profile); -static DEVICE_ATTR(kone_abi_version, 0440, - kone_sysfs_show_abi_version, NULL); - static struct attribute *kone_attributes[] = { &dev_attr_actual_dpi.attr, &dev_attr_actual_profile.attr, @@ -676,7 +661,6 @@ static struct attribute *kone_attributes[] = { &dev_attr_firmware_version.attr, &dev_attr_tcu.attr, &dev_attr_startup_profile.attr, - &dev_attr_kone_abi_version.attr, NULL }; diff --git a/drivers/hid/hid-roccat-kone.h b/drivers/hid/hid-roccat-kone.h index 71b14fa..130d656 100644 --- a/drivers/hid/hid-roccat-kone.h +++ b/drivers/hid/hid-roccat-kone.h @@ -14,8 +14,6 @@ #include -#define ROCCAT_KONE_ABI_VERSION "1" - #pragma pack(push) #pragma pack(1) -- cgit v1.1 From 8d93efb27ab8927ffc7a357f1b2d10039de50ed4 Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Sun, 20 Jun 2010 21:32:29 -0400 Subject: HID: magicmouse: properly account for scroll movement in state Before this change, sequential scroll events would take a variable amount of movement due to incorrect accounting. This change ensures all scroll movements require a deterministic touch movement for an action to occur. Signed-off-by: Chase Douglas Acked-by: Michael Poole Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 4c4a79c..f44aaf2 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -189,7 +189,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda case TOUCH_STATE_DRAG: step = step / accel_profile[msc->scroll_accel]; if (step != 0) { - msc->touches[id].scroll_y = y; + msc->touches[id].scroll_y -= + step * accel_profile[msc->scroll_accel]; msc->scroll_jiffies = now; input_report_rel(input, REL_WHEEL, step); } -- cgit v1.1 From 0b778e76c1e7ccf49f8980b594e72f984095fd26 Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Sun, 20 Jun 2010 21:32:30 -0400 Subject: HID: magicmouse: add param for scroll speed The new scroll_speed param takes an integer value from 0 to 63, where 0 is slowest and 63 is fastest. The default of 32 remains the same. This parameter also affects scroll acceleration linearly. A second part of this change is a tightly coupled modification to the scroll acceleration. Previously, scroll acceleration could be reset without lifting the scroll finger. This is rather unintuitive and hard to control in the case where a user wants faster scrolling, but wants to hold the scroll touch for longer than a moment. Note that scroll acceleration levels are now 1-7, where 7 is slowest. In the previous implementation, there were 8 levels defined, but it was impossible to start at the slowest level. In order to keep the default scroll speed unchanged, only 7 levels are used now. Signed-off-by: Chase Douglas Acked-by: Michael Poole Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index f44aaf2..fe0c760 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -30,6 +30,17 @@ static bool emulate_scroll_wheel = true; module_param(emulate_scroll_wheel, bool, 0644); 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; module_param(scroll_acceleration, bool, 0644); 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_DRAG 0x40 +#define SCROLL_ACCEL_DEFAULT 7 + /** * struct magicmouse_sc - Tracks Magic Mouse-specific data. * @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); 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) @@ -167,30 +180,28 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda * vertical touch motions. */ if (emulate_scroll_wheel) { - static const int accel_profile[] = { - 256, 228, 192, 160, 128, 96, 64, 32, - }; unsigned long now = jiffies; 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. */ switch (tdata[7] & TOUCH_STATE_MASK) { case TOUCH_STATE_START: 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; case TOUCH_STATE_DRAG: - step = step / accel_profile[msc->scroll_accel]; + step /= (64 - (int)scroll_speed) * msc->scroll_accel; 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; input_report_rel(input, REL_WHEEL, step); } @@ -351,6 +362,8 @@ static int magicmouse_probe(struct hid_device *hdev, return -ENOMEM; } + msc->scroll_accel = SCROLL_ACCEL_DEFAULT; + msc->quirks = id->driver_data; hid_set_drvdata(hdev, msc); -- cgit v1.1 From c04266889b591165bdea396b20313bebb83c0fd6 Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Sun, 20 Jun 2010 21:32:31 -0400 Subject: HID: magicmouse: enable horizontal scrolling Mimicks OS X behavior. Signed-off-by: Chase Douglas Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index fe0c760..0b89c1c 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -95,6 +95,7 @@ struct magicmouse_sc { struct { short x; short y; + short scroll_x; short scroll_y; u8 size; } touches[16]; @@ -181,11 +182,13 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda */ if (emulate_scroll_wheel) { unsigned long now = jiffies; - int step = msc->touches[id].scroll_y - y; + int step_x = msc->touches[id].scroll_x - x; + int step_y = msc->touches[id].scroll_y - y; /* Calculate and apply the scroll motion. */ switch (tdata[7] & TOUCH_STATE_MASK) { case TOUCH_STATE_START: + msc->touches[id].scroll_x = x; msc->touches[id].scroll_y = y; /* Reset acceleration after half a second. */ @@ -198,12 +201,20 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda break; case TOUCH_STATE_DRAG: - step /= (64 - (int)scroll_speed) * msc->scroll_accel; - if (step != 0) { - msc->touches[id].scroll_y -= step * + step_x /= (64 - (int)scroll_speed) * msc->scroll_accel; + if (step_x != 0) { + msc->touches[id].scroll_x -= step_x * (64 - scroll_speed) * msc->scroll_accel; msc->scroll_jiffies = now; - input_report_rel(input, REL_WHEEL, step); + input_report_rel(input, REL_HWHEEL, -step_x); + } + + step_y /= (64 - (int)scroll_speed) * msc->scroll_accel; + if (step_y != 0) { + msc->touches[id].scroll_y -= step_y * + (64 - scroll_speed) * msc->scroll_accel; + msc->scroll_jiffies = now; + input_report_rel(input, REL_WHEEL, step_y); } break; } @@ -318,8 +329,10 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h __set_bit(EV_REL, input->evbit); __set_bit(REL_X, input->relbit); __set_bit(REL_Y, input->relbit); - if (emulate_scroll_wheel) + if (emulate_scroll_wheel) { __set_bit(REL_WHEEL, input->relbit); + __set_bit(REL_HWHEEL, input->relbit); + } if (report_touches) { __set_bit(EV_ABS, input->evbit); -- cgit v1.1 From e3612e8669b8c15278058f8dd52e3dc6e7d26710 Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Mon, 5 Jul 2010 09:57:52 -0400 Subject: HID: magicmouse: report last touch up The evdev multitouch protocol requires that a last MT sync event must be sent after all touches are up. This change adds the last MT sync event to the hid-magicmouse driver. Also, don't send events when a touch leaves. Signed-off-by: Chase Douglas Acked-by: Michael Poole Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 0b89c1c..ee78787 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -98,6 +98,7 @@ struct magicmouse_sc { short scroll_x; short scroll_y; u8 size; + u8 down; } touches[16]; int tracking_ids[16]; }; @@ -170,6 +171,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda int id = (misc >> 6) & 15; int x = x_y << 12 >> 20; int y = -(x_y >> 20); + int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE; /* Store tracking ID and other fields. */ msc->tracking_ids[raw_id] = id; @@ -221,9 +223,11 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda } /* Generate the input events for this touch. */ - if (report_touches) { + if (report_touches && down) { int orientation = (misc >> 10) - 32; + msc->touches[id].down = 1; + input_report_abs(input, ABS_MT_TRACKING_ID, id); input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]); input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]); @@ -243,7 +247,7 @@ static int magicmouse_raw_event(struct hid_device *hdev, { struct magicmouse_sc *msc = hid_get_drvdata(hdev); struct input_dev *input = msc->input; - int x, y, ts, ii, clicks; + int x, y, ts, ii, clicks, last_up; switch (data[0]) { case 0x10: @@ -263,6 +267,20 @@ static int magicmouse_raw_event(struct hid_device *hdev, msc->ntouches = (size - 6) / 8; for (ii = 0; ii < msc->ntouches; ii++) magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); + + if (report_touches) { + last_up = 1; + for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) { + if (msc->touches[ii].down) { + last_up = 0; + msc->touches[ii].down = 0; + } + } + if (last_up) { + input_mt_sync(input); + } + } + /* When emulating three-button mode, it is important * to have the current touch information before * generating a click event. -- cgit v1.1 From 7d876c05fa6cf82f0274f27276d981ed325697a5 Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Mon, 5 Jul 2010 10:50:09 -0400 Subject: HID: magicmouse: Correct parsing of large X and Y motions. The X and Y values have two more significant bits in the same byte that contains click status. Include these in the reported value. Thanks to Iain Hibbert of NetBSD for pointing this out. Signed-off-by: Michael Poole Acked-by: Chase Douglas Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index ee78787..319b0e5 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -285,8 +285,8 @@ static int magicmouse_raw_event(struct hid_device *hdev, * to have the current touch information before * generating a click event. */ - x = (signed char)data[1]; - y = (signed char)data[2]; + x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; + y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; clicks = data[3]; break; case 0x20: /* Theoretically battery status (0-100), but I have -- cgit v1.1 From fc99f22c5de2177431cada350417ac6e353380c7 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 12 Jul 2010 19:28:26 +0200 Subject: HID: hid-input.c: indentation fixes Signed-off-by: Daniel Mack Cc: Jiri Kosina Cc: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 7a0d2e4..36c2148 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -199,11 +199,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case HID_GD_MOUSE: case HID_GD_POINTER: code += 0x110; break; case HID_GD_JOYSTICK: - if (code <= 0xf) - code += BTN_JOYSTICK; - else - code += BTN_TRIGGER_HAPPY; - break; + if (code <= 0xf) + code += BTN_JOYSTICK; + else + code += BTN_TRIGGER_HAPPY; + break; case HID_GD_GAMEPAD: code += 0x130; break; default: switch (field->physical) { @@ -480,7 +480,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case HID_UP_LOGIVENDOR: goto ignore; - + case HID_UP_PID: switch (usage->hid & HID_USAGE) { case 0xa4: map_key_clear(BTN_DEAD); break; @@ -586,9 +586,9 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1; if (hat_dir < 0 || hat_dir > 8) hat_dir = 0; input_event(input, usage->type, usage->code , hid_hat_to_axis[hat_dir].x); - input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y); - return; - } + input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y); + return; + } if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */ *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT); -- cgit v1.1 From 3a343ee4509c982552b35fbc99d3213f3bb1acde Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 12 Jul 2010 19:28:27 +0200 Subject: HID: add HID_QUIRK_HIDINPUT_FORCE For devices with exotic HID report descriptors, it might be necessary to make the HID core force the registration of an input device. Make that possible by introducing a new quirk type. Signed-off-by: Daniel Mack Cc: Jiri Kosina Cc: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 866e54e..7ccee89 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1157,6 +1157,8 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE) connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV); + if (hdev->quirks & HID_QUIRK_HIDINPUT_FORCE) + connect_mask |= HID_CONNECT_HIDINPUT_FORCE; if (hdev->bus != BUS_USB) connect_mask &= ~HID_CONNECT_HIDDEV; if (hid_hiddev(hdev)) -- cgit v1.1 From 70c7c9c4438fc3ca573744c5448df90dbcc5e159 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 12 Jul 2010 19:28:28 +0200 Subject: HID: Force input registration for "VEC footpedal" These devices report a usage page of type "consumer" and a usage of "Programmable buttons". They are hence ignored by the hid-input layer. Force the registration of an input device by using the new quirk type HID_QUIRK_HIDINPUT_FORCE. Signed-off-by: Daniel Mack Cc: Jiri Kosina Cc: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 2 ++ drivers/hid/usbhid/hid-quirks.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 31601ee..d42c88f 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -526,5 +526,7 @@ #define USB_DEVICE_ID_KYE_ERGO_525V 0x0087 #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 +#define USB_VENDOR_ID_PI_ENGINEERING 0x05f3 +#define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff #endif diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 5f5aa39..2643d31 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -75,6 +75,8 @@ static const struct hid_blacklist { { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE }, + { 0, 0 } }; -- cgit v1.1