* Re: [PATCH v3 0/3] Input: omap-keypad: Convert to threaded IRQ and cleanup
From: Dmitry Torokhov @ 2013-08-26 6:27 UTC (permalink / raw)
To: Illia Smyrnov; +Cc: Felipe Balbi, linux-input, linux-kernel, linux-omap
In-Reply-To: <1374681293-5320-1-git-send-email-illia.smyrnov@ti.com>
On Wed, Jul 24, 2013 at 06:54:50PM +0300, Illia Smyrnov wrote:
> Replace unclear hardcoded values with bit field, convert to threaded IRQ and
> clear interrupts when open the keypad.
>
> Based on top of v3.11-rc2.
>
> Tested on OMAP4 SDP.
>
> Illia Smyrnov (3):
> Input: omap-keypad: Cleanup - use bitfiled instead of hardcoded
> values
> Input: omap-keypad: Convert to threaded IRQ
> Input: omap-keypad: Clear interrupts on open
>
> drivers/input/keyboard/omap4-keypad.c | 57 +++++++++++++++++++--------------
> 1 files changed, 33 insertions(+), 24 deletions(-)
>
Applied, thank you.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v2] Input: cyttsp4 - remove useless NULL test from cyttsp4_watchdog_timer()
From: Dmitry Torokhov @ 2013-08-26 7:16 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: Wei Yongjun, javier, yongjun_wei, linux-input
In-Reply-To: <521AF58C.1010004@cypress.com>
On Mon, Aug 26, 2013 at 09:28:28AM +0300, Ferruh Yigit wrote:
> On 08/26/2013 09:00 AM, Wei Yongjun wrote:
> >From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
> >
> >Remove useless NULL test from cyttsp4_watchdog_timer().
> >
> >Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
> >---
> >v1 -> v2: remove NULL test instead.
> > (was: Input: cyttsp4 - fix potential NULL pointer dereference in cyttsp4_watchdog_timer())
> >---
> > drivers/input/touchscreen/cyttsp4_core.c | 3 ---
> > 1 file changed, 3 deletions(-)
>
> Acked-by: Ferruh Yigit <fery@cypress.com>
Applied, thank you.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v8 1/1] input: ideapad_slidebar: new input driver
From: Dmitry Torokhov @ 2013-08-26 7:51 UTC (permalink / raw)
To: Andrey Moiseev
Cc: linux-input, arnoques, russianneuromancer, ike.pan, linux-kernel
In-Reply-To: <52144C19.80701@gmail.com>
Hi Andrey,
On Wed, Aug 21, 2013 at 09:11:53AM +0400, Andrey Moiseev wrote:
> v8: added `extended = false;` line
>
> ideapad_slidebar is a new driver which enables slidebars on some
> Lenovo IdeaPad laptops (the slidebars work with SlideNav/Desktop
> Navigator under Windows)
Could you tell me if after applying the patch below on top of yours the
device still works?
Thanks!
--
Dmitry
Input: lenovo-ideapad - a few cleanups
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/misc/Kconfig | 7 +-
drivers/input/misc/ideapad_slidebar.c | 130 +++++++++++++++++++--------------
2 files changed, 79 insertions(+), 58 deletions(-)
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index b19defe..3321b60 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -676,10 +676,11 @@ config INPUT_SIRFSOC_ONKEY
config INPUT_IDEAPAD_SLIDEBAR
tristate "IdeaPad Laptop Slidebar"
depends on INPUT
+ depends on SERIO_I8042
help
- Input driver for slidebars on some Lenovo IdeaPad laptops.
+ Say Y here if you have an IdeaPad laptop with a slidebar.
- If you have an IdeaPad laptop with a slidebar, say Y or M here.
- Module name is ideapad_slidebar.
+ To compile this driver as a module, choose M here: the
+ module will be called ideapad_slidebar.
endif
diff --git a/drivers/input/misc/ideapad_slidebar.c b/drivers/input/misc/ideapad_slidebar.c
index 5deeeff..0d5b167 100644
--- a/drivers/input/misc/ideapad_slidebar.c
+++ b/drivers/input/misc/ideapad_slidebar.c
@@ -73,6 +73,8 @@
* 0x11 ONMOV
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/dmi.h>
@@ -82,6 +84,9 @@
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/i8042.h>
+#include <linux/serio.h>
+
+#define IDEAPAD_BASE 0xff29
static bool force;
module_param(force, bool, 0);
@@ -92,9 +97,9 @@ static DEFINE_SPINLOCK(io_lock);
static struct input_dev *slidebar_input_dev;
static struct platform_device *slidebar_platform_dev;
-static unsigned char slidebar_pos_get(void)
+static u8 slidebar_pos_get(void)
{
- int res;
+ u8 res;
unsigned long flags;
spin_lock_irqsave(&io_lock, flags);
@@ -102,12 +107,13 @@ static unsigned char slidebar_pos_get(void)
outb(0xbf, 0xff2a);
res = inb(0xff2b);
spin_unlock_irqrestore(&io_lock, flags);
+
return res;
}
-static unsigned char slidebar_mode_get(void)
+static u8 slidebar_mode_get(void)
{
- int res;
+ u8 res;
unsigned long flags;
spin_lock_irqsave(&io_lock, flags);
@@ -115,10 +121,11 @@ static unsigned char slidebar_mode_get(void)
outb(0x8b, 0xff2a);
res = inb(0xff2b);
spin_unlock_irqrestore(&io_lock, flags);
+
return res;
}
-static void slidebar_mode_set(unsigned char mode)
+static void slidebar_mode_set(u8 mode)
{
unsigned long flags;
@@ -130,52 +137,61 @@ static void slidebar_mode_set(unsigned char mode)
}
static bool slidebar_i8042_filter(unsigned char data, unsigned char str,
- struct serio *port)
+ struct serio *port)
{
static bool extended = false;
/* Scancodes: e03b on move, e0bb on release */
- if (unlikely(data == 0xe0)) {
+ if (data == 0xe0) {
extended = true;
+ return true;
+ }
+
+ if (!extended)
return false;
- } else if (unlikely(extended && (data == 0x3b))) {
- extended = false;
- input_report_key(slidebar_input_dev, BTN_TOUCH, 1);
- input_report_abs(slidebar_input_dev, ABS_X, slidebar_pos_get());
- input_sync(slidebar_input_dev);
+
+ if (likely((data & 0x7f) != 0x3b)) {
+ serio_interrupt(port, 0xe0, 0);
return false;
- } else if (unlikely(extended && (data == 0xbb))) {
- extended = false;
+ }
+
+ if (data & 0x80) {
input_report_key(slidebar_input_dev, BTN_TOUCH, 0);
- input_sync(slidebar_input_dev);
- return false;
+ } else {
+ input_report_key(slidebar_input_dev, BTN_TOUCH, 1);
+ input_report_abs(slidebar_input_dev, ABS_X, slidebar_pos_get());
}
- return false;
+ input_sync(slidebar_input_dev);
+
+ extended = false;
+ return true;
}
static ssize_t show_slidebar_mode(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%x\n", slidebar_mode_get());
}
static ssize_t store_slidebar_mode(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- int mode;
+ u8 mode;
+ int error;
+
+ error = kstrtou8(buf, 0, &mode);
+ if (error)
+ return error;
- if (!count)
- return 0;
- if (sscanf(buf, "%x", &mode) != 1)
- return -EINVAL;
slidebar_mode_set(mode);
+
return count;
}
-static DEVICE_ATTR(slidebar_mode, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH,
- show_slidebar_mode, store_slidebar_mode);
+static DEVICE_ATTR(slidebar_mode, S_IWUSR | S_IRUGO,
+ show_slidebar_mode, store_slidebar_mode);
static struct attribute *ideapad_attrs[] = {
&dev_attr_slidebar_mode.attr,
@@ -191,40 +207,42 @@ static const struct attribute_group *ideapad_attr_groups[] = {
NULL
};
-static int probe(struct platform_device* dev)
+static int __init ideapad_probe(struct platform_device* pdev)
{
int err;
- if (!request_region(0xff29, 3, "ideapad_slidebar")) {
- pr_err("ideapad_slidebar: IO ports are busy\n");
+ if (!request_region(IDEAPAD_BASE, 3, "ideapad_slidebar")) {
+ dev_err(&pdev->dev, "IO ports are busy\n");
return -EBUSY;
}
slidebar_input_dev = input_allocate_device();
if (!slidebar_input_dev) {
- pr_err("ideapad_slidebar: Not enough memory\n");
+ dev_err(&pdev->dev, "Failed to allocate input device\n");
err = -ENOMEM;
goto err_release_ports;
}
slidebar_input_dev->name = "IdeaPad Slidebar";
slidebar_input_dev->id.bustype = BUS_HOST;
- slidebar_input_dev->dev.parent = &slidebar_platform_dev->dev;
+ slidebar_input_dev->dev.parent = &pdev->dev;
input_set_capability(slidebar_input_dev, EV_KEY, BTN_TOUCH);
- input_set_capability(slidebar_input_dev, EV_ABS, ABS_X);
input_set_abs_params(slidebar_input_dev, ABS_X, 0, 0xff, 0, 0);
err = i8042_install_filter(slidebar_i8042_filter);
if (err) {
- pr_err("ideapad_slidebar: Can't install i8042 filter \n");
+ dev_err(&pdev->dev,
+ "Failed to install i8042 filter: %d\n", err);
goto err_free_dev;
}
err = input_register_device(slidebar_input_dev);
if (err) {
- pr_err("ideapad_slidebar: Failed to register input device\n");
+ dev_err(&pdev->dev,
+ "Failed to register input device: %d\n", err);
goto err_remove_filter;
}
+
return 0;
err_remove_filter:
@@ -232,15 +250,16 @@ err_remove_filter:
err_free_dev:
input_free_device(slidebar_input_dev);
err_release_ports:
- release_region(0xff29, 3);
+ release_region(IDEAPAD_BASE, 3);
return err;
}
-static int remove(struct platform_device *dev)
+static int ideapad_remove(struct platform_device *dev)
{
i8042_remove_filter(slidebar_i8042_filter);
input_unregister_device(slidebar_input_dev);
- release_region(0xff29, 3);
+ release_region(IDEAPAD_BASE, 3);
+
return 0;
}
@@ -249,13 +268,12 @@ static struct platform_driver slidebar_drv = {
.name = "ideapad_slidebar",
.owner = THIS_MODULE,
},
- .probe = probe,
- .remove = remove
+ .remove = ideapad_remove,
};
static int __init ideapad_dmi_check(const struct dmi_system_id *id)
{
- pr_info("ideapad_slidebar: Laptop model '%s'\n", id->ident);
+ pr_info("Laptop model '%s'\n", id->ident);
return 1;
}
@@ -287,34 +305,36 @@ static int __init slidebar_init(void)
int err;
if (!force && !dmi_check_system(ideapad_dmi)) {
- pr_err("ideapad_slidebar: DMI didn't match\n");
+ pr_err("DMI does not match\n");
return -ENODEV;
}
- err = platform_driver_register(&slidebar_drv);
- if (err) {
- pr_err("ideapad_slidebar: Failed to register platform driver\n");
- return err;
- }
-
slidebar_platform_dev = platform_device_alloc("ideapad_slidebar", -1);
- slidebar_platform_dev->dev.groups = ideapad_attr_groups;
if (!slidebar_platform_dev) {
- pr_err("ideapad_slidebar: Not enough memory\n");
- goto err_unregister_drv;
+ pr_err("Not enough memory\n");
+ return -ENOMEM;
}
+ slidebar_platform_dev->dev.groups = ideapad_attr_groups;
+
err = platform_device_add(slidebar_platform_dev);
if (err) {
- pr_err("ideapad_slidebar: Failed to register plarform device\n");
+ pr_err("Failed to register platform device\n");
goto err_free_dev;
}
+
+ err = platform_driver_probe(&slidebar_drv, ideapad_probe);
+ if (err) {
+ pr_err("Failed to register platform driver\n");
+ goto err_delete_dev;
+ }
+
return 0;
+err_delete_dev:
+ platform_device_del(slidebar_platform_dev);
err_free_dev:
platform_device_put(slidebar_platform_dev);
-err_unregister_drv:
- platform_driver_unregister(&slidebar_drv);
return err;
}
^ permalink raw reply related
* Re: [PATCH -next] HID: use module_hid_driver() to simplify the code
From: Jiri Kosina @ 2013-08-26 11:23 UTC (permalink / raw)
To: Wei Yongjun; +Cc: yongjun_wei, linux-input
In-Reply-To: <CAPgLHd9pb+49BC7BOOSrgkOWMQJQ76GcEGStt-UeaqGqtYfpFQ@mail.gmail.com>
On Fri, 23 Aug 2013, Wei Yongjun wrote:
> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
>
> module_hid_driver() makes the code simpler by eliminating
> boilerplate code.
>
> Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
> ---
> drivers/hid/hid-xinmo.c | 13 +------------
> 1 file changed, 1 insertion(+), 12 deletions(-)
>
> diff --git a/drivers/hid/hid-xinmo.c b/drivers/hid/hid-xinmo.c
> index 6153e50..7df5227 100644
> --- a/drivers/hid/hid-xinmo.c
> +++ b/drivers/hid/hid-xinmo.c
> @@ -57,16 +57,5 @@ static struct hid_driver xinmo_driver = {
> .event = xinmo_event
> };
>
> -static int __init xinmo_init(void)
> -{
> - return hid_register_driver(&xinmo_driver);
> -}
> -
> -static void __exit xinmo_exit(void)
> -{
> - hid_unregister_driver(&xinmo_driver);
> -}
> -
> -module_init(xinmo_init);
> -module_exit(xinmo_exit);
> +module_hid_driver(xinmo_driver);
> MODULE_LICENSE("GPL");
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v3 0/3] HID: Win 8 multitouch panels detection in core
From: Jiri Kosina @ 2013-08-26 11:43 UTC (permalink / raw)
To: Henrik Rydberg
Cc: Benjamin Tissoires, Benjamin Tissoires, Stephane Chatty,
Alexander Holler, Srinivas Pandruvada, linux-input, linux-kernel
In-Reply-To: <20130822175515.GA5215@polaris.bitmath.org>
On Thu, 22 Aug 2013, Henrik Rydberg wrote:
> > this is the v3 of this patch series.
> >
> > Srinivas, I still did not added your tested-by as I made minors modifications of
> > the patches 1 and 2. Now only the patch 1 will impact sensor_hub, and patch 2
> > will not impact this. Maybe just wait for Henrik to put his "Reviewed-by" before
> > giving one last test.
>
> Here goes:
>
> Reviewed-by: Henrik Rydberg <rydberg@euromail.se>
Thanks guys. Not applying this just yet, waiting for Tested-by: from
Srinivas.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v1 23/49] hid: usbhid: prepare for enabling irq in complete()
From: Jiri Kosina @ 2013-08-26 11:44 UTC (permalink / raw)
To: Ming Lei
Cc: Greg Kroah-Hartman, linux-usb, Oliver Neukum, Alan Stern,
Jiri Kosina, linux-input
In-Reply-To: <1376756714-25479-24-git-send-email-ming.lei@canonical.com>
On Sun, 18 Aug 2013, Ming Lei wrote:
> Complete() will be run with interrupt enabled, so change to
> spin_lock_irqsave().
>
> Cc: Jiri Kosina <jkosina@suse.cz>
> Cc: linux-input@vger.kernel.org
> Signed-off-by: Ming Lei <ming.lei@canonical.com>
Acked-by: Jiri Kosina <jkosina@suse.cz>
> ---
> drivers/hid/usbhid/hid-core.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
> index bd38cdf..2445fd6 100644
> --- a/drivers/hid/usbhid/hid-core.c
> +++ b/drivers/hid/usbhid/hid-core.c
> @@ -489,8 +489,9 @@ static void hid_ctrl(struct urb *urb)
> struct hid_device *hid = urb->context;
> struct usbhid_device *usbhid = hid->driver_data;
> int unplug = 0, status = urb->status;
> + unsigned long flags;
>
> - spin_lock(&usbhid->lock);
> + spin_lock_irqsave(&usbhid->lock, flags);
>
> switch (status) {
> case 0: /* success */
> @@ -525,7 +526,7 @@ static void hid_ctrl(struct urb *urb)
> }
>
> clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
> - spin_unlock(&usbhid->lock);
> + spin_unlock_irqrestore(&usbhid->lock, flags);
> usb_autopm_put_interface_async(usbhid->intf);
> wake_up(&usbhid->wait);
> }
>
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 1/4] hid-sensor-hub: fix style of comments
From: Jiri Kosina @ 2013-08-26 11:46 UTC (permalink / raw)
To: Andy Shevchenko; +Cc: linux-input, Srinivas Pandruvada
In-Reply-To: <1376467631-20857-1-git-send-email-andriy.shevchenko@linux.intel.com>
On Wed, 14 Aug 2013, Andy Shevchenko wrote:
> This patch fixes the style of the comments to be like following
> /* The commentary */
>
> There is no functional change.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Applied.
> ---
> drivers/hid/hid-sensor-hub.c | 2 +-
> include/linux/hid-sensor-hub.h | 2 +-
> include/linux/hid-sensor-ids.h | 2 +-
> 3 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
> index ca749810..ffc80cf 100644
> --- a/drivers/hid/hid-sensor-hub.c
> +++ b/drivers/hid/hid-sensor-hub.c
> @@ -416,7 +416,7 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
> return 1;
>
> ptr = raw_data;
> - ptr++; /*Skip report id*/
> + ptr++; /* Skip report id */
>
> spin_lock_irqsave(&pdata->lock, flags);
>
> diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h
> index ecefb73..32ba451 100644
> --- a/include/linux/hid-sensor-hub.h
> +++ b/include/linux/hid-sensor-hub.h
> @@ -172,7 +172,7 @@ struct hid_sensor_common {
> struct hid_sensor_hub_attribute_info sensitivity;
> };
>
> -/*Convert from hid unit expo to regular exponent*/
> +/* Convert from hid unit expo to regular exponent */
> static inline int hid_sensor_convert_exponent(int unit_expo)
> {
> if (unit_expo < 0x08)
> diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h
> index 6f24446..4f945d3 100644
> --- a/include/linux/hid-sensor-ids.h
> +++ b/include/linux/hid-sensor-ids.h
> @@ -37,7 +37,7 @@
> #define HID_USAGE_SENSOR_ANGL_VELOCITY_Y_AXIS 0x200458
> #define HID_USAGE_SENSOR_ANGL_VELOCITY_Z_AXIS 0x200459
>
> -/*ORIENTATION: Compass 3D: (200083) */
> +/* ORIENTATION: Compass 3D: (200083) */
> #define HID_USAGE_SENSOR_COMPASS_3D 0x200083
> #define HID_USAGE_SENSOR_ORIENT_MAGN_HEADING 0x200471
> #define HID_USAGE_SENSOR_ORIENT_MAGN_HEADING_X 0x200472
> --
> 1.8.4.rc2
>
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] hid: Fix Speedlink VAD Cezanne support for some devices
From: Jiri Kosina @ 2013-08-26 11:51 UTC (permalink / raw)
To: Stefan Kriwanek; +Cc: Dmitry Torokhov, linux-input
In-Reply-To: <5219C455.7040309@stefankriwanek.de>
On Sun, 25 Aug 2013, Stefan Kriwanek wrote:
> Some devices of the "Speedlink VAD Cezanne" model need more aggressive fixing than already done.
Applied, thanks Stefan.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 1/1] HID: hidraw: Add spinlock in struct hidraw to protect list
From: Jiri Kosina @ 2013-08-26 12:03 UTC (permalink / raw)
To: Yonghua Zheng; +Cc: linux-input
In-Reply-To: <20130815145658.GA5813@gmail.com>
On Thu, 15 Aug 2013, Yonghua Zheng wrote:
> As hidraw_report_event can be called from interrupt context, it is a mistake
> to use mutex_lock for protecting the list member in my previous patch, so
> update the patch which adds a spinlock in struct hidraw to protect the list
> member from concurrent access:
Hi,
thanks for the patch.
I already have
commit 212a871a3934beccf43431608c27ed2e05a476ec
Author: Manoj Chourasia <mchourasia@nvidia.com>
Date: Mon Jul 22 15:33:13 2013 +0530
HID: hidraw: correctly deallocate memory on device disconnect
in the tree, which collides with your patch. Could you please check what
changes are needed on top of it so that it makes sense for my 'for-next'
branch, rebase, and resend to me?
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 1/1] HID: hidraw: Add spinlock in struct hidraw to protect list
From: Yonghua Zheng @ 2013-08-26 15:38 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input
In-Reply-To: <alpine.LNX.2.00.1308261359440.2077@pobox.suse.cz>
Hi Jiri,
Fix the conflict and update the patch:
>From 7c06e1f3a5959e73a5b827bda67e7c1eaed7da67 Mon Sep 17 00:00:00 2001
From: Yonghua Zheng <younghua.zheng@gmail.com>
Date: Wed, 14 Aug 2013 17:43:36 +0800
Subject: [PATCH 1/1] HID: hidraw: Add spinlock in struct hidraw to protect
member list
It is unsafe to call list_for_each_entry in hidraw_report_event to
traverse each hidraw_list node without a lock protection, the list
could be modified if someone calls hidraw_release and list_del to
remove itself from the list, this can cause hidraw_report_event
to touch a deleted list struct and panic.
To prevent this, introduce a spinlock in struct hidraw to protect
list from concurrent access.
Signed-off-by: Yonghua Zheng <younghua.zheng@gmail.com>
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index dbfe300..8918dd1 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -253,6 +253,7 @@ static int hidraw_open(struct inode *inode, struct file *file)
unsigned int minor = iminor(inode);
struct hidraw *dev;
struct hidraw_list *list;
+ unsigned long flags;
int err = 0;
if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) {
@@ -266,11 +267,6 @@ static int hidraw_open(struct inode *inode, struct file *file)
goto out_unlock;
}
- list->hidraw = hidraw_table[minor];
- mutex_init(&list->read_mutex);
- list_add_tail(&list->node, &hidraw_table[minor]->list);
- file->private_data = list;
-
dev = hidraw_table[minor];
if (!dev->open++) {
err = hid_hw_power(dev->hid, PM_HINT_FULLON);
@@ -283,9 +279,16 @@ static int hidraw_open(struct inode *inode, struct file *file)
if (err < 0) {
hid_hw_power(dev->hid, PM_HINT_NORMAL);
dev->open--;
+ goto out_unlock;
}
}
+ list->hidraw = hidraw_table[minor];
+ mutex_init(&list->read_mutex);
+ spin_lock_irqsave(&hidraw_table[minor]->list_lock, flags);
+ list_add_tail(&list->node, &hidraw_table[minor]->list);
+ spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags);
+ file->private_data = list;
out_unlock:
mutex_unlock(&minors_lock);
out:
@@ -324,10 +327,13 @@ static int hidraw_release(struct inode * inode, struct file * file)
{
unsigned int minor = iminor(inode);
struct hidraw_list *list = file->private_data;
+ unsigned long flags;
mutex_lock(&minors_lock);
+ spin_lock_irqsave(&hidraw_table[minor]->list_lock, flags);
list_del(&list->node);
+ spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags);
kfree(list);
drop_ref(hidraw_table[minor], 0);
@@ -456,7 +462,9 @@ int hidraw_report_event(struct hid_device *hid, u8 *data, int len)
struct hidraw *dev = hid->hidraw;
struct hidraw_list *list;
int ret = 0;
+ unsigned long flags;
+ spin_lock_irqsave(&dev->list_lock, flags);
list_for_each_entry(list, &dev->list, node) {
int new_head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1);
@@ -471,6 +479,7 @@ int hidraw_report_event(struct hid_device *hid, u8 *data, int len)
list->head = new_head;
kill_fasync(&list->fasync, SIGIO, POLL_IN);
}
+ spin_unlock_irqrestore(&dev->list_lock, flags);
wake_up_interruptible(&dev->wait);
return ret;
@@ -518,6 +527,7 @@ int hidraw_connect(struct hid_device *hid)
}
init_waitqueue_head(&dev->wait);
+ spin_lock_init(&dev->list_lock);
INIT_LIST_HEAD(&dev->list);
dev->hid = hid;
diff --git a/include/linux/hidraw.h b/include/linux/hidraw.h
index 2451662..ddf5261 100644
--- a/include/linux/hidraw.h
+++ b/include/linux/hidraw.h
@@ -23,6 +23,7 @@ struct hidraw {
wait_queue_head_t wait;
struct hid_device *hid;
struct device *dev;
+ spinlock_t list_lock;
struct list_head list;
};
--
1.7.9.5
Thanks
Yonghua
On Mon, Aug 26, 2013 at 02:03:18PM +0200, Jiri Kosina wrote:
> On Thu, 15 Aug 2013, Yonghua Zheng wrote:
>
> > As hidraw_report_event can be called from interrupt context, it is a mistake
> > to use mutex_lock for protecting the list member in my previous patch, so
> > update the patch which adds a spinlock in struct hidraw to protect the list
> > member from concurrent access:
>
> Hi,
>
> thanks for the patch.
>
> I already have
>
> commit 212a871a3934beccf43431608c27ed2e05a476ec
> Author: Manoj Chourasia <mchourasia@nvidia.com>
> Date: Mon Jul 22 15:33:13 2013 +0530
>
> HID: hidraw: correctly deallocate memory on device disconnect
>
> in the tree, which collides with your patch. Could you please check what
> changes are needed on top of it so that it makes sense for my 'for-next'
> branch, rebase, and resend to me?
>
> Thanks,
>
> --
> Jiri Kosina
> SUSE Labs
On Mon, Aug 26, 2013 at 02:03:18PM +0200, Jiri Kosina wrote:
> On Thu, 15 Aug 2013, Yonghua Zheng wrote:
>
> > As hidraw_report_event can be called from interrupt context, it is a mistake
> > to use mutex_lock for protecting the list member in my previous patch, so
> > update the patch which adds a spinlock in struct hidraw to protect the list
> > member from concurrent access:
>
> Hi,
>
> thanks for the patch.
>
> I already have
>
> commit 212a871a3934beccf43431608c27ed2e05a476ec
> Author: Manoj Chourasia <mchourasia@nvidia.com>
> Date: Mon Jul 22 15:33:13 2013 +0530
>
> HID: hidraw: correctly deallocate memory on device disconnect
>
> in the tree, which collides with your patch. Could you please check what
> changes are needed on top of it so that it makes sense for my 'for-next'
> branch, rebase, and resend to me?
>
> Thanks,
>
> --
> Jiri Kosina
> SUSE Labs
^ permalink raw reply related
* Re: kernel Oops: 0003 on usbhid_submit_report
From: Andreas Lillebø Holm @ 2013-08-26 16:16 UTC (permalink / raw)
To: Jiri Kosina; +Cc: Benjamin Tissoires, Greg KH, linux-usb, linux-input
In-Reply-To: <alpine.LNX.2.00.1308231447440.11021@pobox.suse.cz>
On Friday, August 23, 2013 at 2:49 PM, Jiri Kosina wrote:
> On Fri, 23 Aug 2013, Benjamin Tissoires wrote:
>
> > IIRC, Jiri fixed some paging requests with the two following patches:
> > http://git.kernel.org/cgit/linux/kernel/git/jikos/hid.git/commit/?h=for-next&id=27ce405039bfe6d3f4143415c638f56a3df77dca
> > http://git.kernel.org/cgit/linux/kernel/git/jikos/hid.git/commit/?h=for-next&id=bc197eedef1ae082ec662c64c3f4aa302821fb7a
> >
> > At least, these two patches are related to hid_output_report(). I
> > think they are scheduled for 3.12, so I can not find them in Linus'
> > tree.
> >
> > It would worth trying them :)
>
> All three reported oopses happened on page boundary exactly, so this
> pretty much looks like my implement() fix is the one.
>
> Andreas, could you please apply
>
> http://git.kernel.org/cgit/linux/kernel/git/jikos/hid.git/commit/?h=for-next&id=27ce405039bfe6d3f4143415c638f56a3df77dca
>
> and report back whether it makes your problem go away?
Hi,
You are my hero Jiri :-) These two patches fixes the issues I was seeing and I can no longer reproduce them.
I have only tried them on one hardware platform yet; the one that I had failing: Atom Intel e6xx CPU with EG20T PCH platform controller. I have had approximately 300 boots in our test rigg now and no fails yet. Before was the failrate 1/25 boots.
I made the kernel based on 3.10.9 stable tag and applied them directly on there. I do recommend that these patches makes it way into the stable tree :-)
Thanks again :)
Best regards
Andreas Lillebø Holm
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 1/3 v2] Input: wacom - Support EMR and MFT sensors of Cintiq Companion Hybrid
From: Jason Gerecke @ 2013-08-26 17:13 UTC (permalink / raw)
To: linuxwacom-devel, linux-input, pinglinux; +Cc: Jason Gerecke
In-Reply-To: <1377220537-1474-1-git-send-email-killertofu@gmail.com>
Adds support for the sensors integrated in to the Cintiq Companion
Hybrid. These sensors use by-and-large the same protocol as the
Cintiq 24HD touch.
NOTE: The ExpressKeys on the Cintiq Companion Hybrid are wired to
both the EMR controller and CPU GPIO pins. It may be necessary to
disable their functionality in this driver if building a custom
Android kernel for this device (lest two events be sent to userspace
for every button press).
Signed-off-by: Jason Gerecke <killertofu@gmail.com>
---
Changes in v2:
* Remove "#if 1" block surrounding conditional ExpressKey reporting
* Change to C-style comments
drivers/input/tablet/wacom_sys.c | 2 +-
drivers/input/tablet/wacom_wac.c | 46 +++++++++++++++++++++++++++++++++++++++-
drivers/input/tablet/wacom_wac.h | 1 +
3 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 1ad3e07..8fa7af7 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -548,7 +548,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
/* MT Tablet PC touch */
return wacom_set_device_mode(intf, 3, 4, 4);
}
- else if (features->type == WACOM_24HDT) {
+ else if (features->type == WACOM_24HDT || features->type == ASTERIX) {
return wacom_set_device_mode(intf, 18, 3, 2);
}
} else if (features->device_type == BTN_TOOL_PEN) {
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 541197b..9265b3d 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -475,7 +475,7 @@ static void wacom_intuos_general(struct wacom_wac *wacom)
/* general pen packet */
if ((data[1] & 0xb8) == 0xa0) {
t = (data[6] << 2) | ((data[7] >> 6) & 3);
- if (features->type >= INTUOS4S && features->type <= WACOM_24HD) {
+ if (features->type >= INTUOS4S && features->type <= ASTERIX) {
t = (t << 1) | (data[1] & 1);
}
input_report_abs(input, ABS_PRESSURE, t);
@@ -619,6 +619,22 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
} else {
input_report_abs(input, ABS_MISC, 0);
}
+ } else if (features->type == ASTERIX) {
+ /*
+ * Do not send hardware buttons under Android. They
+ * are already sent to the system through GPIO (and
+ * have different meaning).
+ */
+ input_report_key(input, BTN_1, (data[4] & 0x01));
+ input_report_key(input, BTN_2, (data[4] & 0x02));
+ input_report_key(input, BTN_3, (data[4] & 0x04));
+ input_report_key(input, BTN_4, (data[4] & 0x08));
+
+ input_report_key(input, BTN_5, (data[4] & 0x10)); /* Right */
+ input_report_key(input, BTN_6, (data[4] & 0x20)); /* Up */
+ input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */
+ input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */
+ input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */
} else if (features->type >= INTUOS5S && features->type <= INTUOS5L) {
int i;
@@ -1325,6 +1341,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
case WACOM_22HD:
case WACOM_24HD:
case DTK:
+ case ASTERIX:
sync = wacom_intuos_irq(wacom_wac);
break;
@@ -1763,6 +1780,24 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
0, 0);
}
break;
+
+ case ASTERIX:
+ __set_bit(BTN_1, input_dev->keybit);
+ __set_bit(BTN_2, input_dev->keybit);
+ __set_bit(BTN_3, input_dev->keybit);
+ __set_bit(BTN_4, input_dev->keybit);
+
+ __set_bit(BTN_5, input_dev->keybit);
+ __set_bit(BTN_6, input_dev->keybit);
+ __set_bit(BTN_7, input_dev->keybit);
+ __set_bit(BTN_8, input_dev->keybit);
+ __set_bit(BTN_0, input_dev->keybit);
+
+ input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
+ __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+
+ wacom_setup_cintiq(wacom_wac);
+ break;
}
return 0;
}
@@ -2117,6 +2152,13 @@ static const struct wacom_features wacom_features_0xDF =
static const struct wacom_features wacom_features_0x6004 =
{ "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255,
0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0x0307 =
+ { "Wacom ISDv5 307", WACOM_PKGLEN_INTUOS, 59552, 33848, 2047,
+ 63, ASTERIX, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+ .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 };
+static const struct wacom_features wacom_features_0x0309 =
+ { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */
+ .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10 };
#define USB_DEVICE_WACOM(prod) \
USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \
@@ -2247,6 +2289,8 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0xF8) },
{ USB_DEVICE_DETAILED(0xF6, USB_CLASS_HID, 0, 0) },
{ USB_DEVICE_WACOM(0xFA) },
+ { USB_DEVICE_WACOM(0x0307) },
+ { USB_DEVICE_DETAILED(0x0309, USB_CLASS_HID, 0, 0) },
{ USB_DEVICE_LENOVO(0x6004) },
{ }
};
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index dfc9e08..f47a5c1 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -80,6 +80,7 @@ enum {
WACOM_22HD,
DTK,
WACOM_24HD,
+ ASTERIX,
CINTIQ,
WACOM_BEE,
WACOM_13HD,
--
1.8.3.4
^ permalink raw reply related
* [PATCH 0/3] Input/HID: Guitar/Drums support
From: David Herrmann @ 2013-08-26 17:14 UTC (permalink / raw)
To: linux-input
Cc: Jiri Kosina, Nicolas Adenis-Lamarre, Dmitry Torokhov,
David Herrmann
Hi
This series adds wiimote extension support for guitars and drums. The patches
are fairly simple and work the same as the other 5 wiimote extensions. But as we
currently don't have IDs to report drums or guitar events to user-space, I had
to add them.
Patch #1 adds basic IDs to <linux/input.h>. I tried to find as many devices as I
could and looked what IDs would be required. Turned out, the device I was
implementing already supported almost all (except 2 instead of 4 cymbals and 3
instead of 4 toms).
Patch #2 and #3 add the wiimote extensions.
This has been mostly worked out and tested by Nicolas (thanks!) and we started
this work almost 3 month ago. Due to holidays it took a bit longer to get
pressure reports working. But now everything should be fine.
The xwiimote user-space tools already support this and provide testing utilities
if someone is interested: http://github.com/dvdhrm/xwiimote
Jiri, Dmitry, can we try merging this for 3.13? I know it's late, but it did see
a lot of testing from Nicolas.
Regards
David
Btw., if someone has similar PS3 or WorldTour devices, I'd be glad to add
support for them!
David Herrmann (2):
Input: introduce BTN/ABS bits for drums and guitars
HID: wiimote: add support for Guitar-Hero drums
Nicolas Adenis-Lamarre (1):
HID: wiimote: add support for Guitar-Hero guitars
drivers/hid/hid-wiimote-core.c | 14 ++
drivers/hid/hid-wiimote-modules.c | 392 ++++++++++++++++++++++++++++++++++++++
drivers/hid/hid-wiimote.h | 3 +
include/linux/mod_devicetable.h | 2 +-
include/uapi/linux/input.h | 25 ++-
5 files changed, 433 insertions(+), 3 deletions(-)
--
1.8.4
^ permalink raw reply
* [PATCH 1/3] Input: introduce BTN/ABS bits for drums and guitars
From: David Herrmann @ 2013-08-26 17:14 UTC (permalink / raw)
To: linux-input
Cc: Jiri Kosina, Nicolas Adenis-Lamarre, Dmitry Torokhov,
David Herrmann
In-Reply-To: <1377537288-19289-1-git-send-email-dh.herrmann@gmail.com>
There are a bunch of guitar and drums devices out there that all report
similar data. To avoid reporting this as BTN_MISC or ABS_MISC, we
allocate some proper namespace for them. Note that most of these devices
are toys and we cannot report any sophisticated physics via this API.
I did some google-images research and tried to provide definitions that
work with all common devices. That's why I went with 4 toms, 4 cymbals,
one bass, one hi-hat. I haven't seen other drums and I doubt that we need
any additions to that. Anyway, the naming-scheme is intentionally done in
an extensible way.
For guitars, we support 5 frets (normally aligned vertically, compared to
the real horizontal layouts), a single strum-bar with up/down directions,
an optional fret-board and a whammy-bar.
Most of the devices provide pressure values so I went with ABS_* bits. If
we ever support devices which only provide digital input, we have to
decide whether to emulate pressure data or add additional BTN_* bits.
If someone is not familiar with these devices, here are two pictures which
provide almost all introduced interfaces (or try the given keywords
with a google-image search):
Guitar: ("guitar hero world tour guitar")
http://images1.wikia.nocookie.net/__cb20120911023442/applezone/es/images/f/f9/Wii_Guitar.jpg
Drums: ("guitar hero drums")
http://oyster.ignimgs.com/franchises/images/03/55/35526_band-hero-drum-set-hands-on-20090929040735768.jpg
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
include/linux/mod_devicetable.h | 2 +-
include/uapi/linux/input.h | 25 +++++++++++++++++++++++--
2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 45e9214..329aa30 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -277,7 +277,7 @@ struct pcmcia_device_id {
#define INPUT_DEVICE_ID_KEY_MIN_INTERESTING 0x71
#define INPUT_DEVICE_ID_KEY_MAX 0x2ff
#define INPUT_DEVICE_ID_REL_MAX 0x0f
-#define INPUT_DEVICE_ID_ABS_MAX 0x3f
+#define INPUT_DEVICE_ID_ABS_MAX 0x4f
#define INPUT_DEVICE_ID_MSC_MAX 0x07
#define INPUT_DEVICE_ID_LED_MAX 0x0f
#define INPUT_DEVICE_ID_SND_MAX 0x07
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
index d584047..76457ee 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -716,6 +716,14 @@ struct input_keymap_entry {
#define BTN_DPAD_LEFT 0x222
#define BTN_DPAD_RIGHT 0x223
+#define BTN_FRET_FAR_UP 0x224
+#define BTN_FRET_UP 0x225
+#define BTN_FRET_MID 0x226
+#define BTN_FRET_LOW 0x227
+#define BTN_FRET_FAR_LOW 0x228
+#define BTN_STRUM_BAR_UP 0x229
+#define BTN_STRUM_BAR_DOWN 0x22a
+
#define BTN_TRIGGER_HAPPY 0x2c0
#define BTN_TRIGGER_HAPPY1 0x2c0
#define BTN_TRIGGER_HAPPY2 0x2c1
@@ -829,8 +837,21 @@ struct input_keymap_entry {
#define ABS_MT_TOOL_X 0x3c /* Center X tool position */
#define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */
-
-#define ABS_MAX 0x3f
+/* Drums and guitars (mostly toys) */
+#define ABS_TOM_FAR_LEFT 0x40
+#define ABS_TOM_LEFT 0x41
+#define ABS_TOM_RIGHT 0x42
+#define ABS_TOM_FAR_RIGHT 0x43
+#define ABS_CYMBAL_FAR_LEFT 0x44
+#define ABS_CYMBAL_LEFT 0x45
+#define ABS_CYMBAL_RIGHT 0x46
+#define ABS_CYMBAL_FAR_RIGHT 0x47
+#define ABS_BASS 0x48
+#define ABS_HI_HAT 0x49
+#define ABS_FRET_BOARD 0x4a /* Guitar fret board, vertical pos */
+#define ABS_WHAMMY_BAR 0x4b /* Guitar whammy bar (or vibrato) */
+
+#define ABS_MAX 0x4f
#define ABS_CNT (ABS_MAX+1)
/*
--
1.8.4
^ permalink raw reply related
* [PATCH 2/3] HID: wiimote: add support for Guitar-Hero drums
From: David Herrmann @ 2013-08-26 17:14 UTC (permalink / raw)
To: linux-input
Cc: Jiri Kosina, Nicolas Adenis-Lamarre, Dmitry Torokhov,
David Herrmann
In-Reply-To: <1377537288-19289-1-git-send-email-dh.herrmann@gmail.com>
Guitar-Hero comes with a drums extension. Use the newly introduced input
drums-bits to report this back to user-space. This is a usual extension
like any other device. Nothing special to take care of.
We report this to user-space as "Nintendo Wii Remote Drums". There are
other drums (like "RockBand" drums) which we currently do not support and
maybe will at some point. However, it is quite likely that we can report
these via the same interface. This allows user-space to work with them
without knowing the exact branding.
I couldn't find anyone who owns a "RockBand" device, though.
Initial-work-by: Nicolas Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com>
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
drivers/hid/hid-wiimote-core.c | 7 ++
drivers/hid/hid-wiimote-modules.c | 218 ++++++++++++++++++++++++++++++++++++++
drivers/hid/hid-wiimote.h | 2 +
3 files changed, 227 insertions(+)
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index 6602098..946cdef 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -456,6 +456,9 @@ static __u8 wiimote_cmd_read_ext(struct wiimote_data *wdata, __u8 *rmem)
return WIIMOTE_EXT_BALANCE_BOARD;
if (rmem[4] == 0x01 && rmem[5] == 0x20)
return WIIMOTE_EXT_PRO_CONTROLLER;
+ if (rmem[0] == 0x01 && rmem[1] == 0x00 &&
+ rmem[4] == 0x01 && rmem[5] == 0x03)
+ return WIIMOTE_EXT_GUITAR_HERO_DRUMS;
return WIIMOTE_EXT_UNKNOWN;
}
@@ -489,6 +492,7 @@ static bool wiimote_cmd_map_mp(struct wiimote_data *wdata, __u8 exttype)
/* map MP with correct pass-through mode */
switch (exttype) {
case WIIMOTE_EXT_CLASSIC_CONTROLLER:
+ case WIIMOTE_EXT_GUITAR_HERO_DRUMS:
wmem = 0x07;
break;
case WIIMOTE_EXT_NUNCHUK:
@@ -1079,6 +1083,7 @@ static const char *wiimote_exttype_names[WIIMOTE_EXT_NUM] = {
[WIIMOTE_EXT_CLASSIC_CONTROLLER] = "Nintendo Wii Classic Controller",
[WIIMOTE_EXT_BALANCE_BOARD] = "Nintendo Wii Balance Board",
[WIIMOTE_EXT_PRO_CONTROLLER] = "Nintendo Wii U Pro Controller",
+ [WIIMOTE_EXT_GUITAR_HERO_DRUMS] = "Nintendo Wii Guitar Hero Drums",
};
/*
@@ -1665,6 +1670,8 @@ static ssize_t wiimote_ext_show(struct device *dev,
return sprintf(buf, "balanceboard\n");
case WIIMOTE_EXT_PRO_CONTROLLER:
return sprintf(buf, "procontroller\n");
+ case WIIMOTE_EXT_GUITAR_HERO_DRUMS:
+ return sprintf(buf, "drums\n");
case WIIMOTE_EXT_UNKNOWN:
/* fallthrough */
default:
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index 2e7d644..08a44a7 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -1834,6 +1834,223 @@ static const struct wiimod_ops wiimod_pro = {
};
/*
+ * Drums
+ * Guitar-Hero, Rock-Band and other games came bundled with drums which can
+ * be plugged as extension to a Wiimote. Drum-reports are still not entirely
+ * figured out, but the most important information is known.
+ * We create a separate device for drums and report all information via this
+ * input device.
+ */
+
+static inline void wiimod_drums_report_pressure(struct wiimote_data *wdata,
+ __u8 none, __u8 which,
+ __u8 pressure, __u8 onoff,
+ __u8 *store, __u16 code,
+ __u8 which_code)
+{
+ static const __u8 default_pressure = 3;
+
+ if (!none && which == which_code) {
+ *store = pressure;
+ input_report_abs(wdata->extension.input, code, *store);
+ } else if (onoff != !!*store) {
+ *store = onoff ? default_pressure : 0;
+ input_report_abs(wdata->extension.input, code, *store);
+ }
+}
+
+static void wiimod_drums_in_ext(struct wiimote_data *wdata, const __u8 *ext)
+{
+ __u8 pressure, which, none, hhp, sx, sy;
+ __u8 o, r, y, g, b, bass, bm, bp;
+
+ /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 1 | 0 | 0 | SX <5:0> |
+ * 2 | 0 | 0 | SY <5:0> |
+ * -----+-----+-----+-----------------------------+-----+
+ * 3 | HPP | NON | WHICH <5:1> | ? |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 4 | SOFT <7:5> | 0 | 1 | 1 | 0 | ? |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 5 | ? | 1 | 1 | B- | 1 | B+ | 1 | ? |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 6 | O | R | Y | G | B | BSS | 1 | 1 |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * All buttons are 0 if pressed
+ *
+ * With Motion+ enabled, the following bits will get invalid:
+ * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 1 | 0 | 0 | SX <5:1> |XXXXX|
+ * 2 | 0 | 0 | SY <5:1> |XXXXX|
+ * -----+-----+-----+-----------------------------+-----+
+ * 3 | HPP | NON | WHICH <5:1> | ? |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 4 | SOFT <7:5> | 0 | 1 | 1 | 0 | ? |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 5 | ? | 1 | 1 | B- | 1 | B+ | 1 |XXXXX|
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 6 | O | R | Y | G | B | BSS |XXXXX|XXXXX|
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ */
+
+ pressure = 7 - (ext[3] >> 5);
+ which = (ext[2] >> 1) & 0x1f;
+ none = !!(ext[2] & 0x40);
+ hhp = !(ext[2] & 0x80);
+ sx = ext[0] & 0x3f;
+ sy = ext[1] & 0x3f;
+ o = !(ext[5] & 0x80);
+ r = !(ext[5] & 0x40);
+ y = !(ext[5] & 0x20);
+ g = !(ext[5] & 0x10);
+ b = !(ext[5] & 0x08);
+ bass = !(ext[5] & 0x04);
+ bm = !(ext[4] & 0x10);
+ bp = !(ext[4] & 0x04);
+
+ wiimod_drums_report_pressure(wdata, none, which, pressure,
+ o, &wdata->state.pressure_drums[0],
+ ABS_CYMBAL_RIGHT, 0x0e);
+ wiimod_drums_report_pressure(wdata, none, which, pressure,
+ r, &wdata->state.pressure_drums[1],
+ ABS_TOM_LEFT, 0x19);
+ wiimod_drums_report_pressure(wdata, none, which, pressure,
+ y, &wdata->state.pressure_drums[2],
+ ABS_CYMBAL_LEFT, 0x11);
+ wiimod_drums_report_pressure(wdata, none, which, pressure,
+ g, &wdata->state.pressure_drums[3],
+ ABS_TOM_FAR_RIGHT, 0x12);
+ wiimod_drums_report_pressure(wdata, none, which, pressure,
+ b, &wdata->state.pressure_drums[4],
+ ABS_TOM_RIGHT, 0x0f);
+
+ /* Bass shares pressure with hi-hat (set via hhp) */
+ wiimod_drums_report_pressure(wdata, none, hhp ? 0xff : which, pressure,
+ bass, &wdata->state.pressure_drums[5],
+ ABS_BASS, 0x1b);
+ /* Hi-hat has no on/off values, just pressure. Force to off/0. */
+ wiimod_drums_report_pressure(wdata, none, hhp ? which : 0xff, pressure,
+ 0, &wdata->state.pressure_drums[6],
+ ABS_HI_HAT, 0x0e);
+
+ input_report_abs(wdata->extension.input, ABS_X, sx - 0x20);
+ input_report_abs(wdata->extension.input, ABS_Y, sy - 0x20);
+
+ input_report_key(wdata->extension.input, BTN_START, bp);
+ input_report_key(wdata->extension.input, BTN_SELECT, bm);
+
+ input_sync(wdata->extension.input);
+}
+
+static int wiimod_drums_open(struct input_dev *dev)
+{
+ struct wiimote_data *wdata = input_get_drvdata(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&wdata->state.lock, flags);
+ wdata->state.flags |= WIIPROTO_FLAG_EXT_USED;
+ wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+ spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+ return 0;
+}
+
+static void wiimod_drums_close(struct input_dev *dev)
+{
+ struct wiimote_data *wdata = input_get_drvdata(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&wdata->state.lock, flags);
+ wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED;
+ wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+ spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static int wiimod_drums_probe(const struct wiimod_ops *ops,
+ struct wiimote_data *wdata)
+{
+ int ret;
+
+ wdata->extension.input = input_allocate_device();
+ if (!wdata->extension.input)
+ return -ENOMEM;
+
+ input_set_drvdata(wdata->extension.input, wdata);
+ wdata->extension.input->open = wiimod_drums_open;
+ wdata->extension.input->close = wiimod_drums_close;
+ wdata->extension.input->dev.parent = &wdata->hdev->dev;
+ wdata->extension.input->id.bustype = wdata->hdev->bus;
+ wdata->extension.input->id.vendor = wdata->hdev->vendor;
+ wdata->extension.input->id.product = wdata->hdev->product;
+ wdata->extension.input->id.version = wdata->hdev->version;
+ wdata->extension.input->name = WIIMOTE_NAME " Drums";
+
+ set_bit(EV_KEY, wdata->extension.input->evbit);
+ set_bit(BTN_START, wdata->extension.input->keybit);
+ set_bit(BTN_SELECT, wdata->extension.input->keybit);
+
+ set_bit(EV_ABS, wdata->extension.input->evbit);
+ set_bit(ABS_X, wdata->extension.input->absbit);
+ set_bit(ABS_Y, wdata->extension.input->absbit);
+ set_bit(ABS_TOM_LEFT, wdata->extension.input->absbit);
+ set_bit(ABS_TOM_RIGHT, wdata->extension.input->absbit);
+ set_bit(ABS_TOM_FAR_RIGHT, wdata->extension.input->absbit);
+ set_bit(ABS_CYMBAL_LEFT, wdata->extension.input->absbit);
+ set_bit(ABS_CYMBAL_RIGHT, wdata->extension.input->absbit);
+ set_bit(ABS_BASS, wdata->extension.input->absbit);
+ set_bit(ABS_HI_HAT, wdata->extension.input->absbit);
+ input_set_abs_params(wdata->extension.input,
+ ABS_X, -32, 31, 1, 1);
+ input_set_abs_params(wdata->extension.input,
+ ABS_Y, -32, 31, 1, 1);
+ input_set_abs_params(wdata->extension.input,
+ ABS_TOM_LEFT, 0, 7, 0, 0);
+ input_set_abs_params(wdata->extension.input,
+ ABS_TOM_RIGHT, 0, 7, 0, 0);
+ input_set_abs_params(wdata->extension.input,
+ ABS_TOM_FAR_RIGHT, 0, 7, 0, 0);
+ input_set_abs_params(wdata->extension.input,
+ ABS_CYMBAL_LEFT, 0, 7, 0, 0);
+ input_set_abs_params(wdata->extension.input,
+ ABS_CYMBAL_RIGHT, 0, 7, 0, 0);
+ input_set_abs_params(wdata->extension.input,
+ ABS_BASS, 0, 7, 0, 0);
+ input_set_abs_params(wdata->extension.input,
+ ABS_HI_HAT, 0, 7, 0, 0);
+
+ ret = input_register_device(wdata->extension.input);
+ if (ret)
+ goto err_free;
+
+ return 0;
+
+err_free:
+ input_free_device(wdata->extension.input);
+ wdata->extension.input = NULL;
+ return ret;
+}
+
+static void wiimod_drums_remove(const struct wiimod_ops *ops,
+ struct wiimote_data *wdata)
+{
+ if (!wdata->extension.input)
+ return;
+
+ input_unregister_device(wdata->extension.input);
+ wdata->extension.input = NULL;
+}
+
+static const struct wiimod_ops wiimod_drums = {
+ .flags = 0,
+ .arg = 0,
+ .probe = wiimod_drums_probe,
+ .remove = wiimod_drums_remove,
+ .in_ext = wiimod_drums_in_ext,
+};
+
+/*
* Builtin Motion Plus
* This module simply sets the WIIPROTO_FLAG_BUILTIN_MP protocol flag which
* disables polling for Motion-Plus. This should be set only for devices which
@@ -2083,4 +2300,5 @@ const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = {
[WIIMOTE_EXT_CLASSIC_CONTROLLER] = &wiimod_classic,
[WIIMOTE_EXT_BALANCE_BOARD] = &wiimod_bboard,
[WIIMOTE_EXT_PRO_CONTROLLER] = &wiimod_pro,
+ [WIIMOTE_EXT_GUITAR_HERO_DRUMS] = &wiimod_drums,
};
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
index f1474f3..6e18b55 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -88,6 +88,7 @@ enum wiimote_exttype {
WIIMOTE_EXT_CLASSIC_CONTROLLER,
WIIMOTE_EXT_BALANCE_BOARD,
WIIMOTE_EXT_PRO_CONTROLLER,
+ WIIMOTE_EXT_GUITAR_HERO_DRUMS,
WIIMOTE_EXT_NUM,
};
@@ -135,6 +136,7 @@ struct wiimote_state {
/* calibration data */
__u16 calib_bboard[4][3];
+ __u8 pressure_drums[7];
};
struct wiimote_data {
--
1.8.4
^ permalink raw reply related
* [PATCH 3/3] HID: wiimote: add support for Guitar-Hero guitars
From: David Herrmann @ 2013-08-26 17:14 UTC (permalink / raw)
To: linux-input
Cc: Jiri Kosina, Nicolas Adenis-Lamarre, Dmitry Torokhov,
David Herrmann
In-Reply-To: <1377537288-19289-1-git-send-email-dh.herrmann@gmail.com>
From: Nicolas Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com>
Apart from drums, Guitar-Hero also ships with guitars. Use the recently
introduced input ABS/BTN-bits to report this to user-space.
Devices are reported as "Nintendo Wii Remote Guitar". If I ever get my
hands on "RockBand" guitars, I will try to report them via the same
interface so user-space does not have to bother which device it deals
with.
Signed-off-by: Nicolas.Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com>
(add commit-msg and adjust to new BTN_* IDs)
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
drivers/hid/hid-wiimote-core.c | 7 ++
drivers/hid/hid-wiimote-modules.c | 174 ++++++++++++++++++++++++++++++++++++++
drivers/hid/hid-wiimote.h | 1 +
3 files changed, 182 insertions(+)
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index 946cdef..d3055d1 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -459,6 +459,9 @@ static __u8 wiimote_cmd_read_ext(struct wiimote_data *wdata, __u8 *rmem)
if (rmem[0] == 0x01 && rmem[1] == 0x00 &&
rmem[4] == 0x01 && rmem[5] == 0x03)
return WIIMOTE_EXT_GUITAR_HERO_DRUMS;
+ if (rmem[0] == 0x00 && rmem[1] == 0x00 &&
+ rmem[4] == 0x01 && rmem[5] == 0x03)
+ return WIIMOTE_EXT_GUITAR_HERO_GUITAR;
return WIIMOTE_EXT_UNKNOWN;
}
@@ -493,6 +496,7 @@ static bool wiimote_cmd_map_mp(struct wiimote_data *wdata, __u8 exttype)
switch (exttype) {
case WIIMOTE_EXT_CLASSIC_CONTROLLER:
case WIIMOTE_EXT_GUITAR_HERO_DRUMS:
+ case WIIMOTE_EXT_GUITAR_HERO_GUITAR:
wmem = 0x07;
break;
case WIIMOTE_EXT_NUNCHUK:
@@ -1084,6 +1088,7 @@ static const char *wiimote_exttype_names[WIIMOTE_EXT_NUM] = {
[WIIMOTE_EXT_BALANCE_BOARD] = "Nintendo Wii Balance Board",
[WIIMOTE_EXT_PRO_CONTROLLER] = "Nintendo Wii U Pro Controller",
[WIIMOTE_EXT_GUITAR_HERO_DRUMS] = "Nintendo Wii Guitar Hero Drums",
+ [WIIMOTE_EXT_GUITAR_HERO_GUITAR] = "Nintendo Wii Guitar Hero Guitar",
};
/*
@@ -1672,6 +1677,8 @@ static ssize_t wiimote_ext_show(struct device *dev,
return sprintf(buf, "procontroller\n");
case WIIMOTE_EXT_GUITAR_HERO_DRUMS:
return sprintf(buf, "drums\n");
+ case WIIMOTE_EXT_GUITAR_HERO_GUITAR:
+ return sprintf(buf, "guitar\n");
case WIIMOTE_EXT_UNKNOWN:
/* fallthrough */
default:
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index 08a44a7..7e124c3 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -2051,6 +2051,179 @@ static const struct wiimod_ops wiimod_drums = {
};
/*
+ * Guitar
+ * Guitar-Hero, Rock-Band and other games came bundled with guitars which can
+ * be plugged as extension to a Wiimote.
+ * We create a separate device for guitars and report all information via this
+ * input device.
+ */
+
+static void wiimod_guitar_in_ext(struct wiimote_data *wdata, const __u8 *ext)
+{
+ __u8 sx, sy, tb, wb, bd, bm, bp, bo, br, bb, bg, by, bu;
+
+ /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 1 | 0 | 0 | SX <5:0> |
+ * 2 | 0 | 0 | SY <5:0> |
+ * -----+-----+-----+-----+-----------------------------+
+ * 3 | 0 | 0 | 0 | TB <4:0> |
+ * -----+-----+-----+-----+-----------------------------+
+ * 4 | 0 | 0 | 0 | WB <4:0> |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 5 | 1 | BD | 1 | B- | 1 | B+ | 1 | 1 |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 6 | BO | BR | BB | BG | BY | 1 | 1 | BU |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * All buttons are 0 if pressed
+ *
+ * With Motion+ enabled, the following bits will get invalid:
+ * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 1 | 0 | 0 | SX <5:1> |XXXXX|
+ * 2 | 0 | 0 | SY <5:1> |XXXXX|
+ * -----+-----+-----+-----+-----------------------+-----+
+ * 3 | 0 | 0 | 0 | TB <4:0> |
+ * -----+-----+-----+-----+-----------------------------+
+ * 4 | 0 | 0 | 0 | WB <4:0> |
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 5 | 1 | BD | 1 | B- | 1 | B+ | 1 |XXXXX|
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * 6 | BO | BR | BB | BG | BY | 1 |XXXXX|XXXXX|
+ * -----+-----+-----+-----+-----+-----+-----+-----+-----+
+ */
+
+ sx = ext[0] & 0x3f;
+ sy = ext[1] & 0x3f;
+ tb = ext[2] & 0x1f;
+ wb = ext[3] & 0x1f;
+ bd = !(ext[4] & 0x40);
+ bm = !(ext[4] & 0x10);
+ bp = !(ext[4] & 0x04);
+ bo = !(ext[5] & 0x80);
+ br = !(ext[5] & 0x40);
+ bb = !(ext[5] & 0x20);
+ bg = !(ext[5] & 0x10);
+ by = !(ext[5] & 0x08);
+ bu = !(ext[5] & 0x01);
+
+ input_report_abs(wdata->extension.input, ABS_X, sx - 0x20);
+ input_report_abs(wdata->extension.input, ABS_Y, sy - 0x20);
+ input_report_abs(wdata->extension.input, ABS_FRET_BOARD, tb);
+ input_report_abs(wdata->extension.input, ABS_WHAMMY_BAR, wb - 0x10);
+
+ input_report_key(wdata->extension.input, BTN_MODE, bm);
+ input_report_key(wdata->extension.input, BTN_START, bp);
+ input_report_key(wdata->extension.input, BTN_STRUM_BAR_UP, bu);
+ input_report_key(wdata->extension.input, BTN_STRUM_BAR_DOWN, bd);
+ input_report_key(wdata->extension.input, BTN_FRET_FAR_UP, bg);
+ input_report_key(wdata->extension.input, BTN_FRET_UP, br);
+ input_report_key(wdata->extension.input, BTN_FRET_MID, by);
+ input_report_key(wdata->extension.input, BTN_FRET_LOW, bb);
+ input_report_key(wdata->extension.input, BTN_FRET_FAR_LOW, bo);
+
+ input_sync(wdata->extension.input);
+}
+
+static int wiimod_guitar_open(struct input_dev *dev)
+{
+ struct wiimote_data *wdata = input_get_drvdata(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&wdata->state.lock, flags);
+ wdata->state.flags |= WIIPROTO_FLAG_EXT_USED;
+ wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+ spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+ return 0;
+}
+
+static void wiimod_guitar_close(struct input_dev *dev)
+{
+ struct wiimote_data *wdata = input_get_drvdata(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&wdata->state.lock, flags);
+ wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED;
+ wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+ spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static int wiimod_guitar_probe(const struct wiimod_ops *ops,
+ struct wiimote_data *wdata)
+{
+ int ret;
+
+ wdata->extension.input = input_allocate_device();
+ if (!wdata->extension.input)
+ return -ENOMEM;
+
+ input_set_drvdata(wdata->extension.input, wdata);
+ wdata->extension.input->open = wiimod_guitar_open;
+ wdata->extension.input->close = wiimod_guitar_close;
+ wdata->extension.input->dev.parent = &wdata->hdev->dev;
+ wdata->extension.input->id.bustype = wdata->hdev->bus;
+ wdata->extension.input->id.vendor = wdata->hdev->vendor;
+ wdata->extension.input->id.product = wdata->hdev->product;
+ wdata->extension.input->id.version = wdata->hdev->version;
+ wdata->extension.input->name = WIIMOTE_NAME " Guitar";
+
+ set_bit(EV_KEY, wdata->extension.input->evbit);
+ set_bit(BTN_MODE, wdata->extension.input->keybit);
+ set_bit(BTN_START, wdata->extension.input->keybit);
+ set_bit(BTN_FRET_FAR_UP, wdata->extension.input->keybit);
+ set_bit(BTN_FRET_UP, wdata->extension.input->keybit);
+ set_bit(BTN_FRET_MID, wdata->extension.input->keybit);
+ set_bit(BTN_FRET_LOW, wdata->extension.input->keybit);
+ set_bit(BTN_FRET_FAR_LOW, wdata->extension.input->keybit);
+ set_bit(BTN_STRUM_BAR_UP, wdata->extension.input->keybit);
+ set_bit(BTN_STRUM_BAR_DOWN, wdata->extension.input->keybit);
+
+ set_bit(EV_ABS, wdata->extension.input->evbit);
+ set_bit(ABS_X, wdata->extension.input->absbit);
+ set_bit(ABS_Y, wdata->extension.input->absbit);
+ set_bit(ABS_FRET_BOARD, wdata->extension.input->absbit);
+ set_bit(ABS_WHAMMY_BAR, wdata->extension.input->absbit);
+ input_set_abs_params(wdata->extension.input,
+ ABS_X, -32, 31, 1, 1);
+ input_set_abs_params(wdata->extension.input,
+ ABS_Y, -32, 31, 1, 1);
+ input_set_abs_params(wdata->extension.input,
+ ABS_FRET_BOARD, 0, 0x1f, 1, 1);
+ input_set_abs_params(wdata->extension.input,
+ ABS_WHAMMY_BAR, 0, 0x0f, 1, 1);
+
+ ret = input_register_device(wdata->extension.input);
+ if (ret)
+ goto err_free;
+
+ return 0;
+
+err_free:
+ input_free_device(wdata->extension.input);
+ wdata->extension.input = NULL;
+ return ret;
+}
+
+static void wiimod_guitar_remove(const struct wiimod_ops *ops,
+ struct wiimote_data *wdata)
+{
+ if (!wdata->extension.input)
+ return;
+
+ input_unregister_device(wdata->extension.input);
+ wdata->extension.input = NULL;
+}
+
+static const struct wiimod_ops wiimod_guitar = {
+ .flags = 0,
+ .arg = 0,
+ .probe = wiimod_guitar_probe,
+ .remove = wiimod_guitar_remove,
+ .in_ext = wiimod_guitar_in_ext,
+};
+
+/*
* Builtin Motion Plus
* This module simply sets the WIIPROTO_FLAG_BUILTIN_MP protocol flag which
* disables polling for Motion-Plus. This should be set only for devices which
@@ -2301,4 +2474,5 @@ const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = {
[WIIMOTE_EXT_BALANCE_BOARD] = &wiimod_bboard,
[WIIMOTE_EXT_PRO_CONTROLLER] = &wiimod_pro,
[WIIMOTE_EXT_GUITAR_HERO_DRUMS] = &wiimod_drums,
+ [WIIMOTE_EXT_GUITAR_HERO_GUITAR] = &wiimod_guitar,
};
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
index 6e18b55..379cdfb 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -89,6 +89,7 @@ enum wiimote_exttype {
WIIMOTE_EXT_BALANCE_BOARD,
WIIMOTE_EXT_PRO_CONTROLLER,
WIIMOTE_EXT_GUITAR_HERO_DRUMS,
+ WIIMOTE_EXT_GUITAR_HERO_GUITAR,
WIIMOTE_EXT_NUM,
};
--
1.8.4
^ permalink raw reply related
* Re: [PATCH 1/1] HID: hidraw: Add spinlock in struct hidraw to protect list
From: Jiri Kosina @ 2013-08-26 19:44 UTC (permalink / raw)
To: Yonghua Zheng; +Cc: linux-input
In-Reply-To: <20130826153833.GA2962@gmail.com>
On Mon, 26 Aug 2013, Yonghua Zheng wrote:
> Hi Jiri,
>
> Fix the conflict and update the patch:
>
> >From 7c06e1f3a5959e73a5b827bda67e7c1eaed7da67 Mon Sep 17 00:00:00 2001
> From: Yonghua Zheng <younghua.zheng@gmail.com>
> Date: Wed, 14 Aug 2013 17:43:36 +0800
> Subject: [PATCH 1/1] HID: hidraw: Add spinlock in struct hidraw to protect
> member list
>
> It is unsafe to call list_for_each_entry in hidraw_report_event to
> traverse each hidraw_list node without a lock protection, the list
> could be modified if someone calls hidraw_release and list_del to
> remove itself from the list, this can cause hidraw_report_event
> to touch a deleted list struct and panic.
>
> To prevent this, introduce a spinlock in struct hidraw to protect
> list from concurrent access.
>
> Signed-off-by: Yonghua Zheng <younghua.zheng@gmail.com>
Applied now, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v3 0/3] HID: Win 8 multitouch panels detection in core
From: Srinivas Pandruvada @ 2013-08-26 21:12 UTC (permalink / raw)
To: Jiri Kosina
Cc: Henrik Rydberg, Benjamin Tissoires, Benjamin Tissoires,
Stephane Chatty, Alexander Holler, linux-input, linux-kernel
In-Reply-To: <alpine.LNX.2.00.1308261342430.2077@pobox.suse.cz>
On 08/26/2013 04:43 AM, Jiri Kosina wrote:
> On Thu, 22 Aug 2013, Henrik Rydberg wrote:
>
>>> this is the v3 of this patch series.
>>>
>>> Srinivas, I still did not added your tested-by as I made minors modifications of
>>> the patches 1 and 2. Now only the patch 1 will impact sensor_hub, and patch 2
>>> will not impact this. Maybe just wait for Henrik to put his "Reviewed-by" before
>>> giving one last test.
>> Here goes:
>>
>> Reviewed-by: Henrik Rydberg <rydberg@euromail.se>
> Thanks guys. Not applying this just yet, waiting for Tested-by: from
> Srinivas.
>
Tested-by: Srinivas Pandruvada<srinivas.pandruvada@linux.intel.com>
^ permalink raw reply
* [PATCH] HID: uhid: add devname module alias
From: Marcel Holtmann @ 2013-08-27 5:07 UTC (permalink / raw)
To: linux-input
For simple device node creation, add the devname module alias.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
drivers/hid/uhid.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
index fc307e0..9ab7dfc 100644
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -659,3 +659,4 @@ module_exit(uhid_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem");
+MODULE_ALIAS("devname:" UHID_NAME);
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH v3 0/3] HID: Win 8 multitouch panels detection in core
From: Jiri Kosina @ 2013-08-27 8:02 UTC (permalink / raw)
To: Srinivas Pandruvada
Cc: Henrik Rydberg, Benjamin Tissoires, Benjamin Tissoires,
Stephane Chatty, Alexander Holler, linux-input, linux-kernel
In-Reply-To: <521BC4D7.5050507@linux.intel.com>
On Mon, 26 Aug 2013, Srinivas Pandruvada wrote:
> > > > Srinivas, I still did not added your tested-by as I made minors
> > > > modifications of
> > > > the patches 1 and 2. Now only the patch 1 will impact sensor_hub, and
> > > > patch 2
> > > > will not impact this. Maybe just wait for Henrik to put his
> > > > "Reviewed-by" before
> > > > giving one last test.
> > > Here goes:
> > >
> > > Reviewed-by: Henrik Rydberg <rydberg@euromail.se>
> > Thanks guys. Not applying this just yet, waiting for Tested-by: from
> > Srinivas.
> >
> Tested-by: Srinivas Pandruvada<srinivas.pandruvada@linux.intel.com>
Applied, thanks everybody.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 2/2] iio: ti_am335x_adc: Add continuous sampling support
From: Lee Jones @ 2013-08-27 8:42 UTC (permalink / raw)
To: Zubair Lutfullah
Cc: jic23, bigeasy, linux-iio, linux-input, linux-kernel, gregkh
In-Reply-To: <1377470724-15710-3-git-send-email-zubair.lutfullah@gmail.com>
On Sun, 25 Aug 2013, Zubair Lutfullah wrote:
> Previously the driver had only one-shot reading functionality.
> This patch adds triggered buffer support to the driver.
>
> Continuous sampling starts when buffer is enabled.
> And samples are pushed to userpace by the trigger which
> triggers automatically at every hardware interrupt
> of FIFO1 filling with samples upto threshold value.
>
> Userspace responsibility to stop sampling by writing zero
> in the buffer enable file.
>
> Patil Rachna (TI) laid the ground work for ADC HW register access.
> Russ Dill (TI) fixed bugs in the driver relevant to FIFOs and IRQs.
>
> I fixed channel scanning so multiple ADC channels can be read
> simultaneously and pushed to userspace.
> Restructured the driver to fit IIO ABI.
> And added trigger support.
>
> Signed-off-by: Zubair Lutfullah <zubair.lutfullah@gmail.com>
> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Russ Dill <Russ.Dill@ti.com>
> ---
> drivers/iio/adc/ti_am335x_adc.c | 254 +++++++++++++++++++++++++++++++---
> include/linux/mfd/ti_am335x_tscadc.h | 13 ++
> 2 files changed, 246 insertions(+), 21 deletions(-)
MFD stuff looks okay to me.
Acked-by: Lee Jones <lee.jones@linaro.org>
<snip>
> diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
> index db1791b..a372ebf 100644
> --- a/include/linux/mfd/ti_am335x_tscadc.h
> +++ b/include/linux/mfd/ti_am335x_tscadc.h
> @@ -46,17 +46,25 @@
> /* Step Enable */
> #define STEPENB_MASK (0x1FFFF << 0)
> #define STEPENB(val) ((val) << 0)
> +#define ENB(val) (1 << (val))
> +#define STPENB_STEPENB STEPENB(0x1FFFF)
> +#define STPENB_STEPENB_TC STEPENB(0x1FFF)
>
> /* IRQ enable */
> #define IRQENB_HW_PEN BIT(0)
> #define IRQENB_FIFO0THRES BIT(2)
> +#define IRQENB_FIFO0OVRRUN BIT(3)
> +#define IRQENB_FIFO0UNDRFLW BIT(4)
> #define IRQENB_FIFO1THRES BIT(5)
> +#define IRQENB_FIFO1OVRRUN BIT(6)
> +#define IRQENB_FIFO1UNDRFLW BIT(7)
> #define IRQENB_PENUP BIT(9)
>
> /* Step Configuration */
> #define STEPCONFIG_MODE_MASK (3 << 0)
> #define STEPCONFIG_MODE(val) ((val) << 0)
> #define STEPCONFIG_MODE_HWSYNC STEPCONFIG_MODE(2)
> +#define STEPCONFIG_MODE_SWCNT STEPCONFIG_MODE(1)
> #define STEPCONFIG_AVG_MASK (7 << 2)
> #define STEPCONFIG_AVG(val) ((val) << 2)
> #define STEPCONFIG_AVG_16 STEPCONFIG_AVG(4)
> @@ -124,6 +132,7 @@
> #define MAX_CLK_DIV 7
> #define TOTAL_STEPS 16
> #define TOTAL_CHANNELS 8
> +#define FIFO1_THRESHOLD 19
>
> /*
> * ADC runs at 3MHz, and it takes
> @@ -153,6 +162,10 @@ struct ti_tscadc_dev {
>
> /* adc device */
> struct adc_device *adc;
> +
> + /* Context save */
> + unsigned int irqstat;
> + unsigned int ctrl;
> };
>
> static inline struct ti_tscadc_dev *ti_tscadc_dev_get(struct platform_device *p)
--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 0/3] Input: omap-keypad: Wakeup capability and w/a for i689 errata.
From: Illia Smyrnov @ 2013-08-27 10:08 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Illia Smyrnov, linux-input, linux-kernel, linux-omap,
Felipe Balbi
In-Reply-To: <1375116311-13999-1-git-send-email-illia.smyrnov@ti.com>
Hello Dmitry,
could you take reviewed patches from this patchset?
Reviewed patches:
[PATCH v3 1/3] Input: omap-keypad: Enable wakeup capability for keypad.
[PATCH v3 3/3] Input: omap-keypad: Setup irq type from DT
are not depend on
[PATCH v3 2/3] Input: omap-keypad: errata i689: Correct debounce time
Thanks.
On 07/29/2013 07:45 PM, Illia Smyrnov wrote:
> This patchset adds wake up capability for the keypad and
> workaround for i689 errata.
>
> Based on top of v3.11-rc3
>
> Depends on:
>
> Input: omap-keypad: Convert to threaded IRQ
> https://patchwork.kernel.org/patch/2832920/
>
> Input: omap-keypad: Cleanup - use bitfiled instead of hardcoded values
> https://patchwork.kernel.org/patch/2832913/
>
> Axel Haslam (1):
> Input: omap-keypad: errata i689: Correct debounce time
>
> Illia Smyrnov (2):
> Input: omap-keypad: Enable wakeup capability for keypad.
> Input: omap-keypad: Setup irq type from DT
>
> drivers/input/keyboard/omap4-keypad.c | 52 ++++++++++++++++++++++++++++++---
> 1 file changed, 48 insertions(+), 4 deletions(-)
>
^ permalink raw reply
* Re: Rotary encoder platform device driver code examples
From: Christian Gmeiner @ 2013-08-27 10:39 UTC (permalink / raw)
To: GRENON Loïc; +Cc: linux-input
In-Reply-To: <52152808.1000608@rs2i.net>
2013/8/21 GRENON Loïc <difool@rs2i.net>:
> Hi guys,
>
> I want to interface a magnetic scale position sensor with a BeagleBone Black
> (an ARM development platform).
> While I was reading this following article :
> http://bwgz57.wordpress.com/2012/04/11/beaglebone-with-a-rotary-encoder/ I
> discovered that linux has built-in support for rotary encoders connected via
> GPIO.
>
> The magnetic scale position sensor can be considered like a rotary encoder
> so I would use the rotary_encoder platform device driver.
>
> I've read the code example at the end of this document :
> https://www.kernel.org/doc/Documentation/input/rotary-encoder.txt
> But I don't know how to access to the "pos" value of the rotary encoder.
>
> Do you have some code example of use of this driver ? Or anything that can
> be helpful for me.
>
As the rotary encoder is an input device it is accessible via
/dev/input/eventX where X is
a number. Have a look at evtest user space application.
greets
--
Christian Gmeiner, MSc
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] Input: add SYN_MAX and SYN_CNT constants
From: David Herrmann @ 2013-08-27 11:23 UTC (permalink / raw)
To: linux-input; +Cc: Dmitry Torokhov, David Herrmann
SYN_* events are special and not enabled via set_bit() for devices. Hence,
they haven't been really needed, yet. However, user-space can still make
great use of that for int->string debugging helpers or alike.
Also, I haven't seen any reason not to define these, so here they are.
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
include/uapi/linux/input.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
index 4649ee3..2fb6fae 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -194,6 +194,8 @@ struct input_keymap_entry {
#define SYN_CONFIG 1
#define SYN_MT_REPORT 2
#define SYN_DROPPED 3
+#define SYN_MAX 0xf
+#define SYN_CNT (SYN_MAX+1)
/*
* Keys and buttons
--
1.8.4
^ permalink raw reply related
* [PATCH] Input: evdev - add EVIOCREVOKE ioctl
From: David Herrmann @ 2013-08-27 11:25 UTC (permalink / raw)
To: linux-input; +Cc: Dmitry Torokhov, Kristian Høgsberg, David Herrmann
If we have multiple sessions on a system, we normally don't want
background sessions to read input events. Otherwise, it could capture
passwords and more entered by the user on the foreground session. This is
a real world problem as the recent XMir development showed:
http://mjg59.dreamwidth.org/27327.html
We currently rely on sessions to release input devices when being
deactivated. This relies on trust across sessions. But that's not given on
usual systems. We therefore need a way to control which processes have
access to input devices.
With VTs the kernel simply routed them through the active /dev/ttyX. This
is not possible with evdev devices, though. Moreover, we want to avoid
routing input-devices through some dispatcher-daemon in userspace (which
would add some latency).
This patch introduces EVIOCREVOKE. If called on an evdev fd, this revokes
device-access irrecoverably for that *single* open-file. Hence, once you
call EVIOCREVOKE on any dup()ed fd, all fds for that open-file will be
rather useless now (but still valid compared to close()!). This allows us
to pass fds directly to session-processes from a trusted source. The
source keeps a dup()ed fd and revokes access once the session-process is
no longer active.
Compared to the EVIOCMUTE proposal, we can avoid the CAP_SYS_ADMIN
restriction now as there is no way to revive the fd again. Hence, a user
is free to call EVIOCREVOKE themself to kill the fd.
Additionally, this ioctl allows multi-layer access-control (again compared
to EVIOCMUTE which was limited to one layer via CAP_SYS_ADMIN). A middle
layer can simply request a new open-file from the layer above and pass it
to the layer below. Now each layer can call EVIOCREVOKE on the fds to
revoke access for all layers below, at the expense of one fd per layer.
There's already ongoing experimental user-space work which demonstrates
how it can be used:
http://lists.freedesktop.org/archives/systemd-devel/2013-August/012897.html
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
drivers/input/evdev.c | 30 +++++++++++++++++++++++++++++-
include/uapi/linux/input.h | 1 +
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index d2b34fb..2ea70ec 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -48,6 +48,7 @@ struct evdev_client {
struct evdev *evdev;
struct list_head node;
int clkid;
+ bool revoked;
unsigned int bufsize;
struct input_event buffer[];
};
@@ -164,6 +165,9 @@ static void evdev_pass_values(struct evdev_client *client,
struct input_event event;
bool wakeup = false;
+ if (client->revoked)
+ return;
+
event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ?
mono : real);
@@ -795,6 +799,15 @@ static int evdev_handle_mt_request(struct input_dev *dev,
return 0;
}
+static int evdev_revoke(struct evdev *evdev, struct evdev_client *client,
+ struct file *file)
+{
+ client->revoked = true;
+ input_flush_device(&evdev->handle, file);
+
+ return 0;
+}
+
static long evdev_do_ioctl(struct file *file, unsigned int cmd,
void __user *p, int compat_mode)
{
@@ -808,12 +821,27 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
unsigned int size;
int error;
- /* First we check for fixed-length commands */
+ /* First check for ioctls allowed while revoked */
switch (cmd) {
case EVIOCGVERSION:
return put_user(EV_VERSION, ip);
+ case EVIOCREVOKE:
+ if (p)
+ return -EINVAL;
+ else
+ return evdev_revoke(evdev, client, file);
+
+ default:
+ if (client->revoked)
+ return -EACCES;
+ break;
+ }
+
+ /* Then check for fixed-length commands */
+ switch (cmd) {
+
case EVIOCGID:
if (copy_to_user(p, &dev->id, sizeof(struct input_id)))
return -EFAULT;
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
index 2fb6fae..d61c61c 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -152,6 +152,7 @@ struct input_keymap_entry {
#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
+#define EVIOCREVOKE _IOW('E', 0x91, int) /* Revoke device access */
#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */
--
1.8.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox