summaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2014-09-30 13:18:32 -0400
committerJiri Kosina <jkosina@suse.cz>2014-10-29 05:51:41 -0400
commitc39e3d5fc9dd3e16c6f59dd94d827540040de66d (patch)
tree289479d7963ecd9dcfac5b618faf776557f99abc /drivers/hid
parent6a9ddc8978835deae0b2d918df74fc83588a4104 (diff)
HID: logitech-hidpp: late bind the input device on wireless connection
Now that the receiver forwards the connect/disconnect events, we can know when the device is available to communicate with us. When it is ready, we can for instance retrieve its full name, which guarantee that we always have the same name for the DJ device (the DJ name is somewhat shorter than the HID++ name). This mechanism is mandatory for the touchpads line, which has the min/max information stored in the device. This information can only be retrieved when the device is connected. So we can not populate the input device until we are sure that the device is connected. This patch creates a new input device for such devices. However, this input is not bound to hid directly, so the various drivers which wants to use it are required to process completely the incoming reports in .raw_event(). Note that the patch in itself just adds the bits for the next ones, and this feature is disabled by default. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Tested-by: Andrew de los Reyes <adlr@chromium.org> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-logitech-hidpp.c155
1 files changed, 147 insertions, 8 deletions
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index e748e45b5b2f..9561a1f9b42b 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -36,6 +36,9 @@ MODULE_AUTHOR("Nestor Lopez Casado <nlopezcasad@logitech.com>");
36 36
37#define HIDPP_QUIRK_CLASS_WTP BIT(0) 37#define HIDPP_QUIRK_CLASS_WTP BIT(0)
38 38
39/* bits 1..20 are reserved for classes */
40#define HIDPP_QUIRK_DELAYED_INIT BIT(21)
41
39/* 42/*
40 * There are two hidpp protocols in use, the first version hidpp10 is known 43 * There are two hidpp protocols in use, the first version hidpp10 is known
41 * as register access protocol or RAP, the second version hidpp20 is known as 44 * as register access protocol or RAP, the second version hidpp20 is known as
@@ -91,6 +94,11 @@ struct hidpp_device {
91 94
92 void *private_data; 95 void *private_data;
93 96
97 struct work_struct work;
98 struct kfifo delayed_work_fifo;
99 atomic_t connected;
100 struct input_dev *delayed_input;
101
94 unsigned long quirks; 102 unsigned long quirks;
95}; 103};
96 104
@@ -110,6 +118,8 @@ struct hidpp_device {
110#define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b 118#define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b
111#define HIDPP_ERROR_WRONG_PIN_CODE 0x0c 119#define HIDPP_ERROR_WRONG_PIN_CODE 0x0c
112 120
121static void hidpp_connect_event(struct hidpp_device *hidpp_dev);
122
113static int __hidpp_send_report(struct hid_device *hdev, 123static int __hidpp_send_report(struct hid_device *hdev,
114 struct hidpp_report *hidpp_report) 124 struct hidpp_report *hidpp_report)
115{ 125{
@@ -230,6 +240,13 @@ static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev,
230 return ret; 240 return ret;
231} 241}
232 242
243static void delayed_work_cb(struct work_struct *work)
244{
245 struct hidpp_device *hidpp = container_of(work, struct hidpp_device,
246 work);
247 hidpp_connect_event(hidpp);
248}
249
233static inline bool hidpp_match_answer(struct hidpp_report *question, 250static inline bool hidpp_match_answer(struct hidpp_report *question,
234 struct hidpp_report *answer) 251 struct hidpp_report *answer)
235{ 252{
@@ -245,6 +262,12 @@ static inline bool hidpp_match_error(struct hidpp_report *question,
245 (answer->fap.params[0] == question->fap.funcindex_clientid); 262 (answer->fap.params[0] == question->fap.funcindex_clientid);
246} 263}
247 264
265static inline bool hidpp_report_is_connect_event(struct hidpp_report *report)
266{
267 return (report->report_id == REPORT_ID_HIDPP_SHORT) &&
268 (report->rap.sub_id == 0x41);
269}
270
248/* -------------------------------------------------------------------------- */ 271/* -------------------------------------------------------------------------- */
249/* HIDP++ 1.0 commands */ 272/* HIDP++ 1.0 commands */
250/* -------------------------------------------------------------------------- */ 273/* -------------------------------------------------------------------------- */
@@ -535,12 +558,10 @@ static int wtp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
535 return -1; 558 return -1;
536} 559}
537 560
538static void wtp_input_configured(struct hid_device *hdev, 561static void wtp_populate_input(struct hidpp_device *hidpp,
539 struct hid_input *hidinput) 562 struct input_dev *input_dev, bool origin_is_hid_core)
540{ 563{
541 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
542 struct wtp_data *wd = hidpp->private_data; 564 struct wtp_data *wd = hidpp->private_data;
543 struct input_dev *input_dev = hidinput->input;
544 565
545 __set_bit(EV_ABS, input_dev->evbit); 566 __set_bit(EV_ABS, input_dev->evbit);
546 __set_bit(EV_KEY, input_dev->evbit); 567 __set_bit(EV_KEY, input_dev->evbit);
@@ -716,13 +737,20 @@ static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
716 return 0; 737 return 0;
717} 738}
718 739
740static void hidpp_populate_input(struct hidpp_device *hidpp,
741 struct input_dev *input, bool origin_is_hid_core)
742{
743 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
744 wtp_populate_input(hidpp, input, origin_is_hid_core);
745}
746
719static void hidpp_input_configured(struct hid_device *hdev, 747static void hidpp_input_configured(struct hid_device *hdev,
720 struct hid_input *hidinput) 748 struct hid_input *hidinput)
721{ 749{
722 struct hidpp_device *hidpp = hid_get_drvdata(hdev); 750 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
751 struct input_dev *input = hidinput->input;
723 752
724 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) 753 hidpp_populate_input(hidpp, input, true);
725 wtp_input_configured(hdev, hidinput);
726} 754}
727 755
728static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, 756static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
@@ -756,6 +784,15 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
756 } 784 }
757 } 785 }
758 786
787 if (unlikely(hidpp_report_is_connect_event(report))) {
788 atomic_set(&hidpp->connected,
789 !(report->rap.params[0] & (1 << 6)));
790 if ((hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) &&
791 (schedule_work(&hidpp->work) == 0))
792 dbg_hid("%s: connect event already queued\n", __func__);
793 return 1;
794 }
795
759 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) 796 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
760 return wtp_raw_event(hidpp->hid_dev, data, size); 797 return wtp_raw_event(hidpp->hid_dev, data, size);
761 798
@@ -814,11 +851,99 @@ static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying)
814 kfree(name); 851 kfree(name);
815} 852}
816 853
854static int hidpp_input_open(struct input_dev *dev)
855{
856 struct hid_device *hid = input_get_drvdata(dev);
857
858 return hid_hw_open(hid);
859}
860
861static void hidpp_input_close(struct input_dev *dev)
862{
863 struct hid_device *hid = input_get_drvdata(dev);
864
865 hid_hw_close(hid);
866}
867
868static struct input_dev *hidpp_allocate_input(struct hid_device *hdev)
869{
870 struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev);
871
872 if (!input_dev)
873 return NULL;
874
875 input_set_drvdata(input_dev, hdev);
876 input_dev->open = hidpp_input_open;
877 input_dev->close = hidpp_input_close;
878
879 input_dev->name = hdev->name;
880 input_dev->phys = hdev->phys;
881 input_dev->uniq = hdev->uniq;
882 input_dev->id.bustype = hdev->bus;
883 input_dev->id.vendor = hdev->vendor;
884 input_dev->id.product = hdev->product;
885 input_dev->id.version = hdev->version;
886 input_dev->dev.parent = &hdev->dev;
887
888 return input_dev;
889}
890
891static void hidpp_connect_event(struct hidpp_device *hidpp)
892{
893 struct hid_device *hdev = hidpp->hid_dev;
894 int ret = 0;
895 bool connected = atomic_read(&hidpp->connected);
896 struct input_dev *input;
897 char *name, *devm_name;
898 u8 name_length;
899
900 if (!connected || hidpp->delayed_input)
901 return;
902
903 if (!hidpp->protocol_major) {
904 ret = !hidpp_is_connected(hidpp);
905 if (ret) {
906 hid_err(hdev, "Can not get the protocol version.\n");
907 return;
908 }
909 }
910
911 /* the device is already connected, we can ask for its name and
912 * protocol */
913 hid_info(hdev, "HID++ %u.%u device connected.\n",
914 hidpp->protocol_major, hidpp->protocol_minor);
915
916 input = hidpp_allocate_input(hdev);
917 if (!input) {
918 hid_err(hdev, "cannot allocate new input device: %d\n", ret);
919 return;
920 }
921
922 name = hidpp_get_device_name(hidpp, &name_length);
923 if (!name) {
924 hid_err(hdev, "unable to retrieve the name of the device");
925 } else {
926 devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
927 if (devm_name)
928 input->name = devm_name;
929 kfree(name);
930 }
931
932 hidpp_populate_input(hidpp, input, false);
933
934 ret = input_register_device(input);
935 if (ret)
936 input_free_device(input);
937
938 hidpp->delayed_input = input;
939}
940
817static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) 941static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
818{ 942{
819 struct hidpp_device *hidpp; 943 struct hidpp_device *hidpp;
820 int ret; 944 int ret;
821 bool connected; 945 bool connected;
946 unsigned int connect_mask = HID_CONNECT_DEFAULT;
822 947
823 hidpp = devm_kzalloc(&hdev->dev, sizeof(struct hidpp_device), 948 hidpp = devm_kzalloc(&hdev->dev, sizeof(struct hidpp_device),
824 GFP_KERNEL); 949 GFP_KERNEL);
@@ -836,6 +961,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
836 return ret; 961 return ret;
837 } 962 }
838 963
964 INIT_WORK(&hidpp->work, delayed_work_cb);
839 mutex_init(&hidpp->send_mutex); 965 mutex_init(&hidpp->send_mutex);
840 init_waitqueue_head(&hidpp->wait); 966 init_waitqueue_head(&hidpp->wait);
841 967
@@ -860,8 +986,9 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
860 } 986 }
861 987
862 hidpp_overwrite_name(hdev, id->group == HID_GROUP_LOGITECH_DJ_DEVICE); 988 hidpp_overwrite_name(hdev, id->group == HID_GROUP_LOGITECH_DJ_DEVICE);
989 atomic_set(&hidpp->connected, connected);
863 990
864 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { 991 if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
865 ret = wtp_get_config(hidpp); 992 ret = wtp_get_config(hidpp);
866 if (ret) 993 if (ret)
867 goto hid_parse_fail; 994 goto hid_parse_fail;
@@ -870,16 +997,27 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
870 /* Block incoming packets */ 997 /* Block incoming packets */
871 hid_device_io_stop(hdev); 998 hid_device_io_stop(hdev);
872 999
873 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 1000 if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT)
1001 connect_mask &= ~HID_CONNECT_HIDINPUT;
1002
1003 ret = hid_hw_start(hdev, connect_mask);
874 if (ret) { 1004 if (ret) {
875 hid_err(hdev, "%s:hid_hw_start returned error\n", __func__); 1005 hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
876 goto hid_hw_start_fail; 1006 goto hid_hw_start_fail;
877 } 1007 }
878 1008
1009 if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) {
1010 /* Allow incoming packets */
1011 hid_device_io_start(hdev);
1012
1013 hidpp_connect_event(hidpp);
1014 }
1015
879 return ret; 1016 return ret;
880 1017
881hid_hw_start_fail: 1018hid_hw_start_fail:
882hid_parse_fail: 1019hid_parse_fail:
1020 cancel_work_sync(&hidpp->work);
883 mutex_destroy(&hidpp->send_mutex); 1021 mutex_destroy(&hidpp->send_mutex);
884 hid_set_drvdata(hdev, NULL); 1022 hid_set_drvdata(hdev, NULL);
885 return ret; 1023 return ret;
@@ -889,6 +1027,7 @@ static void hidpp_remove(struct hid_device *hdev)
889{ 1027{
890 struct hidpp_device *hidpp = hid_get_drvdata(hdev); 1028 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
891 1029
1030 cancel_work_sync(&hidpp->work);
892 mutex_destroy(&hidpp->send_mutex); 1031 mutex_destroy(&hidpp->send_mutex);
893 hid_hw_stop(hdev); 1032 hid_hw_stop(hdev);
894} 1033}