xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/focaltech_touch_ft5436/focaltech_ex_mode.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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