50
50
#define ETP_MAX_FINGERS 5
51
51
#define ETP_FINGER_DATA_LEN 5
52
52
#define ETP_REPORT_ID 0x5D
53
+ #define ETP_REPORT_ID2 0x60 /* High precision report */
53
54
#define ETP_TP_REPORT_ID 0x5E
54
55
#define ETP_REPORT_ID_OFFSET 2
55
56
#define ETP_TOUCH_INFO_OFFSET 3
56
57
#define ETP_FINGER_DATA_OFFSET 4
57
58
#define ETP_HOVER_INFO_OFFSET 30
58
- #define ETP_MAX_REPORT_LEN 34
59
+ #define ETP_MK_DATA_OFFSET 33 /* For high precision reports */
60
+ #define ETP_MAX_REPORT_LEN 39
59
61
60
62
/* The main device structure */
61
63
struct elan_tp_data {
@@ -85,6 +87,8 @@ struct elan_tp_data {
85
87
u8 sm_version ;
86
88
u8 iap_version ;
87
89
u16 fw_checksum ;
90
+ unsigned int report_features ;
91
+ unsigned int report_len ;
88
92
int pressure_adjustment ;
89
93
u8 mode ;
90
94
u16 ic_type ;
@@ -359,6 +363,12 @@ static int elan_query_device_info(struct elan_tp_data *data)
359
363
if (error )
360
364
return error ;
361
365
366
+ error = data -> ops -> get_report_features (data -> client , data -> pattern ,
367
+ & data -> report_features ,
368
+ & data -> report_len );
369
+ if (error )
370
+ return error ;
371
+
362
372
error = elan_get_fwinfo (data -> ic_type , data -> iap_version ,
363
373
& data -> fw_validpage_count ,
364
374
& data -> fw_signature_address ,
@@ -371,16 +381,21 @@ static int elan_query_device_info(struct elan_tp_data *data)
371
381
return 0 ;
372
382
}
373
383
374
- static unsigned int elan_convert_resolution (u8 val )
384
+ static unsigned int elan_convert_resolution (u8 val , u8 pattern )
375
385
{
376
386
/*
377
- * (value from firmware) * 10 + 790 = dpi
378
- *
387
+ * pattern <= 0x01:
388
+ * (value from firmware) * 10 + 790 = dpi
389
+ * else
390
+ * ((value from firmware) + 3) * 100 = dpi
391
+ */
392
+ int res = pattern <= 0x01 ?
393
+ (int )(char )val * 10 + 790 : ((int )(char )val + 3 ) * 100 ;
394
+ /*
379
395
* We also have to convert dpi to dots/mm (*10/254 to avoid floating
380
396
* point).
381
397
*/
382
-
383
- return ((int )(char )val * 10 + 790 ) * 10 / 254 ;
398
+ return res * 10 / 254 ;
384
399
}
385
400
386
401
static int elan_query_device_parameters (struct elan_tp_data * data )
@@ -429,8 +444,8 @@ static int elan_query_device_parameters(struct elan_tp_data *data)
429
444
if (error )
430
445
return error ;
431
446
432
- data -> x_res = elan_convert_resolution (hw_x_res );
433
- data -> y_res = elan_convert_resolution (hw_y_res );
447
+ data -> x_res = elan_convert_resolution (hw_x_res , data -> pattern );
448
+ data -> y_res = elan_convert_resolution (hw_y_res , data -> pattern );
434
449
} else {
435
450
data -> x_res = (data -> max_x + 1 ) / x_mm ;
436
451
data -> y_res = (data -> max_y + 1 ) / y_mm ;
@@ -908,24 +923,22 @@ static const struct attribute_group *elan_sysfs_groups[] = {
908
923
* Elan isr functions
909
924
******************************************************************
910
925
*/
911
- static void elan_report_contact (struct elan_tp_data * data ,
912
- int contact_num , bool contact_valid ,
913
- u8 * finger_data )
926
+ static void elan_report_contact (struct elan_tp_data * data , int contact_num ,
927
+ bool contact_valid , bool high_precision ,
928
+ u8 * packet , u8 * finger_data )
914
929
{
915
930
struct input_dev * input = data -> input ;
916
931
unsigned int pos_x , pos_y ;
917
- unsigned int pressure , mk_x , mk_y ;
918
- unsigned int area_x , area_y , major , minor ;
919
- unsigned int scaled_pressure ;
932
+ unsigned int pressure , scaled_pressure ;
920
933
921
934
if (contact_valid ) {
922
- pos_x = (( finger_data [ 0 ] & 0xf0 ) << 4 ) |
923
- finger_data [1 ] ;
924
- pos_y = (( finger_data [0 ] & 0x0f ) << 8 ) |
925
- finger_data [ 2 ];
926
- mk_x = (finger_data [3 ] & 0x0f ) ;
927
- mk_y = (finger_data [3 ] >> 4 ) ;
928
- pressure = finger_data [ 4 ];
935
+ if ( high_precision ) {
936
+ pos_x = get_unaligned_be16 ( & finger_data [0 ]) ;
937
+ pos_y = get_unaligned_be16 ( & finger_data [2 ]);
938
+ } else {
939
+ pos_x = (( finger_data [0 ] & 0xf0 ) << 4 ) | finger_data [ 1 ] ;
940
+ pos_y = (( finger_data [0 ] & 0x0f ) << 8 ) | finger_data [ 2 ] ;
941
+ }
929
942
930
943
if (pos_x > data -> max_x || pos_y > data -> max_y ) {
931
944
dev_dbg (input -> dev .parent ,
@@ -935,18 +948,8 @@ static void elan_report_contact(struct elan_tp_data *data,
935
948
return ;
936
949
}
937
950
938
- /*
939
- * To avoid treating large finger as palm, let's reduce the
940
- * width x and y per trace.
941
- */
942
- area_x = mk_x * (data -> width_x - ETP_FWIDTH_REDUCE );
943
- area_y = mk_y * (data -> width_y - ETP_FWIDTH_REDUCE );
944
-
945
- major = max (area_x , area_y );
946
- minor = min (area_x , area_y );
947
-
951
+ pressure = finger_data [4 ];
948
952
scaled_pressure = pressure + data -> pressure_adjustment ;
949
-
950
953
if (scaled_pressure > ETP_MAX_PRESSURE )
951
954
scaled_pressure = ETP_MAX_PRESSURE ;
952
955
@@ -955,16 +958,37 @@ static void elan_report_contact(struct elan_tp_data *data,
955
958
input_report_abs (input , ABS_MT_POSITION_X , pos_x );
956
959
input_report_abs (input , ABS_MT_POSITION_Y , data -> max_y - pos_y );
957
960
input_report_abs (input , ABS_MT_PRESSURE , scaled_pressure );
958
- input_report_abs (input , ABS_TOOL_WIDTH , mk_x );
959
- input_report_abs (input , ABS_MT_TOUCH_MAJOR , major );
960
- input_report_abs (input , ABS_MT_TOUCH_MINOR , minor );
961
+
962
+ if (data -> report_features & ETP_FEATURE_REPORT_MK ) {
963
+ unsigned int mk_x , mk_y , area_x , area_y ;
964
+ u8 mk_data = high_precision ?
965
+ packet [ETP_MK_DATA_OFFSET + contact_num ] :
966
+ finger_data [3 ];
967
+
968
+ mk_x = mk_data & 0x0f ;
969
+ mk_y = mk_data >> 4 ;
970
+
971
+ /*
972
+ * To avoid treating large finger as palm, let's reduce
973
+ * the width x and y per trace.
974
+ */
975
+ area_x = mk_x * (data -> width_x - ETP_FWIDTH_REDUCE );
976
+ area_y = mk_y * (data -> width_y - ETP_FWIDTH_REDUCE );
977
+
978
+ input_report_abs (input , ABS_TOOL_WIDTH , mk_x );
979
+ input_report_abs (input , ABS_MT_TOUCH_MAJOR ,
980
+ max (area_x , area_y ));
981
+ input_report_abs (input , ABS_MT_TOUCH_MINOR ,
982
+ min (area_x , area_y ));
983
+ }
961
984
} else {
962
985
input_mt_slot (input , contact_num );
963
986
input_mt_report_slot_state (input , MT_TOOL_FINGER , false);
964
987
}
965
988
}
966
989
967
- static void elan_report_absolute (struct elan_tp_data * data , u8 * packet )
990
+ static void elan_report_absolute (struct elan_tp_data * data , u8 * packet ,
991
+ bool high_precision )
968
992
{
969
993
struct input_dev * input = data -> input ;
970
994
u8 * finger_data = & packet [ETP_FINGER_DATA_OFFSET ];
@@ -973,11 +997,12 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
973
997
u8 hover_info = packet [ETP_HOVER_INFO_OFFSET ];
974
998
bool contact_valid , hover_event ;
975
999
976
- hover_event = hover_info & 0x40 ;
977
- for (i = 0 ; i < ETP_MAX_FINGERS ; i ++ ) {
978
- contact_valid = tp_info & (1U << (3 + i ));
979
- elan_report_contact (data , i , contact_valid , finger_data );
1000
+ hover_event = hover_info & BIT (6 );
980
1001
1002
+ for (i = 0 ; i < ETP_MAX_FINGERS ; i ++ ) {
1003
+ contact_valid = tp_info & BIT (3 + i );
1004
+ elan_report_contact (data , i , contact_valid , high_precision ,
1005
+ packet , finger_data );
981
1006
if (contact_valid )
982
1007
finger_data += ETP_FINGER_DATA_LEN ;
983
1008
}
@@ -1034,15 +1059,18 @@ static irqreturn_t elan_isr(int irq, void *dev_id)
1034
1059
goto out ;
1035
1060
}
1036
1061
1037
- error = data -> ops -> get_report (data -> client , report );
1062
+ error = data -> ops -> get_report (data -> client , report , data -> report_len );
1038
1063
if (error )
1039
1064
goto out ;
1040
1065
1041
1066
pm_wakeup_event (dev , 0 );
1042
1067
1043
1068
switch (report [ETP_REPORT_ID_OFFSET ]) {
1044
1069
case ETP_REPORT_ID :
1045
- elan_report_absolute (data , report );
1070
+ elan_report_absolute (data , report , false);
1071
+ break ;
1072
+ case ETP_REPORT_ID2 :
1073
+ elan_report_absolute (data , report , true);
1046
1074
break ;
1047
1075
case ETP_TP_REPORT_ID :
1048
1076
elan_report_trackpoint (data , report );
@@ -1133,7 +1161,9 @@ static int elan_setup_input_device(struct elan_tp_data *data)
1133
1161
input_abs_set_res (input , ABS_X , data -> x_res );
1134
1162
input_abs_set_res (input , ABS_Y , data -> y_res );
1135
1163
input_set_abs_params (input , ABS_PRESSURE , 0 , ETP_MAX_PRESSURE , 0 , 0 );
1136
- input_set_abs_params (input , ABS_TOOL_WIDTH , 0 , ETP_FINGER_WIDTH , 0 , 0 );
1164
+ if (data -> report_features & ETP_FEATURE_REPORT_MK )
1165
+ input_set_abs_params (input , ABS_TOOL_WIDTH ,
1166
+ 0 , ETP_FINGER_WIDTH , 0 , 0 );
1137
1167
input_set_abs_params (input , ABS_DISTANCE , 0 , 1 , 0 , 0 );
1138
1168
1139
1169
/* And MT parameters */
@@ -1143,10 +1173,12 @@ static int elan_setup_input_device(struct elan_tp_data *data)
1143
1173
input_abs_set_res (input , ABS_MT_POSITION_Y , data -> y_res );
1144
1174
input_set_abs_params (input , ABS_MT_PRESSURE , 0 ,
1145
1175
ETP_MAX_PRESSURE , 0 , 0 );
1146
- input_set_abs_params (input , ABS_MT_TOUCH_MAJOR , 0 ,
1147
- ETP_FINGER_WIDTH * max_width , 0 , 0 );
1148
- input_set_abs_params (input , ABS_MT_TOUCH_MINOR , 0 ,
1149
- ETP_FINGER_WIDTH * min_width , 0 , 0 );
1176
+ if (data -> report_features & ETP_FEATURE_REPORT_MK ) {
1177
+ input_set_abs_params (input , ABS_MT_TOUCH_MAJOR ,
1178
+ 0 , ETP_FINGER_WIDTH * max_width , 0 , 0 );
1179
+ input_set_abs_params (input , ABS_MT_TOUCH_MINOR ,
1180
+ 0 , ETP_FINGER_WIDTH * min_width , 0 , 0 );
1181
+ }
1150
1182
1151
1183
data -> input = input ;
1152
1184
0 commit comments