LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 1/5] HID: move pantherlord FF processing
@ 2008-09-04 12:59 Jiri Slaby
  2008-09-04 12:59 ` [PATCH 2/5] HID: move thrustmaster " Jiri Slaby
  2008-09-17 17:03 ` [PATCH 1/5] HID: move pantherlord FF processing Jiri Kosina
  0 siblings, 2 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-09-04 12:59 UTC (permalink / raw)
  To: jkosina; +Cc: linux-input, Anssi Hannula, linux-kernel, Jiri Slaby

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 17117 bytes --]

Move the force feedback precessing into a separate module.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
 drivers/hid/Kconfig             |   16 +++
 drivers/hid/Makefile            |    1 +
 drivers/hid/hid-core.c          |    2 +
 drivers/hid/hid-dummy.c         |    3 +
 drivers/hid/hid-ids.h           |    2 +
 drivers/hid/hid-pl.c            |  205 +++++++++++++++++++++++++++++++++++++++
 drivers/hid/usbhid/Kconfig      |    8 --
 drivers/hid/usbhid/Makefile     |    3 -
 drivers/hid/usbhid/hid-ff.c     |    4 -
 drivers/hid/usbhid/hid-plff.c   |  139 --------------------------
 drivers/hid/usbhid/hid-quirks.c |    1 -
 include/linux/hid.h             |    1 -
 12 files changed, 229 insertions(+), 156 deletions(-)
 create mode 100644 drivers/hid/hid-pl.c
 delete mode 100644 drivers/hid/usbhid/hid-plff.c

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 46337a2..7220e6f 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -199,6 +199,22 @@ config HID_MONTEREY
 	---help---
 	Support for Monterey Genius KB29E.
 
+config HID_PANTHERLORD
+	tristate "Pantherlord"
+	default m
+	depends on USB_HID
+	---help---
+	Support for PantherLord/GreenAsia based device support (including
+	force feedback).
+
+config PANTHERLORD_FF
+	bool "Force feedback support"
+	depends on HID_PANTHERLORD
+	select INPUT_FF_MEMLESS
+	help
+	  Say Y here if you have a PantherLord/GreenAsia based game controller
+	  or adapter and want to enable force feedback support for it.
+
 config HID_PETALYNX
 	tristate "Petalynx"
 	default m
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 300ee00..e607068 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_HID_GYRATION)	+= hid-gyration.o
 obj-$(CONFIG_HID_LOGITECH)	+= hid-logitech.o
 obj-$(CONFIG_HID_MICROSOFT)	+= hid-microsoft.o
 obj-$(CONFIG_HID_MONTEREY)	+= hid-monterey.o
+obj-$(CONFIG_HID_PANTHERLORD)	+= hid-pl.o
 obj-$(CONFIG_HID_PETALYNX)	+= hid-petalynx.o
 obj-$(CONFIG_HID_SAMSUNG)	+= hid-samsung.o
 obj-$(CONFIG_HID_SONY)		+= hid-sony.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 798bb0a..3a12bb6 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1411,6 +1411,7 @@ static const struct hid_device_id hid_ignore_list[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) },
@@ -1426,6 +1427,7 @@ static const struct hid_device_id hid_ignore_list[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB) },
diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c
index 69dcf9b..2f5d9a1 100644
--- a/drivers/hid/hid-dummy.c
+++ b/drivers/hid/hid-dummy.c
@@ -40,6 +40,9 @@ static int __init hid_dummy_init(void)
 #ifdef CONFIG_HID_MONTEREY_MODULE
 	HID_COMPAT_CALL_DRIVER(monterey);
 #endif
+#ifdef CONFIG_HID_PANTHERLORD_MODULE
+	HID_COMPAT_CALL_DRIVER(pantherlord);
+#endif
 #ifdef CONFIG_HID_PETALYNX_MODULE
 	HID_COMPAT_CALL_DRIVER(petalynx);
 #endif
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 0784a09..a4d9695 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -373,6 +373,8 @@
 #define USB_DEVICE_ID_QUAD_USB_JOYPAD	0x8800
 #define USB_DEVICE_ID_DUAL_USB_JOYPAD	0x8866
 
+#define USB_VENDOR_ID_GREENASIA		0x0e8f
+
 #define USB_VENDOR_ID_WISEGROUP_LTD	0x6666
 #define USB_VENDOR_ID_WISEGROUP_LTD2	0x6677
 #define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
new file mode 100644
index 0000000..b450084
--- /dev/null
+++ b/drivers/hid/hid-pl.c
@@ -0,0 +1,205 @@
+/*
+ *  Force feedback support for PantherLord/GreenAsia based devices
+ *
+ *  The devices are distributed under various names and the same USB device ID
+ *  can be used in both adapters and actual game controllers.
+ *
+ *  0810:0001 "Twin USB Joystick"
+ *   - tested with PantherLord USB/PS2 2in1 Adapter
+ *   - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT)
+ *
+ *  0e8f:0003 "GreenAsia Inc.    USB Joystick     "
+ *   - tested with Köng Gaming gamepad
+ *
+ *  Copyright (c) 2007 Anssi Hannula <anssi.hannula@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+/* #define DEBUG */
+
+#define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg)
+
+#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/hid.h>
+
+#include "hid-ids.h"
+
+#ifdef CONFIG_PANTHERLORD_FF
+#include "usbhid/usbhid.h"
+
+struct plff_device {
+	struct hid_report *report;
+};
+
+static int hid_plff_play(struct input_dev *dev, void *data,
+			 struct ff_effect *effect)
+{
+	struct hid_device *hid = input_get_drvdata(dev);
+	struct plff_device *plff = data;
+	int left, right;
+
+	left = effect->u.rumble.strong_magnitude;
+	right = effect->u.rumble.weak_magnitude;
+	debug("called with 0x%04x 0x%04x", left, right);
+
+	left = left * 0x7f / 0xffff;
+	right = right * 0x7f / 0xffff;
+
+	plff->report->field[0]->value[2] = left;
+	plff->report->field[0]->value[3] = right;
+	debug("running with 0x%02x 0x%02x", left, right);
+	usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
+
+	return 0;
+}
+
+static int plff_init(struct hid_device *hid)
+{
+	struct plff_device *plff;
+	struct hid_report *report;
+	struct hid_input *hidinput;
+	struct list_head *report_list =
+			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct list_head *report_ptr = report_list;
+	struct input_dev *dev;
+	int error;
+
+	/* The device contains one output report per physical device, all
+	   containing 1 field, which contains 4 ff00.0002 usages and 4 16bit
+	   absolute values.
+
+	   The input reports also contain a field which contains
+	   8 ff00.0001 usages and 8 boolean values. Their meaning is
+	   currently unknown. */
+
+	if (list_empty(report_list)) {
+		printk(KERN_ERR "hid-plff: no output reports found\n");
+		return -ENODEV;
+	}
+
+	list_for_each_entry(hidinput, &hid->inputs, list) {
+
+		report_ptr = report_ptr->next;
+
+		if (report_ptr == report_list) {
+			printk(KERN_ERR "hid-plff: required output report is missing\n");
+			return -ENODEV;
+		}
+
+		report = list_entry(report_ptr, struct hid_report, list);
+		if (report->maxfield < 1) {
+			printk(KERN_ERR "hid-plff: no fields in the report\n");
+			return -ENODEV;
+		}
+
+		if (report->field[0]->report_count < 4) {
+			printk(KERN_ERR "hid-plff: not enough values in the field\n");
+			return -ENODEV;
+		}
+
+		plff = kzalloc(sizeof(struct plff_device), GFP_KERNEL);
+		if (!plff)
+			return -ENOMEM;
+
+		dev = hidinput->input;
+
+		set_bit(FF_RUMBLE, dev->ffbit);
+
+		error = input_ff_create_memless(dev, plff, hid_plff_play);
+		if (error) {
+			kfree(plff);
+			return error;
+		}
+
+		plff->report = report;
+		plff->report->field[0]->value[0] = 0x00;
+		plff->report->field[0]->value[1] = 0x00;
+		plff->report->field[0]->value[2] = 0x00;
+		plff->report->field[0]->value[3] = 0x00;
+		usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
+	}
+
+	printk(KERN_INFO "hid-plff: Force feedback for PantherLord/GreenAsia "
+	       "devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
+
+	return 0;
+}
+#else
+static inline int plff_init(struct hid_device *hid)
+{
+	return 0;
+}
+#endif
+
+static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+
+	if (id->driver_data)
+		hdev->quirks |= HID_QUIRK_MULTI_INPUT;
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		dev_err(&hdev->dev, "parse failed\n");
+		goto err;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+	if (ret) {
+		dev_err(&hdev->dev, "hw start failed\n");
+		goto err;
+	}
+
+	plff_init(hdev);
+
+	return 0;
+err:
+	return ret;
+}
+
+static const struct hid_device_id pl_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR),
+		.driver_data = 1 }, /* Twin USB Joystick */
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, /* GreenAsia Inc. USB Joystick */
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, pl_devices);
+
+static struct hid_driver pl_driver = {
+	.name = "pantherlord",
+	.id_table = pl_devices,
+	.probe = pl_probe,
+};
+
+static int pl_init(void)
+{
+	return hid_register_driver(&pl_driver);
+}
+
+static void pl_exit(void)
+{
+	hid_unregister_driver(&pl_driver);
+}
+
+module_init(pl_init);
+module_exit(pl_exit);
+MODULE_LICENSE("GPL");
+
+HID_COMPAT_LOAD_DRIVER(pantherlord);
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig
index 0e7e2e6..02c8228 100644
--- a/drivers/hid/usbhid/Kconfig
+++ b/drivers/hid/usbhid/Kconfig
@@ -44,14 +44,6 @@ config HID_PID
 	  feedback for it. Microsoft Sidewinder Force Feedback 2 is one of such
 	  devices.
 
-config PANTHERLORD_FF
-	bool "PantherLord/GreenAsia based device support"
-	depends on HID_FF
-	select INPUT_FF_MEMLESS if USB_HID
-	help
-	  Say Y here if you have a PantherLord/GreenAsia based game controller
-	  or adapter and want to enable force feedback support for it.
-
 config THRUSTMASTER_FF
 	bool "ThrustMaster devices support"
 	depends on HID_FF
