p977: 1.tp: set int ct363_first_init_flag to static int.
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / ct36x / ct363.c
1 #define CT363_POINT_NUM         10
2
3 struct ct363_finger_data {
4         unsigned char   xhi;                    // X coordinate Hi
5         unsigned char   yhi;                    // Y coordinate Hi
6         unsigned char   ylo : 4;                // Y coordinate Lo
7         unsigned char   xlo : 4;                // X coordinate Lo
8         unsigned char   status : 3;             // Action information, 1: Down; 2: Move; 3: Up
9         unsigned char   id : 5;                 // ID information, from 1 to CFG_MAX_POINT_NUM
10         unsigned char   area;                   // Touch area
11         unsigned char   pressure;               // Touch Pressure
12 };
13
14
15 struct ct363_priv{
16         int press;
17         int release;
18         int x, y;
19         union{
20                 struct ct363_finger_data pts[CT363_POINT_NUM];
21                 char buf[CT363_POINT_NUM * sizeof(struct ct363_finger_data)];
22         };
23 };
24
25 static int ct363_init_hw(struct ct36x_data *ts)
26 {
27 /*
28         int ret = 0;
29         ret = gpio_request(ts->rst_io.gpio, "ct363_rst");
30         if(ret < 0){
31                 dev_err(ts->dev, "Failed to request rst gpio\n");
32                 return ret;
33         }
34
35         ret = gpio_request(ts->irq_io.gpio, "ct363_irq");
36         if(ret < 0){
37                 gpio_free(ts->rst_io.gpio);
38                 dev_err(ts->dev, "Failed to request irq gpio\n");
39                 return ret;
40         }*/
41         gpio_direction_input(ts->irq_io.gpio);
42         //gpio_pull_updown(ts->irq_io.gpio, 1);
43         //gpio_set_value(ts->irq_io.gpio,1);
44         gpio_direction_output(ts->rst_io.gpio, ts->rst_io.active_low);
45
46         return 0;
47 }
48 static void ct363_deinit_hw(struct ct36x_data *ts)
49 {
50         gpio_free(ts->rst_io.gpio);
51         gpio_free(ts->irq_io.gpio);
52 }
53
54 static void ct363_reset_hw(struct ct36x_data *ts)
55 {
56         gpio_direction_output(ts->rst_io.gpio, ts->rst_io.active_low);
57         msleep(50);
58         gpio_set_value(ts->rst_io.gpio, !ts->rst_io.active_low);
59         msleep(50);
60         gpio_set_value(ts->rst_io.gpio, ts->rst_io.active_low);
61         msleep(500);
62 }
63
64 static int ct363_init(struct ct36x_data *ts)
65 {
66         int ret = 0, fwchksum, binchksum, updcnt = 5;
67         struct ct363_priv *ct363 = NULL;
68         
69         ret = ct363_init_hw(ts);
70         if(ret < 0)
71                 return ret;
72
73          /* Hardware reset */
74         ct363_reset_hw(ts);
75         // Get binary Checksum
76         binchksum = ct36x_chip_get_binchksum();
77         ct36x_dbg(ts, "CT363 init: binchksum = %d\n", binchksum);
78
79         ret = ct36x_chip_get_fwchksum(ts);
80         if(ret < 0){
81                 dev_err(ts->dev, "CT36X chip: Failed to get fwchksum\n");
82                 return ret;
83         }
84         fwchksum = ret;
85         ct36x_dbg(ts, "CT363 init: fwchksum = %d\n", fwchksum);
86         while(binchksum != fwchksum && updcnt--) {
87                 /* Update Firmware */
88                 ret = ct36x_chip_go_bootloader(ts);
89                 if(ret < 0){
90                         dev_err(ts->dev, "CT36X chip: Failed to go bootloader\n");
91                         return ret;
92                 }
93                  /* Hardware reset */
94                 ct363_reset_hw(ts);
95
96                 ret = ct36x_chip_get_fwchksum(ts);
97                 if(ret < 0){
98                         dev_err(ts->dev, "CT36X chip: Failed to get fwchksum\n");
99                         return ret;
100                 }
101                 fwchksum = ret;
102                 ct36x_dbg(ts, "CT363 update FW: fwchksum = %d\n", fwchksum);
103         }
104         if(binchksum != fwchksum){
105                 dev_err(ts->dev, "Fail to update FW\n");
106                 return -ENODEV;
107         }
108
109         /* Hardware reset */
110         ct363_reset_hw(ts);
111         msleep(5);
112
113         ts->point_num = CT363_POINT_NUM;
114         
115         ct363 = kzalloc(sizeof(struct ct363_priv), GFP_KERNEL);
116         if(!ct363){
117                 dev_err(ts->dev, "No memory for ct36x");
118                 return -ENOMEM;
119         }
120         ts->priv = ct363;
121
122         return 0;
123 }
124
125 static void ct363_deinit(struct ct36x_data *ts)
126 {
127         struct ct363_priv *ct363 = ts->priv;
128
129         ct363_deinit_hw(ts);
130         kfree(ct363);
131         ts->priv = NULL;
132
133         return;
134 }
135
136 static int ct363_first_init_flag = 1;
137 static int ct363_suspend(struct ct36x_data *ts)
138 {
139         int ret = 0;
140
141         ret = ct36x_chip_go_sleep(ts);
142         ct363_first_init_flag=0;
143         if(ret < 0)
144                 dev_warn(ts->dev, "CT363 chip: failed to go to sleep\n");
145         return ret;
146 }
147
148 static int ct363_resume(struct ct36x_data *ts)
149 {
150         int i;
151
152         /* Hardware reset */
153         if(ct363_first_init_flag)
154                 ct363_reset_hw(ts);
155         else
156         {
157         //      gpio_direction_output(ts->rst_io.gpio, ts->rst_io.active_low);
158         //      msleep(50);
159                 gpio_set_value(ts->rst_io.gpio, !ts->rst_io.active_low);
160                 msleep(50);
161                 gpio_set_value(ts->rst_io.gpio, ts->rst_io.active_low);
162                 msleep(50);
163         }
164         for(i = 0; i < ts->point_num; i++){
165                 input_mt_slot(ts->input, i);
166                 input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false);
167         }
168         input_sync(ts->input);
169
170         return 0;
171 }
172
173 static void ct363_report(struct ct36x_data *ts)
174 {
175         int t ,m;
176         int i, ret = 0;
177         int sync = 0, x, y;
178         int len = sizeof(struct ct363_finger_data) * ts->point_num;
179         struct ct363_priv *ct363 = ts->priv;
180
181         ret = ct36x_read(ts, ct363->buf, len);
182         if(ret < 0){
183                 dev_warn(ts->dev, "Failed to read finger data\n");
184                 return;
185         }
186
187        if(ct36x_dbg_level==2)
188        for(t=0;t< ts->point_num;t++){
189             ct36x_dbg(ts, "CT363buf[%d]: ", t);
190             for(m=0;m<6;m++){
191                     ct36x_dbg(ts, " 0x%x  %x  %x  %x  %x  %x  %x  %x ",ct363->pts[t].xhi,
192                                                                                                ct363->pts[t].yhi,
193                                                                                                ct363->pts[t].ylo,
194                                                                                                ct363->pts[t].xlo,
195                                                                                                ct363->pts[t].status,
196                                                                                                ct363->pts[t].id,
197                                                                                                ct363->pts[t].area,
198                                                                                                ct363->pts[t].pressure);
199              }
200              ct36x_dbg(ts, " \n ");
201        }
202        
203         ct363->press = 0;
204         for(i = 0; i < ts->point_num; i++){
205                 if((ct363->pts[i].xhi != 0xFF && ct363->pts[i].yhi != 0xFF) &&
206                         (ct363->pts[i].status == 1 || ct363->pts[i].status == 2)){
207                         x = (ct363->pts[i].xhi<<4)|(ct363->pts[i].xlo&0xF);
208                         y = (ct363->pts[i].yhi<<4)|(ct363->pts[i].ylo&0xF);
209
210                         ct363->x = ts->orientation[0] * x + ts->orientation[1] * y;
211                         ct363->y = ts->orientation[2] * x + ts->orientation[3] * y;
212
213                    if( (ct363->x > ts->x_max) || (ct363->y > ts->y_max) || (ct363->x < 0) || (ct363->y < 0) ){
214                           continue ;
215                     }
216                    if(flag_ct36x_model==363){
217                         ct363->y = ts->y_max - ct363->y;      //add for p977 
218                    }       
219                         input_mt_slot(ts->input, ct363->pts[i].id - 1);
220                         input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
221                         input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 1);
222                         input_report_abs(ts->input, ABS_MT_POSITION_X, ct363->x);
223                         input_report_abs(ts->input, ABS_MT_POSITION_Y, ct363->y);
224                         input_report_abs(ts->input, ABS_MT_PRESSURE, ct363->pts[i].pressure);
225                         ct36x_dbg(ts, "CT363 report value: id: %d,  x: %d, y:%d\n",ct363->pts[i].id - 1, ct363->x, ct363->y);
226
227                         sync = 1;
228                         ct363->press |= 0x01 << (ct363->pts[i].id - 1);
229                 }
230         }
231         ct363->release &= ct363->release ^ ct363->press;
232         for(i = 0; i < ts->point_num; i++){
233                 if ( ct363->release & (0x01<<i) ) {
234                         input_mt_slot(ts->input, i);
235                         input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false);
236                         ct36x_dbg(ts, "CT363 release\n");
237                         sync = 1;
238                 }
239         }
240         ct363->release = ct363->press;
241
242         if(sync)
243                 input_sync(ts->input);
244
245         return;
246 }
247 struct ct36x_ops ct363_ops = {
248         .init = ct363_init,
249         .deinit = ct363_deinit,
250         .suspend = ct363_suspend,
251         .resume = ct363_resume,
252         .report = ct363_report,
253 };