Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH] typo fixes (coordiante -> coordinate) in am335x
From: Jan Lübbe @ 2013-11-05 16:01 UTC (permalink / raw)
  To: Lee Jones
  Cc: Dmitry Torokhov, Tony Lindgren, Samuel Ortiz, Zubair Lutfullah,
	linux-doc, linux-kernel, linux-omap, linux-arm-kernel,
	linux-input
In-Reply-To: <20131022090552.GE19112@lee--X1>

On Tue, 2013-10-22 at 10:05 +0100, Lee Jones wrote:
> This is the first time this patch has been sent to me.
> 
> I need Dmitry's input (no pun intended) on how he's like to deal with
> this. At a bare minimum I'd like his Ack.

Is there anything I can do to push this forward? The earlier we get the
typo fixed in the documentation, the less chance that someone will use
it that way.

Regards,
Jan


^ permalink raw reply

* Re: [PATCH] hid: add driver for IBM/Lenovo ScrollPoint mice
From: Jiri Kosina @ 2013-11-05 13:45 UTC (permalink / raw)
  To: Peter De Wachter; +Cc: linux-input, linux-kernel, Bernhard Seibold
In-Reply-To: <alpine.LNX.2.00.1308051357210.17512@pobox.suse.cz>

On Mon, 5 Aug 2013, Jiri Kosina wrote:

> > IBM Scrollpoint have a trackpoint-like gizmo instead of a scroll wheel,
> > which allows for two-dimensional scrolling. This driver provides an
> > input mapping to make that work.
> > 
> > The scrollpoint is also much more sensitive than a typical mouse wheel.
> > X can use this to provide smooth scrolling, but the kernel doesn't seem
> > to have a way to communicate this fact. As a result this mouse simply
> > scrolls way too fast. For now I've created an xorg patch to provide a
> > manual setting (fdo #48118).
> > 
> > Signed-off-by: Peter De Wachter <pdewacht@gmail.com>
> 
> Hi,
> 
> thanks for the driver.
> 
> I'd like to ask you to put a few more effort into this, unifying this a 
> little bit more with the existing driver for Lenovo devices we aready have 
> in the tree -- hid-lenovo-tpkbd.
> 
> As most of the drivers are divided on a per-vendor basis anyway, what I'd 
> probably like to see the most would be:
> 
> - drop HID_LENOVO_TPKBD (*)
> - create HID_LENOVO
> - rename your driver to hid-lenovo-scrollpoint
> - build both hid-lenovo-tpkbd and hid-lenovo-scrollpoint when HID_LENOVO 
>   is set
> 
> (*) or keep it for compatibility reasons, but make it just an alias for 
> CONFIG_HID_LENOVO.
> 
> Sounds feasible?

Peter, what are your plans with this, please?

> 
> > ---
> >  drivers/hid/Kconfig           |  8 ++++++
> >  drivers/hid/Makefile          |  1 +
> >  drivers/hid/hid-core.c        |  7 +++++
> >  drivers/hid/hid-ids.h         |  7 +++++
> >  drivers/hid/hid-scrollpoint.c | 67 +++++++++++++++++++++++++++++++++++++++++++
> >  5 files changed, 90 insertions(+)
> >  create mode 100644 drivers/hid/hid-scrollpoint.c
> > 
> > diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> > index fb52f3f..fdc49ca 100644
> > --- a/drivers/hid/Kconfig
> > +++ b/drivers/hid/Kconfig
> > @@ -593,6 +593,14 @@ config HID_SAMSUNG
> >  	---help---
> >  	Support for Samsung InfraRed remote control or keyboards.
> >  
> > +config HID_SCROLLPOINT
> > +	tristate "IBM/Lenovo ScrollPoint mice"
> > +	depends on HID
> > +	---help---
> > +	Support for IBM/Lenovo ScrollPoint mice.
> > +	Say Y here if you have a ScrollPoint mouse and want horizontal
> > +	scrolling to work.
> > +
> >  config HID_SONY
> >  	tristate "Sony PS3 controller"
> >  	depends on USB_HID
> > diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> > index 2065694..4a4c279 100644
> > --- a/drivers/hid/Makefile
> > +++ b/drivers/hid/Makefile
> > @@ -99,6 +99,7 @@ obj-$(CONFIG_HID_ROCCAT)	+= hid-roccat.o hid-roccat-common.o \
> >  	hid-roccat-lua.o hid-roccat-pyra.o hid-roccat-savu.o
> >  obj-$(CONFIG_HID_SAITEK)	+= hid-saitek.o
> >  obj-$(CONFIG_HID_SAMSUNG)	+= hid-samsung.o
> > +obj-$(CONFIG_HID_SCROLLPOINT)	+= hid-scrollpoint.o
> >  obj-$(CONFIG_HID_SMARTJOYPLUS)	+= hid-sjoy.o
> >  obj-$(CONFIG_HID_SONY)		+= hid-sony.o
> >  obj-$(CONFIG_HID_SPEEDLINK)	+= hid-speedlink.o
> > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> > index 264f550..003f419 100644
> > --- a/drivers/hid/hid-core.c
> > +++ b/drivers/hid/hid-core.c
> > @@ -1584,6 +1584,13 @@ static const struct hid_device_id hid_have_special_driver[] = {
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
> > +#if IS_ENABLED(CONFIG_HID_SCROLLPOINT)
> > +	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_III) },
> > +	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_PRO) },
> > +	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL) },
> > +	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL) },
> > +	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO) },
> > +#endif
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
> >  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
> > diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> > index 38535c9..f813fab 100644
> > --- a/drivers/hid/hid-ids.h
> > +++ b/drivers/hid/hid-ids.h
> > @@ -441,6 +441,13 @@
> >  #define USB_VENDOR_ID_HOLTEK_ALT		0x04d9
> >  #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD	0xa055
> >  
> > +#define USB_VENDOR_ID_IBM					0x04b3
> > +#define USB_DEVICE_ID_IBM_SCROLLPOINT_III			0x3100
> > +#define USB_DEVICE_ID_IBM_SCROLLPOINT_PRO			0x3103
> > +#define USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL			0x3105
> > +#define USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL		0x3108
> > +#define USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO	0x3109
> > +
> >  #define USB_VENDOR_ID_IMATION		0x0718
> >  #define USB_DEVICE_ID_DISC_STAKKA	0xd000
> >  
> > diff --git a/drivers/hid/hid-scrollpoint.c b/drivers/hid/hid-scrollpoint.c
> > new file mode 100644
> > index 0000000..48e7696
> > --- /dev/null
> > +++ b/drivers/hid/hid-scrollpoint.c
> > @@ -0,0 +1,67 @@
> > +/*
> > + * HID driver for IBM/Lenovo ScrollPoint mice
> > + *
> > + * Copyright (c) 2012 Peter De Wachter <pdewacht@gmail.com>
> > + */
> > +
> > +/*
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms of the GNU General Public License as published by the Free
> > + * Software Foundation; either version 2 of the License, or (at your option)
> > + * any later version.
> > + */
> > +
> > +#include <linux/device.h>
> > +#include <linux/hid.h>
> > +#include <linux/module.h>
> > +
> > +#include "hid-ids.h"
> > +
> > +static int scrollpoint_input_mapping(struct hid_device *hdev,
> > +		struct hid_input *hi, struct hid_field *field,
> > +		struct hid_usage *usage, unsigned long **bit, int *max)
> > +{
> > +	if (usage->hid == HID_GD_Z) {
> > +		hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL);
> > +		return 1;
> > +	}
> > +	return 0;
> > +}
> > +
> > +static const struct hid_device_id scrollpoint_devices[] = {
> > +	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM,
> > +		USB_DEVICE_ID_IBM_SCROLLPOINT_III) },
> > +	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM,
> > +		USB_DEVICE_ID_IBM_SCROLLPOINT_PRO) },
> > +	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM,
> > +		USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL) },
> > +	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM,
> > +		USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL) },
> > +	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM,
> > +		USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO) },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(hid, scrollpoint_devices);
> > +
> > +static struct hid_driver scrollpoint_driver = {
> > +	.name = "scrollpoint",
> > +	.id_table = scrollpoint_devices,
> > +	.input_mapping = scrollpoint_input_mapping
> > +};
> > +
> > +static int __init scrollpoint_init(void)
> > +{
> > +	return hid_register_driver(&scrollpoint_driver);
> > +}
> > +
> > +static void __exit scrollpoint_exit(void)
> > +{
> > +	hid_unregister_driver(&scrollpoint_driver);
> > +}
> > +
> > +module_init(scrollpoint_init);
> > +module_exit(scrollpoint_exit);
> > +
> > +MODULE_AUTHOR("Peter De Wachter");
> > +MODULE_DESCRIPTION("IBM/Lenovo ScrollPoint mouse driver");
> > +MODULE_LICENSE("GPL");
> > -- 
> > 1.8.3.2
> > 
> 
> -- 
> Jiri Kosina
> SUSE Labs
> 

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* [PATCHv9][ 2/2] ARM: dts: cpuimx51 Add touchscreen support.
From: Denis Carikli @ 2013-11-05 13:37 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Dmitry Torokhov, linux-input, Linus Walleij, Denis Carikli,
	Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
	Ian Campbell, devicetree, Sascha Hauer, linux-arm-kernel,
	Lothar Waßmann, Shawn Guo, Eric Bénard
In-Reply-To: <1383658627-1948-1-git-send-email-denis@eukrea.com>

Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: devicetree@vger.kernel.org
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: linux-input@vger.kernel.org
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Lothar Waßmann <LW@KARO-electronics.de>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
ChangeLog v8->v9:
- Rebased.
- Adapted to request the tsc2007 gpio pinctrl outside of the tsc2007 bindings.

ChangeLog v7->v8:
- Added Shawn Guo in the cc list.
---
 arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi |   14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi b/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi
index b22841a..dfd9549 100644
--- a/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi
+++ b/arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi
@@ -42,11 +42,23 @@
 		compatible = "nxp,pcf8563";
 		reg = <0x51>;
 	};