diff --git a/drivers/hid/usbhid/Makefile b/drivers/hid/usbhid/Makefile
index 224c62d..0ee4803 100644
--- a/drivers/hid/usbhid/Makefile
+++ b/drivers/hid/usbhid/Makefile
@@ -13,9 +13,6 @@ endif
 ifeq ($(CONFIG_HID_PID),y)
 	usbhid-objs	+= hid-pidff.o
 endif
-ifeq ($(CONFIG_PANTHERLORD_FF),y)
-	usbhid-objs	+= hid-plff.o
-endif
 ifeq ($(CONFIG_THRUSTMASTER_FF),y)
 	usbhid-objs	+= hid-tmff.o
 endif
diff --git a/drivers/hid/usbhid/hid-ff.c b/drivers/hid/usbhid/hid-ff.c
index 8891f60..a868eef 100644
--- a/drivers/hid/usbhid/hid-ff.c
+++ b/drivers/hid/usbhid/hid-ff.c
@@ -50,10 +50,6 @@ struct hid_ff_initializer {
  * be a PID device
  */
 static struct hid_ff_initializer inits[] = {
-#ifdef CONFIG_PANTHERLORD_FF
-	{ 0x810, 0x0001, hid_plff_init }, /* "Twin USB Joystick" */
-	{ 0xe8f, 0x0003, hid_plff_init }, /* "GreenAsia Inc.    USB Joystick     " */
-#endif
 #ifdef CONFIG_THRUSTMASTER_FF
 	{ 0x44f, 0xb300, hid_tmff_init },
 	{ 0x44f, 0xb304, hid_tmff_init },
diff --git a/drivers/hid/usbhid/hid-plff.c b/drivers/hid/usbhid/hid-plff.c
deleted file mode 100644
index 9eb83cf..0000000
--- a/drivers/hid/usbhid/hid-plff.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- *  Force feedback support for PantherLord/GreenAsia based devices
- *
- *  The devices are distributed under various names and the same USB device ID
- *  can be used in both adapters and actual game controllers.
- *
- *  0810:0001 "Twin USB Joystick"
- *   - tested with PantherLord USB/PS2 2in1 Adapter
- *   - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT)
- *
- *  0e8f:0003 "GreenAsia Inc.    USB Joystick     "
- *   - tested with Köng Gaming gamepad
- *
- *  Copyright (c) 2007 Anssi Hannula <anssi.hannula@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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-/* #define DEBUG */
-
-#define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg)
-
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-#include "usbhid.h"
-
-struct plff_device {
-	struct hid_report *report;
-};
-
-static int hid_plff_play(struct input_dev *dev, void *data,
-			 struct ff_effect *effect)
-{
-	struct hid_device *hid = input_get_drvdata(dev);
-	struct plff_device *plff = data;
-	int left, right;
-
-	left = effect->u.rumble.strong_magnitude;
-	right = effect->u.rumble.weak_magnitude;
-	debug("called with 0x%04x 0x%04x", left, right);
-
-	left = left * 0x7f / 0xffff;
-	right = right * 0x7f / 0xffff;
-
-	plff->report->field[0]->value[2] = left;
-	plff->report->field[0]->value[3] = right;
-	debug("running with 0x%02x 0x%02x", left, right);
-	usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
-
-	return 0;
-}
-
-int hid_plff_init(struct hid_device *hid)
-{
-	struct plff_device *plff;
-	struct hid_report *report;
-	struct hid_input *hidinput;
-	struct list_head *report_list =
-			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
-	struct list_head *report_ptr = report_list;
-	struct input_dev *dev;
-	int error;
-
-	/* The device contains one output report per physical device, all
-	   containing 1 field, which contains 4 ff00.0002 usages and 4 16bit
-	   absolute values.
-
-	   The input reports also contain a field which contains
-	   8 ff00.0001 usages and 8 boolean values. Their meaning is
-	   currently unknown. */
-
-	if (list_empty(report_list)) {
-		printk(KERN_ERR "hid-plff: no output reports found\n");
-		return -ENODEV;
-	}
-
-	list_for_each_entry(hidinput, &hid->inputs, list) {
-
-		report_ptr = report_ptr->next;
-
-		if (report_ptr == report_list) {
-			printk(KERN_ERR "hid-plff: required output report is missing\n");
-			return -ENODEV;
-		}
-
-		report = list_entry(report_ptr, struct hid_report, list);
-		if (report->maxfield < 1) {
-			printk(KERN_ERR "hid-plff: no fields in the report\n");
-			return -ENODEV;
-		}
-
-		if (report->field[0]->report_count < 4) {
-			printk(KERN_ERR "hid-plff: not enough values in the field\n");
-			return -ENODEV;
-		}
-
-		plff = kzalloc(sizeof(struct plff_device), GFP_KERNEL);
-		if (!plff)
-			return -ENOMEM;
-
-		dev = hidinput->input;
-
-		set_bit(FF_RUMBLE, dev->ffbit);
-
-		error = input_ff_create_memless(dev, plff, hid_plff_play);
-		if (error) {
-			kfree(plff);
-			return error;
-		}
-
-		plff->report = report;
-		plff->report->field[0]->value[0] = 0x00;
-		plff->report->field[0]->value[1] = 0x00;
-		plff->report->field[0]->value[2] = 0x00;
-		plff->report->field[0]->value[3] = 0x00;
-		usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
-	}
-
-	printk(KERN_INFO "hid-plff: Force feedback for PantherLord/GreenAsia "
-	       "devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
-
-	return 0;
-}
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index d40f009..47ebe04 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -32,7 +32,6 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
 	{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
 	{ USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
-	{ USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 164ce7f..260beba 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -760,7 +760,6 @@ void usbhid_set_leds(struct hid_device *hid);
 #ifdef CONFIG_HID_FF
 int hid_ff_init(struct hid_device *hid);
 
-int hid_plff_init(struct hid_device *hid);
 int hid_tmff_init(struct hid_device *hid);
 int hid_zpff_init(struct hid_device *hid);
 #ifdef CONFIG_HID_PID
-- 
1.6.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/5] HID: move thrustmaster FF processing
  2008-09-04 12:59 [PATCH 1/5] HID: move pantherlord FF processing Jiri Slaby
@ 2008-09-04 12:59 ` Jiri Slaby
  2008-09-04 12:59   ` [PATCH 3/5] HID: move zeroplus " Jiri Slaby
  2008-09-17 17:03 ` [PATCH 1/5] HID: move pantherlord FF processing Jiri Kosina
  1 sibling, 1 reply; 9+ messages in thread
From: Jiri Slaby @ 2008-09-04 12:59 UTC (permalink / raw)
  To: jkosina; +Cc: linux-input, Anssi Hannula, linux-kernel, Jiri Slaby

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
 drivers/hid/Kconfig           |    9 ++
 drivers/hid/Makefile          |    1 +
 drivers/hid/hid-core.c        |    4 +
 drivers/hid/hid-dummy.c       |    3 +
 drivers/hid/hid-ids.h         |    2 +
 drivers/hid/hid-tmff.c        |  265 +++++++++++++++++++++++++++++++++++++++++
 drivers/hid/usbhid/Kconfig    |   11 --
 drivers/hid/usbhid/Makefile   |    3 -
 drivers/hid/usbhid/hid-ff.c   |    6 -
 drivers/hid/usbhid/hid-tmff.c |  232 ------------------------------------
 include/linux/hid.h           |    1 -
 11 files changed, 284 insertions(+), 253 deletions(-)
 create mode 100644 drivers/hid/hid-tmff.c
 delete mode 100644 drivers/hid/usbhid/hid-tmff.c

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 7220e6f..268fcd1 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -243,6 +243,15 @@ config HID_SUNPLUS
 	---help---
 	Support for Sunplus WDesktop input device.
 
+config THRUSTMASTER_FF
+	tristate "ThrustMaster devices support"
+	default m
+	depends on USB_HID
+	select INPUT_FF_MEMLESS
+	help
+	  Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
+	  a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel.
+
 endmenu
 
 endif # HID_SUPPORT
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index e607068..9bd6daf 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_HID_PETALYNX)	+= hid-petalynx.o
 obj-$(CONFIG_HID_SAMSUNG)	+= hid-samsung.o
 obj-$(CONFIG_HID_SONY)		+= hid-sony.o
 obj-$(CONFIG_HID_SUNPLUS)	+= hid-sunplus.o
+obj-$(CONFIG_THRUSTMASTER_FF)	+= hid-tmff.o
 
 obj-$(CONFIG_USB_HID)		+= usbhid/
 obj-$(CONFIG_USB_MOUSE)		+= usbhid/
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 3a12bb6..e6624d9 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1514,6 +1514,10 @@ static const struct hid_device_id hid_ignore_list[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c
index 2f5d9a1..ae122a1 100644
--- a/drivers/hid/hid-dummy.c
+++ b/drivers/hid/hid-dummy.c
@@ -55,6 +55,9 @@ static int __init hid_dummy_init(void)
 #ifdef CONFIG_HID_SUNPLUS_MODULE
 	HID_COMPAT_CALL_DRIVER(sunplus);
 #endif
+#ifdef CONFIG_THRUSTMASTER_FF_MODULE
+	HID_COMPAT_CALL_DRIVER(thrustmaster);
+#endif
 
 	return -EIO;
 }
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index a4d9695..30dcc93 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -348,6 +348,8 @@
 #define USB_VENDOR_ID_SUN		0x0430
 #define USB_DEVICE_ID_RARITAN_KVM_DONGLE	0xcdab
 
+#define USB_VENDOR_ID_THRUSTMASTER	0x044f
+
 #define USB_VENDOR_ID_SUNPLUS		0x04fc
 #define USB_DEVICE_ID_SUNPLUS_WDESKTOP	0x05d8
 
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
new file mode 100644
index 0000000..7b85bbb
--- /dev/null
+++ b/drivers/hid/hid-tmff.c
@@ -0,0 +1,265 @@
+/*
+ * Force feedback support for various HID compliant devices by ThrustMaster:
+ *    ThrustMaster FireStorm Dual Power 2
+ * and possibly others whose device ids haven't been added.
+ *
+ *  Modified to support ThrustMaster devices by Zinx Verituse
+ *  on 2003-01-25 from the Logitech force feedback driver,
+ *  which is by Johann Deneux.
+ *
+ *  Copyright (c) 2003 Zinx Verituse <zinx@epicsol.org>
+ *  Copyright (c) 2002 Johann Deneux
+ */
+
+/*
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/hid.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#include "hid-ids.h"
+
+#include "usbhid/usbhid.h"
+
+/* Usages for thrustmaster devices I know about */
+#define THRUSTMASTER_USAGE_FF	(HID_UP_GENDESK | 0xbb)
+
+static const signed short ff_rumble[] = {
+	FF_RUMBLE,
+	-1
+};
+
+static const signed short ff_joystick[] = {
+	FF_CONSTANT,
+	-1
+};
+
+struct tmff_device {
+	struct hid_report *report;
+	struct hid_field *ff_field;
+};
+
+/* Changes values from 0 to 0xffff into values from minimum to maximum */
+static inline int tmff_scale_u16(unsigned int in, int minimum, int maximum)
+{
+	int ret;
+
+	ret = (in * (maximum - minimum) / 0xffff) + minimum;
+	if (ret < minimum)
+		return minimum;
+	if (ret > maximum)
+		return maximum;
+	return ret;
+}
+
+/* Changes values from -0x80 to 0x7f into values from minimum to maximum */
+static inline int tmff_scale_s8(int in, int minimum, int maximum)
+{
+	int ret;
+
+	ret = (((in + 0x80) * (maximum - minimum)) / 0xff) + minimum;
+	if (ret < minimum)
+		return minimum;
+	if (ret > maximum)
+		return maximum;
+	return ret;
+}
+
+static int tmff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
+{
+	struct hid_device *hid = input_get_drvdata(dev);
+	struct tmff_device *tmff = data;
+	struct hid_field *ff_field = tmff->ff_field;
+	int x, y;
+	int left, right;	/* Rumbling */
+
+	switch (effect->type) {
+	case FF_CONSTANT:
+		x = tmff_scale_s8(effect->u.ramp.start_level,
+					ff_field->logical_minimum,
+					ff_field->logical_maximum);
+		y = tmff_scale_s8(effect->u.ramp.end_level,
+					ff_field->logical_minimum,
+					ff_field->logical_maximum);
+
+		dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
+		ff_field->value[0] = x;
+		ff_field->value[1] = y;
+		usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
+		break;
+
+	case FF_RUMBLE:
+		left = tmff_scale_u16(effect->u.rumble.weak_magnitude,
+					ff_field->logical_minimum,
+					ff_field->logical_maximum);
+		right = tmff_scale_u16(effect->u.rumble.strong_magnitude,
+					ff_field->logical_minimum,
+					ff_field->logical_maximum);
+
+		dbg_hid("(left,right)=(%08x, %08x)\n", left, right);
+		ff_field->value[0] = left;
+		ff_field->value[1] = right;
+		usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
+		break;
+	}
+	return 0;
+}
+
+static int tmff_init(struct hid_device *hid, const signed short *ff_bits)
+{
+	struct tmff_device *tmff;
+	struct hid_report *report;
+	struct list_head *report_list;
+	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+	struct input_dev *input_dev = hidinput->input;
+	int error;
+	int i;
+
+	tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL);
+	if (!tmff)
+		return -ENOMEM;
+
+	/* Find the report to use */
+	report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	list_for_each_entry(report, report_list, list) {
+		int fieldnum;
+
+		for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) {
+			struct hid_field *field = report->field[fieldnum];
+
+			if (field->maxusage <= 0)
+				continue;
+
+			switch (field->usage[0].hid) {
+			case THRUSTMASTER_USAGE_FF:
+				if (field->report_count < 2) {
+					dev_warn(&hid->dev,
+						 "ignoring FF field with report_count < 2\n");
+					continue;
+				}
+
+				if (field->logical_maximum == field->logical_minimum) {
+					dev_warn(&hid->dev,
+						 "ignoring FF field with logical_maximum == logical_minimum\n");
+					continue;
+				}
+
+				if (tmff->report && tmff->report != report) {
+					dev_warn(&hid->dev,
+						 "ignoring FF field in other report\n");
+					continue;
+				}
+
+				if (tmff->ff_field && tmff->ff_field != field) {
+					dev_warn(&hid->dev,
+						 "ignoring duplicate FF field\n");
+					continue;
+				}
+
+				tmff->report = report;
+				tmff->ff_field = field;
+
+				for (i = 0; ff_bits[i] >= 0; i++)
+					set_bit(ff_bits[i], input_dev->ffbit);
+
+				break;
+
+			default:
+				dev_warn(&hid->dev,
+					 "ignoring unknown output usage %08x\n",
+					 field->usage[0].hid);
+				continue;
+			}
+		}
+	}
+
+	if (!tmff->report) {
+		err("cant find FF field in output reports\n");
+		error = -ENODEV;
+		goto fail;
+	}
+
+	error = input_ff_create_memless(input_dev, tmff, tmff_play);
+	if (error)
+		goto fail;
+
+	dev_info(&hid->dev,
+		 "Force feedback for ThrustMaster devices by Zinx Verituse <zinx@epicsol.org>\n");
+	return 0;
+
+fail:
+	kfree(tmff);
+	return error;
+}
+
+static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		dev_err(&hdev->dev, "parse failed\n");
+		goto err;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+	if (ret) {
+		dev_err(&hdev->dev, "hw start failed\n");
+		goto err;
+	}
+
+	tmff_init(hdev, (void *)id->driver_data);
+
+	return 0;
+err:
+	return ret;
+}
+
+static const struct hid_device_id tm_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300),
+		.driver_data = (unsigned long)ff_rumble },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304),
+		.driver_data = (unsigned long)ff_rumble },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651),	/* FGT Rumble Force Wheel */
+		.driver_data = (unsigned long)ff_rumble },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654),	/* FGT Force Feedback Wheel */
+		.driver_data = (unsigned long)ff_joystick },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, tm_devices);
+
+static struct hid_driver tm_driver = {
+	.name = "thrustmaster",
+	.id_table = tm_devices,
+	.probe = tm_probe,
+};
+
+static int tm_init(void)
+{
+	return hid_register_driver(&tm_driver);
+}
+
+static void tm_exit(void)
+{
+	hid_unregister_driver(&tm_driver);
+}
+
+module_init(tm_init);
+module_exit(tm_exit);
+MODULE_LICENSE("GPL");
+
+HID_COMPAT_LOAD_DRIVER(thrustmaster);
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig
index 02c8228..c236fb3 100644
--- a/drivers/hid/usbhid/Kconfig
+++ b/drivers/hid/usbhid/Kconfig
@@ -44,17 +44,6 @@ config HID_PID
 	  feedback for it. Microsoft Sidewinder Force Feedback 2 is one of such
 	  devices.
 
-config THRUSTMASTER_FF
-	bool "ThrustMaster devices support"
-	depends on HID_FF
-	select INPUT_FF_MEMLESS if USB_HID
-	help
-	  Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
-	  a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel,
-	  and want to enable force feedback support for it.
-	  Note: if you say N here, this device will still be supported, but without
-	  force feedback.
-
 config ZEROPLUS_FF
 	bool "Zeroplus based game controller support"
 	depends on HID_FF
diff --git a/drivers/hid/usbhid/Makefile b/drivers/hid/usbhid/Makefile
index 0ee4803..dd3b863 100644
--- a/drivers/hid/usbhid/Makefile
+++ b/drivers/hid/usbhid/Makefile
@@ -13,9 +13,6 @@ endif
 ifeq ($(CONFIG_HID_PID),y)
 	usbhid-objs	+= hid-pidff.o
 endif
-ifeq ($(CONFIG_THRUSTMASTER_FF),y)
-	usbhid-objs	+= hid-tmff.o
-endif
 ifeq ($(CONFIG_ZEROPLUS_FF),y)
 	usbhid-objs	+= hid-zpff.o
 endif
diff --git a/drivers/hid/usbhid/hid-ff.c b/drivers/hid/usbhid/hid-ff.c
index a868eef..ed3a869 100644
--- a/drivers/hid/usbhid/hid-ff.c
+++ b/drivers/hid/usbhid/hid-ff.c
@@ -50,12 +50,6 @@ struct hid_ff_initializer {
  * be a PID device
  */
 static struct hid_ff_initializer inits[] = {
-#ifdef CONFIG_THRUSTMASTER_FF
-	{ 0x44f, 0xb300, hid_tmff_init },
-	{ 0x44f, 0xb304, hid_tmff_init },
-	{ 0x44f, 0xb651, hid_tmff_init }, /* FGT Rumble Force Wheel */
-	{ 0x44f, 0xb654, hid_tmff_init }, /* FGT Force Feedback Wheel */
-#endif
 #ifdef CONFIG_ZEROPLUS_FF
 	{ 0xc12, 0x0005, hid_zpff_init },
 	{ 0xc12, 0x0030, hid_zpff_init },
diff --git a/drivers/hid/usbhid/hid-tmff.c b/drivers/hid/usbhid/hid-tmff.c
deleted file mode 100644
index 451a8e6..0000000
--- a/drivers/hid/usbhid/hid-tmff.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Force feedback support for various HID compliant devices by ThrustMaster:
- *    ThrustMaster FireStorm Dual Power 2
- * and possibly others whose device ids haven't been added.
- *
- *  Modified to support ThrustMaster devices by Zinx Verituse
- *  on 2003-01-25 from the Logitech force feedback driver,
- *  which is by Johann Deneux.
- *
- *  Copyright (c) 2003 Zinx Verituse <zinx@epicsol.org>
- *  Copyright (c) 2002 Johann Deneux
- */
-
-/*
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/input.h>
-
-#undef DEBUG
-#include <linux/usb.h>
-
-#include <linux/hid.h>
-#include "usbhid.h"
-
-/* Usages for thrustmaster devices I know about */
-#define THRUSTMASTER_USAGE_FF	(HID_UP_GENDESK | 0xbb)
-
-struct dev_type {
-	u16 idVendor;
-	u16 idProduct;
-	const signed short *ff;
-};
-
-static const signed short ff_rumble[] = {
-	FF_RUMBLE,
-	-1
-};
-
-static const signed short ff_joystick[] = {
-	FF_CONSTANT,
-	-1
-};
-
-static const struct dev_type devices[] = {
-	{ 0x44f, 0xb300, ff_rumble },
-	{ 0x44f, 0xb304, ff_rumble },
-	{ 0x44f, 0xb651, ff_rumble },	/* FGT Rumble Force Wheel */
-	{ 0x44f, 0xb654, ff_joystick },	/* FGT Force Feedback Wheel */
-};
-
-struct tmff_device {
-	struct hid_report *report;
-	struct hid_field *ff_field;
-};
-
-/* Changes values from 0 to 0xffff into values from minimum to maximum */
-static inline int hid_tmff_scale_u16(unsigned int in,
-				int minimum, int maximum)
-{
-	int ret;
-
-	ret = (in * (maximum - minimum) / 0xffff) + minimum;
-	if (ret < minimum)
-		return minimum;
-	if (ret > maximum)
-		return maximum;
-	return ret;
-}
-
-/* Changes values from -0x80 to 0x7f into values from minimum to maximum */
-static inline int hid_tmff_scale_s8(int in,
-				    int minimum, int maximum)
-{
-	int ret;
-
-	ret = (((in + 0x80) * (maximum - minimum)) / 0xff) + minimum;
-	if (ret < minimum)
-		return minimum;
-	if (ret > maximum)
-		return maximum;
-	return ret;
-}
-
-static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
-{
-	struct hid_device *hid = input_get_drvdata(dev);
-	struct tmff_device *tmff = data;
-	struct hid_field *ff_field = tmff->ff_field;
-	int x, y;
-	int left, right;	/* Rumbling */
-
-	switch (effect->type) {
-	case FF_CONSTANT:
-		x = hid_tmff_scale_s8(effect->u.ramp.start_level,
-					ff_field->logical_minimum,
-					ff_field->logical_maximum);
-		y = hid_tmff_scale_s8(effect->u.ramp.end_level,
-					ff_field->logical_minimum,
-					ff_field->logical_maximum);
-
-		dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
-		ff_field->value[0] = x;
-		ff_field->value[1] = y;
-		usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
-		break;
-
-	case FF_RUMBLE:
-		left = hid_tmff_scale_u16(effect->u.rumble.weak_magnitude,
-					ff_field->logical_minimum,
-					ff_field->logical_maximum);
-		right = hid_tmff_scale_u16(effect->u.rumble.strong_magnitude,
-					ff_field->logical_minimum,
-					ff_field->logical_maximum);
-
-		dbg_hid("(left,right)=(%08x, %08x)\n", left, right);
-		ff_field->value[0] = left;
-		ff_field->value[1] = right;
-		usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
-		break;
-	}
-	return 0;
-}
-
-int hid_tmff_init(struct hid_device *hid)
-{
-	struct tmff_device *tmff;
-	struct hid_report *report;
-	struct list_head *report_list;
-	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
-	struct input_dev *input_dev = hidinput->input;
-	const signed short *ff_bits = ff_joystick;
-	int error;
-	int i;
-
-	tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL);
-	if (!tmff)
-		return -ENOMEM;
-
-	/* Find the report to use */
-	report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
-	list_for_each_entry(report, report_list, list) {
-		int fieldnum;
-
-		for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) {
-			struct hid_field *field = report->field[fieldnum];
-
-			if (field->maxusage <= 0)
-				continue;
-
-			switch (field->usage[0].hid) {
-			case THRUSTMASTER_USAGE_FF:
-				if (field->report_count < 2) {
-					dev_warn(&hid->dev,
-						 "ignoring FF field with report_count < 2\n");
-					continue;
-				}
-
-				if (field->logical_maximum == field->logical_minimum) {
-					dev_warn(&hid->dev,
-						 "ignoring FF field with logical_maximum == logical_minimum\n");
-					continue;
-				}
-
-				if (tmff->report && tmff->report != report) {
-					dev_warn(&hid->dev,
-						 "ignoring FF field in other report\n");
-					continue;
-				}
-
-				if (tmff->ff_field && tmff->ff_field != field) {
-					dev_warn(&hid->dev,
-						 "ignoring duplicate FF field\n");
-					continue;
-				}
-
-				tmff->report = report;
-				tmff->ff_field = field;
-
-				for (i = 0; i < ARRAY_SIZE(devices); i++) {
-					if (input_dev->id.vendor == devices[i].idVendor &&
-					    input_dev->id.product == devices[i].idProduct) {
-						ff_bits = devices[i].ff;
-						break;
-					}
-				}
-
-				for (i = 0; ff_bits[i] >= 0; i++)
-					set_bit(ff_bits[i], input_dev->ffbit);
-
-				break;
-
-			default:
-				dev_warn(&hid->dev,
-					 "ignoring unknown output usage %08x\n",
-					 field->usage[0].hid);
-				continue;
-			}
-		}
-	}
-
-	if (!tmff->report) {
-		err("cant find FF field in output reports\n");
-		error = -ENODEV;
-		goto fail;
-	}
-
-	error = input_ff_create_memless(input_dev, tmff, hid_tmff_play);
-	if (error)
-		goto fail;
-
-	dev_info(&hid->dev,
-		 "Force feedback for ThrustMaster devices by Zinx Verituse <zinx@epicsol.org>\n");
-	return 0;
-
- fail:
-	kfree(tmff);
-	return error;
-}
-
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 260beba..2af65a7 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -760,7 +760,6 @@ void usbhid_set_leds(struct hid_device *hid);
 #ifdef CONFIG_HID_FF
 int hid_ff_init(struct hid_device *hid);
 
-int hid_tmff_init(struct hid_device *hid);
 int hid_zpff_init(struct hid_device *hid);
 #ifdef CONFIG_HID_PID
 int hid_pidff_init(struct hid_device *hid);
-- 
1.6.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 3/5] HID: move zeroplus FF processing
  2008-09-04 12:59 ` [PATCH 2/5] HID: move thrustmaster " Jiri Slaby
@ 2008-09-04 12:59   ` Jiri Slaby
  2008-09-04 12:59     ` [PATCH 4/5] HID: remove hid-ff Jiri Slaby
  0 siblings, 1 reply; 9+ messages in thread
From: Jiri Slaby @ 2008-09-04 12:59 UTC (permalink / raw)
  To: jkosina; +Cc: linux-input, Anssi Hannula, linux-kernel, Jiri Slaby

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
 drivers/hid/Kconfig           |    8 ++
 drivers/hid/Makefile          |    1 +
 drivers/hid/hid-core.c        |    2 +
 drivers/hid/hid-dummy.c       |    3 +
 drivers/hid/hid-ids.h         |    2 +
 drivers/hid/hid-zpff.c        |  162 +++++++++++++++++++++++++++++++++++++++++
 drivers/hid/usbhid/Kconfig    |    8 --
 drivers/hid/usbhid/Makefile   |    3 -
 drivers/hid/usbhid/hid-ff.c   |    4 -
 drivers/hid/usbhid/hid-zpff.c |  107 ---------------------------
 include/linux/hid.h           |    1 -
 11 files changed, 178 insertions(+), 123 deletions(-)
 create mode 100644 drivers/hid/hid-zpff.c
 delete mode 100644 drivers/hid/usbhid/hid-zpff.c

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 268fcd1..e4d5263 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -252,6 +252,14 @@ config THRUSTMASTER_FF
 	  Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
 	  a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel.
 
+config ZEROPLUS_FF
+	tristate "Zeroplus based game controller support"
+	default m
+	depends on USB_HID
+	select INPUT_FF_MEMLESS
+	help
+	  Say Y here if you have a Zeroplus based game controller.
+
 endmenu
 
 endif # HID_SUPPORT
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 9bd6daf..767f295 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_HID_SAMSUNG)	+= hid-samsung.o
 obj-$(CONFIG_HID_SONY)		+= hid-sony.o
 obj-$(CONFIG_HID_SUNPLUS)	+= hid-sunplus.o
 obj-$(CONFIG_THRUSTMASTER_FF)	+= hid-tmff.o
+obj-$(CONFIG_ZEROPLUS_FF)	+= hid-zpff.o
 
 obj-$(CONFIG_USB_HID)		+= usbhid/
 obj-$(CONFIG_USB_MOUSE)		+= usbhid/
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index e6624d9..92c16e1 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1528,6 +1528,8 @@ static const struct hid_device_id hid_ignore_list[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
 	{ }
 };
 
diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c
index ae122a1..54d1fb6 100644
--- a/drivers/hid/hid-dummy.c
+++ b/drivers/hid/hid-dummy.c
@@ -58,6 +58,9 @@ static int __init hid_dummy_init(void)
 #ifdef CONFIG_THRUSTMASTER_FF_MODULE
 	HID_COMPAT_CALL_DRIVER(thrustmaster);
 #endif
+#ifdef CONFIG_ZEROPLUS_FF_MODULE
+	HID_COMPAT_CALL_DRIVER(zeroplus);
+#endif
 
 	return -EIO;
 }
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 30dcc93..11b0720 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -375,6 +375,8 @@
 #define USB_DEVICE_ID_QUAD_USB_JOYPAD	0x8800
 #define USB_DEVICE_ID_DUAL_USB_JOYPAD	0x8866
 
+#define USB_VENDOR_ID_ZEROPLUS		0x0c12
+
 #define USB_VENDOR_ID_GREENASIA		0x0e8f
 
 #define USB_VENDOR_ID_WISEGROUP_LTD	0x6666
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
new file mode 100644
index 0000000..9ed04ee
--- /dev/null
+++ b/drivers/hid/hid-zpff.c
@@ -0,0 +1,162 @@
+/*
+ *  Force feedback support for Zeroplus based devices
+ *
+ *  Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include <linux/hid.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#include "hid-ids.h"
+
+#include "usbhid/usbhid.h"
+
+struct zpff_device {
+	struct hid_report *report;
+};
+
+static int zpff_play(struct input_dev *dev, void *data,
+			 struct ff_effect *effect)
+{
+	struct hid_device *hid = input_get_drvdata(dev);
+	struct zpff_device *zpff = data;
+	int left, right;
+
+	/*
+	 * The following is specified the other way around in the Zeroplus
+	 * datasheet but the order below is correct for the XFX Executioner;
+	 * however it is possible that the XFX Executioner is an exception
+	 */
+
+	left = effect->u.rumble.strong_magnitude;
+	right = effect->u.rumble.weak_magnitude;
+	dbg_hid("called with 0x%04x 0x%04x\n", left, right);
+
+	left = left * 0x7f / 0xffff;
+	right = right * 0x7f / 0xffff;
+
+	zpff->report->field[2]->value[0] = left;
+	zpff->report->field[3]->value[0] = right;
+	dbg_hid("running with 0x%02x 0x%02x\n", left, right);
+	usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
+
+	return 0;
+}
+
+static int zpff_init(struct hid_device *hid)
+{
+	struct zpff_device *zpff;
+	struct hid_report *report;
+	struct hid_input *hidinput = list_entry(hid->inputs.next,
+						struct hid_input, list);
+	struct list_head *report_list =
+			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct input_dev *dev = hidinput->input;
+	int error;
+
+	if (list_empty(report_list)) {
+		printk(KERN_ERR "hid-zpff: no output report found\n");
+		return -ENODEV;
+	}
+
+	report = list_entry(report_list->next, struct hid_report, list);
+
+	if (report->maxfield < 4) {
+		printk(KERN_ERR "hid-zpff: not enough fields in report\n");
+		return -ENODEV;
+	}
+
+	zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
+	if (!zpff)
+		return -ENOMEM;
+
+	set_bit(FF_RUMBLE, dev->ffbit);
+
+	error = input_ff_create_memless(dev, zpff, zpff_play);
+	if (error) {
+		kfree(zpff);
+		return error;
+	}
+
+	zpff->report = report;
+	zpff->report->field[0]->value[0] = 0x00;
+	zpff->report->field[1]->value[0] = 0x02;
+	zpff->report->field[2]->value[0] = 0x00;
+	zpff->report->field[3]->value[0] = 0x00;
+	usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
+
+	printk(KERN_INFO "Force feedback for Zeroplus based devices by "
+	       "Anssi Hannula <anssi.hannula@gmail.com>\n");
+
+	return 0;
+}
+
+static int zp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		dev_err(&hdev->dev, "parse failed\n");
+		goto err;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+	if (ret) {
+		dev_err(&hdev->dev, "hw start failed\n");
+		goto err;
+	}
+
+	zpff_init(hdev);
+
+	return 0;
+err:
+	return ret;
+}
+
+static const struct hid_device_id zp_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, zp_devices);
+
+static struct hid_driver zp_driver = {
+	.name = "zeroplus",
+	.id_table = zp_devices,
+	.probe = zp_probe,
+};
+
+static int zp_init(void)
+{
+	return hid_register_driver(&zp_driver);
+}
+
+static void zp_exit(void)
+{
+	hid_unregister_driver(&zp_driver);
+}
+
+module_init(zp_init);
+module_exit(zp_exit);
+MODULE_LICENSE("GPL");
+
+HID_COMPAT_LOAD_DRIVER(zeroplus);
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig
index c236fb3..3cfc076 100644
--- a/drivers/hid/usbhid/Kconfig
+++ b/drivers/hid/usbhid/Kconfig
@@ -44,14 +44,6 @@ config HID_PID
 	  feedback for it. Microsoft Sidewinder Force Feedback 2 is one of such
 	  devices.
 
