forked from CyanogenMod/android_kernel_xiaomi_cancro
-
Notifications
You must be signed in to change notification settings - Fork 3
/
atmel_mxt_ts.c
5713 lines (4832 loc) · 140 KB
/
atmel_mxt_ts.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Atmel maXTouch Touchscreen driver
*
* Copyright (C) 2010 Samsung Electronics Co.Ltd
* Copyright (C) 2011 Atmel Corporation
* Author: Joonyoung Shim <jy0922.shim@samsung.com>
* Copyright (C) 2015 XiaoMi, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/i2c.h>
#include <linux/i2c/atmel_mxt_ts_640t.h>
#include <linux/debugfs.h>
#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
#include <linux/gpio.h>
#include <linux/string.h>
#include <linux/of_gpio.h>
#include <asm/bootinfo.h>
#include <mach/gpiomux.h>
#ifdef CONFIG_FB
#include <linux/notifier.h>
#include <linux/fb.h>
#endif
/* Version */
#define MXT_VER_20 20
#define MXT_VER_21 21
#define MXT_VER_22 22
/* Firmware files */
#define MXT_FW_NAME "maxtouch.fw"
#define MXT_CFG_MAGIC "OBP_RAW V1"
#define REV_D 0x32
/* Registers */
#define MXT_FAMILY_ID 0x00
#define MXT_VARIANT_ID 0x01
#define MXT_VERSION 0x02
#define MXT_BUILD 0x03
#define MXT_MATRIX_X_SIZE 0x04
#define MXT_MATRIX_Y_SIZE 0x05
#define MXT_OBJECT_NUM 0x06
#define MXT_OBJECT_START 0x07
#define MXT_OBJECT_SIZE 6
#define MXT_MAX_BLOCK_WRITE 256
/* Object types */
#define MXT_DEBUG_DIAGNOSTIC_T37 37
#define MXT_SPT_USERDATA_T38 38
#define MXT_GEN_MESSAGE_T5 5
#define MXT_GEN_COMMAND_T6 6
#define MXT_GEN_POWER_T7 7
#define MXT_GEN_ACQUIRE_T8 8
#define MXT_GEN_DATASOURCE_T53 53
#define MXT_TOUCH_MULTI_T9 9
#define MXT_TOUCH_KEYARRAY_T15 15
#define MXT_TOUCH_PROXIMITY_T23 23
#define MXT_TOUCH_PROXKEY_T52 52
#define MXT_PROCI_GRIPFACE_T20 20
#define MXT_PROCG_NOISE_T22 22
#define MXT_PROCI_ACTIVE_STYLUS_T63 63
#define MXT_PROCI_ONETOUCH_T24 24
#define MXT_PROCI_TWOTOUCH_T27 27
#define MXT_PROCI_GRIP_T40 40
#define MXT_PROCI_PALM_T41 41
#define MXT_PROCI_TOUCHSUPPRESSION_T42 42
#define MXT_PROCI_STYLUS_T47 47
#define MXT_PROCG_NOISESUPPRESSION_T48 48
#define MXT_SPT_COMMSCONFIG_T18 18
#define MXT_SPT_GPIOPWM_T19 19
#define MXT_SPT_SELFTEST_T25 25
#define MXT_SPT_CTECONFIG_T28 28
#define MXT_SPT_DIGITIZER_T43 43
#define MXT_SPT_MESSAGECOUNT_T44 44
#define MXT_SPT_CTECONFIG_T46 46
#define MXT_SPT_NOISESUPPRESSION_T48 48
#define MXT_PROCI_LENSBENDING_T65 65
#define MXT_SPT_GOLDENREF_T66 66
#define MXT_SERIALDATACOMMAND_T68 68
#define MXT_SPT_DYMCFG_T70 70
#define MXT_SPT_DYMDATA_T71 71
#define MXT_PROCG_NOISESUPPRESSION_T72 72
#define MXT_PROCI_GLOVEDETECTION_T78 78
#define MXT_PROCI_RETRANSMISSIONCOMPENSATION_T80 80
#define MXT_TOUCH_MORE_GESTURE_T81 81
#define MXT_TOUCH_GESTURE_T92 92
#define MXT_TOUCH_MULTI_T100 100
#define MXT_SPT_TOUCHSCREENHOVER_T101 101
#define MXT_PROCG_NOISESUPSELFCAP_T108 108
#define MXT_SPT_SELFCAPGLOBALCONFIG_T109 109
#define MXT_SPT_AUXTOUCHCONFIG_T104 104
/* MXT_GEN_MESSAGE_T5 object */
#define MXT_RPTID_NOMSG 0xff
/* MXT_GEN_COMMAND_T6 field */
#define MXT_COMMAND_RESET 0
#define MXT_COMMAND_BACKUPNV 1
#define MXT_COMMAND_CALIBRATE 2
#define MXT_COMMAND_REPORTALL 3
#define MXT_COMMAND_DIAGNOSTIC 5
/* MXT_GEN_POWER_T7 field */
#define MXT_POWER_IDLEACQINT 0
#define MXT_POWER_ACTVACQINT 1
#define MXT_POWER_ACTV2IDLETO 2
#define MXT_POWER_CFG_RUN 0
#define MXT_POWER_CFG_DEEPSLEEP 1
/* MXT_GEN_ACQUIRE_T8 field */
#define MXT_ACQUIRE_CHRGTIME 0
#define MXT_ACQUIRE_TCHDRIFT 2
#define MXT_ACQUIRE_DRIFTST 3
#define MXT_ACQUIRE_TCHAUTOCAL 4
#define MXT_ACQUIRE_SYNC 5
#define MXT_ACQUIRE_ATCHCALST 6
#define MXT_ACQUIRE_ATCHCALSTHR 7
#define MXT_ACQUIRE_MEASALLOW 10
/* MXT_TOUCH_MULTI_T9 field */
#define MXT_TOUCH_CTRL 0
#define MXT_TOUCH_XORIGIN 1
#define MXT_TOUCH_YORIGIN 2
#define MXT_TOUCH_XSIZE 3
#define MXT_TOUCH_YSIZE 4
#define MXT_TOUCH_BLEN 6
#define MXT_TOUCH_TCHTHR 7
#define MXT_TOUCH_TCHDI 8
#define MXT_TOUCH_ORIENT 9
#define MXT_TOUCH_MOVHYSTI 11
#define MXT_TOUCH_MOVHYSTN 12
#define MXT_TOUCH_NUMTOUCH 14
#define MXT_TOUCH_MRGHYST 15
#define MXT_TOUCH_MRGTHR 16
#define MXT_TOUCH_AMPHYST 17
#define MXT_TOUCH_XRANGE_LSB 18
#define MXT_TOUCH_XRANGE_MSB 19
#define MXT_TOUCH_YRANGE_LSB 20
#define MXT_TOUCH_YRANGE_MSB 21
#define MXT_TOUCH_XLOCLIP 22
#define MXT_TOUCH_XHICLIP 23
#define MXT_TOUCH_YLOCLIP 24
#define MXT_TOUCH_YHICLIP 25
#define MXT_TOUCH_XEDGECTRL 26
#define MXT_TOUCH_XEDGEDIST 27
#define MXT_TOUCH_YEDGECTRL 28
#define MXT_TOUCH_YEDGEDIST 29
#define MXT_TOUCH_JUMPLIMIT 30
/* MXT_TOUCH_MULTI_T100 field */
#define MXT_MULTITOUCH_CTRL 0
#define MXT_MULTITOUCH_CFG1 1
#define MXT_MULTITOUCH_SCRAUX 2
#define MXT_MULTITOUCH_TCHAUX 3
#define MXT_MULTITOUCH_TCHEVENTCFG 4
#define MXT_MULTITOUCH_AKSCFG 5
#define MXT_MULTITOUCH_NUMTCH 6
#define MXT_MULTITOUCH_XYCFG 7
#define MXT_MULTITOUCH_XORIGIN 8
#define MXT_MULTITOUCH_XSIZE 9
#define MXT_MULTITOUCH_XPITCH 10
#define MXT_MULTITOUCH_XLOCLIP 11
#define MXT_MULTITOUCH_XHICLIP 12
#define MXT_MULTITOUCH_XRANGE_LSB 13
#define MXT_MULTITOUCH_XRANGE_MSB 14
#define MXT_MULTITOUCH_XEDGECFG 15
#define MXT_MULTITOUCH_XEDGEDIST 16
#define MXT_MULTITOUCH_DXEDGECFG 17
#define MXT_MULTITOUCH_DXEDGEDIST 18
#define MXT_MULTITOUCH_YORIGIN 19
#define MXT_MULTITOUCH_YSIZE 20
#define MXT_MULTITOUCH_YPITCH 21
#define MXT_MULTITOUCH_YLOCLIP 22
#define MXT_MULTITOUCH_YHICLIP 23
#define MXT_MULTITOUCH_YRANGE_LSB 24
#define MXT_MULTITOUCH_YRANGE_MSB 25
#define MXT_MULTITOUCH_YEDGECFG 26
#define MXT_MULTITOUCH_YEDGEDIST 27
#define MXT_MULTITOUCH_GAIN 28
#define MXT_MULTITOUCH_DXGAIN 29
#define MXT_MULTITOUCH_TCHTHR 30
#define MXT_MULTITOUCH_TCHHYST 31
#define MXT_MULTITOUCH_INTTHR 32
#define MXT_MULTITOUCH_NOISESF 33
#define MXT_MULTITOUCH_MGRTHR 35
#define MXT_MULTITOUCH_MRGTHRADJSTR 36
#define MXT_MULTITOUCH_MRGHYST 37
#define MXT_MULTITOUCH_DXTHRSF 38
#define MXT_MULTITOUCH_TCHDIDOWN 39
#define MXT_MULTITOUCH_TCHDIUP 40
#define MXT_MULTITOUCH_NEXTTCHDI 41
#define MXT_MULTITOUCH_JUMPLIMIT 43
#define MXT_MULTITOUCH_MOVFILTER 44
#define MXT_MULTITOUCH_MOVSMOOTH 45
#define MXT_MULTITOUCH_MOVPRED 46
#define MXT_MULTITOUCH_MOVHYSTILSB 47
#define MXT_MULTITOUCH_MOVHYSTIMSB 48
#define MXT_MULTITOUCH_MOVHYSTNLSB 49
#define MXT_MULTITOUCH_MOVHYSTNMSB 50
#define MXT_MULTITOUCH_AMPLHYST 51
#define MXT_MULTITOUCH_SCRAREAHYST 52
/* MXT_TOUCH_KEYARRAY_T15 */
#define MXT_KEYARRAY_CTRL 0
/* MXT_PROCI_GRIPFACE_T20 field */
#define MXT_GRIPFACE_CTRL 0
#define MXT_GRIPFACE_XLOGRIP 1
#define MXT_GRIPFACE_XHIGRIP 2
#define MXT_GRIPFACE_YLOGRIP 3
#define MXT_GRIPFACE_YHIGRIP 4
#define MXT_GRIPFACE_MAXTCHS 5
#define MXT_GRIPFACE_SZTHR1 7
#define MXT_GRIPFACE_SZTHR2 8
#define MXT_GRIPFACE_SHPTHR1 9
#define MXT_GRIPFACE_SHPTHR2 10
#define MXT_GRIPFACE_SUPEXTTO 11
/* MXT_PROCI_NOISE field */
#define MXT_NOISE_CTRL 0
#define MXT_NOISE_OUTFLEN 1
#define MXT_NOISE_GCAFUL_LSB 3
#define MXT_NOISE_GCAFUL_MSB 4
#define MXT_NOISE_GCAFLL_LSB 5
#define MXT_NOISE_GCAFLL_MSB 6
#define MXT_NOISE_ACTVGCAFVALID 7
#define MXT_NOISE_NOISETHR 8
#define MXT_NOISE_FREQHOPSCALE 10
#define MXT_NOISE_FREQ0 11
#define MXT_NOISE_FREQ1 12
#define MXT_NOISE_FREQ2 13
#define MXT_NOISE_FREQ3 14
#define MXT_NOISE_FREQ4 15
#define MXT_NOISE_IDLEGCAFVALID 16
/* MXT_SPT_COMMSCONFIG_T18 */
#define MXT_COMMS_CTRL 0
#define MXT_COMMS_CMD 1
/* MXT_SPT_GPIOPWM_T19 */
#define MXT_GPIOPWM_CTRL 0
#define MXT_GPIOPWM_INTPULLUP 3
#define MXT_GPIO_FORCERPT 0x7
#define MXT_GPIO_DISABLEOUTPUT 0
/* MXT_SPT_CTECONFIG_T28 field */
#define MXT_CTE_CTRL 0
#define MXT_CTE_CMD 1
#define MXT_CTE_MODE 2
#define MXT_CTE_IDLEGCAFDEPTH 3
#define MXT_CTE_ACTVGCAFDEPTH 4
#define MXT_CTE_VOLTAGE 5
#define MXT_VOLTAGE_DEFAULT 2700000
#define MXT_VOLTAGE_STEP 10000
/* MXT_DEBUG_DIAGNOSTIC_T37 */
#define MXT_DIAG_PAGE_UP 0x01
#define MXT_DIAG_MULT_DELTA 0x10
#define MXT_DIAG_SELF_REF 0xF5
#define MXT_DIAG_SELF_DELTA 0xFC
#define MXT_DIAG_PAGE_SIZE 0x80
#define MXT_DIAG_TOTAL_SIZE 0x438
#define MXT_DIAG_SELF_SIZE 0x6C
#define MXT_DIAG_REV_ID 21
#define MXT_LOCKDOWN_OFFSET 4
/* MXT_SPT_USERDATA_T38 */
#define MXT_FW_UPDATE_FLAG 0
#define MXT_USERDATA_SIZE 8
/* MXT_PROCI_STYLUS_T47 */
#define MXT_PSTYLUS_CTRL 0
/* MXT_PROCI_LENSBENDING_T65 */
#define MXT_LENSBENDING_CTRL 0
/* MXT_SERIALDATACOMMAND_T68 */
#define MXT_LOCKDOWN_SIZE 8
/* MXT_PROCG_NOISESUPPRESSION_T72 */
#define MXT_NOISESUP_CTRL 0
#define MXT_NOISESUP_CALCFG 1
#define MXT_NOISESUP_CFG1 2
/* MXT_PROCI_GLOVEDETECTION_T78 */
#define MXT_GLOVE_CTRL 0x00
/* MXT_SPT_TOUCHSCREENHOVER_T101 */
#define MXT_HOVER_CTRL 0x00
/* MXT_SPT_AUXTOUCHCONFIG_T104 */
#define MXT_AUXTCHCFG_XTCHTHR 2
#define MXT_AUXTCHCFG_INTTHRX 4
#define MXT_AUXTCHCFG_YTCHTHR 7
#define MXT_AUXTCHCFG_INTTHRY 9
/* MXT_SPT_SELFCAPGLOBALCONFIG_T109 */
#define MXT_SELFCAPCFG_CTRL 0
#define MXT_SELFCAPCFG_CMD 3
/* Defines for Suspend/Resume */
#define MXT_SUSPEND_STATIC 0
#define MXT_SUSPEND_DYNAMIC 1
#define MXT_T7_IDLEACQ_DISABLE 0
#define MXT_T7_ACTVACQ_DISABLE 0
#define MXT_T7_ACTV2IDLE_DISABLE 0
#define MXT_T9_DISABLE 0
#define MXT_T9_ENABLE 0x83
#define MXT_T22_DISABLE 0
#define MXT_T100_DISABLE 0
/* Define for MXT_GEN_COMMAND_T6 */
#define MXT_RESET_VALUE 0x01
#define MXT_BACKUP_VALUE 0x55
/* Define for MXT_PROCG_NOISESUPPRESSION_T42 */
#define MXT_T42_MSG_TCHSUP (1 << 0)
/* Delay times */
#define MXT_BACKUP_TIME 25 /* msec */
#define MXT_RESET_TIME 200 /* msec */
#define MXT_RESET_NOCHGREAD 400 /* msec */
#define MXT_FWRESET_TIME 1000 /* msec */
#define MXT_WAKEUP_TIME 25 /* msec */
/* Defines for MXT_SLOWSCAN_EXTENSIONS */
#define SLOSCAN_DISABLE 0 /* Disable slow scan */
#define SLOSCAN_ENABLE 1 /* Enable slow scan */
#define SLOSCAN_SET_ACTVACQINT 2 /* Set ACTV scan rate */
#define SLOSCAN_SET_IDLEACQINT 3 /* Set IDLE scan rate */
#define SLOSCAN_SET_ACTV2IDLETO 4 /* Set the ACTIVE to IDLE TimeOut */
/* Command to unlock bootloader */
#define MXT_UNLOCK_CMD_MSB 0xaa
#define MXT_UNLOCK_CMD_LSB 0xdc
/* Bootloader mode status */
#define MXT_WAITING_BOOTLOAD_CMD 0xc0 /* valid 7 6 bit only */
#define MXT_WAITING_FRAME_DATA 0x80 /* valid 7 6 bit only */
#define MXT_FRAME_CRC_CHECK 0x02
#define MXT_FRAME_CRC_FAIL 0x03
#define MXT_FRAME_CRC_PASS 0x04
#define MXT_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */
#define MXT_BOOT_STATUS_MASK 0x3f
#define MXT_BOOT_EXTENDED_ID (1 << 5)
#define MXT_BOOT_ID_MASK 0x1f
/* Define for T6 status byte */
#define MXT_STATUS_RESET (1 << 7)
#define MXT_STATUS_OFL (1 << 6)
#define MXT_STATUS_SIGERR (1 << 5)
#define MXT_STATUS_CAL (1 << 4)
#define MXT_STATUS_CFGERR (1 << 3)
#define MXT_STATUS_COMSERR (1 << 2)
/* Define for T8 measallow byte */
#define MXT_MEASALLOW_MULT (1 << 0)
#define MXT_MEASALLOW_SELT (1 << 1)
/* T9 Touch status */
#define MXT_T9_UNGRIP (1 << 0)
#define MXT_T9_SUPPRESS (1 << 1)
#define MXT_T9_AMP (1 << 2)
#define MXT_T9_VECTOR (1 << 3)
#define MXT_T9_MOVE (1 << 4)
#define MXT_T9_RELEASE (1 << 5)
#define MXT_T9_PRESS (1 << 6)
#define MXT_T9_DETECT (1 << 7)
/* T100 Touch status */
#define MXT_T100_CTRL_RPTEN (1 << 1)
#define MXT_T100_EVENT_NONE 0
#define MXT_T100_EVENT_MOVE 1
#define MXT_T100_EVENT_UNSUP 2
#define MXT_T100_EVENT_SUP 3
#define MXT_T100_EVENT_DOWN 4
#define MXT_T100_EVENT_UP 5
#define MXT_T100_EVENT_UNSUPSUP 6
#define MXT_T100_EVENT_UNSUPUP 7
#define MXT_T100_EVENT_DOWNSUP 8
#define MXT_T100_EVENT_DOWNUP 9
#define MXT_T100_TYPE_RESERVED 0
#define MXT_T100_TYPE_FINGER 1
#define MXT_T100_TYPE_PASSIVE_STYLUS 2
#define MXT_T100_TYPE_ACTIVE_STYLUS 3
#define MXT_T100_TYPE_HOVERING_FINGER 4
#define MXT_T100_TYPE_HOVERING_GLOVE 5
#define MXT_T100_DETECT (1 << 7)
#define MXT_T100_VECT (1 << 0)
#define MXT_T100_AMPL (1 << 1)
#define MXT_T100_AREA (1 << 2)
#define MXT_T100_PEAK (1 << 4)
#define MXT_T100_SUP (1 << 6)
/* T15 KeyArray */
#define MXT_KEY_RPTEN (1 << 1)
#define MXT_KEY_ADAPTTHREN (1 << 2)
/* Touch orient bits */
#define MXT_XY_SWITCH (1 << 0)
#define MXT_X_INVERT (1 << 1)
#define MXT_Y_INVERT (1 << 2)
/* T47 passive stylus */
#define MXT_PSTYLUS_ENABLE (1 << 0)
/* T63 Stylus */
#define MXT_STYLUS_PRESS (1 << 0)
#define MXT_STYLUS_RELEASE (1 << 1)
#define MXT_STYLUS_MOVE (1 << 2)
#define MXT_STYLUS_SUPPRESS (1 << 3)
#define MXT_STYLUS_DETECT (1 << 4)
#define MXT_STYLUS_TIP (1 << 5)
#define MXT_STYLUS_ERASER (1 << 6)
#define MXT_STYLUS_BARREL (1 << 7)
#define MXT_STYLUS_PRESSURE_MASK 0x3F
/* Touchscreen absolute values */
#define MXT_MAX_AREA 0xff
/* T66 Golden Reference */
#define MXT_GOLDENREF_CTRL 0x00
#define MXT_GOLDENREF_FCALFAILTHR 0x01
#define MXT_GOLDENREF_FCALDRIFTCNT 0x02
#define MXT_GOLDENREF_FCALDRIFTCOEF 0x03
#define MXT_GOLDENREF_FCALDRIFTTLIM 0x04
#define MXT_GOLDCTRL_ENABLE (1 << 0)
#define MXT_GOLDCTRL_REPEN (1 << 1)
#define MXT_GOLDSTS_BADSTOREDATA (1 << 0)
#define MXT_GOLDSTS_FCALSEQERR (1 << 3)
#define MXT_GOLDSTS_FCALSEQTO (1 << 4)
#define MXT_GOLDSTS_FCALSEQDONE (1 << 5)
#define MXT_GOLDSTS_FCALPASS (1 << 6)
#define MXT_GOLDSTS_FCALFAIL (1 << 7)
#define MXT_GOLDCMD_NONE 0x00
#define MXT_GOLDCMD_PRIME 0x04
#define MXT_GOLDCMD_GENERATE 0x08
#define MXT_GOLDCMD_CONFIRM 0x0C
#define MXT_GOLD_CMD_MASK 0x0C
#define MXT_GOLDSTATE_INVALID 0xFF
#define MXT_GOLDSTATE_IDLE MXT_GOLDSTS_FCALSEQDONE
#define MXT_GOLDSTATE_PRIME 0x02
#define MXT_GOLDSTATE_GEN 0x04
#define MXT_GOLDSTATE_GEN_PASS (0x04 | MXT_GOLDSTS_FCALPASS)
#define MXT_GOLDSTATE_GEN_FAIL (0x04 | MXT_GOLDSTS_FCALFAIL)
#define MXT_GOLD_STATE_MASK 0x06
/* T78 glove setting */
#define MXT_GLOVECTL_ALL_ENABLE 0xB9
#define MXT_GLOVECTL_GAINEN (1 << 4)
/* T80 retransmission */
#define MXT_RETRANS_CTRL 0x0
#define MXT_RETRANS_ATCHTHR 0x4
#define MXT_RETRANS_CTRL_MOISTCALEN (1 << 4)
/* T81 gesture */
#define MXT_GESTURE_CTRL 0x0
/* T72 noise suppression */
#define MXT_NOICTRL_ENABLE (1 << 0)
#define MXT_NOICFG_VNOISY (1 << 1)
#define MXT_NOICFG_NOISY (1 << 0)
/* T109 self-cap */
#define MXT_SELFCTL_RPTEN 0x2
#define MXT_SELFCMD_TUNE 0x1
#define MXT_SELFCMD_STM_TUNE 0x2
#define MXT_SELFCMD_AFN_TUNE 0x3
#define MXT_SELFCMD_STCR_TUNE 0x4
#define MXT_SELFCMD_AFCR_TUNE 0x5
#define MXT_SELFCMD_AFNVMSTCR_TUNE 0x6
#define MXT_SELFCMD_RCR_TUNE 0x7
#define MXT_DEBUGFS_DIR "atmel_mxt_ts"
#define MXT_DEBUGFS_FILE "object"
#define MXT_INPUT_EVENT_START 0
#define MXT_INPUT_EVENT_SENSITIVE_MODE_OFF 0
#define MXT_INPUT_EVENT_SENSITIVE_MODE_ON 1
#define MXT_INPUT_EVENT_STYLUS_MODE_OFF 2
#define MXT_INPUT_EVENT_STYLUS_MODE_ON 3
#define MXT_INPUT_EVENT_WAKUP_MODE_OFF 4
#define MXT_INPUT_EVENT_WAKUP_MODE_ON 5
#define MXT_INPUT_EVENT_END 5
#define MXT_MAX_FINGER_NUM 16
#define BOOTLOADER_1664_1188 1
struct mxt_info {
u8 family_id;
u8 variant_id;
u8 version;
u8 build;
u8 matrix_xsize;
u8 matrix_ysize;
u8 object_num;
};
struct mxt_object {
u8 type;
u16 start_address;
u16 size;
u16 instances;
u8 num_report_ids;
/* to map object and message */
u8 min_reportid;
u8 max_reportid;
};
enum mxt_device_state { INIT, APPMODE, BOOTLOADER, FAILED, SHUTDOWN };
/* This structure is used to save/restore values during suspend/resume */
struct mxt_suspend {
u8 suspend_obj;
u8 suspend_reg;
u8 suspend_val;
u8 suspend_flags;
u8 restore_val;
};
struct mxt_golden_msg {
u8 status;
u8 fcalmaxdiff;
u8 fcalmaxdiffx;
u8 fcalmaxdiffy;
};
struct mxt_selfcap_status {
u8 cmd;
u8 error_code;
};
struct mxt_mode_switch {
struct mxt_data *data;
u8 mode;
struct work_struct switch_mode_work;
};
/* Each client has this additional data */
struct mxt_data {
struct i2c_client *client;
struct input_dev *input_dev;
const struct mxt_platform_data *pdata;
enum mxt_device_state state;
struct mxt_object *object_table;
struct regulator *regulator_vdd;
struct regulator *regulator_avdd;
struct regulator *regulator_vddio;
u16 mem_size;
struct mxt_info info;
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
struct bin_attribute mem_access_attr;
bool debug_enabled;
bool driver_paused;
u8 bootloader_addr;
u8 actv_cycle_time;
u8 idle_cycle_time;
u8 actv2idle_timeout;
u8 is_stopped;
u8 max_reportid;
u32 config_crc;
u32 info_block_crc;
u8 num_touchids;
u8 num_stylusids;
u8 *msg_buf;
u8 last_message_count;
u8 t100_tchaux_bits;
unsigned long keystatus;
u8 vendor_id;
u8 rev_id;
int current_index;
u8 update_flag;
u8 test_result[6];
int touch_num;
u8 diag_mode;
u8 atchthr;
u8 sensitive_mode;
u8 stylus_mode;
u8 wakeup_gesture_mode;
bool is_wakeup_by_gesture;
int hover_tune_status;
struct delayed_work calibration_delayed_work;
u8 adcperx_normal[10];
u8 adcperx_wakeup[10];
bool irq_enabled;
u8 lockdown_info[MXT_LOCKDOWN_SIZE];
u8 userdata_info[MXT_USERDATA_SIZE];
bool firmware_updated;
bool keys_off;
bool hw_wakeup;
bool screen_off;
/* Slowscan parameters */
int slowscan_enabled;
u8 slowscan_actv_cycle_time;
u8 slowscan_idle_cycle_time;
u8 slowscan_actv2idle_timeout;
u8 slowscan_shad_actv_cycle_time;
u8 slowscan_shad_idle_cycle_time;
u8 slowscan_shad_actv2idle_timeout;
struct mxt_golden_msg golden_msg;
struct mxt_selfcap_status selfcap_status;
struct work_struct self_tuning_work;
struct work_struct hover_loading_work;
bool finger_down[MXT_MAX_FINGER_NUM];
/* Cached parameters from object table */
u16 T5_address;
u8 T5_msg_size;
u8 T6_reportid;
u16 T7_address;
u8 T9_reportid_min;
u8 T9_reportid_max;
u8 T15_reportid_min;
u8 T15_reportid_max;
u8 T19_reportid_min;
u8 T19_reportid_max;
u8 T25_reportid_min;
u8 T25_reportid_max;
u16 T37_address;
u8 T42_reportid_min;
u8 T42_reportid_max;
u16 T44_address;
u8 T48_reportid;
u8 T63_reportid_min;
u8 T63_reportid_max;
u8 T66_reportid;
u8 T81_reportid_min;
u8 T81_reportid_max;
u8 T92_reportid_min;
u8 T92_reportid_max;
u8 T100_reportid_min;
u8 T100_reportid_max;
u8 T109_reportid;
#ifdef CONFIG_FB
struct notifier_block fb_notif;
#endif
};
static struct mxt_suspend mxt_save[] = {
{MXT_GEN_POWER_T7, MXT_POWER_IDLEACQINT,
MXT_T7_IDLEACQ_DISABLE, MXT_SUSPEND_DYNAMIC, 0},
{MXT_GEN_POWER_T7, MXT_POWER_ACTVACQINT,
MXT_T7_ACTVACQ_DISABLE, MXT_SUSPEND_DYNAMIC, 0},
{MXT_GEN_POWER_T7, MXT_POWER_ACTV2IDLETO,
MXT_T7_ACTV2IDLE_DISABLE, MXT_SUSPEND_DYNAMIC, 0}
};
/* I2C slave address pairs */
struct mxt_i2c_address_pair {
u8 bootloader;
u8 application;
};
static const struct mxt_i2c_address_pair mxt_i2c_addresses[] = {
#ifdef BOOTLOADER_1664_1188
{ 0x26, 0x4a },
{ 0x27, 0x4b },
#else
{ 0x24, 0x4a },
{ 0x25, 0x4b },
{ 0x26, 0x4c },
{ 0x27, 0x4d },
{ 0x34, 0x5a },
{ 0x35, 0x5b },
#endif
};
static struct gpiomux_setting mxt_rst_cutoff_pwr_cfg = {
.func = GPIOMUX_FUNC_GPIO,
.drv = GPIOMUX_DRV_6MA,
.pull = GPIOMUX_PULL_NONE,
};
static struct gpiomux_setting mxt_int_cutoff_pwr_cfg = {
.func = GPIOMUX_FUNC_GPIO,
.drv = GPIOMUX_DRV_6MA,
.pull = GPIOMUX_PULL_NONE,
};
static ssize_t mxt_update_firmware(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count, bool *upgraded);
static int mxt_bootloader_read(struct mxt_data *data, u8 *val, unsigned int count)
{
int ret;
struct i2c_msg msg;
msg.addr = data->bootloader_addr;
msg.flags = data->client->flags & I2C_M_TEN;
msg.flags |= I2C_M_RD;
msg.len = count;
msg.buf = val;
ret = i2c_transfer(data->client->adapter, &msg, 1);
return (ret == 1) ? 0 : ret;
}
static int mxt_bootloader_write(struct mxt_data *data, const u8 * const val,
unsigned int count)
{
int ret;
struct i2c_msg msg;
msg.addr = data->bootloader_addr;
msg.flags = data->client->flags & I2C_M_TEN;
msg.len = count;
msg.buf = (u8 *)val;
ret = i2c_transfer(data->client->adapter, &msg, 1);
return (ret == 1) ? 0 : ret;
}
static int mxt_get_bootloader_address(struct mxt_data *data)
{
struct i2c_client *client = data->client;
int i;
for (i = 0; i < ARRAY_SIZE(mxt_i2c_addresses); i++) {
if (mxt_i2c_addresses[i].application == client->addr) {
data->bootloader_addr = mxt_i2c_addresses[i].bootloader;
dev_info(&client->dev, "Bootloader i2c addr: 0x%02x\n",
data->bootloader_addr);
return 0;
}
}
dev_err(&client->dev, "Address 0x%02x not found in address table\n",
client->addr);
return -EINVAL;
}
static int mxt_probe_bootloader(struct mxt_data *data)
{
struct device *dev = &data->client->dev;
int ret;
u8 val;
bool crc_failure;
ret = mxt_get_bootloader_address(data);
if (ret)
return ret;
ret = mxt_bootloader_read(data, &val, 1);
if (ret) {
dev_err(dev, "%s: i2c recv failed\n", __func__);
return -EIO;
}
/* Check app crc fail mode */
crc_failure = (val & ~MXT_BOOT_STATUS_MASK) == MXT_APP_CRC_FAIL;
dev_err(dev, "Detected bootloader, status:%02X%s\n",
val, crc_failure ? ", APP_CRC_FAIL" : "");
return 0;
}
static u8 mxt_read_chg(struct mxt_data *data)
{
int gpio_intr = data->pdata->irq_gpio;
u8 val = (u8)gpio_get_value(gpio_intr);
return val;
}
static void mxt_disable_irq(struct mxt_data *data)
{
if (likely(data->irq_enabled)) {
disable_irq(data->irq);
data->irq_enabled = false;
}
}
static void mxt_enable_irq(struct mxt_data *data)
{
if (likely(!data->irq_enabled)) {
enable_irq(data->irq);
data->irq_enabled = true;
}
}
static int mxt_wait_for_chg(struct mxt_data *data)
{
int timeout_counter = 0;
int count = 10;
while ((timeout_counter++ <= count) && mxt_read_chg(data))
mdelay(10);
if (timeout_counter > count) {
dev_err(&data->client->dev, "mxt_wait_for_chg() timeout!\n");
return -EIO;
}
return 0;
}
static u8 mxt_get_bootloader_version(struct mxt_data *data, u8 val)
{
struct device *dev = &data->client->dev;
u8 buf[3];
if (val & MXT_BOOT_EXTENDED_ID) {
if (mxt_bootloader_read(data, &buf[0], 3) != 0) {
dev_err(dev, "%s: i2c failure\n", __func__);
return -EIO;
}
dev_info(dev, "Bootloader ID:%d Version:%d\n", buf[1], buf[2]);
return buf[0];
} else {
dev_info(dev, "Bootloader ID:%d\n", val & MXT_BOOT_ID_MASK);
return val;
}
}
static int mxt_check_bootloader(struct mxt_data *data,
unsigned int state)
{
struct device *dev = &data->client->dev;
int ret;
u8 val;
recheck:
ret = mxt_bootloader_read(data, &val, 1);
if (ret) {
dev_err(dev, "%s: i2c recv failed, ret=%d\n",
__func__, ret);
return ret;
}
if (state == MXT_WAITING_BOOTLOAD_CMD) {
val = mxt_get_bootloader_version(data, val);
}
switch (state) {
case MXT_WAITING_BOOTLOAD_CMD:
val &= ~MXT_BOOT_STATUS_MASK;
break;
case MXT_WAITING_FRAME_DATA:
case MXT_APP_CRC_FAIL:
val &= ~MXT_BOOT_STATUS_MASK;
break;
case MXT_FRAME_CRC_PASS:
if (val == MXT_FRAME_CRC_CHECK) {
mxt_wait_for_chg(data);
goto recheck;
} else if (val == MXT_FRAME_CRC_FAIL) {
dev_err(dev, "Bootloader CRC fail\n");
return -EINVAL;
}
break;
default:
return -EINVAL;
}
if (val != state) {
dev_err(dev, "Invalid bootloader mode state 0x%02X\n", val);
return -EINVAL;
}
return 0;
}
static int mxt_send_bootloader_cmd(struct mxt_data *data, bool unlock)
{
int ret;
u8 buf[2];
if (unlock) {
buf[0] = MXT_UNLOCK_CMD_LSB;
buf[1] = MXT_UNLOCK_CMD_MSB;
} else {
buf[0] = 0x01;
buf[1] = 0x01;
}
ret = mxt_bootloader_write(data, buf, 2);
if (ret) {
dev_err(&data->client->dev, "%s: i2c send failed, ret=%d\n",
__func__, ret);
return ret;
}
return 0;
}
static int mxt_read_reg(struct i2c_client *client,
u16 reg, u16 len, void *val)
{
struct device *dev = &client->dev;
struct i2c_msg xfer[2];
u8 buf[2];
int ret;
buf[0] = reg & 0xff;
buf[1] = (reg >> 8) & 0xff;
/* Write register */
xfer[0].addr = client->addr;
xfer[0].flags = 0;
xfer[0].len = 2;
xfer[0].buf = buf;
/* Read data */
xfer[1].addr = client->addr;
xfer[1].flags = I2C_M_RD;
xfer[1].len = len;
xfer[1].buf = val;
ret = i2c_transfer(client->adapter, xfer, ARRAY_SIZE(xfer));
if (ret != ARRAY_SIZE(xfer)) {
dev_err(dev, "%s: i2c transfer failed (%d)\n",
__func__, ret);
return -EIO;
}
return 0;
}
static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val)
{
struct device *dev = &client->dev;
u8 buf[3];
buf[0] = reg & 0xff;
buf[1] = (reg >> 8) & 0xff;
buf[2] = val;
if (i2c_master_send(client, buf, 3) != 3) {
dev_err(dev, "%s: i2c send failed\n", __func__);
return -EIO;
}
return 0;
}
static int mxt_write_block(struct i2c_client *client, u16 addr, u16 length, u8 *value)
{
int i;
struct {
__le16 le_addr;
u8 data[MXT_MAX_BLOCK_WRITE];
} i2c_block_transfer;
if (length > MXT_MAX_BLOCK_WRITE)
return -EINVAL;
memcpy(i2c_block_transfer.data, value, length);
i2c_block_transfer.le_addr = cpu_to_le16(addr);
i = i2c_master_send(client, (u8 *) &i2c_block_transfer, length + 2);
if (i == (length + 2))
return 0;