xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  *
3  * FocalTech ftxxxx 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_ex_mode.c
21 *
22 * Author: Focaltech Driver Team
23 *
24 * Created: 2016-08-31
25 *
26 * Abstract:
27 *
28 * Reference:
29 *
30 *****************************************************************************/
31 
32 /*****************************************************************************
33 * 1.Included header files
34 *****************************************************************************/
35 #include "focaltech_core.h"
36 
37 /*****************************************************************************
38 * 2.Private constant and macro definitions using #define
39 *****************************************************************************/
40 
41 /*****************************************************************************
42 * 3.Private enumerations, structures and unions using typedef
43 *****************************************************************************/
44 struct fts_mode_flag {
45     int  fts_glove_mode_flag;
46     int  fts_cover_mode_flag;
47     int  fts_charger_mode_flag;
48 };
49 
50 struct fts_mode_flag g_fts_mode_flag;
51 
52 /*****************************************************************************
53 * 4.Static variables
54 *****************************************************************************/
55 
56 /*****************************************************************************
57 * 5.Global variable or extern global variabls/functions
58 *****************************************************************************/
59 int fts_enter_glove_mode(struct i2c_client *client, int mode );
60 int fts_enter_cover_mode(struct i2c_client *client, int mode );
61 int fts_enter_charger_mode(struct i2c_client *client, int mode );
62 
63 /*****************************************************************************
64 * 6.Static function prototypes
65 *******************************************************************************/
66 
67 #if FTS_GLOVE_EN
fts_touch_glove_show(struct device * dev,struct device_attribute * attr,char * buf)68 static ssize_t fts_touch_glove_show(struct device *dev, struct device_attribute *attr, char *buf)
69 {
70     int count;
71     u8 val;
72     struct input_dev *input_dev = fts_data->input_dev;
73     struct i2c_client *client = container_of(dev, struct i2c_client, dev);
74 
75     mutex_lock(&input_dev->mutex);
76     fts_i2c_read_reg(client, FTS_REG_GLOVE_MODE_EN, &val);
77     count = snprintf(buf, PAGE_SIZE, "Glove Mode: %s\n", g_fts_mode_flag.fts_glove_mode_flag ? "On" : "Off");
78     count += snprintf(buf + count, PAGE_SIZE, "Glove Reg(0xC0) = %d\n", val);
79     mutex_unlock(&input_dev->mutex);
80 
81     return count;
82 }
83 
fts_touch_glove_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)84 static ssize_t fts_touch_glove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
85 {
86     int ret;
87     struct fts_ts_data *ts_data = fts_data;
88     struct i2c_client *client;
89 
90 
91     client = ts_data->client;
92     if (FTS_SYSFS_ECHO_ON(buf)) {
93         if (!g_fts_mode_flag.fts_glove_mode_flag) {
94             FTS_INFO("[Mode]enter glove mode");
95             ret = fts_enter_glove_mode(client, true);
96             if (ret >= 0) {
97                 g_fts_mode_flag.fts_glove_mode_flag = true;
98             }
99         }
100     } else if (FTS_SYSFS_ECHO_OFF(buf)) {
101         if (g_fts_mode_flag.fts_glove_mode_flag) {
102             FTS_INFO("[Mode]exit glove mode");
103             ret = fts_enter_glove_mode(client, false);
104             if (ret >= 0) {
105                 g_fts_mode_flag.fts_glove_mode_flag = false;
106             }
107         }
108     }
109     FTS_INFO("[Mode]glove mode status:  %d", g_fts_mode_flag.fts_glove_mode_flag);
110     return count;
111 }
112 
113 /************************************************************************
114 * Name: fts_enter_glove_mode
115 * Brief:  change glove mode
116 * Input:  glove mode
117 * Output: no
118 * Return: success >=0, otherwise failed
119 ***********************************************************************/
fts_enter_glove_mode(struct i2c_client * client,int mode)120 int fts_enter_glove_mode( struct i2c_client *client, int mode)
121 {
122     int ret = 0;
123     static u8 buf_addr[2] = { 0 };
124     static u8 buf_value[2] = { 0 };
125     buf_addr[0] = FTS_REG_GLOVE_MODE_EN; /* glove control */
126 
127     if (mode)
128         buf_value[0] = 0x01;
129     else
130         buf_value[0] = 0x00;
131 
132     ret = fts_i2c_write_reg( client, buf_addr[0], buf_value[0]);
133     if (ret < 0) {
134         FTS_ERROR("[Mode]fts_enter_glove_mode write value fail");
135     }
136 
137     return ret ;
138 
139 }
140 
141 /* read and write glove mode
142 *   read example: cat  fts_touch_glove_mode---read  glove mode
143 *   write example:echo 01 > fts_touch_glove_mode ---write glove mode to 01
144 *
145 */
146 static DEVICE_ATTR (fts_glove_mode,  S_IRUGO | S_IWUSR, fts_touch_glove_show, fts_touch_glove_store);
147 
148 #endif
149 
150 #if FTS_COVER_EN
fts_touch_cover_show(struct device * dev,struct device_attribute * attr,char * buf)151 static ssize_t fts_touch_cover_show(struct device *dev, struct device_attribute *attr, char *buf)
152 {
153     int count;
154     u8 val;
155     struct input_dev *input_dev = fts_data->input_dev;
156     struct i2c_client *client = container_of(dev, struct i2c_client, dev);
157 
158     mutex_lock(&input_dev->mutex);
159     fts_i2c_read_reg(client, FTS_REG_COVER_MODE_EN, &val);
160     count = snprintf(buf, PAGE_SIZE, "Cover Mode: %s\n", g_fts_mode_flag.fts_cover_mode_flag ? "On" : "Off");
161     count += snprintf(buf + count, PAGE_SIZE, "Cover Reg(0xC1) = %d\n", val);
162     mutex_unlock(&input_dev->mutex);
163 
164     return count;
165 }
166 
fts_touch_cover_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)167 static ssize_t fts_touch_cover_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
168 {
169     int ret;
170     struct fts_ts_data *ts_data = fts_data;
171     struct i2c_client *client;
172 
173     client = ts_data->client;
174     if (FTS_SYSFS_ECHO_ON(buf)) {
175         if (!g_fts_mode_flag.fts_cover_mode_flag) {
176             FTS_INFO("[Mode]enter cover mode");
177             ret = fts_enter_cover_mode(client, true);
178             if (ret >= 0) {
179                 g_fts_mode_flag.fts_cover_mode_flag = true;
180             }
181         }
182     } else if (FTS_SYSFS_ECHO_OFF(buf)) {
183         if (g_fts_mode_flag.fts_cover_mode_flag) {
184             FTS_INFO("[Mode]exit cover mode");
185             ret = fts_enter_cover_mode(client, false);
186             if (ret >= 0) {
187                 g_fts_mode_flag.fts_cover_mode_flag = false;
188             }
189         }
190     }
191     FTS_INFO("[Mode]cover mode status:  %d", g_fts_mode_flag.fts_cover_mode_flag);
192     return count;
193 }
194 
195 /************************************************************************
196 * Name: fts_enter_cover_mode
197 * Brief:  change cover mode
198 * Input:  cover mode
199 * Output: no
200 * Return: success >=0, otherwise failed
201 ***********************************************************************/
fts_enter_cover_mode(struct i2c_client * client,int mode)202 int  fts_enter_cover_mode( struct i2c_client *client, int mode)
203 {
204     int ret = 0;
205     static u8 buf_addr[2] = { 0 };
206     static u8 buf_value[2] = { 0 };
207     buf_addr[0] = FTS_REG_COVER_MODE_EN; /* cover control */
208 
209     if (mode)
210         buf_value[0] = 0x01;
211     else
212         buf_value[0] = 0x00;
213 
214     ret = fts_i2c_write_reg( client, buf_addr[0], buf_value[0]);
215     if (ret < 0) {
216         FTS_ERROR("[Mode] fts_enter_cover_mode write value fail \n");
217     }
218 
219     return ret ;
220 
221 }
222 
223 /* read and write cover mode
224 *   read example: cat  fts_touch_cover_mode---read  cover mode
225 *   write example:echo 01 > fts_touch_cover_mode ---write cover mode to 01
226 *
227 */
228 static DEVICE_ATTR (fts_cover_mode,  S_IRUGO | S_IWUSR, fts_touch_cover_show, fts_touch_cover_store);
229 
230 #endif
231 
232 #if FTS_CHARGER_EN
fts_touch_charger_show(struct device * dev,struct device_attribute * attr,char * buf)233 static ssize_t fts_touch_charger_show(struct device *dev, struct device_attribute *attr, char *buf)
234 {
235     int count;
236     u8 val;
237     struct input_dev *input_dev = fts_data->input_dev;
238     struct i2c_client *client = container_of(dev, struct i2c_client, dev);
239 
240     mutex_lock(&input_dev->mutex);
241     fts_i2c_read_reg(client, FTS_REG_CHARGER_MODE_EN, &val);
242     count = snprintf(buf, PAGE_SIZE, "Charge Mode: %s\n", g_fts_mode_flag.fts_charger_mode_flag ? "On" : "Off");
243     count += snprintf(buf + count, PAGE_SIZE, "Charge Reg(0x8B) = %d\n", val);
244     mutex_unlock(&input_dev->mutex);
245 
246     return count;
247 }
248 
fts_touch_charger_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)249 static ssize_t fts_touch_charger_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
250 {
251     int ret;
252     struct fts_ts_data *ts_data = fts_data;
253     struct i2c_client *client;
254 
255     client = ts_data->client;
256 
257     if (FTS_SYSFS_ECHO_ON(buf)) {
258         if (!g_fts_mode_flag.fts_charger_mode_flag) {
259             FTS_INFO("[Mode]enter charger mode");
260             ret = fts_enter_charger_mode(client, true);
261             if (ret >= 0) {
262                 g_fts_mode_flag.fts_charger_mode_flag = true;
263             }
264         }
265     } else if (FTS_SYSFS_ECHO_OFF(buf)) {
266         if (g_fts_mode_flag.fts_charger_mode_flag) {
267             FTS_INFO("[Mode]exit charger mode");
268             ret = fts_enter_charger_mode(client, false);
269             if (ret >= 0) {
270                 g_fts_mode_flag.fts_charger_mode_flag = false;
271             }
272         }
273     }
274     FTS_INFO("[Mode]charger mode status: %d", g_fts_mode_flag.fts_charger_mode_flag);
275     return count;
276 }
277 
278 /************************************************************************
279 * Name: fts_enter_charger_mode
280 * Brief:  change charger mode
281 * Input:  charger mode
282 * Output: no
283 * Return: success >=0, otherwise failed
284 ***********************************************************************/
fts_enter_charger_mode(struct i2c_client * client,int mode)285 int  fts_enter_charger_mode(struct i2c_client *client, int mode)
286 {
287     int ret = 0;
288     static u8 buf_addr[2] = { 0 };
289     static u8 buf_value[2] = { 0 };
290     buf_addr[0] = FTS_REG_CHARGER_MODE_EN; /* charger control */
291 
292     if (mode)
293         buf_value[0] = 0x01;
294     else
295         buf_value[0] = 0x00;
296 
297     ret = fts_i2c_write_reg( client, buf_addr[0], buf_value[0]);
298     if (ret < 0) {
299         FTS_DEBUG("[Mode]fts_enter_charger_mode write value fail");
300     }
301 
302     return ret ;
303 
304 }
305 
306 /* read and write charger mode
307 *   read example: cat  fts_touch_charger_mode---read  charger mode
308 *   write example:echo 01 > fts_touch_charger_mode ---write charger mode to 01
309 *
310 */
311 static DEVICE_ATTR (fts_charger_mode,  S_IRUGO | S_IWUSR, fts_touch_charger_show, fts_touch_charger_store);
312 
313 #endif
314 
315 static struct attribute *fts_touch_mode_attrs[] = {
316 #if FTS_GLOVE_EN
317     &dev_attr_fts_glove_mode.attr,
318 #endif
319 
320 #if FTS_COVER_EN
321     &dev_attr_fts_cover_mode.attr,
322 #endif
323 
324 #if FTS_CHARGER_EN
325     &dev_attr_fts_charger_mode.attr,
326 #endif
327 
328     NULL,
329 };
330 
331 static struct attribute_group fts_touch_mode_group = {
332     .attrs = fts_touch_mode_attrs,
333 };
334 
fts_ex_mode_init(struct i2c_client * client)335 int fts_ex_mode_init(struct i2c_client *client)
336 {
337     int err = 0;
338 
339     g_fts_mode_flag.fts_glove_mode_flag = false;
340     g_fts_mode_flag.fts_cover_mode_flag = false;
341     g_fts_mode_flag.fts_charger_mode_flag = false;
342 
343     err = sysfs_create_group(&client->dev.kobj, &fts_touch_mode_group);
344     if (0 != err) {
345         FTS_ERROR("[Mode]create sysfs failed.");
346         sysfs_remove_group(&client->dev.kobj, &fts_touch_mode_group);
347         return -EIO;
348     } else {
349         FTS_DEBUG("[Mode]create sysfs succeeded");
350     }
351 
352     return err;
353 
354 }
355 
fts_ex_mode_exit(struct i2c_client * client)356 int fts_ex_mode_exit(struct i2c_client *client)
357 {
358     sysfs_remove_group(&client->dev.kobj, &fts_touch_mode_group);
359     return 0;
360 }
361 
fts_ex_mode_recovery(struct i2c_client * client)362 int fts_ex_mode_recovery(struct i2c_client *client)
363 {
364     int ret = 0;
365 #if FTS_GLOVE_EN
366     if (g_fts_mode_flag.fts_glove_mode_flag)
367         ret = fts_enter_glove_mode(client, true);
368 #endif
369 
370 #if FTS_COVER_EN
371     if (g_fts_mode_flag.fts_cover_mode_flag)
372         ret = fts_enter_cover_mode(client, true);
373 #endif
374 
375 #if FTS_CHARGER_EN
376     if (g_fts_mode_flag.fts_charger_mode_flag)
377         ret = fts_enter_charger_mode(client, true);
378 #endif
379 
380     return ret;
381 }
382 
383