3434#include <linux/device.h>
3535#include <linux/kernel.h>
3636#include <linux/hid.h>
37+ #include <linux/idr.h>
3738#include <linux/input.h>
3839#include <linux/jiffies.h>
3940#include <linux/leds.h>
@@ -569,6 +570,7 @@ static const enum led_brightness joycon_player_led_patterns[JC_NUM_LED_PATTERNS]
569570struct joycon_ctlr {
570571 struct hid_device * hdev ;
571572 struct input_dev * input ;
573+ u32 player_id ;
572574 struct led_classdev leds [JC_NUM_LEDS ]; /* player leds */
573575 struct led_classdev home_led ;
574576 enum joycon_ctlr_state ctlr_state ;
@@ -692,15 +694,6 @@ static inline bool joycon_device_is_n64con(struct joycon_ctlr *ctlr)
692694 return ctlr -> hdev -> product == USB_DEVICE_ID_NINTENDO_N64CON ;
693695}
694696
695- static inline bool joycon_device_has_usb (struct joycon_ctlr * ctlr )
696- {
697- return joycon_device_is_procon (ctlr ) ||
698- joycon_device_is_chrggrip (ctlr ) ||
699- joycon_device_is_snescon (ctlr ) ||
700- joycon_device_is_gencon (ctlr ) ||
701- joycon_device_is_n64con (ctlr );
702- }
703-
704697/*
705698 * Controller type helpers
706699 *
@@ -2261,7 +2254,8 @@ static int joycon_home_led_brightness_set(struct led_classdev *led,
22612254 return ret ;
22622255}
22632256
2264- static DEFINE_SPINLOCK (joycon_input_num_spinlock );
2257+ static DEFINE_IDA (nintendo_player_id_allocator );
2258+
22652259static int joycon_leds_create (struct joycon_ctlr * ctlr )
22662260{
22672261 struct hid_device * hdev = ctlr -> hdev ;
@@ -2272,20 +2266,19 @@ static int joycon_leds_create(struct joycon_ctlr *ctlr)
22722266 char * name ;
22732267 int ret ;
22742268 int i ;
2275- unsigned long flags ;
22762269 int player_led_pattern ;
2277- static int input_num ;
2278-
2279- /*
2280- * Set the player leds based on controller number
2281- * Because there is no standard concept of "player number", the pattern
2282- * number will simply increase by 1 every time a controller is connected.
2283- */
2284- spin_lock_irqsave (& joycon_input_num_spinlock , flags );
2285- player_led_pattern = input_num ++ % JC_NUM_LED_PATTERNS ;
2286- spin_unlock_irqrestore (& joycon_input_num_spinlock , flags );
22872270
22882271 /* configure the player LEDs */
2272+ ctlr -> player_id = U32_MAX ;
2273+ ret = ida_alloc (& nintendo_player_id_allocator , GFP_KERNEL );
2274+ if (ret < 0 ) {
2275+ hid_warn (hdev , "Failed to allocate player ID, skipping; ret=%d\n" , ret );
2276+ goto home_led ;
2277+ }
2278+ ctlr -> player_id = ret ;
2279+ player_led_pattern = ret % JC_NUM_LED_PATTERNS ;
2280+ hid_info (ctlr -> hdev , "assigned player %d led pattern" , player_led_pattern + 1 );
2281+
22892282 for (i = 0 ; i < JC_NUM_LEDS ; i ++ ) {
22902283 name = devm_kasprintf (dev , GFP_KERNEL , "%s:%s:%s" ,
22912284 d_name ,
@@ -2501,8 +2494,11 @@ static int joycon_init(struct hid_device *hdev)
25012494 /* set baudrate for improved latency */
25022495 ret = joycon_send_usb (ctlr , JC_USB_CMD_BAUDRATE_3M , HZ );
25032496 if (ret ) {
2504- hid_err (hdev , "Failed to set baudrate; ret=%d\n" , ret );
2505- goto out_unlock ;
2497+ /*
2498+ * We can function with the default baudrate.
2499+ * Provide a warning, and continue on.
2500+ */
2501+ hid_warn (hdev , "Failed to set baudrate (ret=%d), continuing anyway\n" , ret );
25062502 }
25072503 /* handshake */
25082504 ret = joycon_send_usb (ctlr , JC_USB_CMD_HANDSHAKE , HZ );
@@ -2767,6 +2763,7 @@ static void nintendo_hid_remove(struct hid_device *hdev)
27672763 spin_unlock_irqrestore (& ctlr -> lock , flags );
27682764
27692765 destroy_workqueue (ctlr -> rumble_queue );
2766+ ida_free (& nintendo_player_id_allocator , ctlr -> player_id );
27702767
27712768 hid_hw_close (hdev );
27722769 hid_hw_stop (hdev );
@@ -2824,7 +2821,19 @@ static struct hid_driver nintendo_hid_driver = {
28242821 .resume = nintendo_hid_resume ,
28252822#endif
28262823};
2827- module_hid_driver (nintendo_hid_driver );
2824+ static int __init nintendo_init (void )
2825+ {
2826+ return hid_register_driver (& nintendo_hid_driver );
2827+ }
2828+
2829+ static void __exit nintendo_exit (void )
2830+ {
2831+ hid_unregister_driver (& nintendo_hid_driver );
2832+ ida_destroy (& nintendo_player_id_allocator );
2833+ }
2834+
2835+ module_init (nintendo_init );
2836+ module_exit (nintendo_exit );
28282837
28292838MODULE_LICENSE ("GPL" );
28302839MODULE_AUTHOR ("Ryan McClelland <rymcclel@gmail.com>" );
0 commit comments