-config ZEROPLUS_FF
-	bool "Zeroplus based game controller support"
-	depends on HID_FF
-	select INPUT_FF_MEMLESS if USB_HID
-	help
-	  Say Y here if you have a Zeroplus based game controller and want to
-	  enable force feedback for it.
-
 config USB_HIDDEV
 	bool "/dev/hiddev raw HID device support"
 	depends on USB_HID
diff --git a/drivers/hid/usbhid/Makefile b/drivers/hid/usbhid/Makefile
index dd3b863..5c460fc 100644
--- a/drivers/hid/usbhid/Makefile
+++ b/drivers/hid/usbhid/Makefile
@@ -13,9 +13,6 @@ endif
 ifeq ($(CONFIG_HID_PID),y)
 	usbhid-objs	+= hid-pidff.o
 endif
-ifeq ($(CONFIG_ZEROPLUS_FF),y)
-	usbhid-objs	+= hid-zpff.o
-endif
 ifeq ($(CONFIG_HID_FF),y)
 	usbhid-objs	+= hid-ff.o
 endif
diff --git a/drivers/hid/usbhid/hid-ff.c b/drivers/hid/usbhid/hid-ff.c
index ed3a869..eca01a6 100644
--- a/drivers/hid/usbhid/hid-ff.c
+++ b/drivers/hid/usbhid/hid-ff.c
@@ -50,10 +50,6 @@ struct hid_ff_initializer {
  * be a PID device
  */
 static struct hid_ff_initializer inits[] = {
-#ifdef CONFIG_ZEROPLUS_FF
-	{ 0xc12, 0x0005, hid_zpff_init },
-	{ 0xc12, 0x0030, hid_zpff_init },
-#endif
 	{ 0,	 0,	 hid_pidff_init}  /* Matches anything */
 };
 
diff --git a/drivers/hid/usbhid/hid-zpff.c b/drivers/hid/usbhid/hid-zpff.c
deleted file mode 100644
index 5a68827..0000000
--- a/drivers/hid/usbhid/hid-zpff.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *  Force feedback support for Zeroplus based devices
- *
- *  Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-#include "usbhid.h"
-
-struct zpff_device {
-	struct hid_report *report;
-};
-
-static int hid_zpff_play(struct input_dev *dev, void *data,
-			 struct ff_effect *effect)
-{
-	struct hid_device *hid = input_get_drvdata(dev);
-	struct zpff_device *zpff = data;
-	int left, right;
-
-	/*
-	 * The following is specified the other way around in the Zeroplus
-	 * datasheet but the order below is correct for the XFX Executioner;
-	 * however it is possible that the XFX Executioner is an exception
-	 */
-
-	left = effect->u.rumble.strong_magnitude;
-	right = effect->u.rumble.weak_magnitude;
-	dbg_hid("called with 0x%04x 0x%04x\n", left, right);
-
-	left = left * 0x7f / 0xffff;
-	right = right * 0x7f / 0xffff;
-
-	zpff->report->field[2]->value[0] = left;
-	zpff->report->field[3]->value[0] = right;
-	dbg_hid("running with 0x%02x 0x%02x\n", left, right);
-	usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
-
-	return 0;
-}
-
-int hid_zpff_init(struct hid_device *hid)
-{
-	struct zpff_device *zpff;
-	struct hid_report *report;
-	struct hid_input *hidinput = list_entry(hid->inputs.next,
-						struct hid_input, list);
-	struct list_head *report_list =
-			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
-	struct input_dev *dev = hidinput->input;
-	int error;
-
-	if (list_empty(report_list)) {
-		printk(KERN_ERR "hid-zpff: no output report found\n");
-		return -ENODEV;
-	}
-
-	report = list_entry(report_list->next, struct hid_report, list);
-
-	if (report->maxfield < 4) {
-		printk(KERN_ERR "hid-zpff: not enough fields in report\n");
-		return -ENODEV;
-	}
-
-	zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
-	if (!zpff)
-		return -ENOMEM;
-
-	set_bit(FF_RUMBLE, dev->ffbit);
-
-	error = input_ff_create_memless(dev, zpff, hid_zpff_play);
-	if (error) {
-		kfree(zpff);
-		return error;
-	}
-
-	zpff->report = report;
-	zpff->report->field[0]->value[0] = 0x00;
-	zpff->report->field[1]->value[0] = 0x02;
-	zpff->report->field[2]->value[0] = 0x00;
-	zpff->report->field[3]->value[0] = 0x00;
-	usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
-
-	printk(KERN_INFO "Force feedback for Zeroplus based devices by "
-	       "Anssi Hannula <anssi.hannula@gmail.com>\n");
-
-	return 0;
-}
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 2af65a7..6cf0357 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -760,7 +760,6 @@ void usbhid_set_leds(struct hid_device *hid);
 #ifdef CONFIG_HID_FF
 int hid_ff_init(struct hid_device *hid);
 
-int hid_zpff_init(struct hid_device *hid);
 #ifdef CONFIG_HID_PID
 int hid_pidff_init(struct hid_device *hid);
 #else
-- 
1.6.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 4/5] HID: remove hid-ff
  2008-09-04 12:59   ` [PATCH 3/5] HID: move zeroplus " Jiri Slaby
@ 2008-09-04 12:59     ` Jiri Slaby
  2008-09-04 12:59       ` [PATCH 5/5] HID: convert to dev_* prints Jiri Slaby
  0 siblings, 1 reply; 9+ messages in thread
From: Jiri Slaby @ 2008-09-04 12:59 UTC (permalink / raw)
  To: jkosina; +Cc: linux-input, Anssi Hannula, linux-kernel, Jiri Slaby

hid-ff.c now calls only pidff (generic driver), the special ones are now
in separate drivers. Invoke pidff on all non-special directly.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
 drivers/hid/usbhid/Kconfig    |   13 --------
 drivers/hid/usbhid/Makefile   |    3 --
 drivers/hid/usbhid/hid-core.c |    2 +-
 drivers/hid/usbhid/hid-ff.c   |   69 -----------------------------------------
 include/linux/hid.h           |    9 +-----
 5 files changed, 2 insertions(+), 94 deletions(-)
 delete mode 100644 drivers/hid/usbhid/hid-ff.c

diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig
index 3cfc076..5d9aa95 100644
--- a/drivers/hid/usbhid/Kconfig
+++ b/drivers/hid/usbhid/Kconfig
@@ -24,21 +24,8 @@ config USB_HID
 comment "Input core support is needed for USB HID input layer or HIDBP support"
 	depends on USB_HID && INPUT=n
 
-config HID_FF
-	bool "Force feedback support (EXPERIMENTAL)"
-	depends on USB_HID && EXPERIMENTAL
-	help
-	  Say Y here is you want force feedback support for a few HID devices.
-	  See below for a list of supported devices.
-
-	  See <file:Documentation/input/ff.txt> for a description of the force
-	  feedback API.
-
-	  If unsure, say N.
-
 config HID_PID
 	bool "PID device support"
-	depends on HID_FF
 	help
 	  Say Y here if you have a PID-compliant device and wish to enable force
 	  feedback for it. Microsoft Sidewinder Force Feedback 2 is one of such
diff --git a/drivers/hid/usbhid/Makefile b/drivers/hid/usbhid/Makefile
index 5c460fc..1329ecb 100644
--- a/drivers/hid/usbhid/Makefile
+++ b/drivers/hid/usbhid/Makefile
@@ -13,9 +13,6 @@ endif
 ifeq ($(CONFIG_HID_PID),y)
 	usbhid-objs	+= hid-pidff.o
 endif
-ifeq ($(CONFIG_HID_FF),y)
-	usbhid-objs	+= hid-ff.o
-endif
 
 obj-$(CONFIG_USB_HID)		+= usbhid.o
 obj-$(CONFIG_USB_KBD)		+= usbkbd.o
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 5f32e30..d448e4d 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -938,7 +938,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	usb_set_intfdata(intf, hid);
 	hid->ll_driver = &usb_hid_driver;
 	hid->hid_output_raw_report = usbhid_output_raw_report;
-	hid->ff_init = hid_ff_init;
+	hid->ff_init = hid_pidff_init;
 #ifdef CONFIG_USB_HIDDEV
 	hid->hiddev_connect = hiddev_connect;
 	hid->hiddev_hid_event = hiddev_hid_event;
diff --git a/drivers/hid/usbhid/hid-ff.c b/drivers/hid/usbhid/hid-ff.c
deleted file mode 100644
index eca01a6..0000000
--- a/drivers/hid/usbhid/hid-ff.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *  Force feedback support for hid devices.
- *  Not all hid devices use the same protocol. For example, some use PID,
- *  other use their own proprietary procotol.
- *
- *  Copyright (c) 2002-2004 Johann Deneux
- */
-
-/*
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <johann.deneux@it.uu.se>
- */
-
-#include <linux/input.h>
-
-#undef DEBUG
-#include <linux/usb.h>
-
-#include <linux/hid.h>
-#include "usbhid.h"
-
-/*
- * This table contains pointers to initializers. To add support for new
- * devices, you need to add the USB vendor and product ids here.
- */
-struct hid_ff_initializer {
-	u16 idVendor;
-	u16 idProduct;
-	int (*init)(struct hid_device*);
-};
-
-/*
- * We try pidff when no other driver is found because PID is the
- * standards compliant way of implementing force feedback in HID.
- * pidff_init() will quickly abort if the device doesn't appear to
- * be a PID device
- */
-static struct hid_ff_initializer inits[] = {
-	{ 0,	 0,	 hid_pidff_init}  /* Matches anything */
-};
-
-int hid_ff_init(struct hid_device* hid)
-{
-	struct hid_ff_initializer *init;
-	int vendor = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idVendor);
-	int product = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idProduct);
-
-	for (init = inits; init->idVendor; init++)
-		if (init->idVendor == vendor && init->idProduct == product)
-			break;
-
-	return init->init(hid);
-}
-EXPORT_SYMBOL_GPL(hid_ff_init);
-
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 6cf0357..eb1844c 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -757,17 +757,10 @@ int usbhid_quirks_init(char **quirks_param);
 void usbhid_quirks_exit(void);
 void usbhid_set_leds(struct hid_device *hid);
 
-#ifdef CONFIG_HID_FF
-int hid_ff_init(struct hid_device *hid);
-
 #ifdef CONFIG_HID_PID
 int hid_pidff_init(struct hid_device *hid);
 #else
-static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
-#endif
-
-#else
-#define hid_ff_init	NULL
+#define hid_pidff_init NULL
 #endif
 
 #ifdef CONFIG_HID_DEBUG
-- 
1.6.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 5/5] HID: convert to dev_* prints
  2008-09-04 12:59     ` [PATCH 4/5] HID: remove hid-ff Jiri Slaby
