From 5307de63d71d0b2303a8c645493a36021bedd800 Mon Sep 17 00:00:00 2001 From: Martino Fontana Date: Mon, 18 Mar 2024 11:36:28 +0100 Subject: HID: nintendo: use ida for LED player id Previously, the leds pattern would just increment with every controller connected. This wouldn't take into consideration when controllers are disconnected. The same controller could be connected and disconnected with the pattern increasing player count each time. This patch changes it by using an ID allocator in order to assign the player id, the same way hid-playstation does. Signed-off-by: Martino Fontana Signed-off-by: Ryan McClelland Signed-off-by: Jiri Kosina --- drivers/hid/hid-nintendo.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c index ab5953fc2436..ce88ac7617fd 100644 --- a/drivers/hid/hid-nintendo.c +++ b/drivers/hid/hid-nintendo.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -569,6 +570,7 @@ static const enum led_brightness joycon_player_led_patterns[JC_NUM_LED_PATTERNS] struct joycon_ctlr { struct hid_device *hdev; struct input_dev *input; + u32 player_id; struct led_classdev leds[JC_NUM_LEDS]; /* player leds */ struct led_classdev home_led; enum joycon_ctlr_state ctlr_state; @@ -2261,7 +2263,8 @@ static int joycon_home_led_brightness_set(struct led_classdev *led, return ret; } -static DEFINE_SPINLOCK(joycon_input_num_spinlock); +static DEFINE_IDA(nintendo_player_id_allocator); + static int joycon_leds_create(struct joycon_ctlr *ctlr) { struct hid_device *hdev = ctlr->hdev; @@ -2272,20 +2275,19 @@ static int joycon_leds_create(struct joycon_ctlr *ctlr) char *name; int ret; int i; - unsigned long flags; int player_led_pattern; - static int input_num; - - /* - * Set the player leds based on controller number - * Because there is no standard concept of "player number", the pattern - * number will simply increase by 1 every time a controller is connected. - */ - spin_lock_irqsave(&joycon_input_num_spinlock, flags); - player_led_pattern = input_num++ % JC_NUM_LED_PATTERNS; - spin_unlock_irqrestore(&joycon_input_num_spinlock, flags); /* configure the player LEDs */ + ctlr->player_id = U32_MAX; + ret = ida_alloc(&nintendo_player_id_allocator, GFP_KERNEL); + if (ret < 0) { + hid_warn(hdev, "Failed to allocate player ID, skipping; ret=%d\n", ret); + goto home_led; + } + ctlr->player_id = ret; + player_led_pattern = ret % JC_NUM_LED_PATTERNS; + hid_info(ctlr->hdev, "assigned player %d led pattern", player_led_pattern + 1); + for (i = 0; i < JC_NUM_LEDS; i++) { name = devm_kasprintf(dev, GFP_KERNEL, "%s:%s:%s", d_name, @@ -2767,6 +2769,7 @@ static void nintendo_hid_remove(struct hid_device *hdev) spin_unlock_irqrestore(&ctlr->lock, flags); destroy_workqueue(ctlr->rumble_queue); + ida_free(&nintendo_player_id_allocator, ctlr->player_id); hid_hw_close(hdev); hid_hw_stop(hdev); @@ -2824,7 +2827,19 @@ static struct hid_driver nintendo_hid_driver = { .resume = nintendo_hid_resume, #endif }; -module_hid_driver(nintendo_hid_driver); +static int __init nintendo_init(void) +{ + return hid_register_driver(&nintendo_hid_driver); +} + +static void __exit nintendo_exit(void) +{ + hid_unregister_driver(&nintendo_hid_driver); + ida_destroy(&nintendo_player_id_allocator); +} + +module_init(nintendo_init); +module_exit(nintendo_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ryan McClelland "); -- cgit v1.2.3 From 28ba6011f5dfd337e61e9c5618824115c63be66a Mon Sep 17 00:00:00 2001 From: Max Staudt Date: Sat, 16 Mar 2024 01:57:29 +0900 Subject: HID: nintendo: Don't fail on setting baud rate Some third-party controllers can't change the baud rate. We can still use the gamepad as-is, so let's do that. Signed-off-by: Max Staudt Signed-off-by: Jiri Kosina --- drivers/hid/hid-nintendo.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c index ce88ac7617fd..e311b092e758 100644 --- a/drivers/hid/hid-nintendo.c +++ b/drivers/hid/hid-nintendo.c @@ -2503,8 +2503,11 @@ static int joycon_init(struct hid_device *hdev) /* set baudrate for improved latency */ ret = joycon_send_usb(ctlr, JC_USB_CMD_BAUDRATE_3M, HZ); if (ret) { - hid_err(hdev, "Failed to set baudrate; ret=%d\n", ret); - goto out_unlock; + /* + * We can function with the default baudrate. + * Provide a warning, and continue on. + */ + hid_warn(hdev, "Failed to set baudrate (ret=%d), continuing anyway\n", ret); } /* handshake */ ret = joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE, HZ); -- cgit v1.2.3 From f6e0f53a48809184c6d79177d1435fbff6b672c0 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Sun, 7 Apr 2024 10:11:00 +0800 Subject: HID: nintendo: Remove unused function The function are defined in the hid-nintendo.c file, but not called elsewhere, so delete the unused function. drivers/hid/hid-nintendo.c:697:20: warning: unused function 'joycon_device_has_usb'. Reported-by: Abaci Robot Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=8704 Signed-off-by: Jiapeng Chong Signed-off-by: Jiri Kosina --- drivers/hid/hid-nintendo.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c index e311b092e758..b0d6c6db522d 100644 --- a/drivers/hid/hid-nintendo.c +++ b/drivers/hid/hid-nintendo.c @@ -694,15 +694,6 @@ static inline bool joycon_device_is_n64con(struct joycon_ctlr *ctlr) return ctlr->hdev->product == USB_DEVICE_ID_NINTENDO_N64CON; } -static inline bool joycon_device_has_usb(struct joycon_ctlr *ctlr) -{ - return joycon_device_is_procon(ctlr) || - joycon_device_is_chrggrip(ctlr) || - joycon_device_is_snescon(ctlr) || - joycon_device_is_gencon(ctlr) || - joycon_device_is_n64con(ctlr); -} - /* * Controller type helpers * -- cgit v1.2.3