@@ -471,6 +471,9 @@ static char *hidpp_get_device_name(struct hidpp_device *hidpp, u8 *name_length)
471
471
#define HIDPP_PAGE_TOUCHPAD_RAW_XY 0x6100
472
472
473
473
#define CMD_TOUCHPAD_GET_RAW_INFO 0x01
474
+ #define CMD_TOUCHPAD_SET_RAW_REPORT_STATE 0x21
475
+
476
+ #define EVENT_TOUCHPAD_RAW_XY 0x00
474
477
475
478
#define TOUCHPAD_RAW_XY_ORIGIN_LOWER_LEFT 0x01
476
479
#define TOUCHPAD_RAW_XY_ORIGIN_UPPER_LEFT 0x03
@@ -530,6 +533,59 @@ static int hidpp_touchpad_get_raw_info(struct hidpp_device *hidpp,
530
533
return ret ;
531
534
}
532
535
536
+ static int hidpp_touchpad_set_raw_report_state (struct hidpp_device * hidpp_dev ,
537
+ u8 feature_index , bool send_raw_reports ,
538
+ bool sensor_enhanced_settings )
539
+ {
540
+ struct hidpp_report response ;
541
+
542
+ /*
543
+ * Params:
544
+ * bit 0 - enable raw
545
+ * bit 1 - 16bit Z, no area
546
+ * bit 2 - enhanced sensitivity
547
+ * bit 3 - width, height (4 bits each) instead of area
548
+ * bit 4 - send raw + gestures (degrades smoothness)
549
+ * remaining bits - reserved
550
+ */
551
+ u8 params = send_raw_reports | (sensor_enhanced_settings << 2 );
552
+
553
+ return hidpp_send_fap_command_sync (hidpp_dev , feature_index ,
554
+ CMD_TOUCHPAD_SET_RAW_REPORT_STATE , & params , 1 , & response );
555
+ }
556
+
557
+ static void hidpp_touchpad_touch_event (u8 * data ,
558
+ struct hidpp_touchpad_raw_xy_finger * finger )
559
+ {
560
+ u8 x_m = data [0 ] << 2 ;
561
+ u8 y_m = data [2 ] << 2 ;
562
+
563
+ finger -> x = x_m << 6 | data [1 ];
564
+ finger -> y = y_m << 6 | data [3 ];
565
+
566
+ finger -> contact_type = data [0 ] >> 6 ;
567
+ finger -> contact_status = data [2 ] >> 6 ;
568
+
569
+ finger -> z = data [4 ];
570
+ finger -> area = data [5 ];
571
+ finger -> finger_id = data [6 ] >> 4 ;
572
+ }
573
+
574
+ static void hidpp_touchpad_raw_xy_event (struct hidpp_device * hidpp_dev ,
575
+ u8 * data , struct hidpp_touchpad_raw_xy * raw_xy )
576
+ {
577
+ memset (raw_xy , 0 , sizeof (struct hidpp_touchpad_raw_xy ));
578
+ raw_xy -> end_of_frame = data [8 ] & 0x01 ;
579
+ raw_xy -> spurious_flag = (data [8 ] >> 1 ) & 0x01 ;
580
+ raw_xy -> finger_count = data [15 ] & 0x0f ;
581
+ raw_xy -> button = (data [8 ] >> 2 ) & 0x01 ;
582
+
583
+ if (raw_xy -> finger_count ) {
584
+ hidpp_touchpad_touch_event (& data [2 ], & raw_xy -> fingers [0 ]);
585
+ hidpp_touchpad_touch_event (& data [9 ], & raw_xy -> fingers [1 ]);
586
+ }
587
+ }
588
+
533
589
/* ************************************************************************** */
534
590
/* */
535
591
/* Device Support */
@@ -672,11 +728,28 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size)
672
728
{
673
729
struct hidpp_device * hidpp = hid_get_drvdata (hdev );
674
730
struct wtp_data * wd = hidpp -> private_data ;
731
+ struct hidpp_report * report = (struct hidpp_report * )data ;
732
+ struct hidpp_touchpad_raw_xy raw ;
675
733
676
- if (!wd || !wd -> input || ( data [ 0 ] != 0x02 ) || size < 21 )
734
+ if (!wd || !wd -> input )
677
735
return 1 ;
678
736
679
- return wtp_mouse_raw_xy_event (hidpp , & data [7 ]);
737
+ switch (data [0 ]) {
738
+ case 0x02 :
739
+ if (size < 21 )
740
+ return 1 ;
741
+ return wtp_mouse_raw_xy_event (hidpp , & data [7 ]);
742
+ case REPORT_ID_HIDPP_LONG :
743
+ if ((report -> fap .feature_index != wd -> mt_feature_index ) ||
744
+ (report -> fap .funcindex_clientid != EVENT_TOUCHPAD_RAW_XY ))
745
+ return 1 ;
746
+ hidpp_touchpad_raw_xy_event (hidpp , data + 4 , & raw );
747
+
748
+ wtp_send_raw_xy_event (hidpp , & raw );
749
+ return 0 ;
750
+ }
751
+
752
+ return 0 ;
680
753
}
681
754
682
755
static int wtp_get_config (struct hidpp_device * hidpp )
@@ -721,6 +794,27 @@ static int wtp_allocate(struct hid_device *hdev, const struct hid_device_id *id)
721
794
return 0 ;
722
795
};
723
796
797
+ static void wtp_connect (struct hid_device * hdev , bool connected )
798
+ {
799
+ struct hidpp_device * hidpp = hid_get_drvdata (hdev );
800
+ struct wtp_data * wd = hidpp -> private_data ;
801
+ int ret ;
802
+
803
+ if (!connected )
804
+ return ;
805
+
806
+ if (!wd -> x_size ) {
807
+ ret = wtp_get_config (hidpp );
808
+ if (ret ) {
809
+ hid_err (hdev , "Can not get wtp config: %d\n" , ret );
810
+ return ;
811
+ }
812
+ }
813
+
814
+ hidpp_touchpad_set_raw_report_state (hidpp , wd -> mt_feature_index ,
815
+ true, true);
816
+ }
817
+
724
818
/* -------------------------------------------------------------------------- */
725
819
/* Generic HID++ devices */
726
820
/* -------------------------------------------------------------------------- */
@@ -897,6 +991,9 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
897
991
char * name , * devm_name ;
898
992
u8 name_length ;
899
993
994
+ if (hidpp -> quirks & HIDPP_QUIRK_CLASS_WTP )
995
+ wtp_connect (hdev , connected );
996
+
900
997
if (!connected || hidpp -> delayed_input )
901
998
return ;
902
999
@@ -1033,6 +1130,10 @@ static void hidpp_remove(struct hid_device *hdev)
1033
1130
}
1034
1131
1035
1132
static const struct hid_device_id hidpp_devices [] = {
1133
+ { /* wireless touchpad T650 */
1134
+ HID_DEVICE (BUS_USB , HID_GROUP_LOGITECH_DJ_DEVICE ,
1135
+ USB_VENDOR_ID_LOGITECH , 0x4101 ),
1136
+ .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
1036
1137
{ /* wireless touchpad T651 */
1037
1138
HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_LOGITECH ,
1038
1139
USB_DEVICE_ID_LOGITECH_T651 ),
0 commit comments