@ 2008-09-04 12:59       ` Jiri Slaby
  0 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-09-04 12:59 UTC (permalink / raw)
  To: jkosina; +Cc: linux-input, Anssi Hannula, linux-kernel, Jiri Slaby

Since we have a real device bound to a driver, we may use struct
device for printing. Use dev_* functions instead of printks in
3 drivers.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
 drivers/hid/hid-lg2ff.c |    8 ++++----
 drivers/hid/hid-pl.c    |   11 ++++++-----
 drivers/hid/hid-zpff.c  |    6 +++---
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c
index b2e9a67..4e6dc6e 100644
--- a/drivers/hid/hid-lg2ff.c
+++ b/drivers/hid/hid-lg2ff.c
@@ -71,18 +71,18 @@ int lg2ff_init(struct hid_device *hid)
 	int error;
 
 	if (list_empty(report_list)) {
-		printk(KERN_ERR "hid-lg2ff: no output report found\n");
+		dev_err(&hid->dev, "no output report found\n");
 		return -ENODEV;
 	}
 
 	report = list_entry(report_list->next, struct hid_report, list);
 
 	if (report->maxfield < 1) {
-		printk(KERN_ERR "hid-lg2ff: output report is empty\n");
+		dev_err(&hid->dev, "output report is empty\n");
 		return -ENODEV;
 	}
 	if (report->field[0]->report_count < 7) {
-		printk(KERN_ERR "hid-lg2ff: not enough values in the field\n");
+		dev_err(&hid->dev, "not enough values in the field\n");
 		return -ENODEV;
 	}
 
@@ -109,7 +109,7 @@ int lg2ff_init(struct hid_device *hid)
 
 	usbhid_submit_report(hid, report, USB_DIR_OUT);
 
-	printk(KERN_INFO "Force feedback for Logitech Rumblepad 2 by "
+	dev_info(&hid->dev, "Force feedback for Logitech Rumblepad 2 by "
 	       "Anssi Hannula <anssi.hannula@gmail.com>\n");
 
 	return 0;
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
index b450084..682cac1 100644
--- a/drivers/hid/hid-pl.c
+++ b/drivers/hid/hid-pl.c
@@ -90,7 +90,7 @@ static int plff_init(struct hid_device *hid)
 	   currently unknown. */
 
 	if (list_empty(report_list)) {
-		printk(KERN_ERR "hid-plff: no output reports found\n");
+		dev_err(&hid->dev, "no output reports found\n");
 		return -ENODEV;
 	}
 
@@ -99,18 +99,19 @@ static int plff_init(struct hid_device *hid)
 		report_ptr = report_ptr->next;
 
 		if (report_ptr == report_list) {
-			printk(KERN_ERR "hid-plff: required output report is missing\n");
+			dev_err(&hid->dev, "required output report is "
+					"missing\n");
 			return -ENODEV;
 		}
 
 		report = list_entry(report_ptr, struct hid_report, list);
 		if (report->maxfield < 1) {
-			printk(KERN_ERR "hid-plff: no fields in the report\n");
+			dev_err(&hid->dev, "no fields in the report\n");
 			return -ENODEV;
 		}
 
 		if (report->field[0]->report_count < 4) {
-			printk(KERN_ERR "hid-plff: not enough values in the field\n");
+			dev_err(&hid->dev, "not enough values in the field\n");
 			return -ENODEV;
 		}
 
@@ -136,7 +137,7 @@ static int plff_init(struct hid_device *hid)
 		usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
 	}
 
-	printk(KERN_INFO "hid-plff: Force feedback for PantherLord/GreenAsia "
+	dev_info(&hid->dev, "Force feedback for PantherLord/GreenAsia "
 	       "devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
 
 	return 0;
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
index 9ed04ee..ea82f37 100644
--- a/drivers/hid/hid-zpff.c
+++ b/drivers/hid/hid-zpff.c
@@ -73,14 +73,14 @@ static int zpff_init(struct hid_device *hid)
 	int error;
 
 	if (list_empty(report_list)) {
-		printk(KERN_ERR "hid-zpff: no output report found\n");
+		dev_err(&hid->dev, "no output report found\n");
 		return -ENODEV;
 	}
 
 	report = list_entry(report_list->next, struct hid_report, list);
 
 	if (report->maxfield < 4) {
-		printk(KERN_ERR "hid-zpff: not enough fields in report\n");
+		dev_err(&hid->dev, "not enough fields in report\n");
 		return -ENODEV;
 	}
 
@@ -103,7 +103,7 @@ static int zpff_init(struct hid_device *hid)
 	zpff->report->field[3]->value[0] = 0x00;
 	usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
 
-	printk(KERN_INFO "Force feedback for Zeroplus based devices by "
+	dev_info(&hid->dev, "force feedback for Zeroplus based devices by "
 	       "Anssi Hannula <anssi.hannula@gmail.com>\n");
 
 	return 0;
-- 
1.6.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/5] HID: move pantherlord FF processing
  2008-09-04 12:59 [PATCH 1/5] HID: move pantherlord FF processing Jiri Slaby
  2008-09-04 12:59 ` [PATCH 2/5] HID: move thrustmaster " Jiri Slaby
