34
34
#include <linux/device.h>
35
35
#include <linux/kernel.h>
36
36
#include <linux/hid.h>
37
+ #include <linux/idr.h>
37
38
#include <linux/input.h>
38
39
#include <linux/jiffies.h>
39
40
#include <linux/leds.h>
@@ -569,6 +570,7 @@ static const enum led_brightness joycon_player_led_patterns[JC_NUM_LED_PATTERNS]
569
570
struct joycon_ctlr {
570
571
struct hid_device * hdev ;
571
572
struct input_dev * input ;
573
+ u32 player_id ;
572
574
struct led_classdev leds [JC_NUM_LEDS ]; /* player leds */
573
575
struct led_classdev home_led ;
574
576
enum joycon_ctlr_state ctlr_state ;
@@ -692,15 +694,6 @@ static inline bool joycon_device_is_n64con(struct joycon_ctlr *ctlr)
692
694
return ctlr -> hdev -> product == USB_DEVICE_ID_NINTENDO_N64CON ;
693
695
}
694
696
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
-
704
697
/*
705
698
* Controller type helpers
706
699
*
@@ -2261,7 +2254,8 @@ static int joycon_home_led_brightness_set(struct led_classdev *led,
2261
2254
return ret ;
2262
2255
}
2263
2256
2264
- static DEFINE_SPINLOCK (joycon_input_num_spinlock );
2257
+ static DEFINE_IDA (nintendo_player_id_allocator );
2258
+
2265
2259
static int joycon_leds_create (struct joycon_ctlr * ctlr )
2266
2260
{
2267
2261
struct hid_device * hdev = ctlr -> hdev ;
@@ -2272,20 +2266,19 @@ static int joycon_leds_create(struct joycon_ctlr *ctlr)
2272
2266
char * name ;
2273
2267
int ret ;
2274
2268
int i ;
2275
- unsigned long flags ;
2276
2269
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 );
2287
2270
2288
2271
/* 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
+
2289
2282
for (i = 0 ; i < JC_NUM_LEDS ; i ++ ) {
2290
2283
name = devm_kasprintf (dev , GFP_KERNEL , "%s:%s:%s" ,
2291
2284
d_name ,
@@ -2501,8 +2494,11 @@ static int joycon_init(struct hid_device *hdev)
2501
2494
/* set baudrate for improved latency */
2502
2495
ret = joycon_send_usb (ctlr , JC_USB_CMD_BAUDRATE_3M , HZ );
2503
2496
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 );
2506
2502
}
2507
2503
/* handshake */
2508
2504
ret = joycon_send_usb (ctlr , JC_USB_CMD_HANDSHAKE , HZ );
@@ -2767,6 +2763,7 @@ static void nintendo_hid_remove(struct hid_device *hdev)
2767
2763
spin_unlock_irqrestore (& ctlr -> lock , flags );
2768
2764
2769
2765
destroy_workqueue (ctlr -> rumble_queue );
2766
+ ida_free (& nintendo_player_id_allocator , ctlr -> player_id );
2770
2767
2771
2768
hid_hw_close (hdev );
2772
2769
hid_hw_stop (hdev );
@@ -2824,7 +2821,19 @@ static struct hid_driver nintendo_hid_driver = {
2824
2821
.resume = nintendo_hid_resume ,
2825
2822
#endif
2826
2823
};
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 );
2828
2837
2829
2838
MODULE_LICENSE ("GPL" );
2830
2839
MODULE_AUTHOR (
"Ryan McClelland <[email protected] >" );
0 commit comments