xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  *
3  * FocalTech TouchScreen driver.
4  *
5  * Copyright (c) 2012-2018, Focaltech Ltd. All rights reserved.
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17 
18 /*****************************************************************************
19 *
20 * File Name: focaltech_gestrue.c
21 *
22 * Author: Focaltech Driver Team
23 *
24 * Created: 2016-08-08
25 *
26 * Abstract:
27 *
28 * Reference:
29 *
30 *****************************************************************************/
31 
32 /*****************************************************************************
33 * 1.Included header files
34 *****************************************************************************/
35 #include "focaltech_core.h"
36 #if FTS_GESTURE_EN
37 /******************************************************************************
38 * Private constant and macro definitions using #define
39 *****************************************************************************/
40 #define KEY_GESTURE_U                           KEY_U
41 #define KEY_GESTURE_UP                          KEY_UP
42 #define KEY_GESTURE_DOWN                        KEY_DOWN
43 #define KEY_GESTURE_LEFT                        KEY_LEFT
44 #define KEY_GESTURE_RIGHT                       KEY_RIGHT
45 #define KEY_GESTURE_O                           KEY_O
46 #define KEY_GESTURE_E                           KEY_E
47 #define KEY_GESTURE_M                           KEY_M
48 #define KEY_GESTURE_L                           KEY_L
49 #define KEY_GESTURE_W                           KEY_W
50 #define KEY_GESTURE_S                           KEY_S
51 #define KEY_GESTURE_V                           KEY_V
52 #define KEY_GESTURE_C                           KEY_C
53 #define KEY_GESTURE_Z                           KEY_Z
54 
55 #define GESTURE_LEFT                            0x20
56 #define GESTURE_RIGHT                           0x21
57 #define GESTURE_UP                              0x22
58 #define GESTURE_DOWN                            0x23
59 #define GESTURE_DOUBLECLICK                     0x24
60 #define GESTURE_O                               0x30
61 #define GESTURE_W                               0x31
62 #define GESTURE_M                               0x32
63 #define GESTURE_E                               0x33
64 #define GESTURE_L                               0x44
65 #define GESTURE_S                               0x46
66 #define GESTURE_V                               0x54
67 #define GESTURE_Z                               0x41
68 #define GESTURE_C                               0x34
69 #define FTS_GESTRUE_POINTS                      6
70 #define FTS_GESTRUE_POINTS_HEADER               2
71 
72 /*****************************************************************************
73 * Private enumerations, structures and unions using typedef
74 *****************************************************************************/
75 /*
76 * header        -   byte0:gesture id
77 *                   byte1:pointnum
78 *                   byte2~7:reserved
79 * coordinate_x  -   All gesture point x coordinate
80 * coordinate_y  -   All gesture point y coordinate
81 * mode          -   1:enable gesture function(default)
82 *               -   0:disable
83 * active        -   1:enter into gesture(suspend)
84 *                   0:gesture disable or resume
85 */
86 struct fts_gesture_st {
87     u8 header[FTS_GESTRUE_POINTS_HEADER];
88     u16 coordinate_x[FTS_GESTRUE_POINTS];
89     u16 coordinate_y[FTS_GESTRUE_POINTS];
90     u8 mode;   /*host driver enable gesture flag*/
91     u8 active;  /*gesture actutally work*/
92 };
93 
94 /*****************************************************************************
95 * Static variables
96 *****************************************************************************/
97 static struct fts_gesture_st fts_gesture_data;
98 
99 /*****************************************************************************
100 * Global variable or extern global variabls/functions
101 *****************************************************************************/
102 
103 /*****************************************************************************
104 * Static function prototypes
105 *****************************************************************************/
106 static ssize_t fts_gesture_show(struct device *dev, struct device_attribute *attr, char *buf);
107 static ssize_t fts_gesture_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
108 static ssize_t fts_gesture_buf_show(struct device *dev, struct device_attribute *attr, char *buf);
109 static ssize_t fts_gesture_buf_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
110 
111 /* sysfs gesture node
112  *   read example: cat  fts_gesture_mode        ---read gesture mode
113  *   write example:echo 01 > fts_gesture_mode   ---write gesture mode to 01
114  *
115  */
116 static DEVICE_ATTR (fts_gesture_mode, S_IRUGO | S_IWUSR, fts_gesture_show, fts_gesture_store);
117 /*
118  *   read example: cat fts_gesture_buf        ---read gesture buf
119  */
120 static DEVICE_ATTR (fts_gesture_buf, S_IRUGO | S_IWUSR, fts_gesture_buf_show, fts_gesture_buf_store);
121 static struct attribute *fts_gesture_mode_attrs[] = {
122     &dev_attr_fts_gesture_mode.attr,
123     &dev_attr_fts_gesture_buf.attr,
124     NULL,
125 };
126 
127 static struct attribute_group fts_gesture_group = {
128     .attrs = fts_gesture_mode_attrs,
129 };
130 
131 /************************************************************************
132 * Name: fts_gesture_show
133 *  Brief:
134 *  Input: device, device attribute, char buf
135 * Output:
136 * Return:
137 ***********************************************************************/
fts_gesture_show(struct device * dev,struct device_attribute * attr,char * buf)138 static ssize_t fts_gesture_show(struct device *dev, struct device_attribute *attr, char *buf)
139 {
140     int count;
141     u8 val;
142     struct input_dev *input_dev = fts_data->input_dev;
143     struct i2c_client *client = container_of(dev, struct i2c_client, dev);
144 
145     mutex_lock(&input_dev->mutex);
146     fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, &val);
147     count = snprintf(buf, PAGE_SIZE, "Gesture Mode: %s\n", fts_gesture_data.mode ? "On" : "Off");
148     count += snprintf(buf + count, PAGE_SIZE, "Reg(0xD0) = %d\n", val);
149     mutex_unlock(&input_dev->mutex);
150 
151     return count;
152 }
153 
154 /************************************************************************
155 * Name: fts_gesture_store
156 *  Brief:
157 *  Input: device, device attribute, char buf, char count
158 * Output:
159 * Return:
160 ***********************************************************************/
fts_gesture_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)161 static ssize_t fts_gesture_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
162 {
163     struct input_dev *input_dev = fts_data->input_dev;
164     mutex_lock(&input_dev->mutex);
165     if (FTS_SYSFS_ECHO_ON(buf)) {
166         FTS_INFO("[GESTURE]enable gesture");
167         fts_gesture_data.mode = ENABLE;
168     } else if (FTS_SYSFS_ECHO_OFF(buf)) {
169         FTS_INFO("[GESTURE]disable gesture");
170         fts_gesture_data.mode = DISABLE;
171     }
172     mutex_unlock(&input_dev->mutex);
173 
174     return count;
175 }
176 /************************************************************************
177 * Name: fts_gesture_buf_show
178 *  Brief:
179 *  Input: device, device attribute, char buf
180 * Output:
181 * Return:
182 ***********************************************************************/
fts_gesture_buf_show(struct device * dev,struct device_attribute * attr,char * buf)183 static ssize_t fts_gesture_buf_show(struct device *dev, struct device_attribute *attr, char *buf)
184 {
185     int count;
186     int i = 0;
187     struct input_dev *input_dev = fts_data->input_dev;
188 
189     mutex_lock(&input_dev->mutex);
190     count = snprintf(buf, PAGE_SIZE, "Gesture ID: 0x%x\n", fts_gesture_data.header[0]);
191     count += snprintf(buf + count, PAGE_SIZE, "Gesture PointNum: %d\n", fts_gesture_data.header[1]);
192     count += snprintf(buf + count, PAGE_SIZE, "Gesture Point Buf:\n");
193     for (i = 0; i < fts_gesture_data.header[1]; i++) {
194         count += snprintf(buf + count, PAGE_SIZE, "%3d(%4d,%4d) ", i, fts_gesture_data.coordinate_x[i], fts_gesture_data.coordinate_y[i]);
195         if ((i + 1) % 4 == 0)
196             count += snprintf(buf + count, PAGE_SIZE, "\n");
197     }
198     count += snprintf(buf + count, PAGE_SIZE, "\n");
199     mutex_unlock(&input_dev->mutex);
200 
201     return count;
202 }
203 
204 /************************************************************************
205 * Name: fts_gesture_buf_store
206 *  Brief:
207 *  Input: device, device attribute, char buf, char count
208 * Output:
209 * Return:
210 ***********************************************************************/
fts_gesture_buf_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)211 static ssize_t fts_gesture_buf_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
212 {
213     /* place holder for future use */
214     return -EPERM;
215 }
216 
217 /*****************************************************************************
218 *   Name: fts_create_gesture_sysfs
219 *  Brief:
220 *  Input:
221 * Output:
222 * Return: 0-success or others-error
223 *****************************************************************************/
fts_create_gesture_sysfs(struct i2c_client * client)224 int fts_create_gesture_sysfs(struct i2c_client *client)
225 {
226     int ret = 0;
227 
228     ret = sysfs_create_group(&client->dev.kobj, &fts_gesture_group);
229     if ( ret != 0) {
230         FTS_ERROR( "[GESTURE]fts_gesture_mode_group(sysfs) create failed!");
231         sysfs_remove_group(&client->dev.kobj, &fts_gesture_group);
232         return ret;
233     }
234     return 0;
235 }
236 
237 /*****************************************************************************
238 *   Name: fts_gesture_report
239 *  Brief:
240 *  Input:
241 * Output:
242 * Return:
243 *****************************************************************************/
fts_gesture_report(struct input_dev * input_dev,int gesture_id)244 static void fts_gesture_report(struct input_dev *input_dev, int gesture_id)
245 {
246     int gesture;
247 
248     FTS_FUNC_ENTER();
249     FTS_INFO("fts gesture_id==0x%x ", gesture_id);
250     switch (gesture_id) {
251     case GESTURE_LEFT:
252         gesture = KEY_GESTURE_LEFT;
253         break;
254     case GESTURE_RIGHT:
255         gesture = KEY_GESTURE_RIGHT;
256         break;
257     case GESTURE_UP:
258         gesture = KEY_GESTURE_UP;
259         break;
260     case GESTURE_DOWN:
261         gesture = KEY_GESTURE_DOWN;
262         break;
263     case GESTURE_DOUBLECLICK:
264         gesture = KEY_GESTURE_U;
265         break;
266     case GESTURE_O:
267         gesture = KEY_GESTURE_O;
268         break;
269     case GESTURE_W:
270         gesture = KEY_GESTURE_W;
271         break;
272     case GESTURE_M:
273         gesture = KEY_GESTURE_M;
274         break;
275     case GESTURE_E:
276         gesture = KEY_GESTURE_E;
277         break;
278     case GESTURE_L:
279         gesture = KEY_GESTURE_L;
280         break;
281     case GESTURE_S:
282         gesture = KEY_GESTURE_S;
283         break;
284     case GESTURE_V:
285         gesture = KEY_GESTURE_V;
286         break;
287     case GESTURE_Z:
288         gesture = KEY_GESTURE_Z;
289         break;
290     case  GESTURE_C:
291         gesture = KEY_GESTURE_C;
292         break;
293     default:
294         gesture = -1;
295         break;
296     }
297     /* report event key */
298     if (gesture != -1) {
299         FTS_DEBUG("Gesture Code=%d", gesture);
300         input_report_key(input_dev, gesture, 1);
301         input_sync(input_dev);
302         input_report_key(input_dev, gesture, 0);
303         input_sync(input_dev);
304     }
305 
306     FTS_FUNC_EXIT();
307 }
308 
309 /************************************************************************
310 *   Name: fts_gesture_read_buffer
311 *  Brief: read data from TP register
312 *  Input:
313 * Output:
314 * Return: fail <0
315 ***********************************************************************/
fts_gesture_read_buffer(struct i2c_client * client,u8 * buf,int read_bytes)316 static int fts_gesture_read_buffer(struct i2c_client *client, u8 *buf, int read_bytes)
317 {
318     int remain_bytes;
319     int ret;
320     int i;
321 
322     if (read_bytes <= I2C_BUFFER_LENGTH_MAXINUM) {
323         ret = fts_i2c_read(client, buf, 1, buf, read_bytes);
324     } else {
325         ret = fts_i2c_read(client, buf, 1, buf, I2C_BUFFER_LENGTH_MAXINUM);
326         remain_bytes = read_bytes - I2C_BUFFER_LENGTH_MAXINUM;
327         for (i = 1; remain_bytes > 0; i++) {
328             if (remain_bytes <= I2C_BUFFER_LENGTH_MAXINUM)
329                 ret = fts_i2c_read(client, buf, 0, buf + I2C_BUFFER_LENGTH_MAXINUM * i, remain_bytes);
330             else
331                 ret = fts_i2c_read(client, buf, 0, buf + I2C_BUFFER_LENGTH_MAXINUM * i, I2C_BUFFER_LENGTH_MAXINUM);
332             remain_bytes -= I2C_BUFFER_LENGTH_MAXINUM;
333         }
334     }
335 
336     return ret;
337 }
338 
339 /************************************************************************
340 *   Name: fts_gesture_readdata
341 *  Brief: read data from TP register
342 *  Input:
343 * Output:
344 * Return: return 0 if succuss, otherwise reture error code
345 ***********************************************************************/
fts_gesture_readdata(struct fts_ts_data * ts_data)346 int fts_gesture_readdata(struct fts_ts_data *ts_data)
347 {
348     u8 buf[FTS_GESTRUE_POINTS * 4] = { 0 };
349     int ret = 0;
350     int i = 0;
351     int gestrue_id = 0;
352     int read_bytes = 0;
353     u8 pointnum;
354     u8 state;
355     struct i2c_client *client = ts_data->client;
356     struct input_dev *input_dev = ts_data->input_dev;
357 
358     if (!ts_data->suspended) {
359         return -EINVAL;
360     }
361 
362     ret = fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, &state);
363     if ((ret < 0) || (state != ENABLE)) {
364         FTS_DEBUG("gesture not enable, don't process gesture");
365         return -EIO;
366     }
367 
368     /* init variable before read gesture point */
369     memset(fts_gesture_data.header, 0, FTS_GESTRUE_POINTS_HEADER);
370     memset(fts_gesture_data.coordinate_x, 0, FTS_GESTRUE_POINTS * sizeof(u16));
371     memset(fts_gesture_data.coordinate_y, 0, FTS_GESTRUE_POINTS * sizeof(u16));
372 
373     buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS;
374     ret = fts_i2c_read(client, buf, 1, buf, FTS_GESTRUE_POINTS_HEADER);
375     if (ret < 0) {
376         FTS_ERROR("[GESTURE]Read gesture header data failed!!");
377         FTS_FUNC_EXIT();
378         return ret;
379     }
380 
381     memcpy(fts_gesture_data.header, buf, FTS_GESTRUE_POINTS_HEADER);
382     gestrue_id = buf[0];
383     pointnum = buf[1];
384     read_bytes = ((int)pointnum) * 4 + FTS_GESTRUE_POINTS_HEADER;
385     buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS;
386     FTS_DEBUG("[GESTURE]PointNum=%d", pointnum);
387     if (pointnum > FTS_GESTRUE_POINTS) {
388         FTS_ERROR("[GESTURE]gesture point number(%d) fail");
389         return -EIO;
390     }
391 
392     ret = fts_gesture_read_buffer(client, buf, read_bytes);
393     if (ret < 0) {
394         FTS_ERROR("[GESTURE]Read gesture touch data failed!!");
395         FTS_FUNC_EXIT();
396         return ret;
397     }
398 
399     fts_gesture_report(input_dev, gestrue_id);
400     for (i = 0; i < pointnum; i++) {
401         fts_gesture_data.coordinate_x[i] = (((s16) buf[0 + (4 * i + 2)]) & 0x0F) << 8
402                                            | (((s16) buf[1 + (4 * i + 2)]) & 0xFF);
403         fts_gesture_data.coordinate_y[i] = (((s16) buf[2 + (4 * i + 2)]) & 0x0F) << 8
404                                            | (((s16) buf[3 + (4 * i + 2)]) & 0xFF);
405     }
406 
407     return 0;
408 }
409 
410 /*****************************************************************************
411 *   Name: fts_gesture_recovery
412 *  Brief: recovery gesture state when reset or power on
413 *  Input:
414 * Output:
415 * Return:
416 *****************************************************************************/
fts_gesture_recovery(struct i2c_client * client)417 void fts_gesture_recovery(struct i2c_client *client)
418 {
419     if ((ENABLE == fts_gesture_data.mode) && (ENABLE == fts_gesture_data.active)) {
420         FTS_INFO("enter fts_gesture_recovery");
421         fts_i2c_write_reg(client, 0xD1, 0xff);
422         fts_i2c_write_reg(client, 0xD2, 0xff);
423         fts_i2c_write_reg(client, 0xD5, 0xff);
424         fts_i2c_write_reg(client, 0xD6, 0xff);
425         fts_i2c_write_reg(client, 0xD7, 0xff);
426         fts_i2c_write_reg(client, 0xD8, 0xff);
427         fts_i2c_write_reg(client, FTS_REG_GESTURE_EN, ENABLE);
428     }
429 }
430 
431 /*****************************************************************************
432 *   Name: fts_gesture_suspend
433 *  Brief:
434 *  Input:
435 * Output:
436 * Return: return 0 if succuss, otherwise return error code
437 *****************************************************************************/
fts_gesture_suspend(struct i2c_client * client)438 int fts_gesture_suspend(struct i2c_client *client)
439 {
440     int ret;
441     int i;
442     u8 state;
443 
444     FTS_INFO("gesture suspend...");
445     /* gesture not enable, return immediately */
446     if (fts_gesture_data.mode == DISABLE) {
447         FTS_INFO("gesture is disabled");
448         return -EINVAL;
449     }
450 
451     for (i = 0; i < 5; i++) {
452         fts_i2c_write_reg(client, 0xd1, 0xff);
453         fts_i2c_write_reg(client, 0xd2, 0xff);
454         fts_i2c_write_reg(client, 0xd5, 0xff);
455         fts_i2c_write_reg(client, 0xd6, 0xff);
456         fts_i2c_write_reg(client, 0xd7, 0xff);
457         fts_i2c_write_reg(client, 0xd8, 0xff);
458         fts_i2c_write_reg(client, FTS_REG_GESTURE_EN, ENABLE);
459         msleep(1);
460         fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, &state);
461         if (state == ENABLE)
462             break;
463     }
464 
465     if (i >= 5) {
466         FTS_ERROR("[GESTURE]Enter into gesture(suspend) failed!\n");
467         fts_gesture_data.active = DISABLE;
468         return -EIO;
469     }
470 
471     ret = enable_irq_wake(fts_data->irq);
472     if (ret) {
473         FTS_INFO("enable_irq_wake(irq:%d) failed", fts_data->irq);
474     }
475 
476     fts_gesture_data.active = ENABLE;
477     FTS_INFO("[GESTURE]Enter into gesture(suspend) successfully!");
478     FTS_FUNC_EXIT();
479     return 0;
480 }
481 
482 /*****************************************************************************
483 *   Name: fts_gesture_resume
484 *  Brief:
485 *  Input:
486 * Output:
487 * Return: return 0 if succuss, otherwise return error code
488 *****************************************************************************/
fts_gesture_resume(struct i2c_client * client)489 int fts_gesture_resume(struct i2c_client *client)
490 {
491     int ret;
492     int i;
493     u8 state;
494 
495     FTS_INFO("gesture resume...");
496     /* gesture not enable, return immediately */
497     if (fts_gesture_data.mode == DISABLE) {
498         FTS_DEBUG("gesture is disabled");
499         return -EINVAL;
500     }
501 
502     if (fts_gesture_data.active == DISABLE) {
503         FTS_DEBUG("gesture in suspend is failed, no running fts_gesture_resume");
504         return -EINVAL;
505     }
506 
507     fts_gesture_data.active = DISABLE;
508     for (i = 0; i < 5; i++) {
509         fts_i2c_write_reg(client, FTS_REG_GESTURE_EN, DISABLE);
510         msleep(1);
511         fts_i2c_read_reg(client, FTS_REG_GESTURE_EN, &state);
512         if (state == DISABLE)
513             break;
514     }
515 
516     if (i >= 5) {
517         FTS_ERROR("[GESTURE]Clear gesture(resume) failed!\n");
518         return -EIO;
519     }
520 
521     ret = disable_irq_wake(fts_data->irq);
522     if (ret) {
523         FTS_INFO("disable_irq_wake(irq:%d) failed", fts_data->irq);
524     }
525 
526     FTS_INFO("[GESTURE]resume from gesture successfully!");
527     FTS_FUNC_EXIT();
528     return 0;
529 }
530 
531 /*****************************************************************************
532 *   Name: fts_gesture_init
533 *  Brief:
534 *  Input:
535 * Output:
536 * Return:
537 *****************************************************************************/
fts_gesture_init(struct fts_ts_data * ts_data)538 int fts_gesture_init(struct fts_ts_data *ts_data)
539 {
540     struct i2c_client *client = ts_data->client;
541     struct input_dev *input_dev = ts_data->input_dev;
542 
543     FTS_FUNC_ENTER();
544     input_set_capability(input_dev, EV_KEY, KEY_POWER);
545     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_U);
546     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_UP);
547     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_DOWN);
548     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_LEFT);
549     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_RIGHT);
550     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_O);
551     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_E);
552     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_M);
553     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_L);
554     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_W);
555     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_S);
556     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_V);
557     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_Z);
558     input_set_capability(input_dev, EV_KEY, KEY_GESTURE_C);
559 
560     __set_bit(KEY_GESTURE_RIGHT, input_dev->keybit);
561     __set_bit(KEY_GESTURE_LEFT, input_dev->keybit);
562     __set_bit(KEY_GESTURE_UP, input_dev->keybit);
563     __set_bit(KEY_GESTURE_DOWN, input_dev->keybit);
564     __set_bit(KEY_GESTURE_U, input_dev->keybit);
565     __set_bit(KEY_GESTURE_O, input_dev->keybit);
566     __set_bit(KEY_GESTURE_E, input_dev->keybit);
567     __set_bit(KEY_GESTURE_M, input_dev->keybit);
568     __set_bit(KEY_GESTURE_W, input_dev->keybit);
569     __set_bit(KEY_GESTURE_L, input_dev->keybit);
570     __set_bit(KEY_GESTURE_S, input_dev->keybit);
571     __set_bit(KEY_GESTURE_V, input_dev->keybit);
572     __set_bit(KEY_GESTURE_C, input_dev->keybit);
573     __set_bit(KEY_GESTURE_Z, input_dev->keybit);
574 
575     fts_create_gesture_sysfs(client);
576     fts_gesture_data.mode = ENABLE;
577     fts_gesture_data.active = DISABLE;
578 
579     FTS_FUNC_EXIT();
580     return 0;
581 }
582 
583 /************************************************************************
584 *   Name: fts_gesture_exit
585 *  Brief: call when driver removed
586 *  Input:
587 * Output:
588 * Return:
589 ***********************************************************************/
fts_gesture_exit(struct i2c_client * client)590 int fts_gesture_exit(struct i2c_client *client)
591 {
592     FTS_FUNC_ENTER();
593     sysfs_remove_group(&client->dev.kobj, &fts_gesture_group);
594     FTS_FUNC_EXIT();
595     return 0;
596 }
597 #endif
598