@ 2008-09-17 17:03 ` Jiri Kosina
  2008-09-18  8:41   ` Jiri Slaby
  1 sibling, 1 reply; 9+ messages in thread
From: Jiri Kosina @ 2008-09-17 17:03 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: linux-input, Anssi Hannula, linux-kernel

On Thu, 4 Sep 2008, Jiri Slaby wrote:

> Move the force feedback precessing into a separate module.
> 
> Signed-off-by: Jiri Slaby <jirislaby@gmail.com>

> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 0784a09..a4d9695 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -373,6 +373,8 @@
>  #define USB_DEVICE_ID_QUAD_USB_JOYPAD	0x8800
>  #define USB_DEVICE_ID_DUAL_USB_JOYPAD	0x8866
>  
> +#define USB_VENDOR_ID_GREENASIA		0x0e8f
> +
>  #define USB_VENDOR_ID_WISEGROUP_LTD	0x6666
>  #define USB_VENDOR_ID_WISEGROUP_LTD2	0x6677
>  #define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802

Could we please preserve alphabetical ordering in hid-ids.h file?

Otherwise the series looks good to me, and Anssi didn't complain as well. 
Could you please rebase it on top of the current HID tree, fix the 
ordering, and send it to me again, I will apply it?

Thanks,

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/5] HID: move pantherlord FF processing
  2008-09-17 17:03 ` [PATCH 1/5] HID: move pantherlord FF processing Jiri Kosina
@ 2008-09-18  8:41   ` Jiri Slaby
  0 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-09-18  8:41 UTC (permalink / raw)
  To: Jiri Kosina; +Cc: linux-input, Anssi Hannula, linux-kernel

