| @@ -2088,7 +2088,9 @@ static int joycon_read_info(struct joycon_ctlr *ctlr) · 2087 unmodified lines |
| 2088 | 2088 | struct joycon_input_report *report; |
| 2089 | 2089 | |
| 2090 | 2090 | req.subcmd_id = JC_SUBCMD_REQ_DEV_INFO; |
| 2091 | + mutex_lock(&ctlr->output_mutex); |
| 2091 | 2092 | ret = joycon_send_subcmd(ctlr, &req, 0, HZ); |
| 2093 | + mutex_unlock(&ctlr->output_mutex); |
| 2092 | 2094 | if (ret) { |
| 2093 | 2095 | hid_err(ctlr->hdev, "Failed to get joycon info; ret=%d\n", ret); |
| 2094 | 2096 | return ret; |
| @@ -2117,6 +2119,85 @@ static int joycon_read_info(struct joycon_ctlr *ctlr) · 22 unmodified lines |
| 2117 | 2119 | return 0; |
| 2118 | 2120 | } |
| 2119 | 2121 | |
| 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 | + |
| 2120 | 2201 | /* Common handler for parsing inputs */ |
| 2121 | 2202 | static int joycon_ctlr_read_handler(struct joycon_ctlr *ctlr, u8 *data, |
| 2122 | 2203 | int size) |
| @@ -2248,85 +2329,19 @@ static int nintendo_hid_probe(struct hid_device *hdev, · 125 unmodified lines |
| 2248 | 2329 | |
| 2249 | 2330 | hid_device_io_start(hdev); |
| 2250 | 2331 | |
| 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); |
| 2282 | 2333 | 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; |
| 2319 | 2336 | } |
| 2320 | 2337 | |
| 2321 | 2338 | ret = joycon_read_info(ctlr); |
| 2322 | 2339 | if (ret) { |
| 2323 | 2340 | hid_err(hdev, "Failed to retrieve controller info; ret=%d\n", |
| 2324 | 2341 | ret); |
| 2325 | | − goto err_mutex; |
| 2342 | + goto err_close; |
| 2326 | 2343 | } |
| 2327 | 2344 | |
| 2328 | | − mutex_unlock(&ctlr->output_mutex); |
| 2329 | | − |
| 2330 | 2345 | /* Initialize the leds */ |
| 2331 | 2346 | ret = joycon_leds_create(ctlr); |
| 2332 | 2347 | if (ret) { |
| @@ -2352,8 +2367,6 @@ static int nintendo_hid_probe(struct hid_device *hdev, · 19 unmodified lines |
| 2352 | 2367 | hid_dbg(hdev, "probe - success\n"); |
| 2353 | 2368 | return 0; |
| 2354 | 2369 | |
| 2355 | | −err_mutex: |
| 2356 | | − mutex_unlock(&ctlr->output_mutex); |
| 2357 | 2370 | err_close: |
| 2358 | 2371 | hid_hw_close(hdev); |
| 2359 | 2372 | err_stop: |
| @@ -2383,6 +2396,20 @@ static void nintendo_hid_remove(struct hid_device *hdev) · 23 unmodified lines |
| 2383 | 2396 | hid_hw_stop(hdev); |
| 2384 | 2397 | } |
| 2385 | 2398 | |
| 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 | + |
| 2386 | 2413 | static const struct hid_device_id nintendo_hid_devices[] = { |
| 2387 | 2414 | { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO, |
| 2388 | 2415 | USB_DEVICE_ID_NINTENDO_PROCON) }, |
| @@ -2404,6 +2431,10 @@ static struct hid_driver nintendo_hid_driver = { · 15 unmodified lines |
| 2404 | 2431 | .probe = nintendo_hid_probe, |
| 2405 | 2432 | .remove = nintendo_hid_remove, |
| 2406 | 2433 | .raw_event = nintendo_hid_event, |
| 2434 | + |
| 2435 | +#ifdef CONFIG_PM |
| 2436 | + .resume = nintendo_hid_resume, |
| 2437 | +#endif |
| 2407 | 2438 | }; |
| 2408 | 2439 | module_hid_driver(nintendo_hid_driver); |
| 2409 | 2440 | |