@@ -44,22 +44,13 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
44
44
#define FEATURE_REPORT_ID 0x0d
45
45
#define INPUT_REPORT_ID 0x5d
46
46
#define FEATURE_KBD_REPORT_ID 0x5a
47
-
48
- #define INPUT_REPORT_SIZE 28
49
47
#define FEATURE_KBD_REPORT_SIZE 16
50
48
51
49
#define SUPPORT_KBD_BACKLIGHT BIT(0)
52
50
53
- #define MAX_CONTACTS 5
54
-
55
- #define MAX_X 2794
56
- #define MAX_X_T100 2240
57
- #define MAX_Y 1758
58
51
#define MAX_TOUCH_MAJOR 8
59
52
#define MAX_PRESSURE 128
60
53
61
- #define CONTACT_DATA_SIZE 5
62
-
63
54
#define BTN_LEFT_MASK 0x01
64
55
#define CONTACT_TOOL_TYPE_MASK 0x80
65
56
#define CONTACT_X_MSB_MASK 0xf0
@@ -74,12 +65,11 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
74
65
#define QUIRK_NO_CONSUMER_USAGES BIT(4)
75
66
#define QUIRK_USE_KBD_BACKLIGHT BIT(5)
76
67
#define QUIRK_T100_KEYBOARD BIT(6)
77
- #define QUIRK_T100_TOUCHPAD BIT(7)
78
68
79
69
#define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
80
70
QUIRK_NO_INIT_REPORTS | \
81
71
QUIRK_NO_CONSUMER_USAGES)
82
- #define TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \
72
+ #define I2C_TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \
83
73
QUIRK_SKIP_INPUT_MAPPING | \
84
74
QUIRK_IS_MULTITOUCH)
85
75
@@ -93,19 +83,43 @@ struct asus_kbd_leds {
93
83
bool removed ;
94
84
};
95
85
86
+ struct asus_touchpad_info {
87
+ int max_x ;
88
+ int max_y ;
89
+ int contact_size ;
90
+ int max_contacts ;
91
+ };
92
+
96
93
struct asus_drvdata {
97
94
unsigned long quirks ;
98
95
struct input_dev * input ;
99
96
struct asus_kbd_leds * kbd_backlight ;
97
+ const struct asus_touchpad_info * tp ;
100
98
bool enable_backlight ;
101
99
};
102
100
103
- static void asus_report_contact_down (struct input_dev * input ,
101
+ static const struct asus_touchpad_info asus_i2c_tp = {
102
+ .max_x = 2794 ,
103
+ .max_y = 1758 ,
104
+ .contact_size = 5 ,
105
+ .max_contacts = 5 ,
106
+ };
107
+
108
+ static const struct asus_touchpad_info asus_t100ta_tp = {
109
+ .max_x = 2240 ,
110
+ .max_y = 1758 ,
111
+ .contact_size = 5 ,
112
+ .max_contacts = 5 ,
113
+ };
114
+
115
+ static void asus_report_contact_down (struct asus_drvdata * drvdat ,
104
116
int toolType , u8 * data )
105
117
{
106
- int touch_major , pressure ;
107
- int x = (data [0 ] & CONTACT_X_MSB_MASK ) << 4 | data [1 ];
108
- int y = MAX_Y - ((data [0 ] & CONTACT_Y_MSB_MASK ) << 8 | data [2 ]);
118
+ struct input_dev * input = drvdat -> input ;
119
+ int touch_major , pressure , x , y ;
120
+
121
+ x = (data [0 ] & CONTACT_X_MSB_MASK ) << 4 | data [1 ];
122
+ y = drvdat -> tp -> max_y - ((data [0 ] & CONTACT_Y_MSB_MASK ) << 8 | data [2 ]);
109
123
110
124
if (toolType == MT_TOOL_PALM ) {
111
125
touch_major = MAX_TOUCH_MAJOR ;
@@ -122,9 +136,9 @@ static void asus_report_contact_down(struct input_dev *input,
122
136
}
123
137
124
138
/* Required for Synaptics Palm Detection */
125
- static void asus_report_tool_width (struct input_dev * input )
139
+ static void asus_report_tool_width (struct asus_drvdata * drvdat )
126
140
{
127
- struct input_mt * mt = input -> mt ;
141
+ struct input_mt * mt = drvdat -> input -> mt ;
128
142
struct input_mt_slot * oldest ;
129
143
int oldid , count , i ;
130
144
@@ -146,48 +160,49 @@ static void asus_report_tool_width(struct input_dev *input)
146
160
}
147
161
148
162
if (oldest ) {
149
- input_report_abs (input , ABS_TOOL_WIDTH ,
163
+ input_report_abs (drvdat -> input , ABS_TOOL_WIDTH ,
150
164
input_mt_get_value (oldest , ABS_MT_TOUCH_MAJOR ));
151
165
}
152
166
}
153
167
154
- static void asus_report_input (struct input_dev * input , u8 * data )
168
+ static int asus_report_input (struct asus_drvdata * drvdat , u8 * data , int size )
155
169
{
156
170
int i ;
157
171
u8 * contactData = data + 2 ;
158
172
159
- for (i = 0 ; i < MAX_CONTACTS ; i ++ ) {
173
+ if (size != 3 + drvdat -> tp -> contact_size * drvdat -> tp -> max_contacts )
174
+ return 0 ;
175
+
176
+ for (i = 0 ; i < drvdat -> tp -> max_contacts ; i ++ ) {
160
177
bool down = !!(data [1 ] & BIT (i + 3 ));
161
178
int toolType = contactData [3 ] & CONTACT_TOOL_TYPE_MASK ?
162
179
MT_TOOL_PALM : MT_TOOL_FINGER ;
163
180
164
- input_mt_slot (input , i );
165
- input_mt_report_slot_state (input , toolType , down );
181
+ input_mt_slot (drvdat -> input , i );
182
+ input_mt_report_slot_state (drvdat -> input , toolType , down );
166
183
167
184
if (down ) {
168
- asus_report_contact_down (input , toolType , contactData );
169
- contactData += CONTACT_DATA_SIZE ;
185
+ asus_report_contact_down (drvdat , toolType , contactData );
186
+ contactData += drvdat -> tp -> contact_size ;
170
187
}
171
188
}
172
189
173
- input_report_key (input , BTN_LEFT , data [1 ] & BTN_LEFT_MASK );
174
- asus_report_tool_width (input );
190
+ input_report_key (drvdat -> input , BTN_LEFT , data [1 ] & BTN_LEFT_MASK );
191
+ asus_report_tool_width (drvdat );
192
+
193
+ input_mt_sync_frame (drvdat -> input );
194
+ input_sync (drvdat -> input );
175
195
176
- input_mt_sync_frame (input );
177
- input_sync (input );
196
+ return 1 ;
178
197
}
179
198
180
199
static int asus_raw_event (struct hid_device * hdev ,
181
200
struct hid_report * report , u8 * data , int size )
182
201
{
183
202
struct asus_drvdata * drvdata = hid_get_drvdata (hdev );
184
203
185
- if (drvdata -> quirks & QUIRK_IS_MULTITOUCH &&
186
- data [0 ] == INPUT_REPORT_ID &&
187
- size == INPUT_REPORT_SIZE ) {
188
- asus_report_input (drvdata -> input , data );
189
- return 1 ;
190
- }
204
+ if (drvdata -> tp && data [0 ] == INPUT_REPORT_ID )
205
+ return asus_report_input (drvdata , data , size );
191
206
192
207
return 0 ;
193
208
}
@@ -339,22 +354,22 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
339
354
struct input_dev * input = hi -> input ;
340
355
struct asus_drvdata * drvdata = hid_get_drvdata (hdev );
341
356
342
- if (drvdata -> quirks & QUIRK_IS_MULTITOUCH ) {
357
+ if (drvdata -> tp ) {
343
358
int ret ;
344
359
345
- if (drvdata -> quirks & QUIRK_T100_TOUCHPAD )
346
- input_set_abs_params (input , ABS_MT_POSITION_X , 0 , MAX_X_T100 , 0 , 0 );
347
- else
348
- input_set_abs_params (input , ABS_MT_POSITION_X , 0 , MAX_X , 0 , 0 );
349
- input_set_abs_params (input , ABS_MT_POSITION_Y , 0 , MAX_Y , 0 , 0 );
360
+ input_set_abs_params (input , ABS_MT_POSITION_X , 0 ,
361
+ drvdata -> tp -> max_x , 0 , 0 );
362
+ input_set_abs_params (input , ABS_MT_POSITION_Y , 0 ,
363
+ drvdata -> tp -> max_y , 0 , 0 );
350
364
input_set_abs_params (input , ABS_TOOL_WIDTH , 0 , MAX_TOUCH_MAJOR , 0 , 0 );
351
365
input_set_abs_params (input , ABS_MT_TOUCH_MAJOR , 0 , MAX_TOUCH_MAJOR , 0 , 0 );
352
366
input_set_abs_params (input , ABS_MT_PRESSURE , 0 , MAX_PRESSURE , 0 , 0 );
353
367
354
368
__set_bit (BTN_LEFT , input -> keybit );
355
369
__set_bit (INPUT_PROP_BUTTONPAD , input -> propbit );
356
370
357
- ret = input_mt_init_slots (input , MAX_CONTACTS , INPUT_MT_POINTER );
371
+ ret = input_mt_init_slots (input , drvdata -> tp -> max_contacts ,
372
+ INPUT_MT_POINTER );
358
373
359
374
if (ret ) {
360
375
hid_err (hdev , "Asus input mt init slots failed: %d\n" , ret );
@@ -504,7 +519,7 @@ static int __maybe_unused asus_reset_resume(struct hid_device *hdev)
504
519
{
505
520
struct asus_drvdata * drvdata = hid_get_drvdata (hdev );
506
521
507
- if (drvdata -> quirks & QUIRK_IS_MULTITOUCH )
522
+ if (drvdata -> tp )
508
523
return asus_start_multitouch (hdev );
509
524
510
525
return 0 ;
@@ -525,11 +540,16 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
525
540
526
541
drvdata -> quirks = id -> driver_data ;
527
542
543
+ if (drvdata -> quirks & QUIRK_IS_MULTITOUCH )
544
+ drvdata -> tp = & asus_i2c_tp ;
545
+
528
546
if (drvdata -> quirks & QUIRK_T100_KEYBOARD ) {
529
547
struct usb_interface * intf = to_usb_interface (hdev -> dev .parent );
530
548
531
- if (intf -> altsetting -> desc .bInterfaceNumber == T100_TPAD_INTF )
532
- drvdata -> quirks = TOUCHPAD_QUIRKS | QUIRK_T100_TOUCHPAD ;
549
+ if (intf -> altsetting -> desc .bInterfaceNumber == T100_TPAD_INTF ) {
550
+ drvdata -> quirks = QUIRK_SKIP_INPUT_MAPPING ;
551
+ drvdata -> tp = & asus_t100ta_tp ;
552
+ }
533
553
}
534
554
535
555
if (drvdata -> quirks & QUIRK_NO_INIT_REPORTS )
@@ -553,13 +573,13 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
553
573
goto err_stop_hw ;
554
574
}
555
575
556
- if (drvdata -> quirks & QUIRK_IS_MULTITOUCH ) {
576
+ if (drvdata -> tp ) {
557
577
drvdata -> input -> name = "Asus TouchPad" ;
558
578
} else {
559
579
drvdata -> input -> name = "Asus Keyboard" ;
560
580
}
561
581
562
- if (drvdata -> quirks & QUIRK_IS_MULTITOUCH ) {
582
+ if (drvdata -> tp ) {
563
583
ret = asus_start_multitouch (hdev );
564
584
if (ret )
565
585
goto err_stop_hw ;
@@ -606,7 +626,7 @@ static const struct hid_device_id asus_devices[] = {
606
626
{ HID_I2C_DEVICE (USB_VENDOR_ID_ASUSTEK ,
607
627
USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD ), I2C_KEYBOARD_QUIRKS },
608
628
{ HID_I2C_DEVICE (USB_VENDOR_ID_ASUSTEK ,
609
- USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD ), TOUCHPAD_QUIRKS },
629
+ USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD ), I2C_TOUCHPAD_QUIRKS },
610
630
{ HID_USB_DEVICE (USB_VENDOR_ID_ASUSTEK ,
611
631
USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 ) },
612
632
{ HID_USB_DEVICE (USB_VENDOR_ID_ASUSTEK ,
0 commit comments