@@ -2088,7 +2088,9 @@ static int joycon_read_info(struct joycon_ctlr *ctlr)
20882088 struct joycon_input_report * report ;
20892089
20902090 req .subcmd_id = JC_SUBCMD_REQ_DEV_INFO ;
2091+ mutex_lock (& ctlr -> output_mutex );
20912092 ret = joycon_send_subcmd (ctlr , & req , 0 , HZ );
2093+ mutex_unlock (& ctlr -> output_mutex );
20922094 if (ret ) {
20932095 hid_err (ctlr -> hdev , "Failed to get joycon info; ret=%d\n" , ret );
20942096 return ret ;
@@ -2117,6 +2119,85 @@ static int joycon_read_info(struct joycon_ctlr *ctlr)
21172119 return 0 ;
21182120}
21192121
2122+ static int joycon_init (struct hid_device * hdev )
2123+ {
2124+ struct joycon_ctlr * ctlr = hid_get_drvdata (hdev );
2125+ int ret = 0 ;
2126+
2127+ mutex_lock (& ctlr -> output_mutex );
2128+ /* if handshake command fails, assume ble pro controller */
2129+ if ((jc_type_is_procon (ctlr ) || jc_type_is_chrggrip (ctlr )) &&
2130+ !joycon_send_usb (ctlr , JC_USB_CMD_HANDSHAKE , HZ )) {
2131+ hid_dbg (hdev , "detected USB controller\n" );
2132+ /* set baudrate for improved latency */
2133+ ret = joycon_send_usb (ctlr , JC_USB_CMD_BAUDRATE_3M , HZ );
2134+ if (ret ) {
2135+ hid_err (hdev , "Failed to set baudrate; ret=%d\n" , ret );
2136+ goto out_unlock ;
2137+ }
2138+ /* handshake */
2139+ ret = joycon_send_usb (ctlr , JC_USB_CMD_HANDSHAKE , HZ );
2140+ if (ret ) {
2141+ hid_err (hdev , "Failed handshake; ret=%d\n" , ret );
2142+ goto out_unlock ;
2143+ }
2144+ /*
2145+ * Set no timeout (to keep controller in USB mode).
2146+ * This doesn't send a response, so ignore the timeout.
2147+ */
2148+ joycon_send_usb (ctlr , JC_USB_CMD_NO_TIMEOUT , HZ /10 );
2149+ } else if (jc_type_is_chrggrip (ctlr )) {
2150+ hid_err (hdev , "Failed charging grip handshake\n" );
2151+ ret = - ETIMEDOUT ;
2152+ goto out_unlock ;
2153+ }
2154+
2155+ /* get controller calibration data, and parse it */
2156+ ret = joycon_request_calibration (ctlr );
2157+ if (ret ) {
2158+ /*
2159+ * We can function with default calibration, but it may be
2160+ * inaccurate. Provide a warning, and continue on.
2161+ */
2162+ hid_warn (hdev , "Analog stick positions may be inaccurate\n" );
2163+ }
2164+
2165+ /* get IMU calibration data, and parse it */
2166+ ret = joycon_request_imu_calibration (ctlr );
2167+ if (ret ) {
2168+ /*
2169+ * We can function with default calibration, but it may be
2170+ * inaccurate. Provide a warning, and continue on.
2171+ */
2172+ hid_warn (hdev , "Unable to read IMU calibration data\n" );
2173+ }
2174+
2175+ /* Set the reporting mode to 0x30, which is the full report mode */
2176+ ret = joycon_set_report_mode (ctlr );
2177+ if (ret ) {
2178+ hid_err (hdev , "Failed to set report mode; ret=%d\n" , ret );
2179+ goto out_unlock ;
2180+ }
2181+
2182+ /* Enable rumble */
2183+ ret = joycon_enable_rumble (ctlr );
2184+ if (ret ) {
2185+ hid_err (hdev , "Failed to enable rumble; ret=%d\n" , ret );
2186+ goto out_unlock ;
2187+ }
2188+
2189+ /* Enable the IMU */
2190+ ret = joycon_enable_imu (ctlr );
2191+ if (ret ) {
2192+ hid_err (hdev , "Failed to enable the IMU; ret=%d\n" , ret );
2193+ goto out_unlock ;
2194+ }
2195+
2196+ out_unlock :
2197+ mutex_unlock (& ctlr -> output_mutex );
2198+ return ret ;
2199+ }
2200+
21202201/* Common handler for parsing inputs */
21212202static int joycon_ctlr_read_handler (struct joycon_ctlr * ctlr , u8 * data ,
21222203 int size )
@@ -2248,85 +2329,19 @@ static int nintendo_hid_probe(struct hid_device *hdev,
22482329
22492330 hid_device_io_start (hdev );
22502331
2251- /* Initialize the controller */
2252- mutex_lock (& ctlr -> output_mutex );
2253- /* if handshake command fails, assume ble pro controller */
2254- if ((jc_type_is_procon (ctlr ) || jc_type_is_chrggrip (ctlr )) &&
2255- !joycon_send_usb (ctlr , JC_USB_CMD_HANDSHAKE , HZ )) {
2256- hid_dbg (hdev , "detected USB controller\n" );
2257- /* set baudrate for improved latency */
2258- ret = joycon_send_usb (ctlr , JC_USB_CMD_BAUDRATE_3M , HZ );
2259- if (ret ) {
2260- hid_err (hdev , "Failed to set baudrate; ret=%d\n" , ret );
2261- goto err_mutex ;
2262- }
2263- /* handshake */
2264- ret = joycon_send_usb (ctlr , JC_USB_CMD_HANDSHAKE , HZ );
2265- if (ret ) {
2266- hid_err (hdev , "Failed handshake; ret=%d\n" , ret );
2267- goto err_mutex ;
2268- }
2269- /*
2270- * Set no timeout (to keep controller in USB mode).
2271- * This doesn't send a response, so ignore the timeout.
2272- */
2273- joycon_send_usb (ctlr , JC_USB_CMD_NO_TIMEOUT , HZ /10 );
2274- } else if (jc_type_is_chrggrip (ctlr )) {
2275- hid_err (hdev , "Failed charging grip handshake\n" );
2276- ret = - ETIMEDOUT ;
2277- goto err_mutex ;
2278- }
2279-
2280- /* get controller calibration data, and parse it */
2281- ret = joycon_request_calibration (ctlr );
2332+ ret = joycon_init (hdev );
22822333 if (ret ) {
2283- /*
2284- * We can function with default calibration, but it may be
2285- * inaccurate. Provide a warning, and continue on.
2286- */
2287- hid_warn (hdev , "Analog stick positions may be inaccurate\n" );
2288- }
2289-
2290- /* get IMU calibration data, and parse it */
2291- ret = joycon_request_imu_calibration (ctlr );
2292- if (ret ) {
2293- /*
2294- * We can function with default calibration, but it may be
2295- * inaccurate. Provide a warning, and continue on.
2296- */
2297- hid_warn (hdev , "Unable to read IMU calibration data\n" );
2298- }
2299-
2300- /* Set the reporting mode to 0x30, which is the full report mode */
2301- ret = joycon_set_report_mode (ctlr );
2302- if (ret ) {
2303- hid_err (hdev , "Failed to set report mode; ret=%d\n" , ret );
2304- goto err_mutex ;
2305- }
2306-
2307- /* Enable rumble */
2308- ret = joycon_enable_rumble (ctlr );
2309- if (ret ) {
2310- hid_err (hdev , "Failed to enable rumble; ret=%d\n" , ret );
2311- goto err_mutex ;
2312- }
2313-
2314- /* Enable the IMU */
2315- ret = joycon_enable_imu (ctlr );
2316- if (ret ) {
2317- hid_err (hdev , "Failed to enable the IMU; ret=%d\n" , ret );
2318- goto err_mutex ;
2334+ hid_err (hdev , "Failed to initialize controller; ret=%d\n" , ret );
2335+ goto err_close ;
23192336 }
23202337
23212338 ret = joycon_read_info (ctlr );
23222339 if (ret ) {
23232340 hid_err (hdev , "Failed to retrieve controller info; ret=%d\n" ,
23242341 ret );
2325- goto err_mutex ;
2342+ goto err_close ;
23262343 }
23272344
2328- mutex_unlock (& ctlr -> output_mutex );
2329-
23302345 /* Initialize the leds */
23312346 ret = joycon_leds_create (ctlr );
23322347 if (ret ) {
@@ -2352,8 +2367,6 @@ static int nintendo_hid_probe(struct hid_device *hdev,
23522367 hid_dbg (hdev , "probe - success\n" );
23532368 return 0 ;
23542369
2355- err_mutex :
2356- mutex_unlock (& ctlr -> output_mutex );
23572370err_close :
23582371 hid_hw_close (hdev );
23592372err_stop :
@@ -2383,6 +2396,20 @@ static void nintendo_hid_remove(struct hid_device *hdev)
23832396 hid_hw_stop (hdev );
23842397}
23852398
2399+ #ifdef CONFIG_PM
2400+
2401+ static int nintendo_hid_resume (struct hid_device * hdev )
2402+ {
2403+ int ret = joycon_init (hdev );
2404+
2405+ if (ret )
2406+ hid_err (hdev , "Failed to restore controller after resume" );
2407+
2408+ return ret ;
2409+ }
2410+
2411+ #endif
2412+
23862413static const struct hid_device_id nintendo_hid_devices [] = {
23872414 { HID_USB_DEVICE (USB_VENDOR_ID_NINTENDO ,
23882415 USB_DEVICE_ID_NINTENDO_PROCON ) },
@@ -2404,6 +2431,10 @@ static struct hid_driver nintendo_hid_driver = {
24042431 .probe = nintendo_hid_probe ,
24052432 .remove = nintendo_hid_remove ,
24062433 .raw_event = nintendo_hid_event ,
2434+
2435+ #ifdef CONFIG_PM
2436+ .resume = nintendo_hid_resume ,
2437+ #endif
24072438};
24082439module_hid_driver (nintendo_hid_driver );
24092440
0 commit comments