diff options
| -rw-r--r-- | drivers/hid/hid-sony.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 4ba904b02bc2..1041c44765e1 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
| @@ -1045,6 +1045,7 @@ struct sony_sc { | |||
| 1045 | __u8 battery_charging; | 1045 | __u8 battery_charging; |
| 1046 | __u8 battery_capacity; | 1046 | __u8 battery_capacity; |
| 1047 | __u8 led_state[MAX_LEDS]; | 1047 | __u8 led_state[MAX_LEDS]; |
| 1048 | __u8 resume_led_state[MAX_LEDS]; | ||
| 1048 | __u8 led_delay_on[MAX_LEDS]; | 1049 | __u8 led_delay_on[MAX_LEDS]; |
| 1049 | __u8 led_delay_off[MAX_LEDS]; | 1050 | __u8 led_delay_off[MAX_LEDS]; |
| 1050 | __u8 led_count; | 1051 | __u8 led_count; |
| @@ -1912,6 +1913,12 @@ static void motion_send_output_report(struct sony_sc *sc) | |||
| 1912 | hid_hw_output_report(hdev, (__u8 *)report, MOTION_REPORT_0x02_SIZE); | 1913 | hid_hw_output_report(hdev, (__u8 *)report, MOTION_REPORT_0x02_SIZE); |
| 1913 | } | 1914 | } |
| 1914 | 1915 | ||
| 1916 | static inline void sony_send_output_report(struct sony_sc *sc) | ||
| 1917 | { | ||
| 1918 | if (sc->send_output_report) | ||
| 1919 | sc->send_output_report(sc); | ||
| 1920 | } | ||
| 1921 | |||
| 1915 | static void sony_state_worker(struct work_struct *work) | 1922 | static void sony_state_worker(struct work_struct *work) |
| 1916 | { | 1923 | { |
| 1917 | struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); | 1924 | struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); |
| @@ -2427,6 +2434,56 @@ static void sony_remove(struct hid_device *hdev) | |||
| 2427 | hid_hw_stop(hdev); | 2434 | hid_hw_stop(hdev); |
| 2428 | } | 2435 | } |
| 2429 | 2436 | ||
| 2437 | #ifdef CONFIG_PM | ||
| 2438 | |||
| 2439 | static int sony_suspend(struct hid_device *hdev, pm_message_t message) | ||
| 2440 | { | ||
| 2441 | /* | ||
| 2442 | * On suspend save the current LED state, | ||
| 2443 | * stop running force-feedback and blank the LEDS. | ||
| 2444 | */ | ||
| 2445 | if (SONY_LED_SUPPORT || SONY_FF_SUPPORT) { | ||
| 2446 | struct sony_sc *sc = hid_get_drvdata(hdev); | ||
| 2447 | |||
| 2448 | #ifdef CONFIG_SONY_FF | ||
| 2449 | sc->left = sc->right = 0; | ||
| 2450 | #endif | ||
| 2451 | |||
| 2452 | memcpy(sc->resume_led_state, sc->led_state, | ||
| 2453 | sizeof(sc->resume_led_state)); | ||
| 2454 | memset(sc->led_state, 0, sizeof(sc->led_state)); | ||
| 2455 | |||
| 2456 | sony_send_output_report(sc); | ||
| 2457 | } | ||
| 2458 | |||
| 2459 | return 0; | ||
| 2460 | } | ||
| 2461 | |||
| 2462 | static int sony_resume(struct hid_device *hdev) | ||
| 2463 | { | ||
| 2464 | /* Restore the state of controller LEDs on resume */ | ||
| 2465 | if (SONY_LED_SUPPORT) { | ||
| 2466 | struct sony_sc *sc = hid_get_drvdata(hdev); | ||
| 2467 | |||
| 2468 | memcpy(sc->led_state, sc->resume_led_state, | ||
| 2469 | sizeof(sc->led_state)); | ||
| 2470 | |||
| 2471 | /* | ||
| 2472 | * The Sixaxis and navigation controllers on USB need to be | ||
| 2473 | * reinitialized on resume or they won't behave properly. | ||
| 2474 | */ | ||
| 2475 | if ((sc->quirks & SIXAXIS_CONTROLLER_USB) || | ||
| 2476 | (sc->quirks & NAVIGATION_CONTROLLER_USB)) | ||
| 2477 | sixaxis_set_operational_usb(sc->hdev); | ||
| 2478 | |||
| 2479 | sony_set_leds(sc); | ||
| 2480 | } | ||
| 2481 | |||
| 2482 | return 0; | ||
| 2483 | } | ||
| 2484 | |||
| 2485 | #endif | ||
| 2486 | |||
| 2430 | static const struct hid_device_id sony_devices[] = { | 2487 | static const struct hid_device_id sony_devices[] = { |
| 2431 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), | 2488 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), |
| 2432 | .driver_data = SIXAXIS_CONTROLLER_USB }, | 2489 | .driver_data = SIXAXIS_CONTROLLER_USB }, |
| @@ -2476,7 +2533,13 @@ static struct hid_driver sony_driver = { | |||
| 2476 | .probe = sony_probe, | 2533 | .probe = sony_probe, |
| 2477 | .remove = sony_remove, | 2534 | .remove = sony_remove, |
| 2478 | .report_fixup = sony_report_fixup, | 2535 | .report_fixup = sony_report_fixup, |
| 2479 | .raw_event = sony_raw_event | 2536 | .raw_event = sony_raw_event, |
| 2537 | |||
| 2538 | #ifdef CONFIG_PM | ||
| 2539 | .suspend = sony_suspend, | ||
| 2540 | .resume = sony_resume, | ||
| 2541 | .reset_resume = sony_resume, | ||
| 2542 | #endif | ||
| 2480 | }; | 2543 | }; |
| 2481 | 2544 | ||
| 2482 | static int __init sony_init(void) | 2545 | static int __init sony_init(void) |
