1 /*
2 *
3 * FocalTech ftxxxx TouchScreen driver.
4 *
5 * Copyright (c) 2012-2019, 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 enum _ex_mode {
45 MODE_GLOVE = 0,
46 MODE_COVER,
47 MODE_CHARGER,
48 };
49
50 /*****************************************************************************
51 * 4.Static variables
52 *****************************************************************************/
53
54 /*****************************************************************************
55 * 5.Global variable or extern global variabls/functions
56 *****************************************************************************/
57
58 /*****************************************************************************
59 * 6.Static function prototypes
60 *******************************************************************************/
fts_ex_mode_switch(enum _ex_mode mode,u8 value)61 static int fts_ex_mode_switch(enum _ex_mode mode, u8 value)
62 {
63 int ret = 0;
64 u8 m_val = 0;
65
66 if (value)
67 m_val = 0x01;
68 else
69 m_val = 0x00;
70
71 switch (mode) {
72 case MODE_GLOVE:
73 ret = fts_write_reg(FTS_REG_GLOVE_MODE_EN, m_val);
74 if (ret < 0) {
75 FTS_ERROR("MODE_GLOVE switch to %d fail", m_val);
76 }
77 break;
78 case MODE_COVER:
79 ret = fts_write_reg(FTS_REG_COVER_MODE_EN, m_val);
80 if (ret < 0) {
81 FTS_ERROR("MODE_COVER switch to %d fail", m_val);
82 }
83 break;
84 case MODE_CHARGER:
85 ret = fts_write_reg(FTS_REG_CHARGER_MODE_EN, m_val);
86 if (ret < 0) {
87 FTS_ERROR("MODE_CHARGER switch to %d fail", m_val);
88 }
89 break;
90 default:
91 FTS_ERROR("mode(%d) unsupport", mode);
92 ret = -EINVAL;
93 break;
94 }
95
96 return ret;
97 }
98
fts_glove_mode_show(struct device * dev,struct device_attribute * attr,char * buf)99 static ssize_t fts_glove_mode_show(
100 struct device *dev, struct device_attribute *attr, char *buf)
101 {
102 int count = 0;
103 u8 val = 0;
104 struct fts_ts_data *ts_data = fts_data;
105 struct input_dev *input_dev = ts_data->input_dev;
106
107 mutex_lock(&input_dev->mutex);
108 fts_read_reg(FTS_REG_GLOVE_MODE_EN, &val);
109 count = snprintf(buf + count, PAGE_SIZE, "Glove Mode:%s\n",
110 ts_data->glove_mode ? "On" : "Off");
111 count += snprintf(buf + count, PAGE_SIZE, "Glove Reg(0xC0):%d\n", val);
112 mutex_unlock(&input_dev->mutex);
113
114 return count;
115 }
116
fts_glove_mode_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)117 static ssize_t fts_glove_mode_store(
118 struct device *dev,
119 struct device_attribute *attr, const char *buf, size_t count)
120 {
121 int ret = 0;
122 struct fts_ts_data *ts_data = fts_data;
123
124 if (FTS_SYSFS_ECHO_ON(buf)) {
125 if (!ts_data->glove_mode) {
126 FTS_DEBUG("enter glove mode");
127 ret = fts_ex_mode_switch(MODE_GLOVE, ENABLE);
128 if (ret >= 0) {
129 ts_data->glove_mode = ENABLE;
130 }
131 }
132 } else if (FTS_SYSFS_ECHO_OFF(buf)) {
133 if (ts_data->glove_mode) {
134 FTS_DEBUG("exit glove mode");
135 ret = fts_ex_mode_switch(MODE_GLOVE, DISABLE);
136 if (ret >= 0) {
137 ts_data->glove_mode = DISABLE;
138 }
139 }
140 }
141
142 FTS_DEBUG("glove mode:%d", ts_data->glove_mode);
143 return count;
144 }
145
146
fts_cover_mode_show(struct device * dev,struct device_attribute * attr,char * buf)147 static ssize_t fts_cover_mode_show(
148 struct device *dev, struct device_attribute *attr, char *buf)
149 {
150 int count = 0;
151 u8 val = 0;
152 struct fts_ts_data *ts_data = fts_data;
153 struct input_dev *input_dev = ts_data->input_dev;
154
155 mutex_lock(&input_dev->mutex);
156 fts_read_reg(FTS_REG_COVER_MODE_EN, &val);
157 count = snprintf(buf + count, PAGE_SIZE, "Cover Mode:%s\n",
158 ts_data->cover_mode ? "On" : "Off");
159 count += snprintf(buf + count, PAGE_SIZE, "Cover Reg(0xC1):%d\n", val);
160 mutex_unlock(&input_dev->mutex);
161
162 return count;
163 }
164
fts_cover_mode_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)165 static ssize_t fts_cover_mode_store(
166 struct device *dev,
167 struct device_attribute *attr, const char *buf, size_t count)
168 {
169 int ret = 0;
170 struct fts_ts_data *ts_data = fts_data;
171
172 if (FTS_SYSFS_ECHO_ON(buf)) {
173 if (!ts_data->cover_mode) {
174 FTS_DEBUG("enter cover mode");
175 ret = fts_ex_mode_switch(MODE_COVER, ENABLE);
176 if (ret >= 0) {
177 ts_data->cover_mode = ENABLE;
178 }
179 }
180 } else if (FTS_SYSFS_ECHO_OFF(buf)) {
181 if (ts_data->cover_mode) {
182 FTS_DEBUG("exit cover mode");
183 ret = fts_ex_mode_switch(MODE_COVER, DISABLE);
184 if (ret >= 0) {
185 ts_data->cover_mode = DISABLE;
186 }
187 }
188 }
189
190 FTS_DEBUG("cover mode:%d", ts_data->cover_mode);
191 return count;
192 }
193
fts_charger_mode_show(struct device * dev,struct device_attribute * attr,char * buf)194 static ssize_t fts_charger_mode_show(
195 struct device *dev, struct device_attribute *attr, char *buf)
196 {
197 int count = 0;
198 u8 val = 0;
199 struct fts_ts_data *ts_data = fts_data;
200 struct input_dev *input_dev = ts_data->input_dev;
201
202 mutex_lock(&input_dev->mutex);
203 fts_read_reg(FTS_REG_CHARGER_MODE_EN, &val);
204 count = snprintf(buf + count, PAGE_SIZE, "Charger Mode:%s\n",
205 ts_data->charger_mode ? "On" : "Off");
206 count += snprintf(buf + count, PAGE_SIZE, "Charger Reg(0x8B):%d\n", val);
207 mutex_unlock(&input_dev->mutex);
208
209 return count;
210 }
211
fts_charger_mode_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)212 static ssize_t fts_charger_mode_store(
213 struct device *dev,
214 struct device_attribute *attr, const char *buf, size_t count)
215 {
216 int ret = 0;
217 struct fts_ts_data *ts_data = fts_data;
218
219 if (FTS_SYSFS_ECHO_ON(buf)) {
220 if (!ts_data->charger_mode) {
221 FTS_DEBUG("enter charger mode");
222 ret = fts_ex_mode_switch(MODE_CHARGER, ENABLE);
223 if (ret >= 0) {
224 ts_data->charger_mode = ENABLE;
225 }
226 }
227 } else if (FTS_SYSFS_ECHO_OFF(buf)) {
228 if (ts_data->charger_mode) {
229 FTS_DEBUG("exit charger mode");
230 ret = fts_ex_mode_switch(MODE_CHARGER, DISABLE);
231 if (ret >= 0) {
232 ts_data->charger_mode = DISABLE;
233 }
234 }
235 }
236
237 FTS_DEBUG("charger mode:%d", ts_data->glove_mode);
238 return count;
239 }
240
241
242 /* read and write charger mode
243 * read example: cat fts_glove_mode ---read glove mode
244 * write example:echo 1 > fts_glove_mode ---write glove mode to 01
245 */
246 static DEVICE_ATTR(fts_glove_mode, S_IRUGO | S_IWUSR,
247 fts_glove_mode_show, fts_glove_mode_store);
248
249 static DEVICE_ATTR(fts_cover_mode, S_IRUGO | S_IWUSR,
250 fts_cover_mode_show, fts_cover_mode_store);
251
252 static DEVICE_ATTR(fts_charger_mode, S_IRUGO | S_IWUSR,
253 fts_charger_mode_show, fts_charger_mode_store);
254
255 static struct attribute *fts_touch_mode_attrs[] = {
256 &dev_attr_fts_glove_mode.attr,
257 &dev_attr_fts_cover_mode.attr,
258 &dev_attr_fts_charger_mode.attr,
259 NULL,
260 };
261
262 static struct attribute_group fts_touch_mode_group = {
263 .attrs = fts_touch_mode_attrs,
264 };
265
fts_ex_mode_recovery(struct fts_ts_data * ts_data)266 int fts_ex_mode_recovery(struct fts_ts_data *ts_data)
267 {
268 if (ts_data->glove_mode) {
269 fts_ex_mode_switch(MODE_GLOVE, ENABLE);
270 }
271
272 if (ts_data->cover_mode) {
273 fts_ex_mode_switch(MODE_COVER, ENABLE);
274 }
275
276 if (ts_data->charger_mode) {
277 fts_ex_mode_switch(MODE_CHARGER, ENABLE);
278 }
279
280 return 0;
281 }
282
fts_ex_mode_init(struct fts_ts_data * ts_data)283 int fts_ex_mode_init(struct fts_ts_data *ts_data)
284 {
285 int ret = 0;
286
287 ts_data->glove_mode = DISABLE;
288 ts_data->cover_mode = DISABLE;
289 ts_data->charger_mode = DISABLE;
290
291 ret = sysfs_create_group(&ts_data->dev->kobj, &fts_touch_mode_group);
292 if (ret < 0) {
293 FTS_ERROR("create sysfs(ex_mode) fail");
294 sysfs_remove_group(&ts_data->dev->kobj, &fts_touch_mode_group);
295 return ret;
296 } else {
297 FTS_DEBUG("create sysfs(ex_mode) succeedfully");
298 }
299
300 return 0;
301 }
302
fts_ex_mode_exit(struct fts_ts_data * ts_data)303 int fts_ex_mode_exit(struct fts_ts_data *ts_data)
304 {
305 sysfs_remove_group(&ts_data->dev->kobj, &fts_touch_mode_group);
306 return 0;
307 }
308