@@ -53,6 +53,7 @@ struct goodix_ts_data {
53
53
const char * cfg_name ;
54
54
struct completion firmware_loading_complete ;
55
55
unsigned long irq_flags ;
56
+ unsigned int contact_size ;
56
57
};
57
58
58
59
#define GOODIX_GPIO_INT_NAME "irq"
@@ -62,6 +63,7 @@ struct goodix_ts_data {
62
63
#define GOODIX_MAX_WIDTH 4096
63
64
#define GOODIX_INT_TRIGGER 1
64
65
#define GOODIX_CONTACT_SIZE 8
66
+ #define GOODIX_MAX_CONTACT_SIZE 9
65
67
#define GOODIX_MAX_CONTACTS 10
66
68
67
69
#define GOODIX_CONFIG_MAX_LENGTH 240
@@ -144,6 +146,19 @@ static const struct dmi_system_id rotated_screen[] = {
144
146
{}
145
147
};
146
148
149
+ static const struct dmi_system_id nine_bytes_report [] = {
150
+ #if defined(CONFIG_DMI ) && defined (CONFIG_X86 )
151
+ {
152
+ .ident = "Lenovo YogaBook" ,
153
+ /* YB1-X91L/F and YB1-X90L/F */
154
+ .matches = {
155
+ DMI_MATCH (DMI_PRODUCT_NAME , "Lenovo YB1-X9" )
156
+ }
157
+ },
158
+ #endif
159
+ {}
160
+ };
161
+
147
162
/**
148
163
* goodix_i2c_read - read data from a register of the i2c slave device.
149
164
*
@@ -249,7 +264,7 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
249
264
max_timeout = jiffies + msecs_to_jiffies (GOODIX_BUFFER_STATUS_TIMEOUT );
250
265
do {
251
266
error = goodix_i2c_read (ts -> client , GOODIX_READ_COOR_ADDR ,
252
- data , GOODIX_CONTACT_SIZE + 1 );
267
+ data , ts -> contact_size + 1 );
253
268
if (error ) {
254
269
dev_err (& ts -> client -> dev , "I2C transfer error: %d\n" ,
255
270
error );
@@ -262,12 +277,12 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
262
277
return - EPROTO ;
263
278
264
279
if (touch_num > 1 ) {
265
- data += 1 + GOODIX_CONTACT_SIZE ;
280
+ data += 1 + ts -> contact_size ;
266
281
error = goodix_i2c_read (ts -> client ,
267
282
GOODIX_READ_COOR_ADDR +
268
- 1 + GOODIX_CONTACT_SIZE ,
283
+ 1 + ts -> contact_size ,
269
284
data ,
270
- GOODIX_CONTACT_SIZE *
285
+ ts -> contact_size *
271
286
(touch_num - 1 ));
272
287
if (error )
273
288
return error ;
@@ -286,7 +301,7 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
286
301
return 0 ;
287
302
}
288
303
289
- static void goodix_ts_report_touch (struct goodix_ts_data * ts , u8 * coor_data )
304
+ static void goodix_ts_report_touch_8b (struct goodix_ts_data * ts , u8 * coor_data )
290
305
{
291
306
int id = coor_data [0 ] & 0x0F ;
292
307
int input_x = get_unaligned_le16 (& coor_data [1 ]);
@@ -301,6 +316,21 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
301
316
input_report_abs (ts -> input_dev , ABS_MT_WIDTH_MAJOR , input_w );
302
317
}
303
318
319
+ static void goodix_ts_report_touch_9b (struct goodix_ts_data * ts , u8 * coor_data )
320
+ {
321
+ int id = coor_data [1 ] & 0x0F ;
322
+ int input_x = get_unaligned_le16 (& coor_data [3 ]);
323
+ int input_y = get_unaligned_le16 (& coor_data [5 ]);
324
+ int input_w = get_unaligned_le16 (& coor_data [7 ]);
325
+
326
+ input_mt_slot (ts -> input_dev , id );
327
+ input_mt_report_slot_state (ts -> input_dev , MT_TOOL_FINGER , true);
328
+ touchscreen_report_pos (ts -> input_dev , & ts -> prop ,
329
+ input_x , input_y , true);
330
+ input_report_abs (ts -> input_dev , ABS_MT_TOUCH_MAJOR , input_w );
331
+ input_report_abs (ts -> input_dev , ABS_MT_WIDTH_MAJOR , input_w );
332
+ }
333
+
304
334
/**
305
335
* goodix_process_events - Process incoming events
306
336
*
@@ -311,7 +341,7 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
311
341
*/
312
342
static void goodix_process_events (struct goodix_ts_data * ts )
313
343
{
314
- u8 point_data [1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS ];
344
+ u8 point_data [1 + GOODIX_MAX_CONTACT_SIZE * GOODIX_MAX_CONTACTS ];
315
345
int touch_num ;
316
346
int i ;
317
347
@@ -326,8 +356,12 @@ static void goodix_process_events(struct goodix_ts_data *ts)
326
356
input_report_key (ts -> input_dev , KEY_LEFTMETA , point_data [0 ] & BIT (4 ));
327
357
328
358
for (i = 0 ; i < touch_num ; i ++ )
329
- goodix_ts_report_touch (ts ,
330
- & point_data [1 + GOODIX_CONTACT_SIZE * i ]);
359
+ if (ts -> contact_size == 9 )
360
+ goodix_ts_report_touch_9b (ts ,
361
+ & point_data [1 + ts -> contact_size * i ]);
362
+ else
363
+ goodix_ts_report_touch_8b (ts ,
364
+ & point_data [1 + ts -> contact_size * i ]);
331
365
332
366
input_mt_sync_frame (ts -> input_dev );
333
367
input_sync (ts -> input_dev );
@@ -730,6 +764,13 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
730
764
"Applying '180 degrees rotated screen' quirk\n" );
731
765
}
732
766
767
+ if (dmi_check_system (nine_bytes_report )) {
768
+ ts -> contact_size = 9 ;
769
+
770
+ dev_dbg (& ts -> client -> dev ,
771
+ "Non-standard 9-bytes report format quirk\n" );
772
+ }
773
+
733
774
error = input_mt_init_slots (ts -> input_dev , ts -> max_touch_num ,
734
775
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED );
735
776
if (error ) {
@@ -810,6 +851,7 @@ static int goodix_ts_probe(struct i2c_client *client,
810
851
ts -> client = client ;
811
852
i2c_set_clientdata (client , ts );
812
853
init_completion (& ts -> firmware_loading_complete );
854
+ ts -> contact_size = GOODIX_CONTACT_SIZE ;
813
855
814
856
error = goodix_get_gpio_config (ts );
815
857
if (error )
0 commit comments