All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] HID: hid-logitech: Simplify wheel detection scheme
@ 2015-11-02 14:56 Simon Wood
  2015-11-02 14:56 ` [PATCH 2/2] HID: hid-logitech: Add support for G29 Simon Wood
  2015-11-06 20:18 ` [PATCH 1/2] HID: hid-logitech: Simplify wheel detection scheme Jiri Kosina
  0 siblings, 2 replies; 7+ messages in thread
From: Simon Wood @ 2015-11-02 14:56 UTC (permalink / raw)
  To: linux-input
  Cc: linux-kernel, Jiri Kosina, Edwin, Michal Malý,
	elias vanderstuyft, Simon Wood

Simplfy how hid-logitech driver detects the native mode of the wheel,
done by looking at the USB-ID revision and comparing bit mask.

Signed-off-by: Simon Wood <simon@mungewell.org>
---
 drivers/hid/hid-lg4ff.c | 70 ++++++++++++++++++++-----------------------------
 1 file changed, 28 insertions(+), 42 deletions(-)

diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
index 02cec83..b363d88 100644
--- a/drivers/hid/hid-lg4ff.c
+++ b/drivers/hid/hid-lg4ff.c
@@ -114,16 +114,12 @@ struct lg4ff_compat_mode_switch {
 };
 
 struct lg4ff_wheel_ident_info {
+	const u32 modes;
 	const u16 mask;
 	const u16 result;
 	const u16 real_product_id;
 };
 