On 09/17/2008 07:03 PM, Jiri Kosina wrote:
> On Thu, 4 Sep 2008, Jiri Slaby wrote:
> 
>> Move the force feedback precessing into a separate module.
>>
>> Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
> 
>> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
>> index 0784a09..a4d9695 100644
>> --- a/drivers/hid/hid-ids.h
>> +++ b/drivers/hid/hid-ids.h
>> @@ -373,6 +373,8 @@
>>  #define USB_DEVICE_ID_QUAD_USB_JOYPAD	0x8800
>>  #define USB_DEVICE_ID_DUAL_USB_JOYPAD	0x8866
>>  
>> +#define USB_VENDOR_ID_GREENASIA		0x0e8f
>> +
>>  #define USB_VENDOR_ID_WISEGROUP_LTD	0x6666
>>  #define USB_VENDOR_ID_WISEGROUP_LTD2	0x6677
>>  #define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802
> 
> Could we please preserve alphabetical ordering in hid-ids.h file?

Oops, sorry for that, I tried to sort it numerically not noticing it's sorted
alphabetically.

> Otherwise the series looks good to me, and Anssi didn't complain as well. 
> Could you please rebase it on top of the current HID tree, fix the 
> ordering, and send it to me again, I will apply it?

No problem.

Thanks.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/5] HID: move pantherlord FF processing
  2008-09-18  8:57 Jiri Slaby