+
+	tsc2007: tsc2007@49 {
+		compatible = "ti,tsc2007";
+		reg = <0x49>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <0x0 0x8>;
+		gpios = <&gpio4 0 0>;
+		ti,x-plate-ohms = <180>;
+	};
 };
 
 &iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hog>;
+
 	imx51-eukrea {
-		pinctrl_tsc2007_1: tsc2007grp-1 {
+		pinctrl_hog: hoggrp {
 			fsl,pins = <
 				MX51_PAD_GPIO_NAND__GPIO_NAND 0x1f5
 				MX51_PAD_NANDF_D8__GPIO4_0 0x1f5
-- 
1.7.9.5

--
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 related

* [PATCHv9][ 1/2] Input: tsc2007: Add device tree support.
From: Denis Carikli @ 2013-11-05 13:37 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Dmitry Torokhov, linux-input, Linus Walleij, Denis Carikli,
	Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
	Ian Campbell, devicetree, Sascha Hauer, linux-arm-kernel,
	Lothar Waßmann, Shawn Guo, Eric Bénard

Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: devicetree@vger.kernel.org
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: linux-input@vger.kernel.org
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Lothar Waßmann <LW@KARO-electronics.de>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
ChangeLog v8->v9:
- Removed pinctrl references.

ChangeLog v7->v8:
- Fixed the lack of x and z fuzz properties.
- The pendown gpio is better documented.
- Added Shawn Guo in the cc list.
---
 .../bindings/input/touchscreen/tsc2007.txt         |   41 ++++
 drivers/input/touchscreen/tsc2007.c                |  204 ++++++++++++++++----
 2 files changed, 204 insertions(+), 41 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
new file mode 100644
index 0000000..028aba66d
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
@@ -0,0 +1,41 @@
+* Texas Instruments tsc2007 touchscreen controller
+
+Required properties:
+- compatible: must be "ti,tsc2007".
+- reg: I2C address of the chip.
+- ti,x-plate-ohms: X-plate resistance in ohms.
+
+Optional properties:
+- gpios: the interrupt gpio the chip is connected to (trough the penirq pin).
+  The penirq pin goes to low when the panel is touched.
+  (see GPIO binding[1] for more details).
+- interrupt-parent: the phandle for the gpio controller
+  (see interrupt binding[0]).
+- interrupts: (gpio) interrupt to which the chip is connected
+  (see interrupt binding[0]).
+- ti,max-rt: maximum pressure.
+- ti,fuzzx: specifies the absolute input fuzz x value.
+  If set, it will permit noise in the data up to +- the value given to the fuzz
+  parameter, that is used to filter noise from the event stream.
+- ti,fuzzy: specifies the absolute input fuzz y value.
+- ti,fuzzz: specifies the absolute input fuzz z value.
+- ti,poll-period: how much time to wait(in millisecond) before reading again the
+  values from the tsc2007.
+
+[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+[1]: Documentation/devicetree/bindings/gpio/gpio.txt
+
+Example:
+	&i2c1 {
+		/* ... */
+		tsc2007@49 {
+			compatible = "ti,tsc2007";
+			reg = <0x49>;
+			interrupt-parent = <&gpio4>;
+			interrupts = <0x0 0x8>;
+			gpios = <&gpio4 0 0>;
+			ti,x-plate-ohms = <180>;
+		};
+
+		/* ... */
+	};
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index 0b67ba4..3168a99 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -26,6 +26,9 @@
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/i2c/tsc2007.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 #define TSC2007_MEASURE_TEMP0		(0x0 << 4)
 #define TSC2007_MEASURE_AUX		(0x2 << 4)
@@ -74,7 +77,12 @@ struct tsc2007 {
 	u16			max_rt;
 	unsigned long		poll_delay;
 	unsigned long		poll_period;
+	int			fuzzx;
+	int			fuzzy;
+	int			fuzzz;
+	char			of;
 
+	unsigned		gpio;
 	int			irq;
 
 	wait_queue_head_t	wait;
@@ -84,6 +92,11 @@ struct tsc2007 {
 	void			(*clear_penirq)(void);
 };
 
+static int tsc2007_get_pendown_state_dt(struct tsc2007 *ts)
+{
+	return !gpio_get_value(ts->gpio);
+}
+
 static inline int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
 {
 	s32 data;
@@ -142,6 +155,14 @@ static u32 tsc2007_calculate_pressure(struct tsc2007 *tsc, struct ts_event *tc)
 	return rt;
 }
 
+static bool tsc2007_is_pen_down_valid(struct tsc2007 *ts)
+{
+	if (ts->of)
+		return gpio_is_valid(ts->gpio);
+	else
+		return ts->get_pendown_state ? true : false;
+}
+
 static bool tsc2007_is_pen_down(struct tsc2007 *ts)
 {
 	/*
@@ -158,10 +179,13 @@ static bool tsc2007_is_pen_down(struct tsc2007 *ts)
 	 * to fall back on the pressure reading.
 	 */
 
-	if (!ts->get_pendown_state)
+	if (!tsc2007_is_pen_down_valid(ts))
 		return true;
 
-	return ts->get_pendown_state();
+	if (ts->of)
+		return tsc2007_get_pendown_state_dt(ts);
+	else
+		return ts->get_pendown_state();
 }
 
 static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
@@ -178,7 +202,7 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
 
 		rt = tsc2007_calculate_pressure(ts, &tc);
 
-		if (rt == 0 && !ts->get_pendown_state) {
+		if (!rt && !tsc2007_is_pen_down_valid(ts)) {
 			/*
 			 * If pressure reported is 0 and we don't have
 			 * callback to check pendown state, we have to
@@ -228,7 +252,7 @@ static irqreturn_t tsc2007_hard_irq(int irq, void *handle)
 {
 	struct tsc2007 *ts = handle;
 
-	if (!ts->get_pendown_state || likely(ts->get_pendown_state()))
+	if (tsc2007_is_pen_down(ts))
 		return IRQ_WAKE_THREAD;
 
 	if (ts->clear_penirq)
@@ -273,34 +297,71 @@ static void tsc2007_close(struct input_dev *input_dev)
 	tsc2007_stop(ts);
 }
 
-static int tsc2007_probe(struct i2c_client *client,
-				   const struct i2c_device_id *id)
+#ifdef CONFIG_OF
+static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts,
+			    struct device_node *np)
 {
-	struct tsc2007 *ts;
-	struct tsc2007_platform_data *pdata = client->dev.platform_data;
-	struct input_dev *input_dev;
-	int err;
-
-	if (!pdata) {
-		dev_err(&client->dev, "platform data is required!\n");
+	int err = 0;
+	u32 val32;
+	u64 val64;
+
+	if (!of_property_read_u32(np, "ti,max-rt", &val32))
+		ts->max_rt = val32;
+	else
+		ts->max_rt = MAX_12BIT;
+
+	if (!of_property_read_u32(np, "ti,fuzzx", &val32))
+		ts->fuzzx = val32;
+
+	if (!of_property_read_u32(np, "ti,fuzzy", &val32))
+		ts->fuzzy = val32;
+
+	if (!of_property_read_u32(np, "ti,fuzzz", &val32))
+		ts->fuzzz = val32;
+
+	if (!of_property_read_u64(np, "ti,poll-period", &val64))
+		ts->poll_period = val64;
+	else
+		ts->poll_period = 1;
+
+	if (!of_property_read_u32(np, "ti,x-plate-ohms", &val32)) {
+		ts->x_plate_ohms = val32;
+	} else {
+		dev_err(&client->dev,
+			"Error: lacking ti,x-plate-ohms devicetree property. (err %d).",
+			err);
 		return -EINVAL;
 	}
 
-	if (!i2c_check_functionality(client->adapter,
-				     I2C_FUNC_SMBUS_READ_WORD_DATA))
-		return -EIO;
+	ts->gpio = of_get_gpio(np, 0);
+	if (!gpio_is_valid(ts->gpio))
+		dev_err(&client->dev,
+			"GPIO not found (of_get_gpio returned %d)\n",
+			ts->gpio);
 
-	ts = kzalloc(sizeof(struct tsc2007), GFP_KERNEL);
-	input_dev = input_allocate_device();
-	if (!ts || !input_dev) {
-		err = -ENOMEM;
-		goto err_free_mem;
-	}
+	/* Used to detect if it is probed trough the device tree,
+	 * in order to be able to use that information in the IRQ handler.
+	 */
+	ts->of = 1;
 
-	ts->client = client;
-	ts->irq = client->irq;
-	ts->input = input_dev;
-	init_waitqueue_head(&ts->wait);
+	return 0;
+}
+#else
+static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts,
+			    struct device_node *np)
+{
+	return -ENODEV;
+}
+#endif
+
+static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts,
+			      struct tsc2007_platform_data *pdata,
+			      const struct i2c_device_id *id)
+{
+	if (!pdata) {
+		dev_err(&client->dev, "platform data is required!\n");
+		return -EINVAL;
+	}
 
 	ts->model             = pdata->model;
 	ts->x_plate_ohms      = pdata->x_plate_ohms;
@@ -309,13 +370,59 @@ static int tsc2007_probe(struct i2c_client *client,
 	ts->poll_period       = pdata->poll_period ? : 1;
 	ts->get_pendown_state = pdata->get_pendown_state;
 	ts->clear_penirq      = pdata->clear_penirq;
+	ts->fuzzx             = pdata->fuzzx;
+	ts->fuzzy             = pdata->fuzzy;
+	ts->fuzzz             = pdata->fuzzz;
 
 	if (pdata->x_plate_ohms == 0) {
 		dev_err(&client->dev, "x_plate_ohms is not set up in platform data");
-		err = -EINVAL;
-		goto err_free_mem;
+		return -EINVAL;
 	}
 
+	/* Used to detect if it is probed trough the device tree,
+	 * in order to be able to use that information in the IRQ handler.
+	 */
+	ts->of = 0;
+
+	return 0;
+}
+
+static int tsc2007_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct device_node *np = client->dev.of_node;
+	struct tsc2007_platform_data *pdata = client->dev.platform_data;
+	struct tsc2007 *ts;
+	struct input_dev *input_dev;
+	int err = 0;
+
+	ts = devm_kzalloc(&client->dev, sizeof(struct tsc2007), GFP_KERNEL);
+	if (!ts)
+		return -ENOMEM;
+
+	if (np)
+		err = tsc2007_probe_dt(client, ts, np);
+	else
+		err = tsc2007_probe_pdev(client, ts, pdata, id);
+
+	if (err)
+		return err;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_READ_WORD_DATA))
+		return -EIO;
+
+	input_dev = input_allocate_device();
+	if (!input_dev) {
+		err = -ENOMEM;
+		goto err_free_input;
+	};
+
+	ts->client = client;
+	ts->irq = client->irq;
+	ts->input = input_dev;
+	init_waitqueue_head(&ts->wait);
+
 	snprintf(ts->phys, sizeof(ts->phys),
 		 "%s/input0", dev_name(&client->dev));
 
@@ -331,19 +438,21 @@ static int tsc2007_probe(struct i2c_client *client,
 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
-	input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, pdata->fuzzx, 0);
-	input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, pdata->fuzzy, 0);
+	input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzx, 0);
+	input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0);
 	input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