-struct lg4ff_wheel_ident_checklist {
-	const u32 count;
-	const struct lg4ff_wheel_ident_info *models[];
-};
-
 struct lg4ff_multimode_wheel {
 	const u16 product_id;
 	const u32 alternate_modes;
@@ -174,36 +170,39 @@ static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = {
 
 /* Multimode wheel identificators */
 static const struct lg4ff_wheel_ident_info lg4ff_dfp_ident_info = {
+	LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
 	0xf000,
 	0x1000,
 	USB_DEVICE_ID_LOGITECH_DFP_WHEEL
 };
 
 static const struct lg4ff_wheel_ident_info lg4ff_g25_ident_info = {
+	LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
 	0xff00,
 	0x1200,
 	USB_DEVICE_ID_LOGITECH_G25_WHEEL
 };
 
 static const struct lg4ff_wheel_ident_info lg4ff_g27_ident_info = {
+	LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
 	0xfff0,
 	0x1230,
 	USB_DEVICE_ID_LOGITECH_G27_WHEEL
 };
 
 static const struct lg4ff_wheel_ident_info lg4ff_dfgt_ident_info = {
+	LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
 	0xff00,
 	0x1300,
 	USB_DEVICE_ID_LOGITECH_DFGT_WHEEL
 };
 
 /* Multimode wheel identification checklists */
-static const struct lg4ff_wheel_ident_checklist lg4ff_main_checklist = {
-	4,
-	{&lg4ff_dfgt_ident_info,
-	 &lg4ff_g27_ident_info,
-	 &lg4ff_g25_ident_info,
-	 &lg4ff_dfp_ident_info}
+static const struct lg4ff_wheel_ident_info *lg4ff_main_checklist[] = {
+	&lg4ff_dfgt_ident_info,
+	&lg4ff_g27_ident_info,
+	&lg4ff_g25_ident_info,
+	&lg4ff_dfp_ident_info
 };
 
 /* Compatibility mode switching commands */
@@ -1037,41 +1036,28 @@ static enum led_brightness lg4ff_led_get_brightness(struct led_classdev *led_cde
 
 static u16 lg4ff_identify_multimode_wheel(struct hid_device *hid, const u16 reported_product_id, const u16 bcdDevice)
 {
-	const struct lg4ff_wheel_ident_checklist *checklist;
-	int i, from_idx, to_idx;
+	u32 current_mode;
+	int i;
 
-	switch (reported_product_id) {
-	case USB_DEVICE_ID_LOGITECH_WHEEL:
-	case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
-		checklist = &lg4ff_main_checklist;
-		from_idx = 0;
-		to_idx = checklist->count - 1;
-		break;
-	case USB_DEVICE_ID_LOGITECH_G25_WHEEL:
-		checklist = &lg4ff_main_checklist;
-		from_idx = 0;
-		to_idx = checklist->count - 2; /* End identity check at G25 */
-		break;
-	case USB_DEVICE_ID_LOGITECH_G27_WHEEL:
-		checklist = &lg4ff_main_checklist;
-		from_idx = 1; /* Start identity check at G27 */
-		to_idx = checklist->count - 3; /* End identity check at G27 */
-		break;
-	case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
-		checklist = &lg4ff_main_checklist;
-		from_idx = 0;
-		to_idx = checklist->count - 4; /* End identity check at DFGT */
-		break;
-	default:
-		return 0;
+	/* identify current mode from USB PID */
+	for (i = 1; i < ARRAY_SIZE(lg4ff_alternate_modes); i++) {
+		dbg_hid("Testing whether PID is %X\n", lg4ff_alternate_modes[i].product_id);
+		if (reported_product_id == lg4ff_alternate_modes[i].product_id)
+			break;
 	}
 
-	for (i = from_idx; i <= to_idx; i++) {
-		const u16 mask = checklist->models[i]->mask;
-		const u16 result = checklist->models[i]->result;
-		const u16 real_product_id = checklist->models[i]->real_product_id;
+	if (i == ARRAY_SIZE(lg4ff_alternate_modes))
+		return 0;
+
+	current_mode = BIT(i);
+
+	for (i = 0; i < ARRAY_SIZE(lg4ff_main_checklist); i++) {
+		const u16 mask = lg4ff_main_checklist[i]->mask;
+		const u16 result = lg4ff_main_checklist[i]->result;
+		const u16 real_product_id = lg4ff_main_checklist[i]->real_product_id;
 
-		if ((bcdDevice & mask) == result) {
+		if ((current_mode & lg4ff_main_checklist[i]->modes) && \
+				(bcdDevice & mask) == result) {
 			dbg_hid("Found wheel with real PID %X whose reported PID is %X\n", real_product_id, reported_product_id);
 			return real_product_id;
 		}
-- 
2.1.4


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

* [PATCH 2/2] HID: hid-logitech: Add support for G29
  2015-11-02 14:56 [PATCH 1/2] HID: hid-logitech: Simplify wheel detection scheme Simon Wood
@ 2015-11-02 14:56 ` Simon Wood
  2015-11-30 13:03   ` Joshua Clayton
  2015-11-06 20:18 ` [PATCH 1/2] HID: hid-logitech: Simplify wheel detection scheme Jiri Kosina
  1 sibling, 1 reply; 7+ messages in thread
From: Simon Wood @ 2015-11-02 14:56 UTC (permalink / raw)
  To: linux-input
  Cc: linux-kernel, Jiri Kosina, Edwin, Michal Malý,
	elias vanderstuyft, Simon Wood

At present the G29 is mis-identified as a DFGT, this patch ensures
that the wheel is correctly detected and allows setting the LEDs and
turning range via the '/sys' interface.

This wheel can also emulate other types of Logitech wheels.

Signed-off-by: Simon Wood <simon@mungewell.org>
---
 drivers/hid/hid-core.c  |  1 +
 drivers/hid/hid-lg.c    |  9 ++++++++
 drivers/hid/hid-lg4ff.c | 57 +++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 70a11ac..949d804 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1896,6 +1896,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 5332fb7..c20ac76 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -620,6 +620,7 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi,
 			usage->code == ABS_Y || usage->code == ABS_Z ||
 			usage->code == ABS_RZ)) {
 		switch (hdev->product) {
+		case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
 		case USB_DEVICE_ID_LOGITECH_WHEEL:
 		case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL:
 		case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
@@ -658,10 +659,18 @@ static int lg_event(struct hid_device *hdev, struct hid_field *field,
 
 static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
+	struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
+	__u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
 	unsigned int connect_mask = HID_CONNECT_DEFAULT;
 	struct lg_drv_data *drv_data;
 	int ret;
 
+	/* Only work with the 1st interface (G29 presents multiple) */
+	if (iface_num != 0) {
+		dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num);
+		return -ENODEV;
+	}
+
 	drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL);
 	if (!drv_data) {
 		hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
index b363d88..fbddcb3 100644
--- a/drivers/hid/hid-lg4ff.c
+++ b/drivers/hid/hid-lg4ff.c
@@ -45,7 +45,8 @@
 #define LG4FF_MODE_G25_IDX 3
 #define LG4FF_MODE_DFGT_IDX 4
 #define LG4FF_MODE_G27_IDX 5
-#define LG4FF_MODE_MAX_IDX 6
+#define LG4FF_MODE_G29_IDX 6
+#define LG4FF_MODE_MAX_IDX 7
 
 #define LG4FF_MODE_NATIVE BIT(LG4FF_MODE_NATIVE_IDX)
 #define LG4FF_MODE_DFEX BIT(LG4FF_MODE_DFEX_IDX)
@@ -53,6 +54,7 @@
 #define LG4FF_MODE_G25 BIT(LG4FF_MODE_G25_IDX)
 #define LG4FF_MODE_DFGT BIT(LG4FF_MODE_DFGT_IDX)
 #define LG4FF_MODE_G27 BIT(LG4FF_MODE_G27_IDX)
+#define LG4FF_MODE_G29 BIT(LG4FF_MODE_G29_IDX)
 
 #define LG4FF_DFEX_TAG "DF-EX"
 #define LG4FF_DFEX_NAME "Driving Force / Formula EX"
@@ -62,6 +64,8 @@
 #define LG4FF_G25_NAME "G25 Racing Wheel"
 #define LG4FF_G27_TAG "G27"
 #define LG4FF_G27_NAME "G27 Racing Wheel"
+#define LG4FF_G29_TAG "G29"
+#define LG4FF_G29_NAME "G29 Racing Wheel"
 #define LG4FF_DFGT_TAG "DFGT"
 #define LG4FF_DFGT_NAME "Driving Force GT"
 
@@ -140,6 +144,7 @@ static const struct lg4ff_wheel lg4ff_devices[] = {
 	{USB_DEVICE_ID_LOGITECH_G25_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
 	{USB_DEVICE_ID_LOGITECH_DFGT_WHEEL,  lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
 	{USB_DEVICE_ID_LOGITECH_G27_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
+	{USB_DEVICE_ID_LOGITECH_G29_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
 	{USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270, NULL},
 	{USB_DEVICE_ID_LOGITECH_WII_WHEEL,   lg4ff_wheel_effects, 40, 270, NULL}
 };
@@ -157,6 +162,9 @@ static const struct lg4ff_multimode_wheel lg4ff_multimode_wheels[] = {
 	{USB_DEVICE_ID_LOGITECH_G27_WHEEL,
 	 LG4FF_MODE_NATIVE | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
 	 LG4FF_G27_TAG, LG4FF_G27_NAME},
+	{USB_DEVICE_ID_LOGITECH_G29_WHEEL,
+	 LG4FF_MODE_NATIVE | LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
+	 LG4FF_G29_TAG, LG4FF_G29_NAME},
 };
 
 static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = {
@@ -165,7 +173,8 @@ static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = {
 	[LG4FF_MODE_DFP_IDX] = {USB_DEVICE_ID_LOGITECH_DFP_WHEEL, LG4FF_DFP_TAG, LG4FF_DFP_NAME},
 	[LG4FF_MODE_G25_IDX] = {USB_DEVICE_ID_LOGITECH_G25_WHEEL, LG4FF_G25_TAG, LG4FF_G25_NAME},
 	[LG4FF_MODE_DFGT_IDX] = {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, LG4FF_DFGT_TAG, LG4FF_DFGT_NAME},
-	[LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME}
+	[LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME},
+	[LG4FF_MODE_G29_IDX] = {USB_DEVICE_ID_LOGITECH_G29_WHEEL, LG4FF_G29_TAG, LG4FF_G29_NAME},
 };
 
 /* Multimode wheel identificators */
@@ -197,8 +206,24 @@ static const struct lg4ff_wheel_ident_info lg4ff_dfgt_ident_info = {
 	USB_DEVICE_ID_LOGITECH_DFGT_WHEEL
 };
 
+static const struct lg4ff_wheel_ident_info lg4ff_g29_ident_info = {
+	LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
+	0xfff8,
+	0x1350,
+	USB_DEVICE_ID_LOGITECH_G29_WHEEL
+};
+
+static const struct lg4ff_wheel_ident_info lg4ff_g29_ident_info2 = {
+	LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
+	0xff00,
+	0x8900,
+	USB_DEVICE_ID_LOGITECH_G29_WHEEL
+};
+
 /* Multimode wheel identification checklists */
 static const struct lg4ff_wheel_ident_info *lg4ff_main_checklist[] = {
+	&lg4ff_g29_ident_info,
+	&lg4ff_g29_ident_info2,
 	&lg4ff_dfgt_ident_info,
 	&lg4ff_g27_ident_info,
 	&lg4ff_g25_ident_info,
@@ -237,6 +262,12 @@ static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g27 = {
 	 0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00}	/* Switch mode to G27 with detach */
 };
 
+static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g29 = {
+	2,
+	{0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,	/* Revert mode upon USB reset */
+	 0xf8, 0x09, 0x05, 0x01, 0x01, 0x00, 0x00}	/* Switch mode to G29 with detach */
+};
+
 /* EXT_CMD1 - Understood by DFP, G25, G27 and DFGT */
 static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext01_dfp = {
 	1,
@@ -650,6 +681,23 @@ static const struct lg4ff_compat_mode_switch *lg4ff_get_mode_switch_command(cons
 			return NULL;
 		}
 		break;
+	case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
+		switch (target_product_id) {
+		case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
+			return &lg4ff_mode_switch_ext09_dfp;
+		case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
+			return &lg4ff_mode_switch_ext09_dfgt;
+		case USB_DEVICE_ID_LOGITECH_G25_WHEEL:
+			return &lg4ff_mode_switch_ext09_g25;
+		case USB_DEVICE_ID_LOGITECH_G27_WHEEL:
+			return &lg4ff_mode_switch_ext09_g27;
+		case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
+			return &lg4ff_mode_switch_ext09_g29;
+		/* G29 can only be switched to DF-EX, DFP, DFGT, G25, G27 or its native mode */
+		default:
+			return NULL;
+		}
+		break;
 	case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
 		switch (target_product_id) {
 		case USB_DEVICE_ID_LOGITECH_WHEEL:
@@ -1232,12 +1280,13 @@ int lg4ff_init(struct hid_device *hid)
 		entry->wdata.set_range(hid, entry->wdata.range);
 
 #ifdef CONFIG_LEDS_CLASS
-	/* register led subsystem - G27 only */
+	/* register led subsystem - G27/G29 only */
 	entry->wdata.led_state = 0;
 	for (j = 0; j < 5; j++)
 		entry->wdata.led[j] = NULL;
 
-	if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL) {
+	if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL ||
+			lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G29_WHEEL) {
 		struct led_classdev *led;
 		size_t name_sz;
 		char *name;
-- 
2.1.4


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

* Re: [PATCH 1/2] HID: hid-logitech: Simplify wheel detection scheme
  2015-11-02 14:56 [PATCH 1/2] HID: hid-logitech: Simplify wheel detection scheme Simon Wood
  2015-11-02 14:56 ` [PATCH 2/2] HID: hid-logitech: Add support for G29 Simon Wood
@ 2015-11-06 20:18 ` Jiri Kosina
  1 sibling, 0 replies; 7+ messages in thread
From: Jiri Kosina @ 2015-11-06 20:18 UTC (permalink / raw)
  To: Simon Wood
  Cc: linux-input, linux-kernel, Edwin, Michal Malý, elias vanderstuyft

On Mon, 2 Nov 2015, Simon Wood wrote:

> Simplfy how hid-logitech driver detects the native mode of the wheel,
> done by looking at the USB-ID revision and comparing bit mask.
> 
> Signed-off-by: Simon Wood <simon@mungewell.org>

I've applied both patches to for-4.4/logitech. Thanks,

-- 
Jiri Kosina
SUSE Labs


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

* Re: [PATCH 2/2] HID: hid-logitech: Add support for G29
  2015-11-02 14:56 ` [PATCH 2/2] HID: hid-logitech: Add support for G29 Simon Wood
@ 2015-11-30 13:03   ` Joshua Clayton
  2015-11-30 14:15       ` madcatxster
  0 siblings, 1 reply; 7+ messages in thread
From: Joshua Clayton @ 2015-11-30 13:03 UTC (permalink / raw)
  To: Simon Wood
  Cc: linux-input, linux-kernel, Jiri Kosina, Edwin, Michal Malý,
	elias vanderstuyft

Simon et al,
My logitech cordless mouse is not detected in linux-next
I have bisected the breakage to this patch,
 commit 29fae1c85166ef525b8b6518e749295e0c9d1e20 in linux-next.

On Monday, November 02, 2015 07:56:52 AM Simon Wood wrote:
> At present the G29 is mis-identified as a DFGT, this patch ensures
> that the wheel is correctly detected and allows setting the LEDs and
> turning range via the '/sys' interface.
> 
> This wheel can also emulate other types of Logitech wheels.
> 
> Signed-off-by: Simon Wood <simon@mungewell.org>
> ---
>  drivers/hid/hid-core.c  |  1 +
>  drivers/hid/hid-lg.c    |  9 ++++++++
>  drivers/hid/hid-lg4ff.c | 57 +++++++++++++++++++++++++++++++++++++++++++++----
>  3 files changed, 63 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> index 70a11ac..949d804 100644
> --- a/drivers/hid/hid-core.c
> +++ b/drivers/hid/hid-core.c
> @@ -1896,6 +1896,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
>  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
>  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
>  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
> +	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) },
>  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
>  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },
>  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
> diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
> index 5332fb7..c20ac76 100644
> --- a/drivers/hid/hid-lg.c
> +++ b/drivers/hid/hid-lg.c
> @@ -620,6 +620,7 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi,
>  			usage->code == ABS_Y || usage->code == ABS_Z ||
>  			usage->code == ABS_RZ)) {
>  		switch (hdev->product) {
> +		case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
>  		case USB_DEVICE_ID_LOGITECH_WHEEL:
>  		case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL:
>  		case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
> @@ -658,10 +659,18 @@ static int lg_event(struct hid_device *hdev, struct hid_field *field,
>  
>  static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
>  {
> +	struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
> +	__u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
>  	unsigned int connect_mask = HID_CONNECT_DEFAULT;
>  	struct lg_drv_data *drv_data;
>  	int ret;
>  
> +	/* Only work with the 1st interface (G29 presents multiple) */
> +	if (iface_num != 0) {
> +		dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num);
> +		return -ENODEV;
> +	}
> +
>  	drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL);
>  	if (!drv_data) {
>  		hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
> diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
> index b363d88..fbddcb3 100644
> --- a/drivers/hid/hid-lg4ff.c
> +++ b/drivers/hid/hid-lg4ff.c
> @@ -45,7 +45,8 @@
>  #define LG4FF_MODE_G25_IDX 3
>  #define LG4FF_MODE_DFGT_IDX 4
>  #define LG4FF_MODE_G27_IDX 5
> -#define LG4FF_MODE_MAX_IDX 6
> +#define LG4FF_MODE_G29_IDX 6
> +#define LG4FF_MODE_MAX_IDX 7
>  
>  #define LG4FF_MODE_NATIVE BIT(LG4FF_MODE_NATIVE_IDX)
>  #define LG4FF_MODE_DFEX BIT(LG4FF_MODE_DFEX_IDX)
> @@ -53,6 +54,7 @@
>  #define LG4FF_MODE_G25 BIT(LG4FF_MODE_G25_IDX)
>  #define LG4FF_MODE_DFGT BIT(LG4FF_MODE_DFGT_IDX)
>  #define LG4FF_MODE_G27 BIT(LG4FF_MODE_G27_IDX)
> +#define LG4FF_MODE_G29 BIT(LG4FF_MODE_G29_IDX)
>  
>  #define LG4FF_DFEX_TAG "DF-EX"
>  #define LG4FF_DFEX_NAME "Driving Force / Formula EX"
> @@ -62,6 +64,8 @@
>  #define LG4FF_G25_NAME "G25 Racing Wheel"
>  #define LG4FF_G27_TAG "G27"
>  #define LG4FF_G27_NAME "G27 Racing Wheel"
> +#define LG4FF_G29_TAG "G29"
> +#define LG4FF_G29_NAME "G29 Racing Wheel"
>  #define LG4FF_DFGT_TAG "DFGT"
>  #define LG4FF_DFGT_NAME "Driving Force GT"
>  
> @@ -140,6 +144,7 @@ static const struct lg4ff_wheel lg4ff_devices[] = {
>  	{USB_DEVICE_ID_LOGITECH_G25_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
>  	{USB_DEVICE_ID_LOGITECH_DFGT_WHEEL,  lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
>  	{USB_DEVICE_ID_LOGITECH_G27_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
> +	{USB_DEVICE_ID_LOGITECH_G29_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
>  	{USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270, NULL},
>  	{USB_DEVICE_ID_LOGITECH_WII_WHEEL,   lg4ff_wheel_effects, 40, 270, NULL}
>  };
> @@ -157,6 +162,9 @@ static const struct lg4ff_multimode_wheel lg4ff_multimode_wheels[] = {
>  	{USB_DEVICE_ID_LOGITECH_G27_WHEEL,
>  	 LG4FF_MODE_NATIVE | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
>  	 LG4FF_G27_TAG, LG4FF_G27_NAME},
> +	{USB_DEVICE_ID_LOGITECH_G29_WHEEL,
> +	 LG4FF_MODE_NATIVE | LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
> +	 LG4FF_G29_TAG, LG4FF_G29_NAME},
>  };
>  
>  static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = {
> @@ -165,7 +173,8 @@ static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = {
>  	[LG4FF_MODE_DFP_IDX] = {USB_DEVICE_ID_LOGITECH_DFP_WHEEL, LG4FF_DFP_TAG, LG4FF_DFP_NAME},
>  	[LG4FF_MODE_G25_IDX] = {USB_DEVICE_ID_LOGITECH_G25_WHEEL, LG4FF_G25_TAG, LG4FF_G25_NAME},
>  	[LG4FF_MODE_DFGT_IDX] = {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, LG4FF_DFGT_TAG, LG4FF_DFGT_NAME},
> -	[LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME}
> +	[LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME},
> +	[LG4FF_MODE_G29_IDX] = {USB_DEVICE_ID_LOGITECH_G29_WHEEL, LG4FF_G29_TAG, LG4FF_G29_NAME},
>  };
>  
>  /* Multimode wheel identificators */
> @@ -197,8 +206,24 @@ static const struct lg4ff_wheel_ident_info lg4ff_dfgt_ident_info = {
>  	USB_DEVICE_ID_LOGITECH_DFGT_WHEEL
>  };
>  
> +static const struct lg4ff_wheel_ident_info lg4ff_g29_ident_info = {
> +	LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
> +	0xfff8,
> +	0x1350,
> +	USB_DEVICE_ID_LOGITECH_G29_WHEEL
> +};
> +
> +static const struct lg4ff_wheel_ident_info lg4ff_g29_ident_info2 = {
> +	LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
> +	0xff00,
> +	0x8900,
> +	USB_DEVICE_ID_LOGITECH_G29_WHEEL
> +};
> +
>  /* Multimode wheel identification checklists */
>  static const struct lg4ff_wheel_ident_info *lg4ff_main_checklist[] = {
> +	&lg4ff_g29_ident_info,
> +	&lg4ff_g29_ident_info2,
>  	&lg4ff_dfgt_ident_info,
>  	&lg4ff_g27_ident_info,
>  	&lg4ff_g25_ident_info,
> @@ -237,6 +262,12 @@ static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g27 = {
>  	 0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00}	/* Switch mode to G27 with detach */
>  };
>  
> +static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g29 = {
> +	2,
> +	{0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,	/* Revert mode upon USB reset */
> +	 0xf8, 0x09, 0x05, 0x01, 0x01, 0x00, 0x00}	/* Switch mode to G29 with detach */
> +};
> +
>  /* EXT_CMD1 - Understood by DFP, G25, G27 and DFGT */
>  static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext01_dfp = {
>  	1,
> @@ -650,6 +681,23 @@ static const struct lg4ff_compat_mode_switch *lg4ff_get_mode_switch_command(cons
>  			return NULL;
>  		}
>  		break;
> +	case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
> +		switch (target_product_id) {
> +		case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
> +			return &lg4ff_mode_switch_ext09_dfp;
> +		case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
> +			return &lg4ff_mode_switch_ext09_dfgt;
> +		case USB_DEVICE_ID_LOGITECH_G25_WHEEL:
> +			return &lg4ff_mode_switch_ext09_g25;
> +		case USB_DEVICE_ID_LOGITECH_G27_WHEEL:
> +			return &lg4ff_mode_switch_ext09_g27;
> +		case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
> +			return &lg4ff_mode_switch_ext09_g29;
> +		/* G29 can only be switched to DF-EX, DFP, DFGT, G25, G27 or its native mode */
> +		default:
> +			return NULL;
> +		}
> +		break;
>  	case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
>  		switch (target_product_id) {
>  		case USB_DEVICE_ID_LOGITECH_WHEEL:
> @@ -1232,12 +1280,13 @@ int lg4ff_init(struct hid_device *hid)
>  		entry->wdata.set_range(hid, entry->wdata.range);
>  
>  #ifdef CONFIG_LEDS_CLASS
> -	/* register led subsystem - G27 only */
> +	/* register led subsystem - G27/G29 only */
>  	entry->wdata.led_state = 0;
>  	for (j = 0; j < 5; j++)
>  		entry->wdata.led[j] = NULL;
>  
> -	if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL) {
> +	if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL ||
> +			lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G29_WHEEL) {
>  		struct led_classdev *led;
>  		size_t name_sz;
>  		char *name;

I have a logitech cordless mouse/keyboard combo.  The keyboard still works.

The following is part of my dmesg output on the previous commit (with the mouse working),

before:

[    1.566674] usb 4-3: New USB device found, idVendor=046d, idProduct=c517
[    1.566779] usb 4-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    1.566881] usb 4-3: Product: USB Receiver
[    1.566982] usb 4-3: Manufacturer: Logitech
[    1.573671] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.0/0003:046D:C517.0003/input/input14
[    1.624510] logitech 0003:046D:C517.0003: input,hidraw0: USB HID v1.10 Keyboard [Logitech USB Receiver] on usb-0000:00:12.1-3/input0
[    1.629313] tsc: Refined TSC clocksource calibration: 2511.094 MHz
[    1.629407] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x243229b6f8a, max_idle_ns: 440795226168 ns
[    1.631370] logitech 0003:046D:C517.0004: fixing up Logitech keyboard report descriptor
[    1.632203] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.1/0003:046D:C517.0004/input/input15
[    1.677588] random: nonblocking pool is initialized
[    1.683359] logitech 0003:046D:C517.0004: input,hiddev0,hidraw1: USB HID v1.10 Mouse [Logitech USB Receiver] on usb-0000:00:12.1-3/input1

after:

[    1.577748] usb 4-3: New USB device found, idVendor=046d, idProduct=c517
[    1.577859] usb 4-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    1.577963] usb 4-3: Product: USB Receiver
[    1.578064] usb 4-3: Manufacturer: Logitech
[    1.584746] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.0/0003:046D:C517.0003/input/input14
[    1.635596] logitech 0003:046D:C517.0003: input,hidraw0: USB HID v1.10 Keyboard [Logitech USB Receiver] on usb-0000:00:12.1-3/input0
[    1.642389] tsc: Refined TSC clocksource calibration: 2511.093 MHz
[    1.642507] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x24322913340, max_idle_ns: 440795255552 ns
[    1.696567] random: nonblocking pool is initialized


I can only guess that it is either now being misidentified (regression).
... or do I perhaps need to enable a different driver now???
Happy to help if I can.

warmest regards,

Joshua Clayton

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

* Re: [PATCH 2/2] HID: hid-logitech: Add support for G29
  2015-11-30 13:03   ` Joshua Clayton
@ 2015-11-30 14:15       ` madcatxster
  0 siblings, 0 replies; 7+ messages in thread
From: madcatxster @ 2015-11-30 14:15 UTC (permalink / raw)
  To: stillcompiling
  Cc: linux-input, linux-kernel, jkosina, Edwin, elias.vds, simon

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=utf-8, Size: 12077 bytes --]

Hi all,

my completely off-the-bat guess would be that the combo uses multiple interfaces as well, the patch seems to ignore everything but iface 0. Can you comment out the 'if' that does this and give it a go?

Michal

On Mon Nov 30 14:03:51 2015 GMT+0100, Joshua Clayton wrote:
> Simon et al,
> My logitech cordless mouse is not detected in linux-next
> I have bisected the breakage to this patch,
>  commit 29fae1c85166ef525b8b6518e749295e0c9d1e20 in linux-next.
> 
> On Monday, November 02, 2015 07:56:52 AM Simon Wood wrote:
> > At present the G29 is mis-identified as a DFGT, this patch ensures
> > that the wheel is correctly detected and allows setting the LEDs and
> > turning range via the '/sys' interface.
> > 
> > This wheel can also emulate other types of Logitech wheels.
> > 
> > Signed-off-by: Simon Wood <simon@mungewell.org>
> > ---
> >  drivers/hid/hid-core.c  |  1 +
> >  drivers/hid/hid-lg.c    |  9 ++++++++
> >  drivers/hid/hid-lg4ff.c | 57 +++++++++++++++++++++++++++++++++++++++++++++----
> >  3 files changed, 63 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> > index 70a11ac..949d804 100644
> > --- a/drivers/hid/hid-core.c
> > +++ b/drivers/hid/hid-core.c
> > @@ -1896,6 +1896,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
> > +	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
> > diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
> > index 5332fb7..c20ac76 100644
> > --- a/drivers/hid/hid-lg.c
> > +++ b/drivers/hid/hid-lg.c
> > @@ -620,6 +620,7 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi,
> >  			usage->code == ABS_Y || usage->code == ABS_Z ||
> >  			usage->code == ABS_RZ)) {
> >  		switch (hdev->product) {
> > +		case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
> >  		case USB_DEVICE_ID_LOGITECH_WHEEL:
> >  		case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL:
> >  		case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
> > @@ -658,10 +659,18 @@ static int lg_event(struct hid_device *hdev, struct hid_field *field,
> >  
> >  static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
> >  {
> > +	struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
> > +	__u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
> >  	unsigned int connect_mask = HID_CONNECT_DEFAULT;
> >  	struct lg_drv_data *drv_data;
> >  	int ret;
> >  
> > +	/* Only work with the 1st interface (G29 presents multiple) */
> > +	if (iface_num != 0) {
> > +		dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num);
> > +		return -ENODEV;
> > +	}
> > +
> >  	drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL);
> >  	if (!drv_data) {
> >  		hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
> > diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
> > index b363d88..fbddcb3 100644
> > --- a/drivers/hid/hid-lg4ff.c
> > +++ b/drivers/hid/hid-lg4ff.c
> > @@ -45,7 +45,8 @@
> >  #define LG4FF_MODE_G25_IDX 3
> >  #define LG4FF_MODE_DFGT_IDX 4
> >  #define LG4FF_MODE_G27_IDX 5
> > -#define LG4FF_MODE_MAX_IDX 6
> > +#define LG4FF_MODE_G29_IDX 6
> > +#define LG4FF_MODE_MAX_IDX 7
> >  
> >  #define LG4FF_MODE_NATIVE BIT(LG4FF_MODE_NATIVE_IDX)
> >  #define LG4FF_MODE_DFEX BIT(LG4FF_MODE_DFEX_IDX)
> > @@ -53,6 +54,7 @@
> >  #define LG4FF_MODE_G25 BIT(LG4FF_MODE_G25_IDX)
> >  #define LG4FF_MODE_DFGT BIT(LG4FF_MODE_DFGT_IDX)
> >  #define LG4FF_MODE_G27 BIT(LG4FF_MODE_G27_IDX)
> > +#define LG4FF_MODE_G29 BIT(LG4FF_MODE_G29_IDX)
> >  
> >  #define LG4FF_DFEX_TAG "DF-EX"
> >  #define LG4FF_DFEX_NAME "Driving Force / Formula EX"
> > @@ -62,6 +64,8 @@
> >  #define LG4FF_G25_NAME "G25 Racing Wheel"
> >  #define LG4FF_G27_TAG "G27"
> >  #define LG4FF_G27_NAME "G27 Racing Wheel"
> > +#define LG4FF_G29_TAG "G29"
> > +#define LG4FF_G29_NAME "G29 Racing Wheel"
> >  #define LG4FF_DFGT_TAG "DFGT"
> >  #define LG4FF_DFGT_NAME "Driving Force GT"
> >  
> > @@ -140,6 +144,7 @@ static const struct lg4ff_wheel lg4ff_devices[] = {
> >  	{USB_DEVICE_ID_LOGITECH_G25_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
> >  	{USB_DEVICE_ID_LOGITECH_DFGT_WHEEL,  lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
> >  	{USB_DEVICE_ID_LOGITECH_G27_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
> > +	{USB_DEVICE_ID_LOGITECH_G29_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
> >  	{USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270, NULL},
> >  	{USB_DEVICE_ID_LOGITECH_WII_WHEEL,   lg4ff_wheel_effects, 40, 270, NULL}
> >  };
> > @@ -157,6 +162,9 @@ static const struct lg4ff_multimode_wheel lg4ff_multimode_wheels[] = {
> >  	{USB_DEVICE_ID_LOGITECH_G27_WHEEL,
> >  	 LG4FF_MODE_NATIVE | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
> >  	 LG4FF_G27_TAG, LG4FF_G27_NAME},
> > +	{USB_DEVICE_ID_LOGITECH_G29_WHEEL,
> > +	 LG4FF_MODE_NATIVE | LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
> > +	 LG4FF_G29_TAG, LG4FF_G29_NAME},
> >  };
> >  
> >  static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = {
> > @@ -165,7 +173,8 @@ static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = {
> >  	[LG4FF_MODE_DFP_IDX] = {USB_DEVICE_ID_LOGITECH_DFP_WHEEL, LG4FF_DFP_TAG, LG4FF_DFP_NAME},
> >  	[LG4FF_MODE_G25_IDX] = {USB_DEVICE_ID_LOGITECH_G25_WHEEL, LG4FF_G25_TAG, LG4FF_G25_NAME},
> >  	[LG4FF_MODE_DFGT_IDX] = {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, LG4FF_DFGT_TAG, LG4FF_DFGT_NAME},
> > -	[LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME}
> > +	[LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME},
> > +	[LG4FF_MODE_G29_IDX] = {USB_DEVICE_ID_LOGITECH_G29_WHEEL, LG4FF_G29_TAG, LG4FF_G29_NAME},
> >  };
> >  
> >  /* Multimode wheel identificators */
> > @@ -197,8 +206,24 @@ static const struct lg4ff_wheel_ident_info lg4ff_dfgt_ident_info = {
> >  	USB_DEVICE_ID_LOGITECH_DFGT_WHEEL
> >  };
> >  
> > +static const struct lg4ff_wheel_ident_info lg4ff_g29_ident_info = {
> > +	LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
> > +	0xfff8,
> > +	0x1350,
> > +	USB_DEVICE_ID_LOGITECH_G29_WHEEL
> > +};
> > +
> > +static const struct lg4ff_wheel_ident_info lg4ff_g29_ident_info2 = {
> > +	LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
> > +	0xff00,
> > +	0x8900,
> > +	USB_DEVICE_ID_LOGITECH_G29_WHEEL
> > +};
> > +
> >  /* Multimode wheel identification checklists */
> >  static const struct lg4ff_wheel_ident_info *lg4ff_main_checklist[] = {
> > +	&lg4ff_g29_ident_info,
> > +	&lg4ff_g29_ident_info2,
> >  	&lg4ff_dfgt_ident_info,
> >  	&lg4ff_g27_ident_info,
> >  	&lg4ff_g25_ident_info,
> > @@ -237,6 +262,12 @@ static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g27 = {
> >  	 0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00}	/* Switch mode to G27 with detach */
> >  };
> >  
> > +static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g29 = {
> > +	2,
> > +	{0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,	/* Revert mode upon USB reset */
> > +	 0xf8, 0x09, 0x05, 0x01, 0x01, 0x00, 0x00}	/* Switch mode to G29 with detach */
> > +};
> > +
> >  /* EXT_CMD1 - Understood by DFP, G25, G27 and DFGT */
> >  static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext01_dfp = {
> >  	1,
> > @@ -650,6 +681,23 @@ static const struct lg4ff_compat_mode_switch *lg4ff_get_mode_switch_command(cons
> >  			return NULL;
> >  		}
> >  		break;
> > +	case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
> > +		switch (target_product_id) {
> > +		case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
> > +			return &lg4ff_mode_switch_ext09_dfp;
> > +		case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
> > +			return &lg4ff_mode_switch_ext09_dfgt;
> > +		case USB_DEVICE_ID_LOGITECH_G25_WHEEL:
> > +			return &lg4ff_mode_switch_ext09_g25;
> > +		case USB_DEVICE_ID_LOGITECH_G27_WHEEL:
> > +			return &lg4ff_mode_switch_ext09_g27;
> > +		case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
> > +			return &lg4ff_mode_switch_ext09_g29;
> > +		/* G29 can only be switched to DF-EX, DFP, DFGT, G25, G27 or its native mode */
> > +		default:
> > +			return NULL;
> > +		}
> > +		break;
> >  	case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
> >  		switch (target_product_id) {
> >  		case USB_DEVICE_ID_LOGITECH_WHEEL:
> > @@ -1232,12 +1280,13 @@ int lg4ff_init(struct hid_device *hid)
> >  		entry->wdata.set_range(hid, entry->wdata.range);
> >  
> >  #ifdef CONFIG_LEDS_CLASS
> > -	/* register led subsystem - G27 only */
> > +	/* register led subsystem - G27/G29 only */
> >  	entry->wdata.led_state = 0;
> >  	for (j = 0; j < 5; j++)
> >  		entry->wdata.led[j] = NULL;
> >  
> > -	if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL) {
> > +	if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL ||
> > +			lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G29_WHEEL) {
> >  		struct led_classdev *led;
> >  		size_t name_sz;
> >  		char *name;
> 
> I have a logitech cordless mouse/keyboard combo.  The keyboard still works.
> 
> The following is part of my dmesg output on the previous commit (with the mouse working),
> 
> before:
> 
> [    1.566674] usb 4-3: New USB device found, idVendor=046d, idProduct=c517
> [    1.566779] usb 4-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
> [    1.566881] usb 4-3: Product: USB Receiver
> [    1.566982] usb 4-3: Manufacturer: Logitech
> [    1.573671] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.0/0003:046D:C517.0003/input/input14
> [    1.624510] logitech 0003:046D:C517.0003: input,hidraw0: USB HID v1.10 Keyboard [Logitech USB Receiver] on usb-0000:00:12.1-3/input0
> [    1.629313] tsc: Refined TSC clocksource calibration: 2511.094 MHz
> [    1.629407] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x243229b6f8a, max_idle_ns: 440795226168 ns
> [    1.631370] logitech 0003:046D:C517.0004: fixing up Logitech keyboard report descriptor
> [    1.632203] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.1/0003:046D:C517.0004/input/input15
> [    1.677588] random: nonblocking pool is initialized
> [    1.683359] logitech 0003:046D:C517.0004: input,hiddev0,hidraw1: USB HID v1.10 Mouse [Logitech USB Receiver] on usb-0000:00:12.1-3/input1
> 
> after:
> 
> [    1.577748] usb 4-3: New USB device found, idVendor=046d, idProduct=c517
> [    1.577859] usb 4-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
> [    1.577963] usb 4-3: Product: USB Receiver
> [    1.578064] usb 4-3: Manufacturer: Logitech
> [    1.584746] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.0/0003:046D:C517.0003/input/input14
> [    1.635596] logitech 0003:046D:C517.0003: input,hidraw0: USB HID v1.10 Keyboard [Logitech USB Receiver] on usb-0000:00:12.1-3/input0
> [    1.642389] tsc: Refined TSC clocksource calibration: 2511.093 MHz
> [    1.642507] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x24322913340, max_idle_ns: 440795255552 ns
> [    1.696567] random: nonblocking pool is initialized
> 
> 
> I can only guess that it is either now being misidentified (regression).
> ... or do I perhaps need to enable a different driver now???
> Happy to help if I can.
> 
> warmest regards,
> 
> Joshua Clayton
>ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* Re: [PATCH 2/2] HID: hid-logitech: Add support for G29
@ 2015-11-30 14:15       ` madcatxster
  0 siblings, 0 replies; 7+ messages in thread
From: madcatxster @ 2015-11-30 14:15 UTC (permalink / raw)
  To: stillcompiling
  Cc: linux-input, linux-kernel, jkosina, Edwin, elias.vds, simon

Hi all,

my completely off-the-bat guess would be that the combo uses multiple interfaces as well, the patch seems to ignore everything but iface 0. Can you comment out the 'if' that does this and give it a go?

Michal

On Mon Nov 30 14:03:51 2015 GMT+0100, Joshua Clayton wrote:
> Simon et al,
> My logitech cordless mouse is not detected in linux-next
> I have bisected the breakage to this patch,
>  commit 29fae1c85166ef525b8b6518e749295e0c9d1e20 in linux-next.
> 
> On Monday, November 02, 2015 07:56:52 AM Simon Wood wrote:
> > At present the G29 is mis-identified as a DFGT, this patch ensures
> > that the wheel is correctly detected and allows setting the LEDs and
> > turning range via the '/sys' interface.
> > 
> > This wheel can also emulate other types of Logitech wheels.
> > 
> > Signed-off-by: Simon Wood <simon@mungewell.org>
> > ---
> >  drivers/hid/hid-core.c  |  1 +
> >  drivers/hid/hid-lg.c    |  9 ++++++++
> >  drivers/hid/hid-lg4ff.c | 57 +++++++++++++++++++++++++++++++++++++++++++++----
> >  3 files changed, 63 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> > index 70a11ac..949d804 100644
> > --- a/drivers/hid/hid-core.c
> > +++ b/drivers/hid/hid-core.c
> > @@ -1896,6 +1896,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
> > +	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },
> >  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
> > diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
> > index 5332fb7..c20ac76 100644
> > --- a/drivers/hid/hid-lg.c
> > +++ b/drivers/hid/hid-lg.c
> > @@ -620,6 +620,7 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi,
> >  			usage->code == ABS_Y || usage->code == ABS_Z ||
> >  			usage->code == ABS_RZ)) {
> >  		switch (hdev->product) {
> > +		case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
> >  		case USB_DEVICE_ID_LOGITECH_WHEEL:
> >  		case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL:
> >  		case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
> > @@ -658,10 +659,18 @@ static int lg_event(struct hid_device *hdev, struct hid_field *field,
> >  
> >  static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
> >  {
> > +	struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
> > +	__u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
> >  	unsigned int connect_mask = HID_CONNECT_DEFAULT;
> >  	struct lg_drv_data *drv_data;
> >  	int ret;
> >  
> > +	/* Only work with the 1st interface (G29 presents multiple) */
> > +	if (iface_num != 0) {
> > +		dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num);
> > +		return -ENODEV;
> > +	}
> > +
> >  	drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL);
> >  	if (!drv_data) {
> >  		hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
> > diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
> > index b363d88..fbddcb3 100644
> > --- a/drivers/hid/hid-lg4ff.c
> > +++ b/drivers/hid/hid-lg4ff.c
> > @@ -45,7 +45,8 @@
> >  #define LG4FF_MODE_G25_IDX 3
> >  #define LG4FF_MODE_DFGT_IDX 4
> >  #define LG4FF_MODE_G27_IDX 5
> > -#define LG4FF_MODE_MAX_IDX 6
> > +#define LG4FF_MODE_G29_IDX 6
> > +#define LG4FF_MODE_MAX_IDX 7
> >  
> >  #define LG4FF_MODE_NATIVE BIT(LG4FF_MODE_NATIVE_IDX)
> >  #define LG4FF_MODE_DFEX BIT(LG4FF_MODE_DFEX_IDX)
> > @@ -53,6 +54,7 @@
> >  #define LG4FF_MODE_G25 BIT(LG4FF_MODE_G25_IDX)
> >  #define LG4FF_MODE_DFGT BIT(LG4FF_MODE_DFGT_IDX)
> >  #define LG4FF_MODE_G27 BIT(LG4FF_MODE_G27_IDX)
> > +#define LG4FF_MODE_G29 BIT(LG4FF_MODE_G29_IDX)
> >  
> >  #define LG4FF_DFEX_TAG "DF-EX"
> >  #define LG4FF_DFEX_NAME "Driving Force / Formula EX"
> > @@ -62,6 +64,8 @@
> >  #define LG4FF_G25_NAME "G25 Racing Wheel"
> >  #define LG4FF_G27_TAG "G27"
> >  #define LG4FF_G27_NAME "G27 Racing Wheel"
> > +#define LG4FF_G29_TAG "G29"
> > +#define LG4FF_G29_NAME "G29 Racing Wheel"
> >  #define LG4FF_DFGT_TAG "DFGT"
> >  #define LG4FF_DFGT_NAME "Driving Force GT"
> >  
> > @@ -140,6 +144,7 @@ static const struct lg4ff_wheel lg4ff_devices[] = {
> >  	{USB_DEVICE_ID_LOGITECH_G25_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
> >  	{USB_DEVICE_ID_LOGITECH_DFGT_WHEEL,  lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
> >  	{USB_DEVICE_ID_LOGITECH_G27_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
> > +	{USB_DEVICE_ID_LOGITECH_G29_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
> >  	{USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270, NULL},
> >  	{USB_DEVICE_ID_LOGITECH_WII_WHEEL,   lg4ff_wheel_effects, 40, 270, NULL}
> >  };
> > @@ -157,6 +162,9 @@ static const struct lg4ff_multimode_wheel lg4ff_multimode_wheels[] = {
> >  	{USB_DEVICE_ID_LOGITECH_G27_WHEEL,
> >  	 LG4FF_MODE_NATIVE | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
> >  	 LG4FF_G27_TAG, LG4FF_G27_NAME},
> > +	{USB_DEVICE_ID_LOGITECH_G29_WHEEL,
> > +	 LG4FF_MODE_NATIVE | LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
> > +	 LG4FF_G29_TAG, LG4FF_G29_NAME},
> >  };
> >  
> >  static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = {
> > @@ -165,7 +173,8 @@ static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = {
> >  	[LG4FF_MODE_DFP_IDX] = {USB_DEVICE_ID_LOGITECH_DFP_WHEEL, LG4FF_DFP_TAG, LG4FF_DFP_NAME},
> >  	[LG4FF_MODE_G25_IDX] = {USB_DEVICE_ID_LOGITECH_G25_WHEEL, LG4FF_G25_TAG, LG4FF_G25_NAME},
> >  	[LG4FF_MODE_DFGT_IDX] = {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, LG4FF_DFGT_TAG, LG4FF_DFGT_NAME},
> > -	[LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME}
> > +	[LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME},
> > +	[LG4FF_MODE_G29_IDX] = {USB_DEVICE_ID_LOGITECH_G29_WHEEL, LG4FF_G29_TAG, LG4FF_G29_NAME},
> >  };
> >  
> >  /* Multimode wheel identificators */
> > @@ -197,8 +206,24 @@ static const struct lg4ff_wheel_ident_info lg4ff_dfgt_ident_info = {
> >  	USB_DEVICE_ID_LOGITECH_DFGT_WHEEL
> >  };
> >  
> > +static const struct lg4ff_wheel_ident_info lg4ff_g29_ident_info = {
> > +	LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
> > +	0xfff8,
> > +	0x1350,
> > +	USB_DEVICE_ID_LOGITECH_G29_WHEEL
> > +};
> > +
> > +static const struct lg4ff_wheel_ident_info lg4ff_g29_ident_info2 = {
> > +	LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
> > +	0xff00,
> > +	0x8900,
> > +	USB_DEVICE_ID_LOGITECH_G29_WHEEL
> > +};
> > +
> >  /* Multimode wheel identification checklists */
> >  static const struct lg4ff_wheel_ident_info *lg4ff_main_checklist[] = {
> > +	&lg4ff_g29_ident_info,
> > +	&lg4ff_g29_ident_info2,
> >  	&lg4ff_dfgt_ident_info,
> >  	&lg4ff_g27_ident_info,
> >  	&lg4ff_g25_ident_info,
> > @@ -237,6 +262,12 @@ static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g27 = {
> >  	 0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00}	/* Switch mode to G27 with detach */
> >  };
> >  
> > +static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g29 = {
> > +	2,
> > +	{0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,	/* Revert mode upon USB reset */
> > +	 0xf8, 0x09, 0x05, 0x01, 0x01, 0x00, 0x00}	/* Switch mode to G29 with detach */
> > +};
> > +
> >  /* EXT_CMD1 - Understood by DFP, G25, G27 and DFGT */
> >  static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext01_dfp = {
> >  	1,
> > @@ -650,6 +681,23 @@ static const struct lg4ff_compat_mode_switch *lg4ff_get_mode_switch_command(cons
> >  			return NULL;
> >  		}
> >  		break;
> > +	case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
> > +		switch (target_product_id) {
> > +		case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
> > +			return &lg4ff_mode_switch_ext09_dfp;
> > +		case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
> > +			return &lg4ff_mode_switch_ext09_dfgt;
> > +		case USB_DEVICE_ID_LOGITECH_G25_WHEEL:
> > +			return &lg4ff_mode_switch_ext09_g25;
> > +		case USB_DEVICE_ID_LOGITECH_G27_WHEEL:
> > +			return &lg4ff_mode_switch_ext09_g27;
> > +		case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
> > +			return &lg4ff_mode_switch_ext09_g29;
> > +		/* G29 can only be switched to DF-EX, DFP, DFGT, G25, G27 or its native mode */
> > +		default:
> > +			return NULL;
> > +		}
> > +		break;
> >  	case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
> >  		switch (target_product_id) {
> >  		case USB_DEVICE_ID_LOGITECH_WHEEL:
> > @@ -1232,12 +1280,13 @@ int lg4ff_init(struct hid_device *hid)
> >  		entry->wdata.set_range(hid, entry->wdata.range);
> >  
> >  #ifdef CONFIG_LEDS_CLASS
> > -	/* register led subsystem - G27 only */
> > +	/* register led subsystem - G27/G29 only */
> >  	entry->wdata.led_state = 0;
> >  	for (j = 0; j < 5; j++)
> >  		entry->wdata.led[j] = NULL;
> >  
> > -	if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL) {
> > +	if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL ||
> > +			lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G29_WHEEL) {
> >  		struct led_classdev *led;
> >  		size_t name_sz;
> >  		char *name;
> 
> I have a logitech cordless mouse/keyboard combo.  The keyboard still works.
> 
> The following is part of my dmesg output on the previous commit (with the mouse working),
> 
> before:
> 
> [    1.566674] usb 4-3: New USB device found, idVendor=046d, idProduct=c517
> [    1.566779] usb 4-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
> [    1.566881] usb 4-3: Product: USB Receiver
> [    1.566982] usb 4-3: Manufacturer: Logitech
> [    1.573671] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.0/0003:046D:C517.0003/input/input14
> [    1.624510] logitech 0003:046D:C517.0003: input,hidraw0: USB HID v1.10 Keyboard [Logitech USB Receiver] on usb-0000:00:12.1-3/input0
> [    1.629313] tsc: Refined TSC clocksource calibration: 2511.094 MHz
> [    1.629407] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x243229b6f8a, max_idle_ns: 440795226168 ns
> [    1.631370] logitech 0003:046D:C517.0004: fixing up Logitech keyboard report descriptor
> [    1.632203] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.1/0003:046D:C517.0004/input/input15
> [    1.677588] random: nonblocking pool is initialized
> [    1.683359] logitech 0003:046D:C517.0004: input,hiddev0,hidraw1: USB HID v1.10 Mouse [Logitech USB Receiver] on usb-0000:00:12.1-3/input1
> 
> after:
> 
> [    1.577748] usb 4-3: New USB device found, idVendor=046d, idProduct=c517
> [    1.577859] usb 4-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
> [    1.577963] usb 4-3: Product: USB Receiver
> [    1.578064] usb 4-3: Manufacturer: Logitech
> [    1.584746] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.0/0003:046D:C517.0003/input/input14
> [    1.635596] logitech 0003:046D:C517.0003: input,hidraw0: USB HID v1.10 Keyboard [Logitech USB Receiver] on usb-0000:00:12.1-3/input0
> [    1.642389] tsc: Refined TSC clocksource calibration: 2511.093 MHz
> [    1.642507] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x24322913340, max_idle_ns: 440795255552 ns
> [    1.696567] random: nonblocking pool is initialized
> 
> 
> I can only guess that it is either now being misidentified (regression).
> ... or do I perhaps need to enable a different driver now???
> Happy to help if I can.
> 
> warmest regards,
> 
> Joshua Clayton
>

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

* Re: [PATCH 2/2] HID: hid-logitech: Add support for G29
  2015-11-30 14:15       ` madcatxster
  (?)
@ 2015-11-30 20:54       ` Benjamin Tissoires
  -1 siblings, 0 replies; 7+ messages in thread
From: Benjamin Tissoires @ 2015-11-30 20:54 UTC (permalink / raw)
  To: Michal Malý
  Cc: stillcompiling, linux-input, linux-kernel, Jiri Kosina, Edwin,
	Elias Vanderstuyft, Simon Wood

On Mon, Nov 30, 2015 at 3:15 PM,  <madcatxster@devoid-pointer.net> wrote:
> Hi all,
>
> my completely off-the-bat guess would be that the combo uses multiple interfaces as well, the patch seems to ignore everything but iface 0. Can you comment out the 'if' that does this and give it a go?

Just a FYI: https://bugzilla.kernel.org/show_bug.cgi?id=108121

I just been reported that the patch I attached here fixed the issue.
I'll send it to the list tomorrow unless Jiri beats me at picking it
up before :)

Cheers,
Benjamin

>
> Michal
>
> On Mon Nov 30 14:03:51 2015 GMT+0100, Joshua Clayton wrote:
>> Simon et al,
>> My logitech cordless mouse is not detected in linux-next
>> I have bisected the breakage to this patch,
>>  commit 29fae1c85166ef525b8b6518e749295e0c9d1e20 in linux-next.
>>
>> On Monday, November 02, 2015 07:56:52 AM Simon Wood wrote:
>> > At present the G29 is mis-identified as a DFGT, this patch ensures
>> > that the wheel is correctly detected and allows setting the LEDs and
>> > turning range via the '/sys' interface.
>> >
>> > This wheel can also emulate other types of Logitech wheels.
>> >
>> > Signed-off-by: Simon Wood <simon@mungewell.org>
>> > ---
>> >  drivers/hid/hid-core.c  |  1 +
>> >  drivers/hid/hid-lg.c    |  9 ++++++++
>> >  drivers/hid/hid-lg4ff.c | 57 +++++++++++++++++++++++++++++++++++++++++++++----
>> >  3 files changed, 63 insertions(+), 4 deletions(-)
>> >
>> > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
>> > index 70a11ac..949d804 100644
>> > --- a/drivers/hid/hid-core.c
>> > +++ b/drivers/hid/hid-core.c
>> > @@ -1896,6 +1896,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
>> >     { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
>> >     { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
>> >     { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
>> > +   { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) },
>> >     { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
>> >     { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },
>> >     { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
>> > diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
>> > index 5332fb7..c20ac76 100644
>> > --- a/drivers/hid/hid-lg.c
>> > +++ b/drivers/hid/hid-lg.c
>> > @@ -620,6 +620,7 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi,
>> >                     usage->code == ABS_Y || usage->code == ABS_Z ||
>> >                     usage->code == ABS_RZ)) {
>> >             switch (hdev->product) {
>> > +           case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
>> >             case USB_DEVICE_ID_LOGITECH_WHEEL:
>> >             case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL:
>> >             case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
>> > @@ -658,10 +659,18 @@ static int lg_event(struct hid_device *hdev, struct hid_field *field,
>> >
>> >  static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
>> >  {
>> > +   struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
>> > +   __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
>> >     unsigned int connect_mask = HID_CONNECT_DEFAULT;
>> >     struct lg_drv_data *drv_data;
>> >     int ret;
>> >
>> > +   /* Only work with the 1st interface (G29 presents multiple) */
>> > +   if (iface_num != 0) {
>> > +           dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num);
>> > +           return -ENODEV;
>> > +   }
>> > +
>> >     drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL);
>> >     if (!drv_data) {
>> >             hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
>> > diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
>> > index b363d88..fbddcb3 100644
>> > --- a/drivers/hid/hid-lg4ff.c
>> > +++ b/drivers/hid/hid-lg4ff.c
>> > @@ -45,7 +45,8 @@
>> >  #define LG4FF_MODE_G25_IDX 3
>> >  #define LG4FF_MODE_DFGT_IDX 4
>> >  #define LG4FF_MODE_G27_IDX 5
>> > -#define LG4FF_MODE_MAX_IDX 6
>> > +#define LG4FF_MODE_G29_IDX 6
>> > +#define LG4FF_MODE_MAX_IDX 7
>> >
>> >  #define LG4FF_MODE_NATIVE BIT(LG4FF_MODE_NATIVE_IDX)
>> >  #define LG4FF_MODE_DFEX BIT(LG4FF_MODE_DFEX_IDX)
>> > @@ -53,6 +54,7 @@
>> >  #define LG4FF_MODE_G25 BIT(LG4FF_MODE_G25_IDX)
>> >  #define LG4FF_MODE_DFGT BIT(LG4FF_MODE_DFGT_IDX)
>> >  #define LG4FF_MODE_G27 BIT(LG4FF_MODE_G27_IDX)
>> > +#define LG4FF_MODE_G29 BIT(LG4FF_MODE_G29_IDX)
>> >
>> >  #define LG4FF_DFEX_TAG "DF-EX"
>> >  #define LG4FF_DFEX_NAME "Driving Force / Formula EX"
>> > @@ -62,6 +64,8 @@
>> >  #define LG4FF_G25_NAME "G25 Racing Wheel"
>> >  #define LG4FF_G27_TAG "G27"
>> >  #define LG4FF_G27_NAME "G27 Racing Wheel"
>> > +#define LG4FF_G29_TAG "G29"
>> > +#define LG4FF_G29_NAME "G29 Racing Wheel"
>> >  #define LG4FF_DFGT_TAG "DFGT"
>> >  #define LG4FF_DFGT_NAME "Driving Force GT"
>> >
>> > @@ -140,6 +144,7 @@ static const struct lg4ff_wheel lg4ff_devices[] = {
>> >     {USB_DEVICE_ID_LOGITECH_G25_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
>> >     {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL,  lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
>> >     {USB_DEVICE_ID_LOGITECH_G27_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
>> > +   {USB_DEVICE_ID_LOGITECH_G29_WHEEL,   lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25},
>> >     {USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270, NULL},
>> >     {USB_DEVICE_ID_LOGITECH_WII_WHEEL,   lg4ff_wheel_effects, 40, 270, NULL}
>> >  };
>> > @@ -157,6 +162,9 @@ static const struct lg4ff_multimode_wheel lg4ff_multimode_wheels[] = {
>> >     {USB_DEVICE_ID_LOGITECH_G27_WHEEL,
>> >      LG4FF_MODE_NATIVE | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
>> >      LG4FF_G27_TAG, LG4FF_G27_NAME},
>> > +   {USB_DEVICE_ID_LOGITECH_G29_WHEEL,
>> > +    LG4FF_MODE_NATIVE | LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
>> > +    LG4FF_G29_TAG, LG4FF_G29_NAME},
>> >  };
>> >
>> >  static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = {
>> > @@ -165,7 +173,8 @@ static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = {
>> >     [LG4FF_MODE_DFP_IDX] = {USB_DEVICE_ID_LOGITECH_DFP_WHEEL, LG4FF_DFP_TAG, LG4FF_DFP_NAME},
>> >     [LG4FF_MODE_G25_IDX] = {USB_DEVICE_ID_LOGITECH_G25_WHEEL, LG4FF_G25_TAG, LG4FF_G25_NAME},
>> >     [LG4FF_MODE_DFGT_IDX] = {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, LG4FF_DFGT_TAG, LG4FF_DFGT_NAME},
>> > -   [LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME}
>> > +   [LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME},
>> > +   [LG4FF_MODE_G29_IDX] = {USB_DEVICE_ID_LOGITECH_G29_WHEEL, LG4FF_G29_TAG, LG4FF_G29_NAME},
>> >  };
>> >
>> >  /* Multimode wheel identificators */
>> > @@ -197,8 +206,24 @@ static const struct lg4ff_wheel_ident_info lg4ff_dfgt_ident_info = {
>> >     USB_DEVICE_ID_LOGITECH_DFGT_WHEEL
>> >  };
>> >
>> > +static const struct lg4ff_wheel_ident_info lg4ff_g29_ident_info = {
>> > +   LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
>> > +   0xfff8,
>> > +   0x1350,
>> > +   USB_DEVICE_ID_LOGITECH_G29_WHEEL
>> > +};
>> > +
>> > +static const struct lg4ff_wheel_ident_info lg4ff_g29_ident_info2 = {
>> > +   LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX,
>> > +   0xff00,
>> > +   0x8900,
>> > +   USB_DEVICE_ID_LOGITECH_G29_WHEEL
>> > +};
>> > +
>> >  /* Multimode wheel identification checklists */
>> >  static const struct lg4ff_wheel_ident_info *lg4ff_main_checklist[] = {
>> > +   &lg4ff_g29_ident_info,
>> > +   &lg4ff_g29_ident_info2,
>> >     &lg4ff_dfgt_ident_info,
>> >     &lg4ff_g27_ident_info,
>> >     &lg4ff_g25_ident_info,
>> > @@ -237,6 +262,12 @@ static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g27 = {
>> >      0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00}      /* Switch mode to G27 with detach */
>> >  };
>> >
>> > +static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g29 = {
>> > +   2,
>> > +   {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,      /* Revert mode upon USB reset */
>> > +    0xf8, 0x09, 0x05, 0x01, 0x01, 0x00, 0x00}      /* Switch mode to G29 with detach */
>> > +};
>> > +
>> >  /* EXT_CMD1 - Understood by DFP, G25, G27 and DFGT */
>> >  static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext01_dfp = {
>> >     1,
>> > @@ -650,6 +681,23 @@ static const struct lg4ff_compat_mode_switch *lg4ff_get_mode_switch_command(cons
>> >                     return NULL;
>> >             }
>> >             break;
>> > +   case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
>> > +           switch (target_product_id) {
>> > +           case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
>> > +                   return &lg4ff_mode_switch_ext09_dfp;
>> > +           case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
>> > +                   return &lg4ff_mode_switch_ext09_dfgt;
>> > +           case USB_DEVICE_ID_LOGITECH_G25_WHEEL:
>> > +                   return &lg4ff_mode_switch_ext09_g25;
>> > +           case USB_DEVICE_ID_LOGITECH_G27_WHEEL:
>> > +                   return &lg4ff_mode_switch_ext09_g27;
>> > +           case USB_DEVICE_ID_LOGITECH_G29_WHEEL:
>> > +                   return &lg4ff_mode_switch_ext09_g29;
>> > +           /* G29 can only be switched to DF-EX, DFP, DFGT, G25, G27 or its native mode */
>> > +           default:
>> > +                   return NULL;
>> > +           }
>> > +           break;
>> >     case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
>> >             switch (target_product_id) {
>> >             case USB_DEVICE_ID_LOGITECH_WHEEL:
>> > @@ -1232,12 +1280,13 @@ int lg4ff_init(struct hid_device *hid)
>> >             entry->wdata.set_range(hid, entry->wdata.range);
>> >
>> >  #ifdef CONFIG_LEDS_CLASS
>> > -   /* register led subsystem - G27 only */
>> > +   /* register led subsystem - G27/G29 only */
>> >     entry->wdata.led_state = 0;
>> >     for (j = 0; j < 5; j++)
>> >             entry->wdata.led[j] = NULL;
>> >
>> > -   if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL) {
>> > +   if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL ||
>> > +                   lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G29_WHEEL) {
>> >             struct led_classdev *led;
>> >             size_t name_sz;
>> >             char *name;
>>
>> I have a logitech cordless mouse/keyboard combo.  The keyboard still works.
>>
>> The following is part of my dmesg output on the previous commit (with the mouse working),
>>
>> before:
>>
>> [    1.566674] usb 4-3: New USB device found, idVendor=046d, idProduct=c517
>> [    1.566779] usb 4-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
>> [    1.566881] usb 4-3: Product: USB Receiver
>> [    1.566982] usb 4-3: Manufacturer: Logitech
>> [    1.573671] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.0/0003:046D:C517.0003/input/input14
>> [    1.624510] logitech 0003:046D:C517.0003: input,hidraw0: USB HID v1.10 Keyboard [Logitech USB Receiver] on usb-0000:00:12.1-3/input0
>> [    1.629313] tsc: Refined TSC clocksource calibration: 2511.094 MHz
>> [    1.629407] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x243229b6f8a, max_idle_ns: 440795226168 ns
>> [    1.631370] logitech 0003:046D:C517.0004: fixing up Logitech keyboard report descriptor
>> [    1.632203] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.1/0003:046D:C517.0004/input/input15
>> [    1.677588] random: nonblocking pool is initialized
>> [    1.683359] logitech 0003:046D:C517.0004: input,hiddev0,hidraw1: USB HID v1.10 Mouse [Logitech USB Receiver] on usb-0000:00:12.1-3/input1
>>
>> after:
>>
>> [    1.577748] usb 4-3: New USB device found, idVendor=046d, idProduct=c517
>> [    1.577859] usb 4-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
>> [    1.577963] usb 4-3: Product: USB Receiver
>> [    1.578064] usb 4-3: Manufacturer: Logitech
>> [    1.584746] input: Logitech USB Receiver as /devices/pci0000:00/0000:00:12.1/usb4/4-3/4-3:1.0/0003:046D:C517.0003/input/input14
>> [    1.635596] logitech 0003:046D:C517.0003: input,hidraw0: USB HID v1.10 Keyboard [Logitech USB Receiver] on usb-0000:00:12.1-3/input0
>> [    1.642389] tsc: Refined TSC clocksource calibration: 2511.093 MHz
>> [    1.642507] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x24322913340, max_idle_ns: 440795255552 ns
>> [    1.696567] random: nonblocking pool is initialized
>>
>>
>> I can only guess that it is either now being misidentified (regression).
>> ... or do I perhaps need to enable a different driver now???
>> Happy to help if I can.
>>
>> warmest regards,
>>
>> Joshua Clayton
>>

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

end of thread, other threads:[~2015-11-30 20:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-02 14:56 [PATCH 1/2] HID: hid-logitech: Simplify wheel detection scheme Simon Wood
2015-11-02 14:56 ` [PATCH 2/2] HID: hid-logitech: Add support for G29 Simon Wood
2015-11-30 13:03   ` Joshua Clayton
2015-11-30 14:15     ` madcatxster
2015-11-30 14:15       ` madcatxster
2015-11-30 20:54       ` Benjamin Tissoires
2015-11-06 20:18 ` [PATCH 1/2] HID: hid-logitech: Simplify wheel detection scheme Jiri Kosina

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.