@ 2008-09-18  8:57 ` Jiri Slaby
  0 siblings, 0 replies; 9+ messages in thread
From: Jiri Slaby @ 2008-09-18  8:57 UTC (permalink / raw)
  To: jkosina; +Cc: linux-input, anssi.hannula, linux-kernel

On 09/18/2008 10:57 AM, Jiri Slaby wrote:
> Move the force feedback processing into a separate module.

Ignore this, sorry.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/5] HID: move pantherlord FF processing
@ 2008-09-18  8:57 Jiri Slaby
  2008-09-18  8:57 ` Jiri Slaby
  0 siblings, 1 reply; 9+ messages in thread
From: Jiri Slaby @ 2008-09-18  8:57 UTC (permalink / raw)
  To: jkosina; +Cc: linux-input, anssi.hannula, linux-kernel, Jiri Slaby

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 17063 bytes --]

Move the force feedback processing into a separate module.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
 drivers/hid/Kconfig             |   16 +++
 drivers/hid/Makefile            |    1 +
 drivers/hid/hid-core.c          |    2 +
 drivers/hid/hid-dummy.c         |    3 +
 drivers/hid/hid-ids.h           |    2 +
 drivers/hid/hid-pl.c            |  205 +++++++++++++++++++++++++++++++++++++++
 drivers/hid/usbhid/Kconfig      |    8 --
 drivers/hid/usbhid/Makefile     |    3 -
 drivers/hid/usbhid/hid-ff.c     |    4 -
 drivers/hid/usbhid/hid-plff.c   |  139 --------------------------
 drivers/hid/usbhid/hid-quirks.c |    1 -
 include/linux/hid.h             |    1 -
 12 files changed, 229 insertions(+), 156 deletions(-)
 create mode 100644 drivers/hid/hid-pl.c
 delete mode 100644 drivers/hid/usbhid/hid-plff.c

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 46337a2..7220e6f 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -199,6 +199,22 @@ config HID_MONTEREY
 	---help---
 	Support for Monterey Genius KB29E.
 
+config HID_PANTHERLORD
+	tristate "Pantherlord"
+	default m
+	depends on USB_HID
+	---help---
+	Support for PantherLord/GreenAsia based device support (including
+	force feedback).
+
+config PANTHERLORD_FF
+	bool "Force feedback support"
+	depends on HID_PANTHERLORD
+	select INPUT_FF_MEMLESS
+	help
+	  Say Y here if you have a PantherLord/GreenAsia based game controller
+	  or adapter and want to enable force feedback support for it.
+
 config HID_PETALYNX
 	tristate "Petalynx"
 	default m
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 300ee00..e607068 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_HID_GYRATION)	+= hid-gyration.o
 obj-$(CONFIG_HID_LOGITECH)	+= hid-logitech.o
 obj-$(CONFIG_HID_MICROSOFT)	+= hid-microsoft.o
 obj-$(CONFIG_HID_MONTEREY)	+= hid-monterey.o
+obj-$(CONFIG_HID_PANTHERLORD)	+= hid-pl.o
 obj-$(CONFIG_HID_PETALYNX)	+= hid-petalynx.o
 obj-$(CONFIG_HID_SAMSUNG)	+= hid-samsung.o
 obj-$(CONFIG_HID_SONY)		+= hid-sony.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 63c8ce5..48a76e7 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1411,6 +1411,7 @@ static const struct hid_device_id hid_ignore_list[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) },
@@ -1426,6 +1427,7 @@ static const struct hid_device_id hid_ignore_list[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB) },
diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c
index 69dcf9b..2f5d9a1 100644
--- a/drivers/hid/hid-dummy.c
+++ b/drivers/hid/hid-dummy.c
@@ -40,6 +40,9 @@ static int __init hid_dummy_init(void)
 #ifdef CONFIG_HID_MONTEREY_MODULE
 	HID_COMPAT_CALL_DRIVER(monterey);
 #endif
+#ifdef CONFIG_HID_PANTHERLORD_MODULE
+	HID_COMPAT_CALL_DRIVER(pantherlord);
+#endif
 #ifdef CONFIG_HID_PETALYNX_MODULE
 	HID_COMPAT_CALL_DRIVER(petalynx);
 #endif
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index fa4e4fd..fdd2d13 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -169,6 +169,8 @@
 #define USB_DEVICE_ID_GOGOPEN		0x00ce
 #define USB_DEVICE_ID_PENPOWER		0x00f4
 
+#define USB_VENDOR_ID_GREENASIA		0x0e8f
+
 #define USB_VENDOR_ID_GRETAGMACBETH	0x0971
 #define USB_DEVICE_ID_GRETAGMACBETH_HUEY	0x2005
 
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
new file mode 100644
index 0000000..b450084
--- /dev/null
+++ b/drivers/hid/hid-pl.c
@@ -0,0 +1,205 @@
+/*
+ *  Force feedback support for PantherLord/GreenAsia based devices
+ *
+ *  The devices are distributed under various names and the same USB device ID
+ *  can be used in both adapters and actual game controllers.
+ *
+ *  0810:0001 "Twin USB Joystick"
+ *   - tested with PantherLord USB/PS2 2in1 Adapter
+ *   - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT)
+ *
+ *  0e8f:0003 "GreenAsia Inc.    USB Joystick     "
+ *   - tested with Köng Gaming gamepad
+ *
+ *  Copyright (c) 2007 Anssi Hannula <anssi.hannula@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+/* #define DEBUG */
+
+#define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg)
+
+#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/hid.h>
+
+#include "hid-ids.h"
+
+#ifdef CONFIG_PANTHERLORD_FF
+#include "usbhid/usbhid.h"
+
+struct plff_device {
+	struct hid_report *report;
+};
+
+static int hid_plff_play(struct input_dev *dev, void *data,
+			 struct ff_effect *effect)
+{
+	struct hid_device *hid = input_get_drvdata(dev);
+	struct plff_device *plff = data;
+	int left, right;
+
+	left = effect->u.rumble.strong_magnitude;
+	right = effect->u.rumble.weak_magnitude;
+	debug("called with 0x%04x 0x%04x", left, right);
+
+	left = left * 0x7f / 0xffff;
+	right = right * 0x7f / 0xffff;
+
+	plff->report->field[0]->value[2] = left;
+	plff->report->field[0]->value[3] = right;
+	debug("running with 0x%02x 0x%02x", left, right);
+	usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
+
+	return 0;
+}
+
+static int plff_init(struct hid_device *hid)
+{
+	struct plff_device *plff;
+	struct hid_report *report;
+	struct hid_input *hidinput;
+	struct list_head *report_list =
+			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct list_head *report_ptr = report_list;
+	struct input_dev *dev;
+	int error;
+
+	/* The device contains one output report per physical device, all
+	   containing 1 field, which contains 4 ff00.0002 usages and 4 16bit
+	   absolute values.
+
+	   The input reports also contain a field which contains
+	   8 ff00.0001 usages and 8 boolean values. Their meaning is
+	   currently unknown. */
+
+	if (list_empty(report_list)) {
+		printk(KERN_ERR "hid-plff: no output reports found\n");
+		return -ENODEV;
+	}
+
+	list_for_each_entry(hidinput, &hid->inputs, list) {
+
+		report_ptr = report_ptr->next;
+
+		if (report_ptr == report_list) {
+			printk(KERN_ERR "hid-plff: required output report is missing\n");
+			return -ENODEV;
+		}
+
+		report = list_entry(report_ptr, struct hid_report, list);
+		if (report->maxfield < 1) {
+			printk(KERN_ERR "hid-plff: no fields in the report\n");
+			return -ENODEV;
+		}
+
+		if (report->field[0]->report_count < 4) {
+			printk(KERN_ERR "hid-plff: not enough values in the field\n");
+			return -ENODEV;
+		}
+
+		plff = kzalloc(sizeof(struct plff_device), GFP_KERNEL);
+		if (!plff)
+			return -ENOMEM;
+
+		dev = hidinput->input;
+
+		set_bit(FF_RUMBLE, dev->ffbit);
+
+		error = input_ff_create_memless(dev, plff, hid_plff_play);
+		if (error) {
+			kfree(plff);
+			return error;
+		}
+
+		plff->report = report;
+		plff->report->field[0]->value[0] = 0x00;
+		plff->report->field[0]->value[1] = 0x00;
+		plff->report->field[0]->value[2] = 0x00;
+		plff->report->field[0]->value[3] = 0x00;
+		usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
+	}
+
+	printk(KERN_INFO "hid-plff: Force feedback for PantherLord/GreenAsia "
+	       "devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
+
+	return 0;
+}
+#else
+static inline int plff_init(struct hid_device *hid)
+{
+	return 0;
+}
+#endif
+
+static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+
+	if (id->driver_data)
+		hdev->quirks |= HID_QUIRK_MULTI_INPUT;
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		dev_err(&hdev->dev, "parse failed\n");
+		goto err;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+	if (ret) {
+		dev_err(&hdev->dev, "hw start failed\n");
+		goto err;
+	}
+
+	plff_init(hdev);
+
+	return 0;
+err:
+	return ret;
+}
+
+static const struct hid_device_id pl_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR),
+		.driver_data = 1 }, /* Twin USB Joystick */
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, /* GreenAsia Inc. USB Joystick */
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, pl_devices);
+
+static struct hid_driver pl_driver = {
+	.name = "pantherlord",
+	.id_table = pl_devices,
+	.probe = pl_probe,
+};
+
+static int pl_init(void)
+{
+	return hid_register_driver(&pl_driver);
+}
+
+static void pl_exit(void)
+{
+	hid_unregister_driver(&pl_driver);
+}
+
+module_init(pl_init);
+module_exit(pl_exit);
+MODULE_LICENSE("GPL");
+
+HID_COMPAT_LOAD_DRIVER(pantherlord);
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig
index 0e7e2e6..02c8228 100644
--- a/drivers/hid/usbhid/Kconfig
+++ b/drivers/hid/usbhid/Kconfig
@@ -44,14 +44,6 @@ config HID_PID
 	  feedback for it. Microsoft Sidewinder Force Feedback 2 is one of such
 	  devices.
 