-			pdata->fuzzz, 0);
+			     ts->fuzzz, 0);
 
-	if (pdata->init_platform_hw)
-		pdata->init_platform_hw();
+	if (!np) {
+		if (pdata->init_platform_hw)
+			pdata->init_platform_hw();
+	}
 
 	err = request_threaded_irq(ts->irq, tsc2007_hard_irq, tsc2007_soft_irq,
 				   IRQF_ONESHOT, client->dev.driver->name, ts);
 	if (err < 0) {
 		dev_err(&client->dev, "irq %d busy?\n", ts->irq);
-		goto err_free_mem;
+		goto err_free_input;
 	}
 
 	tsc2007_stop(ts);
@@ -358,23 +467,27 @@ static int tsc2007_probe(struct i2c_client *client,
 
  err_free_irq:
 	free_irq(ts->irq, ts);
-	if (pdata->exit_platform_hw)
-		pdata->exit_platform_hw();
- err_free_mem:
+	if (!np) {
+		if (pdata->exit_platform_hw)
+			pdata->exit_platform_hw();
+	}
+ err_free_input:
 	input_free_device(input_dev);
-	kfree(ts);
 	return err;
 }
 
 static int tsc2007_remove(struct i2c_client *client)
 {
+	struct device_node *np = client->dev.of_node;
 	struct tsc2007	*ts = i2c_get_clientdata(client);
 	struct tsc2007_platform_data *pdata = client->dev.platform_data;
 
 	free_irq(ts->irq, ts);
 
-	if (pdata->exit_platform_hw)
-		pdata->exit_platform_hw();
+	if (!np) {
+		if (pdata->exit_platform_hw)
+			pdata->exit_platform_hw();
+	}
 
 	input_unregister_device(ts->input);
 	kfree(ts);
@@ -389,10 +502,19 @@ static const struct i2c_device_id tsc2007_idtable[] = {
 
 MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);
 
+#ifdef CONFIG_OF
+static const struct of_device_id tsc2007_of_match[] = {
+	{ .compatible = "ti,tsc2007" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, tsc2007_of_match);
+#endif
+
 static struct i2c_driver tsc2007_driver = {
 	.driver = {
 		.owner	= THIS_MODULE,
-		.name	= "tsc2007"
+		.name	= "tsc2007",
+		.of_match_table = of_match_ptr(tsc2007_of_match),
 	},
 	.id_table	= tsc2007_idtable,
 	.probe		= tsc2007_probe,
-- 
1.7.9.5

--
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 related

* Re: [PATCH 2/2] Input: usbtouchscreen: ignore eGalax/D-Wav/EETI HIDs
From: Jiri Kosina @ 2013-11-05  9:53 UTC (permalink / raw)
  To: Forest Bond
  Cc: Dmitry Torokhov, linux-input, Sebastian Dalfuß, Daniel Ritz,
	Max Weninger, Christian Engelmayer
In-Reply-To: <20131021163818.GB30240@alittletooquiet.net>

On Mon, 21 Oct 2013, Forest Bond wrote:

> From: Forest Bond <forest.bond@rapidrollout.com>
> 
> The HID driver now handles these devices, regardless of what protocol
> the device claims it supports.
> 
> Signed-off-by: Forest Bond <forest.bond@rapidrollout.com>

Dmitry,

could you please Ack this, so that it can be applied together with 1/2? 
Thanks!

> ---
>  drivers/input/touchscreen/usbtouchscreen.c |    4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
> index 721fdb3..ae4b6b9 100644
> --- a/drivers/input/touchscreen/usbtouchscreen.c
> +++ b/drivers/input/touchscreen/usbtouchscreen.c
> @@ -146,12 +146,10 @@ enum {
>  
>  #define USB_DEVICE_HID_CLASS(vend, prod) \
>  	.match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \
> -		| USB_DEVICE_ID_MATCH_INT_PROTOCOL \
>  		| USB_DEVICE_ID_MATCH_DEVICE, \
>  	.idVendor = (vend), \
>  	.idProduct = (prod), \
> -	.bInterfaceClass = USB_INTERFACE_CLASS_HID, \
> -	.bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE
> +	.bInterfaceClass = USB_INTERFACE_CLASS_HID
>  
>  static const struct usb_device_id usbtouch_devices[] = {
>  #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX
> -- 
> 1.7.9.5
> 

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* Re: incorrect determination of the USB-sound card
From: Sohin Vyacheslaw @ 2013-11-05  6:30 UTC (permalink / raw)
  To: linux-input@vger.kernel.org
In-Reply-To: <52775A40.9050209@yandex.ua>



can anybody explain why the usb soundcard is defined as a voip phone in Linux or do I need another mailing list?

--
Best wishes,
Sohin Vyacheslav

^ permalink raw reply

* Re: About the PS3 Sixaxis linux driver
From: Marc @ 2013-11-04 23:03 UTC (permalink / raw)
  To: Antonio Ospite, Benjamin Tissoires; +Cc: linux-input
In-Reply-To: <20131104221824.2bd181e60f01f41e1e4f4898@studenti.unina.it>

Thanks a lot Benjamin (and everyone) to handle this.

Just to let you know, I've updated from 3.5 to 3.11
(basically, from stock ubuntu-12.04 to stock ubuntu-13.10)
and the bug is still there.

On 11/04/2013 10:18 PM, Antonio Ospite wrote:
> The problem with the left D-PAD should be the one I talk about here:
> http://www.spinics.net/lists/linux-input/msg16881.html

I'll try that as soon as possible, but as you noted, it's not a viable
solution for the long term...

> Marc, if you need the latest BlueZ patches for pairing the sixaxis for
> BT operation just let me know.

I forgot to say I've only tested through tethered USB. I'm not even
sure to have a functioning BT host :) but thanks for the proposal.

On 11/04/2013 10:40 PM, simon@mungewell.org wrote:
 > We did some patching here:
 > 
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/hid/hid-sony.c?id=refs/tags/v3.12#n301
 > 
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/hid/hid-sony.c?id=61ab44bebdefab296487e7cd723a634849278827

The kernel I'm currently running (ubuntu-saucy) includes this patch.
Also, I'm not very good at this, but I've made a diff of the last
version of hid-sony.c and the version currently in ubuntu-saucy (3.11) :
the changes are minimal and can't have fixed the bug (see bellow).

$ diff hid-sony.c ~/ubuntu-saucy/drivers/hid/hid-sony.c
631c631
< 	sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
---
 > 	sc = kzalloc(sizeof(*sc), GFP_KERNEL);
643c643
< 		return ret;
---
 > 		goto err_free;
656c656
< 		return ret;
---
 > 		goto err_free;
675a676,677
 > err_free:
 > 	kfree(sc);
686a689
 > 	kfree(sc);


-- 
Marc

^ permalink raw reply

* Re: About the PS3 Sixaxis linux driver
From: simon @ 2013-11-04 21:40 UTC (permalink / raw)
  To: Antonio Ospite; +Cc: Benjamin Tissoires, case, linux-input
In-Reply-To: <20131104221824.2bd181e60f01f41e1e4f4898@studenti.unina.it>


> Actually I intended to rewrite the whole HID descriptor and add a sane
> mapping for all the buttons (maybe following the Gamepad API and
> even using the new ABS_ACCEL_* and ABS_GYRO_* events from David
> Hermann).

I think that the root of the problem here is simply the large number of
axis, and that the keycodes start at 'axis-x' then overflow into/past the
MultiTouch keycode.

This problem is going to be a more common one as HID drivers present more
buttons/axis.

We did some patching here:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/hid/hid-sony.c?id=refs/tags/v3.12#n301
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/hid/hid-sony.c?id=61ab44bebdefab296487e7cd723a634849278827

Do we need to fix this is the HID descriptor, or in 'hid-sony' input stuff?

Do you have example of another driver to copy?
Simon




^ permalink raw reply

* Re: About the PS3 Sixaxis linux driver
From: Antonio Ospite @ 2013-11-04 21:18 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: case, linux-input
In-Reply-To: <1256411740.1745741.1383597450835.JavaMail.root@redhat.com>

On Mon, 4 Nov 2013 15:37:30 -0500 (EST)
Benjamin Tissoires <btissoir@redhat.com> wrote:

> Hi Marc,
> 
> (adding in CC the linux-input mailing list)
> 
> Regarding your problem I vaguely remember something about not having duplicated axis with the buttons. My memory is rather confuse about this, so I may be wrong (but others on the list may have a fresher memory).
> Other than that, if only one axis is not working, then it is definitively a bug...
>

The problem with the left D-PAD should be the one I talk about here:
http://www.spinics.net/lists/linux-input/msg16881.html

Basically the keycode is a multi-touch one and it gets discarded being
the device not a MT one.

I was told the hack I came up with is not OK for mainline, but people
can apply it locally for the time being.

> I'll try to add this to my todo list, but I can not guarantee anything soon. If someone else can confirm and fix this, I'll be happy.
>

Will remapping just the faulty keycode be enough?

Actually I intended to rewrite the whole HID descriptor and add a sane
mapping for all the buttons (maybe following the Gamepad API and
even using the new ABS_ACCEL_* and ABS_GYRO_* events from David
Hermann).

I may try to do some work along these lines myself in the next weeks
but I cannot promise an ETA either.

Marc, if you need the latest BlueZ patches for pairing the sixaxis for
BT operation just let me know.

Ciao,
   Antonio

> Cheers,
> Benjamin
> 
> ----- Original Message -----
> From: "case" <case@corpsmoderne.net>
> To: "Benjamin Tissoires" <benjamin.tissoires@redhat.com>
> Sent: Friday, October 25, 2013 8:52:14 AM
> Subject: About the PS3 Sixaxis linux driver
> 
> Hello Benjamin,
> 
> I'm mailing you because it seems you're one of the kernel developers
> the most involved with the hid-sony.c driver lately, with which I think
> I've an issue. If you feel like I'm mailing the wrong person,
> I apologize, and would be glad if you could point me to the right
> person.
> 
> I'm a game developer experimenting with the sixaxis for a while, and
> I've a big issue with the current state of the driver:
> 
> On the sixaxis all the buttons (except select and start) are mapped
> as buttons but also as axis, which is pretty rad. That was working great
> in 2010 when I started to experiment with the sixaxis but in more
> recent versions of the kernel, one the the buttons has lost his axis.
> It's the left button the the D-PAD, witch is only mapped as button 7
> (up is button 4 and axis 8, right is button 5 axis 9, bottom is button
> 6 axis 10).
>
> This is quite inconsistent and makes impossible to rely on the axis for
> all the D-PAD buttons.
> 
> Again, this bug wasn't there in 2.6.32 . I noticed it for the first time
> in 3.5.x . I'm currently running 3.11.0 and this bug is still here.
> 
> As my experience with kernel hacking is minimal I'm not even sure
> the problem lies in hid-sony, but that's where my investigations lead
> me.
> 
> Thank you to have taken the time to read my mail, I hope it will help
> to fix this issue, and again, sorry if you're not the right person to
> write to.
> 
> Regards,
> -- 
> Marc Planard
> --
> 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
> 


-- 
Antonio Ospite
http://ao2.it

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?

^ permalink raw reply

* Re: About the PS3 Sixaxis linux driver
From: simon @ 2013-11-04 21:07 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: case, linux-input
In-Reply-To: <1256411740.1745741.1383597450835.JavaMail.root@redhat.com>

> Hi Marc,
>
> (adding in CC the linux-input mailing list)
>
> Regarding your problem I vaguely remember something about not having
> duplicated axis with the buttons. My memory is rather confuse about this,
> so I may be wrong (but others on the list may have a fresher memory).
> Other than that, if only one axis is not working, then it is definitively
> a bug...
>
> I'll try to add this to my todo list, but I can not guarantee anything
> soon. If someone else can confirm and fix this, I'll be happy.

There was something a couple of years ago with the multi-touch stuff
screening out HID reports for the D-Pad axis.

http://comments.gmane.org/gmane.linux.kernel.input/19632

Don't know the current situation,
Simon


^ permalink raw reply

* Re: About the PS3 Sixaxis linux driver
From: Benjamin Tissoires @ 2013-11-04 20:37 UTC (permalink / raw)
  To: case; +Cc: linux-input
In-Reply-To: <526A697E.7050605@corpsmoderne.net>

Hi Marc,

(adding in CC the linux-input mailing list)

Regarding your problem I vaguely remember something about not having duplicated axis with the buttons. My memory is rather confuse about this, so I may be wrong (but others on the list may have a fresher memory).
Other than that, if only one axis is not working, then it is definitively a bug...

I'll try to add this to my todo list, but I can not guarantee anything soon. If someone else can confirm and fix this, I'll be happy.

Cheers,
Benjamin

----- Original Message -----
From: "case" <case@corpsmoderne.net>
To: "Benjamin Tissoires" <benjamin.tissoires@redhat.com>
Sent: Friday, October 25, 2013 8:52:14 AM
Subject: About the PS3 Sixaxis linux driver

Hello Benjamin,

I'm mailing you because it seems you're one of the kernel developers
the most involved with the hid-sony.c driver lately, with which I think
I've an issue. If you feel like I'm mailing the wrong person,
I apologize, and would be glad if you could point me to the right
person.

I'm a game developer experimenting with the sixaxis for a while, and
I've a big issue with the current state of the driver:

On the sixaxis all the buttons (except select and start) are mapped
as buttons but also as axis, which is pretty rad. That was working great
in 2010 when I started to experiment with the sixaxis but in more
recent versions of the kernel, one the the buttons has lost his axis.
It's the left button the the D-PAD, witch is only mapped as button 7
(up is button 4 and axis 8, right is button 5 axis 9, bottom is button
6 axis 10).

This is quite inconsistent and makes impossible to rely on the axis for
all the D-PAD buttons.

Again, this bug wasn't there in 2.6.32 . I noticed it for the first time
in 3.5.x . I'm currently running 3.11.0 and this bug is still here.

As my experience with kernel hacking is minimal I'm not even sure
the problem lies in hid-sony, but that's where my investigations lead
me.

Thank you to have taken the time to read my mail, I hope it will help
to fix this issue, and again, sorry if you're not the right person to
write to.

Regards,
-- 
Marc Planard

^ permalink raw reply

* Re: [PATCH 00/13] Input/HID: Bits and Pieces
From: Jiri Kosina @ 2013-11-04 13:04 UTC (permalink / raw)
  To: David Herrmann
  Cc: linux-input, Dmitry Torokhov, Peter Hutterer, Benjamin Tissoires
In-Reply-To: <1383336984-26601-1-git-send-email-dh.herrmann@gmail.com>

On Fri, 1 Nov 2013, David Herrmann wrote:

> My backlog kept growing and most of the stuff depends on the ABS_* fixes, so I
> gave it another try. The first 2 patches introduce EVIOC[GS]ABS2 and friends.
> The rest is wiimote stuff that was laying around for some time and just needs
> new ABS bits. So once the ABS stuff is in, I see no reason to delay the wiimote
> patches (as they're even tested already). Hence, I put it all in a single
> series.
> 
> Jiri, Dmitry, feel free to bribe me to split / not split the series so the
> other one has to take it through their tree. Highest bid wins!

I am fine with the HID changes, but Dmitry definitely needs to Ack the 
ABS_MAX2 stuff.

After that is done, I can either take the series through my tree with his 
Ack, or vice versa, I don't really have strong opinion there.

> And I am still running tests, so please don't merge, yet. I will report back my
> results. Besides, it's probably too late for 3.13, anyway and we should put it
> into -next for 3.14 for some while.

Thanks,

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* Re: [PATCHv7][ 1/4] Input: tsc2007: Add device tree support.
From: Linus Walleij @ 2013-11-04 12:01 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Denis Carikli, Rob Herring, Shawn Guo, Eric Bénard,
	Sascha Hauer, linux-arm-kernel@lists.infradead.org, Grant Likely,
	Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
	devicetree@vger.kernel.org, Dmitry Torokhov, Linux Input,
	Lothar Waßmann
In-Reply-To: <20131024151736.GE9044@ulmo.nvidia.com>

On Thu, Oct 24, 2013 at 5:17 PM, Thierry Reding
<thierry.reding@gmail.com> wrote:
> On Thu, Oct 24, 2013 at 02:42:13PM +0200, Denis Carikli wrote:

>> +Optional properties:
>> +- gpios: the interrupt gpio the chip is connected to (trough the penirq pin)
>> +  (see GPIO binding[2] for more details).
>> +- interrupt-parent: the phandle for the gpio controller
>> +  (see interrupt binding[1]).
>> +- interrupts: (gpio) interrupt to which the chip is connected
>> +  (see interrupt binding[1]).
>> +- pinctrl-0: Should specify pin control groups used for the gpio
>> +  (see pinctrl bindings[0]).
>> +- pinctrl-names: Should contain only one value - "default"
>> +  (see pinctrl bindings[0]).
>
> Also I haven't seen a response as to why this can't be handled by the
> GPIO driver. Adding Linus Walleij, perhaps he knows a more definitive
> answer.
>
> Linus, the issue here is that the pinctrl properties for this chip are
> supposed to pinmux the pendown GPIO for this chip. I was under the
> impression that this should be handled by the GPIO controller itself, so
> that when gpio_request() was called on a pin it would be the GPIO
> controller driver's responsibility to pinmux it appropriately.

If this is the only thing it does (just mux in the GPIO and not setting
any pulls or other pin config properties) then it can fall through from
the GPIO controller's request function to pinctrl_request_gpio()
and then pinctrl_free_gpio(), pinctrl_gpio_direction_input()
and pinctrl_gpio_direction_output() respectively so that pin control
provides a muxing back end to the GPIO driver.

Actually these functions are up to the driver to implement, but
the core will call ->gpio_request_enable() on the pinctrl driver,
and if all GPIOs are set up the same way (i.e. the same bits
are always poked into the hardware) then this can be done
in that routine.

If more fine-grained control is needed, this approach providing
a full pin control handle and state settings connected to the
struct device * can and should be used instead.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH] HID: roccat: Fixed Coverity CID 141438
From: Jiri Kosina @ 2013-11-04  9:59 UTC (permalink / raw)
  To: Stefan Achatz; +Cc: linux-input, linux-kernel
In-Reply-To: <1383456333.4017.2.camel@neuromancer.tessier-ashpool>

Applied, thanks Stefan.

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* incorrect determination of the USB-sound card
From: Sohin Vyacheslaw @ 2013-11-04  8:26 UTC (permalink / raw)
  To: linux-input

Hi,


when an external USB sound card inserted in the logfile the following 
messages:
Oct 28 13:01:34 sldas kernel: [ 3036.571158] usb 2-1.2.1: new full-speed 
USB device number 9 using ehci-pci
Oct 28 13:01:35 sldas kernel: [ 3036.663870] usb 2-1.2.1: New USB device 
found, idVendor=0d8c, idProduct=000e
Oct 28 13:01:35 sldas kernel: [ 3036.663881] usb 2-1.2.1: New USB device 
strings: Mfr=0, Product=1, SerialNumber=0
Oct 28 13:01:35 sldas kernel: [ 3036.663888] usb 2-1.2.1: Product: 
Generic USB Audio Device
Oct 28 13:01:35 sldas kernel: [ 3036.682211] input: CM109 USB driver as 
/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.1/2-1.2.1:1.3/input/input16
Oct 28 13:01:35 sldas mtp-probe: checking bus 2, device 9: 
"/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.1"
Oct 28 13:01:35 sldas mtp-probe: bus: 2, device: 9 was not an MTP device

  idVendor and idProduct -> correct: C-Media
but CM109 USB driver is for voip phones:

$  modinfo cm109
filename: 
/lib/modules/3.2.0-4-686-pae/kernel/drivers/input/misc/cm109.ko
license:        GPL
description:    CM109 phone driver
author:         Alfred E. Heggestad
alias:          usb:v0D8Cp000Ed*dc*dsc*dp*ic03isc00ip00*
depends:        usbcore
intree:         Y
vermagic:       3.2.0-4-686-pae SMP mod_unload modversions 686
parm:           phone:Phone name {kip1000, gtalk, usbph01, atcom} (charp)

I've tried to use each parameter (kip1000, gtalk, usbph01, atcom) and 
try on a different linux distros with different kernels (also compiled 
kernel) - the result is the same card plays audio, but some functions 
don't work properly: increase, decrease volume...

In Windows 7 operating system all functions of this sound card correct...

what's the right driver can be used for this card in Linux?


p.s.  after enabling CONFIG_USB_DEBUG and rebuild the kernel in logfile 
when connecting card:


Oct 30 21:06:35 sky-19 kernel: [  232.453931] usb 2-1.2: new full-speed 
USB device number 7 using ehci-pci
Oct 30 21:06:35 sky-19 kernel: [  232.546522] usb 2-1.2: skipped 10 
descriptors after interface
Oct 30 21:06:35 sky-19 kernel: [  232.546534] usb 2-1.2: skipped 2 
descriptors after interface
Oct 30 21:06:35 sky-19 kernel: [  232.546541] usb 2-1.2: skipped 1 
descriptor after endpoint
Oct 30 21:06:35 sky-19 kernel: [  232.546547] usb 2-1.2: skipped 2 
descriptors after interface
Oct 30 21:06:35 sky-19 kernel: [  232.546552] usb 2-1.2: skipped 1 
descriptor after endpoint
Oct 30 21:06:35 sky-19 kernel: [  232.546558] usb 2-1.2: skipped 1 
descriptor after interface
Oct 30 21:06:35 sky-19 kernel: [  232.546766] usb 2-1.2: default 
language 0x0409
Oct 30 21:06:35 sky-19 kernel: [  232.547012] usb 2-1.2: udev 7, busnum 
2, minor = 134
Oct 30 21:06:35 sky-19 kernel: [  232.547021] usb 2-1.2: New USB device 
found, idVendor=0d8c, idProduct=000e
Oct 30 21:06:35 sky-19 kernel: [  232.547028] usb 2-1.2: New USB device 
strings: Mfr=0, Product=1, SerialNumber=0
Oct 30 21:06:35 sky-19 kernel: [  232.547034] usb 2-1.2: Product: 
Generic USB Audio Device
Oct 30 21:06:35 sky-19 kernel: [  232.547263] usb 2-1.2: usb_probe_device
Oct 30 21:06:35 sky-19 kernel: [  232.547271] usb 2-1.2: configuration 
#1 chosen from 1 choice
Oct 30 21:06:35 sky-19 kernel: [  232.547397] usb 2-1.2: adding 
2-1.2:1.0 (config #1, interface 0)
Oct 30 21:06:35 sky-19 kernel: [  232.547477] snd-usb-audio 2-1.2:1.0: 
usb_probe_interface
Oct 30 21:06:35 sky-19 kernel: [  232.547489] snd-usb-audio 2-1.2:1.0: 
usb_probe_interface - got id
Oct 30 21:06:35 sky-19 kernel: [  232.566883] usb 2-1.2: adding 
2-1.2:1.1 (config #1, interface 1)
Oct 30 21:06:35 sky-19 kernel: [  232.566950] usb 2-1.2: adding 
2-1.2:1.2 (config #1, interface 2)
Oct 30 21:06:35 sky-19 kernel: [  232.567009] usb 2-1.2: adding 
2-1.2:1.3 (config #1, interface 3)
Oct 30 21:06:35 sky-19 kernel: [  232.567062] usbhid 2-1.2:1.3: 
usb_probe_interface
Oct 30 21:06:35 sky-19 kernel: [  232.567069] usbhid 2-1.2:1.3: 
usb_probe_interface - got id
Oct 30 21:06:35 sky-19 kernel: [  232.567186] hub 2-1:1.0: state 7 ports 
6 chg 0000 evt 0004
Oct 30 21:06:35 sky-19 mtp-probe: checking bus 2, device 7: 
"/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2"
Oct 30 21:06:35 sky-19 mtp-probe: bus: 2, device: 7 was not an MTP device
Oct 30 21:06:35 sky-19 kernel: [  232.606164] cm109: Keymap for 
Komunikate KIP1000 phone loaded
Oct 30 21:06:35 sky-19 kernel: [  232.606189] cm109 2-1.2:1.3: 
usb_probe_interface
Oct 30 21:06:35 sky-19 kernel: [  232.606193] cm109 2-1.2:1.3: 
usb_probe_interface - got id
Oct 30 21:06:35 sky-19 kernel: [  232.606279] input: CM109 USB driver as 
/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.3/input/input15
Oct 30 21:06:35 sky-19 kernel: [  232.606474] usb 2-1.2: link 
qh32-0e01/ee754bc0 start 5 [1/2 us]
Oct 30 21:06:35 sky-19 kernel: [  232.607234] usbcore: registered new 
interface driver cm109
Oct 30 21:06:35 sky-19 kernel: [  232.607238] cm109: CM109 phone driver: 
20080805 (C) Alfred E. Heggestad
Oct 30 21:06:35 sky-19 kernel: [  232.611347] usb 2-1.2: unlink 
qh32-0e01/ee754bc0 start 5 [1/2 us]
Oct 30 21:06:35 sky-19 kernel: [  232.613491] ehci-pci 0000:00:1d.0: 
reused qh ee754bc0 schedule
Oct 30 21:06:35 sky-19 kernel: [  232.613498] usb 2-1.2: link 
qh32-0e01/ee754bc0 start 5 [1/2 us]



--
Best wishes,
Sohin Vyacheslav

^ permalink raw reply

* [PATCH] HID: roccat: Fixed Coverity CID 141438
From: Stefan Achatz @ 2013-11-03  5:25 UTC (permalink / raw)
  To: Stefan Achatz, Jiri Kosina, linux-input, linux-kernel


Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net>
---
 drivers/hid/hid-roccat-kovaplus.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c
index 0c8e1ef..9660477 100644
--- a/drivers/hid/hid-roccat-kovaplus.c
+++ b/drivers/hid/hid-roccat-kovaplus.c
@@ -554,9 +554,13 @@ static void kovaplus_keep_values_up_to_date(struct kovaplus_device *kovaplus,
 		break;
 	case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI:
 		kovaplus->actual_cpi = kovaplus_convert_event_cpi(button_report->data1);
+		break;
 	case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY:
 		kovaplus->actual_x_sensitivity = button_report->data1;
 		kovaplus->actual_y_sensitivity = button_report->data2;
+		break;
+	default:
+		break;
 	}
 }
 
-- 
1.7.3.4

^ permalink raw reply related

* [PATCH] INPUT: wacom: Added definition for Wacom CTH680 The Wacom Creative Pen & Touch Tablet M (CTH680, 056A:0303) is a newer revision of the Bamboo series. This patch adds product 0303 to wacom.ko.
From: matthew @ 2013-11-02 19:04 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-input, Matthew Geddes

From: Matthew Geddes <matthew@incomplete.io>

Signed-off-by: Matthew Geddes <matthew@incomplete.io>
---
 drivers/input/tablet/wacom_wac.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index c59b797..5015269 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -2128,6 +2128,9 @@ static const struct wacom_features wacom_features_0x300 =
 static const struct wacom_features wacom_features_0x301 =
 	{ "Wacom Bamboo One M",    WACOM_PKGLEN_BBPEN,    21648, 13530, 1023,
 	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0x303 =
+	{ "Wacom Creative Touch & Pen M", WACOM_PKGLEN_BBPEN, 21648, 13530,
+	  1023, 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
 static const struct wacom_features wacom_features_0x6004 =
 	{ "ISD-V4",               WACOM_PKGLEN_GRAPHIRE,  12800,  8000,  255,
 	  0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -2258,6 +2261,7 @@ const struct usb_device_id wacom_ids[] = {
 	{ USB_DEVICE_WACOM(0x10F) },
 	{ USB_DEVICE_WACOM(0x300) },
 	{ USB_DEVICE_WACOM(0x301) },
+	{ USB_DEVICE_WACOM(0x303) },
 	{ USB_DEVICE_WACOM(0x304) },
 	{ USB_DEVICE_WACOM(0x4001) },
 	{ USB_DEVICE_WACOM(0x47) },
-- 
1.8.3.2


^ permalink raw reply related

* changes to ati_remote to support ATI Remote Wonder Plus RF Remote Control
From: Stephen Oberski @ 2013-11-01 22:45 UTC (permalink / raw)
  To: sfo; +Cc: linux-input

I've been attempting to send a message to the linux-input list describing proposed changes to the ati_remote.c (drivers/media/rc/ati_remote.c) module
that would allow for support of the ATI Remote Wonder Plus RF Remote Control.

I've stripped the message down to these few lines to determine if it is the content of the message that is causing it to be rejected.

Thanks,

--
Stephen Oberski
sfo@cargocult.ca

^ permalink raw reply

* [PATCH 13/13] HID: wiimote: add support for Guitar-Hero guitars
From: David Herrmann @ 2013-11-01 20:16 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Peter Hutterer, Benjamin Tissoires,
	Nicolas Adenis-Lamarre, David Herrmann
In-Reply-To: <1383336984-26601-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 6212678..829e437 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -461,6 +461,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;
 }
@@ -495,6 +498,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",
 };
 
 /*
@@ -1671,6 +1676,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 5f6d66b..625e1f3 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -2307,6 +2307,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
@@ -2577,4 +2750,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 c8a7fc3..0ca6262 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -91,6 +91,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.1


^ permalink raw reply related

* [PATCH 12/13] HID: wiimote: add support for Guitar-Hero drums
From: David Herrmann @ 2013-11-01 20:16 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Peter Hutterer, Benjamin Tissoires,
	David Herrmann
In-Reply-To: <1383336984-26601-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 89ca031..6212678 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -458,6 +458,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;
 }
@@ -491,6 +494,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",
 };
 
 /*
@@ -1664,6 +1669,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 e51e82b..5f6d66b 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -2090,6 +2090,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
@@ -2359,4 +2576,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 6f70823..c8a7fc3 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -90,6 +90,7 @@ enum wiimote_exttype {
 	WIIMOTE_EXT_CLASSIC_CONTROLLER,
 	WIIMOTE_EXT_BALANCE_BOARD,
 	WIIMOTE_EXT_PRO_CONTROLLER,
+	WIIMOTE_EXT_GUITAR_HERO_DRUMS,
 	WIIMOTE_EXT_NUM,
 };
 
@@ -139,6 +140,7 @@ struct wiimote_state {
 	__u16 calib_bboard[4][3];
 	__s16 calib_pro_sticks[4];
 	__u8 cache_rumble;
+	__u8 pressure_drums[7];
 };
 
 struct wiimote_data {
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH 11/13] Input: introduce BTN/ABS bits for drums and guitars
From: David Herrmann @ 2013-11-01 20:16 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Peter Hutterer, Benjamin Tissoires,
	David Herrmann
In-Reply-To: <1383336984-26601-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      | 24 +++++++++++++++++++++++-
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 329aa30..61f358a 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		0x4f
+#define INPUT_DEVICE_ID_ABS_MAX		0x5f
 #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 f347498..3aac45a 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -742,6 +742,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
@@ -870,12 +878,26 @@ struct input_keymap_entry {
 #define ABS_GYRO_Y		0x44	/* Gyroscope Y axis */
 #define ABS_GYRO_Z		0x45	/* Gyroscope Z axis */
 
+/* Drums and guitars (mostly toys) */
+#define ABS_TOM_FAR_LEFT	0x50
+#define ABS_TOM_LEFT		0x51
+#define ABS_TOM_RIGHT		0x52
+#define ABS_TOM_FAR_RIGHT	0x53
+#define ABS_CYMBAL_FAR_LEFT	0x54
+#define ABS_CYMBAL_LEFT		0x55
+#define ABS_CYMBAL_RIGHT	0x56
+#define ABS_CYMBAL_FAR_RIGHT	0x57
+#define ABS_BASS		0x58
+#define ABS_HI_HAT		0x59
+#define ABS_FRET_BOARD		0x5a	/* Guitar fret board, vertical pos */
+#define ABS_WHAMMY_BAR		0x5b	/* Guitar whammy bar (or vibrato) */
+
 /*
  * Due to API restrictions the legacy evdev API only supports ABS values up to
  * ABS_MAX/CNT. Use the extended *ABS2 ioctls to operate on any ABS values in
  * between ABS_MAX and ABS_MAX2.
  */
-#define ABS_MAX2		0x4f
+#define ABS_MAX2		0x5f
 #define ABS_CNT2		(ABS_MAX2+1)
 
 /*
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH 10/13] HID: wiimote: use ABS_GYRO_* bits for MP
From: David Herrmann @ 2013-11-01 20:16 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Peter Hutterer, Benjamin Tissoires,
	David Herrmann
In-Reply-To: <1383336984-26601-1-git-send-email-dh.herrmann@gmail.com>

Use the new gyroscope bits for motion-plus. The used ABS_R? bits are
ambiguous and should be replaced by proper bits to not confuse generic
user-space.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
 drivers/hid/hid-wiimote-modules.c | 44 ++++++++++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index 777f932..e51e82b 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -2222,9 +2222,16 @@ static void wiimod_mp_in_mp(struct wiimote_data *wdata, const __u8 *ext)
 	else
 		z *= 9;
 
-	input_report_abs(wdata->mp, ABS_RX, x);
-	input_report_abs(wdata->mp, ABS_RY, y);
-	input_report_abs(wdata->mp, ABS_RZ, z);
+	if (wdata->state.flags & WIIPROTO_FLAG_LEGACY) {
+		input_report_abs(wdata->mp, ABS_RX, x);
+		input_report_abs(wdata->mp, ABS_RY, y);
+		input_report_abs(wdata->mp, ABS_RZ, z);
+	} else {
+		input_report_abs(wdata->mp, ABS_GYRO_X, x);
+		input_report_abs(wdata->mp, ABS_GYRO_Y, y);
+		input_report_abs(wdata->mp, ABS_GYRO_Z, z);
+	}
+
 	input_sync(wdata->mp);
 }
 
@@ -2274,15 +2281,28 @@ static int wiimod_mp_probe(const struct wiimod_ops *ops,
 	wdata->mp->name = WIIMOTE_NAME " Motion Plus";
 
 	set_bit(EV_ABS, wdata->mp->evbit);
-	set_bit(ABS_RX, wdata->mp->absbit);
-	set_bit(ABS_RY, wdata->mp->absbit);
-	set_bit(ABS_RZ, wdata->mp->absbit);
-	input_set_abs_params(wdata->mp,
-			     ABS_RX, -16000, 16000, 4, 8);
-	input_set_abs_params(wdata->mp,
-			     ABS_RY, -16000, 16000, 4, 8);
-	input_set_abs_params(wdata->mp,
-			     ABS_RZ, -16000, 16000, 4, 8);
+
+	if (wdata->state.flags & WIIPROTO_FLAG_LEGACY) {
+		set_bit(ABS_RX, wdata->mp->absbit);
+		set_bit(ABS_RY, wdata->mp->absbit);
+		set_bit(ABS_RZ, wdata->mp->absbit);
+		input_set_abs_params(wdata->mp,
+				     ABS_RX, -16000, 16000, 4, 8);
+		input_set_abs_params(wdata->mp,
+				     ABS_RY, -16000, 16000, 4, 8);
+		input_set_abs_params(wdata->mp,
+				     ABS_RZ, -16000, 16000, 4, 8);
+	} else {
+		set_bit(ABS_GYRO_X, wdata->mp->absbit);
+		set_bit(ABS_GYRO_Y, wdata->mp->absbit);
+		set_bit(ABS_GYRO_Z, wdata->mp->absbit);
+		input_set_abs_params(wdata->mp,
+				     ABS_GYRO_X, -16000, 16000, 4, 8);
+		input_set_abs_params(wdata->mp,
+				     ABS_GYRO_Y, -16000, 16000, 4, 8);
+		input_set_abs_params(wdata->mp,
+				     ABS_GYRO_Z, -16000, 16000, 4, 8);
+	}
 
 	ret = input_register_device(wdata->mp);
 	if (ret)
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH 09/13] HID: wiimote: use ABS_ACCEL_* for accelerometer
From: David Herrmann @ 2013-11-01 20:16 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Peter Hutterer, Benjamin Tissoires,
	David Herrmann
In-Reply-To: <1383336984-26601-1-git-send-email-dh.herrmann@gmail.com>

Use the new ABS_ACCEL_* bits for accelerometer data _iff_ legacy mode is
not selected. ABS_R? is confusing and ambigiuous. ABS_ACCEL_* was
introduced exactly for accelerometers like the one of the wiimote.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
 drivers/hid/hid-wiimote-modules.c | 38 +++++++++++++++++++++++++++++---------
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index f3de94e..777f932 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -477,9 +477,16 @@ static void wiimod_accel_in_accel(struct wiimote_data *wdata,
 	y |= (accel[1] >> 4) & 0x2;
 	z |= (accel[1] >> 5) & 0x2;
 
-	input_report_abs(wdata->accel, ABS_RX, x - 0x200);
-	input_report_abs(wdata->accel, ABS_RY, y - 0x200);
-	input_report_abs(wdata->accel, ABS_RZ, z - 0x200);
+	if (wdata->state.flags & WIIPROTO_FLAG_LEGACY) {
+		input_report_abs(wdata->accel, ABS_RX, x - 0x200);
+		input_report_abs(wdata->accel, ABS_RY, y - 0x200);
+		input_report_abs(wdata->accel, ABS_RZ, z - 0x200);
+	} else {
+		input_report_abs(wdata->accel, ABS_ACCEL_X, x - 0x200);
+		input_report_abs(wdata->accel, ABS_ACCEL_Y, y - 0x200);
+		input_report_abs(wdata->accel, ABS_ACCEL_Z, z - 0x200);
+	}
+
 	input_sync(wdata->accel);
 }
 
@@ -525,12 +532,25 @@ static int wiimod_accel_probe(const struct wiimod_ops *ops,
 	wdata->accel->name = WIIMOTE_NAME " Accelerometer";
 
 	set_bit(EV_ABS, wdata->accel->evbit);
-	set_bit(ABS_RX, wdata->accel->absbit);
-	set_bit(ABS_RY, wdata->accel->absbit);
-	set_bit(ABS_RZ, wdata->accel->absbit);
-	input_set_abs_params(wdata->accel, ABS_RX, -500, 500, 2, 4);
-	input_set_abs_params(wdata->accel, ABS_RY, -500, 500, 2, 4);
-	input_set_abs_params(wdata->accel, ABS_RZ, -500, 500, 2, 4);
+
+	if (wdata->state.flags & WIIPROTO_FLAG_LEGACY) {
+		set_bit(ABS_RX, wdata->accel->absbit);
+		set_bit(ABS_RY, wdata->accel->absbit);
+		set_bit(ABS_RZ, wdata->accel->absbit);
+		input_set_abs_params(wdata->accel, ABS_RX, -500, 500, 2, 4);
+		input_set_abs_params(wdata->accel, ABS_RY, -500, 500, 2, 4);
+		input_set_abs_params(wdata->accel, ABS_RZ, -500, 500, 2, 4);
+	} else {
+		set_bit(ABS_ACCEL_X, wdata->accel->absbit);
+		set_bit(ABS_ACCEL_Y, wdata->accel->absbit);
+		set_bit(ABS_ACCEL_Z, wdata->accel->absbit);
+		input_set_abs_params(wdata->accel, ABS_ACCEL_X,
+				     -500, 500, 2, 4);
+		input_set_abs_params(wdata->accel, ABS_ACCEL_Y,
+				     -500, 500, 2, 4);
+		input_set_abs_params(wdata->accel, ABS_ACCEL_Z,
+				     -500, 500, 2, 4);
+	}
 
 	ret = input_register_device(wdata->accel);
 	if (ret) {
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH 08/13] HID: wiimote: map classic controller as gamepad
From: David Herrmann @ 2013-11-01 20:16 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Peter Hutterer, Benjamin Tissoires,
	David Herrmann
In-Reply-To: <1383336984-26601-1-git-send-email-dh.herrmann@gmail.com>

Adjust the mappings for the classic-controller extension so it's reported
as normal gamepad. Keep the compatibility mappings so legacy-mode still
works.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
 drivers/hid/hid-wiimote-modules.c | 144 ++++++++++++++++++++++++++------------
 1 file changed, 100 insertions(+), 44 deletions(-)

diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index a02059c..f3de94e 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -1090,7 +1090,7 @@ enum wiimod_classic_keys {
 	WIIMOD_CLASSIC_KEY_NUM,
 };
 
-static const __u16 wiimod_classic_map[] = {
+static const __u16 wiimod_classic_map_legacy[] = {
 	BTN_A,		/* WIIMOD_CLASSIC_KEY_A */
 	BTN_B,		/* WIIMOD_CLASSIC_KEY_B */
 	BTN_X,		/* WIIMOD_CLASSIC_KEY_X */
@@ -1108,10 +1108,32 @@ static const __u16 wiimod_classic_map[] = {
 	BTN_TR,		/* WIIMOD_CLASSIC_KEY_RT */
 };
 
+static const __u16 wiimod_classic_map[] = {
+	BTN_EAST,		/* WIIMOD_CLASSIC_KEY_A */
+	BTN_SOUTH,		/* WIIMOD_CLASSIC_KEY_B */
+	BTN_NORTH,		/* WIIMOD_CLASSIC_KEY_X */
+	BTN_WEST,		/* WIIMOD_CLASSIC_KEY_Y */
+	BTN_TL2,		/* WIIMOD_CLASSIC_KEY_ZL */
+	BTN_TR2,		/* WIIMOD_CLASSIC_KEY_ZR */
+	BTN_START,		/* WIIMOD_CLASSIC_KEY_PLUS */
+	BTN_SELECT,		/* WIIMOD_CLASSIC_KEY_MINUS */
+	BTN_MODE,		/* WIIMOD_CLASSIC_KEY_HOME */
+	BTN_DPAD_LEFT,		/* WIIMOD_CLASSIC_KEY_LEFT */
+	BTN_DPAD_RIGHT,		/* WIIMOD_CLASSIC_KEY_RIGHT */
+	BTN_DPAD_UP,		/* WIIMOD_CLASSIC_KEY_UP */
+	BTN_DPAD_DOWN,		/* WIIMOD_CLASSIC_KEY_DOWN */
+	BTN_TL,			/* WIIMOD_CLASSIC_KEY_LT */
+	BTN_TR,			/* WIIMOD_CLASSIC_KEY_RT */
+};
+
 static void wiimod_classic_in_ext(struct wiimote_data *wdata, const __u8 *ext)
 {
+	const __u16 *map = wiimod_classic_map;
 	__s8 rx, ry, lx, ly, lt, rt;
 
+	if (wdata->state.flags & WIIPROTO_FLAG_LEGACY)
+		map = wiimod_classic_map_legacy;
+
 	/*   Byte |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
 	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
 	 *    1   | RX <5:4>  |              LX <5:0>             |
@@ -1177,66 +1199,75 @@ static void wiimod_classic_in_ext(struct wiimote_data *wdata, const __u8 *ext)
 	rt <<= 1;
 	lt <<= 1;
 
-	input_report_abs(wdata->extension.input, ABS_HAT1X, lx - 0x20);
-	input_report_abs(wdata->extension.input, ABS_HAT1Y, ly - 0x20);
-	input_report_abs(wdata->extension.input, ABS_HAT2X, rx - 0x20);
-	input_report_abs(wdata->extension.input, ABS_HAT2Y, ry - 0x20);
-	input_report_abs(wdata->extension.input, ABS_HAT3X, rt);
-	input_report_abs(wdata->extension.input, ABS_HAT3Y, lt);
+	if (wdata->state.flags & WIIPROTO_FLAG_LEGACY) {
+		input_report_abs(wdata->extension.input, ABS_HAT1X, lx - 0x20);
+		input_report_abs(wdata->extension.input, ABS_HAT1Y, ly - 0x20);
+		input_report_abs(wdata->extension.input, ABS_HAT2X, rx - 0x20);
+		input_report_abs(wdata->extension.input, ABS_HAT2Y, ry - 0x20);
+		input_report_abs(wdata->extension.input, ABS_HAT3X, rt);
+		input_report_abs(wdata->extension.input, ABS_HAT3Y, lt);
+	} else {
+		input_report_abs(wdata->extension.input, ABS_X, lx - 0x20);
+		input_report_abs(wdata->extension.input, ABS_Y, 0x20 - ly);
+		input_report_abs(wdata->extension.input, ABS_RX, rx - 0x20);
+		input_report_abs(wdata->extension.input, ABS_RY, 0x20 - ry);
+		input_report_abs(wdata->extension.input, ABS_HAT1X, rt);
+		input_report_abs(wdata->extension.input, ABS_HAT1Y, lt);
+	}
 
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_RIGHT],
+			 map[WIIMOD_CLASSIC_KEY_RIGHT],
 			 !(ext[4] & 0x80));
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_DOWN],
+			 map[WIIMOD_CLASSIC_KEY_DOWN],
 			 !(ext[4] & 0x40));
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_LT],
+			 map[WIIMOD_CLASSIC_KEY_LT],
 			 !(ext[4] & 0x20));
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_MINUS],
+			 map[WIIMOD_CLASSIC_KEY_MINUS],
 			 !(ext[4] & 0x10));
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_HOME],
+			 map[WIIMOD_CLASSIC_KEY_HOME],
 			 !(ext[4] & 0x08));
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_PLUS],
+			 map[WIIMOD_CLASSIC_KEY_PLUS],
 			 !(ext[4] & 0x04));
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_RT],
+			 map[WIIMOD_CLASSIC_KEY_RT],
 			 !(ext[4] & 0x02));
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_ZL],
+			 map[WIIMOD_CLASSIC_KEY_ZL],
 			 !(ext[5] & 0x80));
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_B],
+			 map[WIIMOD_CLASSIC_KEY_B],
 			 !(ext[5] & 0x40));
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_Y],
+			 map[WIIMOD_CLASSIC_KEY_Y],
 			 !(ext[5] & 0x20));
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_A],
+			 map[WIIMOD_CLASSIC_KEY_A],
 			 !(ext[5] & 0x10));
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_X],
+			 map[WIIMOD_CLASSIC_KEY_X],
 			 !(ext[5] & 0x08));
 	input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_ZR],
+			 map[WIIMOD_CLASSIC_KEY_ZR],
 			 !(ext[5] & 0x04));
 
 	if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) {
 		input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_LEFT],
+			 map[WIIMOD_CLASSIC_KEY_LEFT],
 			 !(ext[1] & 0x01));
 		input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_UP],
+			 map[WIIMOD_CLASSIC_KEY_UP],
 			 !(ext[0] & 0x01));
 	} else {
 		input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_LEFT],
+			 map[WIIMOD_CLASSIC_KEY_LEFT],
 			 !(ext[5] & 0x02));
 		input_report_key(wdata->extension.input,
-			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_UP],
+			 map[WIIMOD_CLASSIC_KEY_UP],
 			 !(ext[5] & 0x01));
 	}
 
@@ -1270,12 +1301,16 @@ static void wiimod_classic_close(struct input_dev *dev)
 static int wiimod_classic_probe(const struct wiimod_ops *ops,
 				struct wiimote_data *wdata)
 {
+	const __u16 *map = wiimod_classic_map;
 	int ret, i;
 
 	wdata->extension.input = input_allocate_device();
 	if (!wdata->extension.input)
 		return -ENOMEM;
 
+	if (wdata->state.flags & WIIPROTO_FLAG_LEGACY)
+		map = wiimod_classic_map_legacy;
+
 	input_set_drvdata(wdata->extension.input, wdata);
 	wdata->extension.input->open = wiimod_classic_open;
 	wdata->extension.input->close = wiimod_classic_close;
@@ -1288,28 +1323,49 @@ static int wiimod_classic_probe(const struct wiimod_ops *ops,
 
 	set_bit(EV_KEY, wdata->extension.input->evbit);
 	for (i = 0; i < WIIMOD_CLASSIC_KEY_NUM; ++i)
-		set_bit(wiimod_classic_map[i],
-			wdata->extension.input->keybit);
+		set_bit(map[i], wdata->extension.input->keybit);
 
 	set_bit(EV_ABS, wdata->extension.input->evbit);
-	set_bit(ABS_HAT1X, wdata->extension.input->absbit);
-	set_bit(ABS_HAT1Y, wdata->extension.input->absbit);
-	set_bit(ABS_HAT2X, wdata->extension.input->absbit);
-	set_bit(ABS_HAT2Y, wdata->extension.input->absbit);
-	set_bit(ABS_HAT3X, wdata->extension.input->absbit);
-	set_bit(ABS_HAT3Y, wdata->extension.input->absbit);
-	input_set_abs_params(wdata->extension.input,
-			     ABS_HAT1X, -30, 30, 1, 1);
-	input_set_abs_params(wdata->extension.input,
-			     ABS_HAT1Y, -30, 30, 1, 1);
-	input_set_abs_params(wdata->extension.input,
-			     ABS_HAT2X, -30, 30, 1, 1);
-	input_set_abs_params(wdata->extension.input,
-			     ABS_HAT2Y, -30, 30, 1, 1);
-	input_set_abs_params(wdata->extension.input,
-			     ABS_HAT3X, -30, 30, 1, 1);
-	input_set_abs_params(wdata->extension.input,
-			     ABS_HAT3Y, -30, 30, 1, 1);
+
+	if (wdata->state.flags & WIIPROTO_FLAG_LEGACY) {
+		set_bit(ABS_HAT1X, wdata->extension.input->absbit);
+		set_bit(ABS_HAT1Y, wdata->extension.input->absbit);
+		set_bit(ABS_HAT2X, wdata->extension.input->absbit);
+		set_bit(ABS_HAT2Y, wdata->extension.input->absbit);
+		set_bit(ABS_HAT3X, wdata->extension.input->absbit);
+		set_bit(ABS_HAT3Y, wdata->extension.input->absbit);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_HAT1X, -30, 30, 1, 1);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_HAT1Y, -30, 30, 1, 1);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_HAT2X, -30, 30, 1, 1);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_HAT2Y, -30, 30, 1, 1);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_HAT3X, -30, 30, 1, 1);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_HAT3Y, -30, 30, 1, 1);
+	} else {
+		set_bit(ABS_X, wdata->extension.input->absbit);
+		set_bit(ABS_Y, wdata->extension.input->absbit);
+		set_bit(ABS_RX, wdata->extension.input->absbit);
+		set_bit(ABS_RY, wdata->extension.input->absbit);
+		set_bit(ABS_HAT1X, wdata->extension.input->absbit);
+		set_bit(ABS_HAT1Y, wdata->extension.input->absbit);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_X, -24, 24, 1, 1);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_Y, -24, 24, 1, 1);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_RX, -24, 24, 1, 1);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_RY, -24, 24, 1, 1);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_HAT1X, 0, 52, 1, 1);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_HAT1Y, 0, 52, 1, 1);
+	}
 
 	ret = input_register_device(wdata->extension.input);
 	if (ret)
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH 07/13] HID: wiimote: map nunchuk as real gamepad
From: David Herrmann @ 2013-11-01 20:16 UTC (permalink / raw)
  To: linux-input
  Cc: Dmitry Torokhov, Jiri Kosina, Peter Hutterer, Benjamin Tissoires,
	David Herrmann
In-Reply-To: <1383336984-26601-1-git-send-email-dh.herrmann@gmail.com>

The nunchuk device can easily be used as reduced gamepad. Add a new
mapping according to linux gamepad rules.

Note that we map it as gamepad with:
 - one analog-stick (left)
 - two trigger buttons (left upper+lower)
 - accelerometer

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
 drivers/hid/hid-wiimote-modules.c | 94 ++++++++++++++++++++++++++++-----------
 1 file changed, 67 insertions(+), 27 deletions(-)

diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index 372fec1..a02059c 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -839,15 +839,24 @@ enum wiimod_nunchuk_keys {
 	WIIMOD_NUNCHUK_KEY_NUM,
 };
 
-static const __u16 wiimod_nunchuk_map[] = {
+static const __u16 wiimod_nunchuk_map_legacy[] = {
 	BTN_C,		/* WIIMOD_NUNCHUK_KEY_C */
 	BTN_Z,		/* WIIMOD_NUNCHUK_KEY_Z */
 };
 
+static const __u16 wiimod_nunchuk_map[] = {
+	BTN_TL,		/* WIIMOD_NUNCHUK_KEY_C */
+	BTN_TL2,	/* WIIMOD_NUNCHUK_KEY_Z */
+};
+
 static void wiimod_nunchuk_in_ext(struct wiimote_data *wdata, const __u8 *ext)
 {
+	const __u16 *map = wiimod_nunchuk_map;
 	__s16 x, y, z, bx, by;
 
+	if (wdata->state.flags & WIIPROTO_FLAG_LEGACY)
+		map = wiimod_nunchuk_map_legacy;
+
 	/*   Byte |   8    7 |  6    5 |  4    3 |  2 |  1  |
 	 *   -----+----------+---------+---------+----+-----+
 	 *    1   |              Button X <7:0>             |
@@ -902,26 +911,35 @@ static void wiimod_nunchuk_in_ext(struct wiimote_data *wdata, const __u8 *ext)
 	y -= 0x200;
 	z -= 0x200;
 
-	input_report_abs(wdata->extension.input, ABS_HAT0X, bx);
-	input_report_abs(wdata->extension.input, ABS_HAT0Y, by);
+	if (wdata->state.flags & WIIPROTO_FLAG_LEGACY) {
+		input_report_abs(wdata->extension.input, ABS_HAT0X, bx);
+		input_report_abs(wdata->extension.input, ABS_HAT0Y, by);
 
-	input_report_abs(wdata->extension.input, ABS_RX, x);
-	input_report_abs(wdata->extension.input, ABS_RY, y);
-	input_report_abs(wdata->extension.input, ABS_RZ, z);
+		input_report_abs(wdata->extension.input, ABS_RX, x);
+		input_report_abs(wdata->extension.input, ABS_RY, y);
+		input_report_abs(wdata->extension.input, ABS_RZ, z);
+	} else {
+		input_report_abs(wdata->extension.input, ABS_X, bx);
+		input_report_abs(wdata->extension.input, ABS_Y, -by);
+
+		input_report_abs(wdata->extension.input, ABS_ACCEL_X, x);
+		input_report_abs(wdata->extension.input, ABS_ACCEL_Y, y);
+		input_report_abs(wdata->extension.input, ABS_ACCEL_Z, z);
+	}
 
 	if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) {
 		input_report_key(wdata->extension.input,
-			wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_Z],
+			map[WIIMOD_NUNCHUK_KEY_Z],
 			!(ext[5] & 0x04));
 		input_report_key(wdata->extension.input,
-			wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_C],
+			map[WIIMOD_NUNCHUK_KEY_C],
 			!(ext[5] & 0x08));
 	} else {
 		input_report_key(wdata->extension.input,
-			wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_Z],
+			map[WIIMOD_NUNCHUK_KEY_Z],
 			!(ext[5] & 0x01));
 		input_report_key(wdata->extension.input,
-			wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_C],
+			map[WIIMOD_NUNCHUK_KEY_C],
 			!(ext[5] & 0x02));
 	}
 
@@ -955,12 +973,16 @@ static void wiimod_nunchuk_close(struct input_dev *dev)
 static int wiimod_nunchuk_probe(const struct wiimod_ops *ops,
 				struct wiimote_data *wdata)
 {
+	const __u16 *map = wiimod_nunchuk_map;
 	int ret, i;
 
 	wdata->extension.input = input_allocate_device();
 	if (!wdata->extension.input)
 		return -ENOMEM;
 
+	if (wdata->state.flags & WIIPROTO_FLAG_LEGACY)
+		map = wiimod_nunchuk_map_legacy;
+
 	input_set_drvdata(wdata->extension.input, wdata);
 	wdata->extension.input->open = wiimod_nunchuk_open;
 	wdata->extension.input->close = wiimod_nunchuk_close;
@@ -973,25 +995,43 @@ static int wiimod_nunchuk_probe(const struct wiimod_ops *ops,
 
 	set_bit(EV_KEY, wdata->extension.input->evbit);
 	for (i = 0; i < WIIMOD_NUNCHUK_KEY_NUM; ++i)
-		set_bit(wiimod_nunchuk_map[i],
-			wdata->extension.input->keybit);
+		set_bit(map[i], wdata->extension.input->keybit);
 
 	set_bit(EV_ABS, wdata->extension.input->evbit);
-	set_bit(ABS_HAT0X, wdata->extension.input->absbit);
-	set_bit(ABS_HAT0Y, wdata->extension.input->absbit);
-	input_set_abs_params(wdata->extension.input,
-			     ABS_HAT0X, -120, 120, 2, 4);
-	input_set_abs_params(wdata->extension.input,
-			     ABS_HAT0Y, -120, 120, 2, 4);
-	set_bit(ABS_RX, wdata->extension.input->absbit);
-	set_bit(ABS_RY, wdata->extension.input->absbit);
-	set_bit(ABS_RZ, wdata->extension.input->absbit);
-	input_set_abs_params(wdata->extension.input,
-			     ABS_RX, -500, 500, 2, 4);
-	input_set_abs_params(wdata->extension.input,
-			     ABS_RY, -500, 500, 2, 4);
-	input_set_abs_params(wdata->extension.input,
-			     ABS_RZ, -500, 500, 2, 4);
+
+	if (wdata->state.flags & WIIPROTO_FLAG_LEGACY) {
+		set_bit(ABS_HAT0X, wdata->extension.input->absbit);
+		set_bit(ABS_HAT0Y, wdata->extension.input->absbit);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_HAT0X, -120, 120, 2, 4);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_HAT0Y, -120, 120, 2, 4);
+		set_bit(ABS_RX, wdata->extension.input->absbit);
+		set_bit(ABS_RY, wdata->extension.input->absbit);
+		set_bit(ABS_RZ, wdata->extension.input->absbit);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_RX, -500, 500, 2, 4);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_RY, -500, 500, 2, 4);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_RZ, -500, 500, 2, 4);
+	} else {
+		set_bit(ABS_X, wdata->extension.input->absbit);
+		set_bit(ABS_Y, wdata->extension.input->absbit);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_X, -120, 120, 2, 4);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_Y, -120, 120, 2, 4);
+		set_bit(ABS_ACCEL_X, wdata->extension.input->absbit);
+		set_bit(ABS_ACCEL_Y, wdata->extension.input->absbit);
+		set_bit(ABS_ACCEL_Z, wdata->extension.input->absbit);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_ACCEL_X, -500, 500, 2, 4);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_ACCEL_Y, -500, 500, 2, 4);
+		input_set_abs_params(wdata->extension.input,
+				     ABS_ACCEL_Z, -500, 500, 2, 4);
+	}
 
 	ret = input_register_device(wdata->extension.input);
 	if (ret)
-- 
1.8.4.1


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox