aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-steam.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-steam.c')
-rw-r--r--drivers/hid/hid-steam.c154
1 files changed, 90 insertions, 64 deletions
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index 0422ec2b13d2..dc4128bfe2ca 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -23,8 +23,9 @@
23 * In order to avoid breaking them this driver creates a layered hidraw device, 23 * In order to avoid breaking them this driver creates a layered hidraw device,
24 * so it can detect when the client is running and then: 24 * so it can detect when the client is running and then:
25 * - it will not send any command to the controller. 25 * - it will not send any command to the controller.
26 * - this input device will be disabled, to avoid double input of the same 26 * - this input device will be removed, to avoid double input of the same
27 * user action. 27 * user action.
28 * When the client is closed, this input device will be created again.
28 * 29 *
29 * For additional functions, such as changing the right-pad margin or switching 30 * For additional functions, such as changing the right-pad margin or switching
30 * the led, you can use the user-space tool at: 31 * the led, you can use the user-space tool at:
@@ -113,7 +114,7 @@ struct steam_device {
113 spinlock_t lock; 114 spinlock_t lock;
114 struct hid_device *hdev, *client_hdev; 115 struct hid_device *hdev, *client_hdev;
115 struct mutex mutex; 116 struct mutex mutex;
116 bool client_opened, input_opened; 117 bool client_opened;
117 struct input_dev __rcu *input; 118 struct input_dev __rcu *input;
118 unsigned long quirks; 119 unsigned long quirks;
119 struct work_struct work_connect; 120 struct work_struct work_connect;
@@ -279,18 +280,6 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)
279 } 280 }
280} 281}
281 282
282static void steam_update_lizard_mode(struct steam_device *steam)
283{
284 mutex_lock(&steam->mutex);
285 if (!steam->client_opened) {
286 if (steam->input_opened)
287 steam_set_lizard_mode(steam, false);
288 else
289 steam_set_lizard_mode(steam, lizard_mode);
290 }
291 mutex_unlock(&steam->mutex);
292}
293
294static int steam_input_open(struct input_dev *dev) 283static int steam_input_open(struct input_dev *dev)
295{ 284{
296 struct steam_device *steam = input_get_drvdata(dev); 285 struct steam_device *steam = input_get_drvdata(dev);
@@ -301,7 +290,6 @@ static int steam_input_open(struct input_dev *dev)
301 return ret; 290 return ret;
302 291
303 mutex_lock(&steam->mutex); 292 mutex_lock(&steam->mutex);
304 steam->input_opened = true;
305 if (!steam->client_opened && lizard_mode) 293 if (!steam->client_opened && lizard_mode)
306 steam_set_lizard_mode(steam, false); 294 steam_set_lizard_mode(steam, false);
307 mutex_unlock(&steam->mutex); 295 mutex_unlock(&steam->mutex);
@@ -313,7 +301,6 @@ static void steam_input_close(struct input_dev *dev)
313 struct steam_device *steam = input_get_drvdata(dev); 301 struct steam_device *steam = input_get_drvdata(dev);
314 302
315 mutex_lock(&steam->mutex); 303 mutex_lock(&steam->mutex);
316 steam->input_opened = false;
317 if (!steam->client_opened && lizard_mode) 304 if (!steam->client_opened && lizard_mode)
318 steam_set_lizard_mode(steam, true); 305 steam_set_lizard_mode(steam, true);
319 mutex_unlock(&steam->mutex); 306 mutex_unlock(&steam->mutex);
@@ -400,7 +387,7 @@ static int steam_battery_register(struct steam_device *steam)
400 return 0; 387 return 0;
401} 388}
402 389
403static int steam_register(struct steam_device *steam) 390static int steam_input_register(struct steam_device *steam)
404{ 391{
405 struct hid_device *hdev = steam->hdev; 392 struct hid_device *hdev = steam->hdev;
406 struct input_dev *input; 393 struct input_dev *input;
@@ -414,17 +401,6 @@ static int steam_register(struct steam_device *steam)
414 return 0; 401 return 0;
415 } 402 }
416 403
417 /*
418 * Unlikely, but getting the serial could fail, and it is not so
419 * important, so make up a serial number and go on.
420 */
421 if (steam_get_serial(steam) < 0)
422 strlcpy(steam->serial_no, "XXXXXXXXXX",
423 sizeof(steam->serial_no));
424
425 hid_info(hdev, "Steam Controller '%s' connected",
426 steam->serial_no);
427
428 input = input_allocate_device(); 404 input = input_allocate_device();
429 if (!input) 405 if (!input)
430 return -ENOMEM; 406 return -ENOMEM;
@@ -492,11 +468,6 @@ static int steam_register(struct steam_device *steam)
492 goto input_register_fail; 468 goto input_register_fail;
493 469
494 rcu_assign_pointer(steam->input, input); 470 rcu_assign_pointer(steam->input, input);
495
496 /* ignore battery errors, we can live without it */
497 if (steam->quirks & STEAM_QUIRK_WIRELESS)
498 steam_battery_register(steam);
499
500 return 0; 471 return 0;
501 472
502input_register_fail: 473input_register_fail:
@@ -504,27 +475,88 @@ input_register_fail:
504 return ret; 475 return ret;
505} 476}
506 477
507static void steam_unregister(struct steam_device *steam) 478static void steam_input_unregister(struct steam_device *steam)
508{ 479{
509 struct input_dev *input; 480 struct input_dev *input;
481 rcu_read_lock();
482 input = rcu_dereference(steam->input);
483 rcu_read_unlock();
484 if (!input)
485 return;
486 RCU_INIT_POINTER(steam->input, NULL);
487 synchronize_rcu();
488 input_unregister_device(input);
489}
490
491static void steam_battery_unregister(struct steam_device *steam)
492{
510 struct power_supply *battery; 493 struct power_supply *battery;
511 494
512 rcu_read_lock(); 495 rcu_read_lock();
513 input = rcu_dereference(steam->input);
514 battery = rcu_dereference(steam->battery); 496 battery = rcu_dereference(steam->battery);
515 rcu_read_unlock(); 497 rcu_read_unlock();
516 498
517 if (battery) { 499 if (!battery)
518 RCU_INIT_POINTER(steam->battery, NULL); 500 return;
519 synchronize_rcu(); 501 RCU_INIT_POINTER(steam->battery, NULL);
520 power_supply_unregister(battery); 502 synchronize_rcu();
503 power_supply_unregister(battery);
504}
505
506static int steam_register(struct steam_device *steam)
507{
508 int ret;
509
510 /*
511 * This function can be called several times in a row with the
512 * wireless adaptor, without steam_unregister() between them, because
513 * another client send a get_connection_status command, for example.
514 * The battery and serial number are set just once per device.
515 */
516 if (!steam->serial_no[0]) {
517 /*
518 * Unlikely, but getting the serial could fail, and it is not so
519 * important, so make up a serial number and go on.
520 */
521 if (steam_get_serial(steam) < 0)
522 strlcpy(steam->serial_no, "XXXXXXXXXX",
523 sizeof(steam->serial_no));
524
525 hid_info(steam->hdev, "Steam Controller '%s' connected",
526 steam->serial_no);
527
528 /* ignore battery errors, we can live without it */
529 if (steam->quirks & STEAM_QUIRK_WIRELESS)
530 steam_battery_register(steam);
531
532 mutex_lock(&steam_devices_lock);
533 list_add(&steam->list, &steam_devices);
534 mutex_unlock(&steam_devices_lock);
521 } 535 }
522 if (input) { 536
523 RCU_INIT_POINTER(steam->input, NULL); 537 mutex_lock(&steam->mutex);
524 synchronize_rcu(); 538 if (!steam->client_opened) {
539 steam_set_lizard_mode(steam, lizard_mode);
540 ret = steam_input_register(steam);
541 } else {
542 ret = 0;
543 }
544 mutex_unlock(&steam->mutex);
545
546 return ret;
547}
548
549static void steam_unregister(struct steam_device *steam)
550{
551 steam_battery_unregister(steam);
552 steam_input_unregister(steam);
553 if (steam->serial_no[0]) {
525 hid_info(steam->hdev, "Steam Controller '%s' disconnected", 554 hid_info(steam->hdev, "Steam Controller '%s' disconnected",
526 steam->serial_no); 555 steam->serial_no);
527 input_unregister_device(input); 556 mutex_lock(&steam_devices_lock);
557 list_del(&steam->list);
558 mutex_unlock(&steam_devices_lock);
559 steam->serial_no[0] = 0;
528 } 560 }
529} 561}
530 562
@@ -600,6 +632,9 @@ static int steam_client_ll_open(struct hid_device *hdev)
600 mutex_lock(&steam->mutex); 632 mutex_lock(&steam->mutex);
601 steam->client_opened = true; 633 steam->client_opened = true;
602 mutex_unlock(&steam->mutex); 634 mutex_unlock(&steam->mutex);
635
636 steam_input_unregister(steam);
637
603 return ret; 638 return ret;
604} 639}
605 640
@@ -609,13 +644,13 @@ static void steam_client_ll_close(struct hid_device *hdev)
609 644
610 mutex_lock(&steam->mutex); 645 mutex_lock(&steam->mutex);
611 steam->client_opened = false; 646 steam->client_opened = false;
612 if (steam->input_opened)
613 steam_set_lizard_mode(steam, false);
614 else
615 steam_set_lizard_mode(steam, lizard_mode);
616 mutex_unlock(&steam->mutex); 647 mutex_unlock(&steam->mutex);
617 648
618 hid_hw_close(steam->hdev); 649 hid_hw_close(steam->hdev);
650 if (steam->connected) {
651 steam_set_lizard_mode(steam, lizard_mode);
652 steam_input_register(steam);
653 }
619} 654}
620 655
621static int steam_client_ll_raw_request(struct hid_device *hdev, 656static int steam_client_ll_raw_request(struct hid_device *hdev,
@@ -744,11 +779,6 @@ static int steam_probe(struct hid_device *hdev,
744 } 779 }
745 } 780 }
746 781
747 mutex_lock(&steam_devices_lock);
748 steam_update_lizard_mode(steam);
749 list_add(&steam->list, &steam_devices);
750 mutex_unlock(&steam_devices_lock);
751
752 return 0; 782 return 0;
753 783
754hid_hw_open_fail: 784hid_hw_open_fail:
@@ -774,10 +804,6 @@ static void steam_remove(struct hid_device *hdev)
774 return; 804 return;
775 } 805 }
776 806
777 mutex_lock(&steam_devices_lock);
778 list_del(&steam->list);
779 mutex_unlock(&steam_devices_lock);
780
781 hid_destroy_device(steam->client_hdev); 807 hid_destroy_device(steam->client_hdev);
782 steam->client_opened = false; 808 steam->client_opened = false;
783 cancel_work_sync(&steam->work_connect); 809 cancel_work_sync(&steam->work_connect);
@@ -792,12 +818,14 @@ static void steam_remove(struct hid_device *hdev)
792static void steam_do_connect_event(struct steam_device *steam, bool connected) 818static void steam_do_connect_event(struct steam_device *steam, bool connected)
793{ 819{
794 unsigned long flags; 820 unsigned long flags;
821 bool changed;
795 822
796 spin_lock_irqsave(&steam->lock, flags); 823 spin_lock_irqsave(&steam->lock, flags);
824 changed = steam->connected != connected;
797 steam->connected = connected; 825 steam->connected = connected;
798 spin_unlock_irqrestore(&steam->lock, flags); 826 spin_unlock_irqrestore(&steam->lock, flags);
799 827
800 if (schedule_work(&steam->work_connect) == 0) 828 if (changed && schedule_work(&steam->work_connect) == 0)
801 dbg_hid("%s: connected=%d event already queued\n", 829 dbg_hid("%s: connected=%d event already queued\n",
802 __func__, connected); 830 __func__, connected);
803} 831}
@@ -1019,13 +1047,8 @@ static int steam_raw_event(struct hid_device *hdev,
1019 return 0; 1047 return 0;
1020 rcu_read_lock(); 1048 rcu_read_lock();
1021 input = rcu_dereference(steam->input); 1049 input = rcu_dereference(steam->input);
1022 if (likely(input)) { 1050 if (likely(input))
1023 steam_do_input_event(steam, input, data); 1051 steam_do_input_event(steam, input, data);
1024 } else {
1025 dbg_hid("%s: input data without connect event\n",
1026 __func__);
1027 steam_do_connect_event(steam, true);
1028 }
1029 rcu_read_unlock(); 1052 rcu_read_unlock();
1030 break; 1053 break;
1031 case STEAM_EV_CONNECT: 1054 case STEAM_EV_CONNECT:
@@ -1074,7 +1097,10 @@ static int steam_param_set_lizard_mode(const char *val,
1074 1097
1075 mutex_lock(&steam_devices_lock); 1098 mutex_lock(&steam_devices_lock);
1076 list_for_each_entry(steam, &steam_devices, list) { 1099 list_for_each_entry(steam, &steam_devices, list) {
1077 steam_update_lizard_mode(steam); 1100 mutex_lock(&steam->mutex);
1101 if (!steam->client_opened)
1102 steam_set_lizard_mode(steam, lizard_mode);
1103 mutex_unlock(&steam->mutex);
1078 } 1104 }
1079 mutex_unlock(&steam_devices_lock); 1105 mutex_unlock(&steam_devices_lock);
1080 return 0; 1106 return 0;