-config PANTHERLORD_FF
-	bool "PantherLord/GreenAsia based device support"
-	depends on HID_FF
-	select INPUT_FF_MEMLESS if USB_HID
-	help
-	  Say Y here if you have a PantherLord/GreenAsia based game controller
-	  or adapter and want to enable force feedback support for it.
-
 config THRUSTMASTER_FF
 	bool "ThrustMaster devices support"
 	depends on HID_FF
diff --git a/drivers/hid/usbhid/Makefile b/drivers/hid/usbhid/Makefile
index 224c62d..0ee4803 100644
--- a/drivers/hid/usbhid/Makefile
+++ b/drivers/hid/usbhid/Makefile
@@ -13,9 +13,6 @@ endif
 ifeq ($(CONFIG_HID_PID),y)
 	usbhid-objs	+= hid-pidff.o
 endif
-ifeq ($(CONFIG_PANTHERLORD_FF),y)
-	usbhid-objs	+= hid-plff.o
-endif
 ifeq ($(CONFIG_THRUSTMASTER_FF),y)
 	usbhid-objs	+= hid-tmff.o
 endif
diff --git a/drivers/hid/usbhid/hid-ff.c b/drivers/hid/usbhid/hid-ff.c
index 8891f60..a868eef 100644
--- a/drivers/hid/usbhid/hid-ff.c
+++ b/drivers/hid/usbhid/hid-ff.c
@@ -50,10 +50,6 @@ struct hid_ff_initializer {
  * be a PID device
  */
 static struct hid_ff_initializer inits[] = {
-#ifdef CONFIG_PANTHERLORD_FF
-	{ 0x810, 0x0001, hid_plff_init }, /* "Twin USB Joystick" */
-	{ 0xe8f, 0x0003, hid_plff_init }, /* "GreenAsia Inc.    USB Joystick     " */
-#endif
 #ifdef CONFIG_THRUSTMASTER_FF
 	{ 0x44f, 0xb300, hid_tmff_init },
 	{ 0x44f, 0xb304, hid_tmff_init },
diff --git a/drivers/hid/usbhid/hid-plff.c b/drivers/hid/usbhid/hid-plff.c
deleted file mode 100644
index 9eb83cf..0000000
--- a/drivers/hid/usbhid/hid-plff.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- *  Force feedback support for PantherLord/GreenAsia based devices
- *
- *  The devices are distributed under various names and the same USB device ID
- *  can be used in both adapters and actual game controllers.
- *
- *  0810:0001 "Twin USB Joystick"
- *   - tested with PantherLord USB/PS2 2in1 Adapter
- *   - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT)
- *
- *  0e8f:0003 "GreenAsia Inc.    USB Joystick     "
- *   - tested with Köng Gaming gamepad
- *
- *  Copyright (c) 2007 Anssi Hannula <anssi.hannula@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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-/* #define DEBUG */
-
-#define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg)
-
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-#include "usbhid.h"
-
-struct plff_device {
-	struct hid_report *report;
-};
-
-static int hid_plff_play(struct input_dev *dev, void *data,
-			 struct ff_effect *effect)
-{
-	struct hid_device *hid = input_get_drvdata(dev);
-	struct plff_device *plff = data;
-	int left, right;
-
-	left = effect->u.rumble.strong_magnitude;
-	right = effect->u.rumble.weak_magnitude;
-	debug("called with 0x%04x 0x%04x", left, right);
-
-	left = left * 0x7f / 0xffff;
-	right = right * 0x7f / 0xffff;
-
-	plff->report->field[0]->value[2] = left;
-	plff->report->field[0]->value[3] = right;
-	debug("running with 0x%02x 0x%02x", left, right);
-	usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
-
-	return 0;
-}
-
-int hid_plff_init(struct hid_device *hid)
-{
-	struct plff_device *plff;
-	struct hid_report *report;
-	struct hid_input *hidinput;
-	struct list_head *report_list =
-			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
-	struct list_head *report_ptr = report_list;
-	struct input_dev *dev;
-	int error;
-
-	/* The device contains one output report per physical device, all
-	   containing 1 field, which contains 4 ff00.0002 usages and 4 16bit
-	   absolute values.
-
-	   The input reports also contain a field which contains
-	   8 ff00.0001 usages and 8 boolean values. Their meaning is
-	   currently unknown. */
-
-	if (list_empty(report_list)) {
-		printk(KERN_ERR "hid-plff: no output reports found\n");
-		return -ENODEV;
-	}
-
-	list_for_each_entry(hidinput, &hid->inputs, list) {
-
-		report_ptr = report_ptr->next;
-
-		if (report_ptr == report_list) {
-			printk(KERN_ERR "hid-plff: required output report is missing\n");
-			return -ENODEV;
-		}
-
-		report = list_entry(report_ptr, struct hid_report, list);
-		if (report->maxfield < 1) {
-			printk(KERN_ERR "hid-plff: no fields in the report\n");
-			return -ENODEV;
-		}
-
-		if (report->field[0]->report_count < 4) {
-			printk(KERN_ERR "hid-plff: not enough values in the field\n");
-			return -ENODEV;
-		}
-
-		plff = kzalloc(sizeof(struct plff_device), GFP_KERNEL);
-		if (!plff)
-			return -ENOMEM;
-
-		dev = hidinput->input;
-
-		set_bit(FF_RUMBLE, dev->ffbit);
-
-		error = input_ff_create_memless(dev, plff, hid_plff_play);
-		if (error) {
-			kfree(plff);
-			return error;
-		}
-
-		plff->report = report;
-		plff->report->field[0]->value[0] = 0x00;
-		plff->report->field[0]->value[1] = 0x00;
-		plff->report->field[0]->value[2] = 0x00;
-		plff->report->field[0]->value[3] = 0x00;
-		usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
-	}
-
-	printk(KERN_INFO "hid-plff: Force feedback for PantherLord/GreenAsia "
-	       "devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
-
-	return 0;
-}
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index d40f009..47ebe04 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -32,7 +32,6 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
 	{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
 	{ USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
-	{ USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 164ce7f..260beba 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -760,7 +760,6 @@ void usbhid_set_leds(struct hid_device *hid);
 #ifdef CONFIG_HID_FF
 int hid_ff_init(struct hid_device *hid);
 
-int hid_plff_init(struct hid_device *hid);
 int hid_tmff_init(struct hid_device *hid);
 int hid_zpff_init(struct hid_device *hid);
 #ifdef CONFIG_HID_PID
-- 
1.6.0.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2008-09-18  8:58 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-04 12:59 [PATCH 1/5] HID: move pantherlord FF processing Jiri Slaby
2008-09-04 12:59 ` [PATCH 2/5] HID: move thrustmaster " Jiri Slaby
2008-09-04 12:59   ` [PATCH 3/5] HID: move zeroplus " Jiri Slaby
2008-09-04 12:59     ` [PATCH 4/5] HID: remove hid-ff Jiri Slaby
2008-09-04 12:59       ` [PATCH 5/5] HID: convert to dev_* prints Jiri Slaby
2008-09-17 17:03 ` [PATCH 1/5] HID: move pantherlord FF processing Jiri Kosina
2008-09-18  8:41   ` Jiri Slaby
2008-09-18  8:57 Jiri Slaby
2008-09-18  8:57 ` Jiri Slaby

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).