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