tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / input / touchscreen / ist30xxa / ist30xx_sec.c
1 /*
2  *  Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved.
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  */
15
16
17 #include <linux/mutex.h>
18 #include <linux/i2c.h>
19 #include <linux/delay.h>
20 #include <linux/slab.h>
21 #include <linux/input.h>
22 #include <linux/stat.h>
23 #include <linux/err.h>
24
25 #include "ist30xx.h"
26 #include "ist30xx_update.h"
27 #include "ist30xx_misc.h"
28
29
30 static char IsfwUpdate[20] = { 0 };
31
32 #define FW_DOWNLOADING "Downloading"
33 #define FW_DOWNLOAD_COMPLETE "Complete"
34 #define FW_DOWNLOAD_FAIL "FAIL"
35
36 #define FACTORY_BUF_SIZE    (1024)
37 #define BUILT_IN            (0)
38 #define UMS                 (1)
39
40 #define CMD_STATE_WAITING   (0)
41 #define CMD_STATE_RUNNING   (1)
42 #define CMD_STATE_OK        (2)
43 #define CMD_STATE_FAIL      (3)
44 #define CMD_STATE_NA        (4)
45
46 #define TSP_NODE_DEBUG      (1)
47
48 static u16 node_value[TSP_TOTAL_NUM];
49
50 extern struct ist30xx_data *ts_data;
51 extern TSP_INFO ist30xx_tsp_info;
52 extern TKEY_INFO ist30xx_tkey_info;
53
54
55 #define TSP_CMD(name, func) .cmd_name = name, .cmd_func = func
56 struct tsp_cmd {
57         struct list_head        list;
58         const char *            cmd_name;
59         void                    (*cmd_func)(void *dev_data);
60 };
61
62 u32 ist30xxb_get_fw_ver(struct ist30xx_data *data)
63 {
64         u32 addr = data->tags.cfg_addr + 4;
65         u32 len = 1;
66         u32 ver = 0;
67         int ret = -EPERM;
68
69         ist30xx_disable_irq(data);
70         ret = ist30xx_cmd_reg(data->client, CMD_ENTER_REG_ACCESS);
71         if (unlikely(ret))
72                 goto get_fw_ver_fail;
73
74         ret = ist30xx_write_cmd(data->client, IST30XX_RX_CNT_ADDR, len);
75         if (unlikely(ret))
76                 goto get_fw_ver_fail;
77
78         ret = ist30xx_read_cmd(data->client, addr, &ver);
79         if (unlikely(ret))
80                 goto get_fw_ver_fail;
81
82         tsp_debug("Reg addr: %x, ver: %x\n", addr, ver);
83
84         ret = ist30xx_cmd_reg(data->client, CMD_EXIT_REG_ACCESS);
85         if (likely(ret == 0))
86                 goto get_fw_ver_end;
87
88 get_fw_ver_fail:
89         ist30xx_reset(false);
90
91 get_fw_ver_end:
92         ist30xx_cmd_start_scan(data->client);
93         ist30xx_enable_irq(data);
94
95         return ver;
96 }
97
98 u32 key_sensitivity = 0;
99 int ist30xxb_get_key_sensitivity(struct ist30xx_data *data, int id)
100 {
101         u32 addr = IST30XXB_MEM_KEYSENSITIVITY + 4 * sizeof(u32);
102         u32 val = 0;
103
104         if (unlikely(id >= ist30xx_tkey_info.key_num))
105                 return 0;
106
107         if (ist30xx_intr_wait(30) < 0)
108                 return 0;
109
110         ist30xx_read_cmd(data->client, addr, &val);
111         if ((val & 0xFFF) == 0xFFF)
112                 return (key_sensitivity >> (16 * id)) & 0xFFFF;
113
114         key_sensitivity = val;
115
116         tsp_debug("Reg addr: %x, val: %8x\n", addr, val);
117
118         val >>= (16 * id);
119
120         return (int)(val & 0xFFFF);
121 }
122
123
124 /* Factory CMD function */
125 static void set_default_result(struct sec_factory *sec)
126 {
127         char delim = ':';
128
129         memset(sec->cmd_result, 0, ARRAY_SIZE(sec->cmd_result));
130         memcpy(sec->cmd_result, sec->cmd, strlen(sec->cmd));
131         strncat(sec->cmd_result, &delim, CMD_STATE_RUNNING);
132 }
133
134 static void set_cmd_result(struct sec_factory *sec, char *buf, int len)
135 {
136         strncat(sec->cmd_result, buf, len);
137 }
138
139 static void not_support_cmd(void *dev_data)
140 {
141         char buf[16] = { 0 };
142
143         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
144         struct sec_factory *sec = (struct sec_factory *)&data->sec;
145
146         set_default_result(sec);
147         snprintf(buf, sizeof(buf), "%s", "NA");
148         tsp_info("%s(), %s\n", __func__, buf);
149
150         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
151         sec->cmd_state = CMD_STATE_NA;
152         dev_info(&data->client->dev, "%s: \"%s(%d)\"\n", __func__,
153                  buf, strnlen(buf, sizeof(buf)));
154         return;
155 }
156
157 static void get_chip_vendor(void *dev_data)
158 {
159         char buf[16] = { 0 };
160
161         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
162         struct sec_factory *sec = (struct sec_factory *)&data->sec;
163
164         set_default_result(sec);
165         snprintf(buf, sizeof(buf), "%s", TSP_CHIP_VENDOR);
166         tsp_info("%s(), %s\n", __func__, buf);
167
168         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
169         sec->cmd_state = CMD_STATE_OK;
170         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__,
171                  buf, strnlen(buf, sizeof(buf)));
172 }
173
174 static void get_chip_name(void *dev_data)
175 {
176         char buf[16] = { 0 };
177
178         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
179         struct sec_factory *sec = (struct sec_factory *)&data->sec;
180
181         set_default_result(sec);
182         snprintf(buf, sizeof(buf), "%s", TSP_CHIP_NAME);
183         tsp_info("%s(), %s\n", __func__, buf);
184
185         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
186         sec->cmd_state = CMD_STATE_OK;
187         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__,
188                  buf, strnlen(buf, sizeof(buf)));
189 }
190
191 static void get_chip_id(void *dev_data)
192 {
193         char buf[16] = { 0 };
194
195         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
196         struct sec_factory *sec = (struct sec_factory *)&data->sec;
197
198         set_default_result(sec);
199         snprintf(buf, sizeof(buf), "%#02x", data->chip_id);
200         tsp_info("%s(), %s\n", __func__, buf);
201
202         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
203         sec->cmd_state = CMD_STATE_OK;
204         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__,
205                  buf, strnlen(buf, sizeof(buf)));
206 }
207 #include <linux/uaccess.h>
208 #define MAX_FW_PATH 255
209 extern u32 ist30xx_fw_ver;
210 extern u32 ist30xx_param_ver;
211 extern u32 ist30xx_sub_ver;
212 static void fw_update(void *dev_data)
213 {
214         int ret;
215         char buf[16] = { 0 };
216         mm_segment_t old_fs = {0};
217         struct file *fp = NULL;
218         long fsize = 0, nread = 0;
219         u8 *fw;
220         char fw_path[MAX_FW_PATH+1];
221
222         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
223         struct sec_factory *sec = (struct sec_factory *)&data->sec;
224
225         set_default_result(sec);
226
227         tsp_info("%s(), %d\n", __func__, sec->cmd_param[0]);
228
229         switch (sec->cmd_param[0]) {
230         case BUILT_IN:
231                 sec->cmd_state = CMD_STATE_OK;
232                 ret = ist30xx_fw_recovery(data);
233                 if (ret < 0)
234                         sec->cmd_state = CMD_STATE_FAIL;
235                 break;
236         case UMS:
237                 sec->cmd_state = CMD_STATE_OK;
238                 old_fs = get_fs();
239                 set_fs(get_ds());
240
241                 snprintf(fw_path, MAX_FW_PATH, "/sdcard/%s", IST30XXB_FW_NAME);
242                 fp = filp_open(fw_path, O_RDONLY, 0);
243                 if (IS_ERR(fp)) {
244                         tsp_warn("%s(), file %s open error:%d\n", __func__, 
245                     fw_path, (s32)fp);
246                         sec->cmd_state= CMD_STATE_FAIL;
247                         set_fs(old_fs);
248                         break;
249                 }
250
251                 fsize = fp->f_path.dentry->d_inode->i_size;
252                 if (fsize != data->fw.buf_size) {
253                         tsp_warn("%s(), invalid fw size!!\n", __func__);
254                         sec->cmd_state = CMD_STATE_FAIL;
255                         set_fs(old_fs);
256                         break;
257                 }
258                 fw = kzalloc((size_t)fsize, GFP_KERNEL);
259                 if (!fw) {
260                         tsp_warn("%s(), failed to alloc buffer for fw\n", __func__);
261                         sec->cmd_state = CMD_STATE_FAIL;
262                         filp_close(fp, NULL);
263                         set_fs(old_fs);
264                         break;
265                 }
266                 nread = vfs_read(fp, (char __user *)fw, fsize, &fp->f_pos);
267                 if (nread != fsize) {
268                         tsp_warn("%s(), failed to read fw\n", __func__);
269                         sec->cmd_state = CMD_STATE_FAIL;
270                         filp_close(fp, NULL);
271                         set_fs(old_fs);
272                         break;
273                 }
274
275                 filp_close(fp, current->files);
276                 set_fs(old_fs);
277                 tsp_info("%s(), ums fw is loaded!!\n", __func__);
278
279                 ist30xx_get_update_info(ts_data, fw, fsize);
280                 ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw);
281                 ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw);
282                 ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw);
283
284                 mutex_lock(&ist30xx_mutex);
285                 ist30xx_fw_update(data->client, fw, fsize, true);
286                 mutex_unlock(&ist30xx_mutex);
287
288                 ist30xx_calibrate(1);
289                 break;
290
291         default:
292                 tsp_warn("%s(), Invalid fw file type!\n", __func__);
293                 break;
294         }
295
296         if (sec->cmd_state == CMD_STATE_OK)
297                 snprintf(buf, sizeof(buf), "%s", "OK");
298         else
299                 snprintf(buf, sizeof(buf), "%s", "NG");
300
301         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
302 }
303
304
305 static void get_fw_ver_bin(void *dev_data)
306 {
307         u32 ver = 0;
308         char buf[16] = { 0 };
309
310         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
311         struct sec_factory *sec = (struct sec_factory *)&data->sec;
312
313         set_default_result(sec);
314
315         ver = ist30xx_parse_ver(FLAG_PARAM, data->fw.buf);
316         snprintf(buf, sizeof(buf), "IM00%04x", ver);
317         tsp_info("%s(), %s\n", __func__, buf);
318
319         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
320         sec->cmd_state = CMD_STATE_OK;
321         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__,
322                  buf, strnlen(buf, sizeof(buf)));
323 }
324
325 static void get_fw_ver_ic(void *dev_data)
326 {
327         u32 ver = 0;
328         char msg[8];
329         char buf[16] = { 0 };
330
331         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
332         struct sec_factory *sec = (struct sec_factory *)&data->sec;
333
334         set_default_result(sec);
335
336         if (data->status.power == 1)
337                 ver = ist30xxb_get_fw_ver(ts_data);
338
339         snprintf(buf, sizeof(buf), "IM00%04x", ver & 0xFFFF);
340
341         if (data->fw.sub_ver > 0) {
342                 sprintf(msg, "(T%d)", data->fw.sub_ver);
343                 strcat(buf, msg);
344         }
345
346         tsp_info("%s(), %s\n", __func__, buf);
347
348         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
349         sec->cmd_state = CMD_STATE_OK;
350         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__,
351                  buf, strnlen(buf, sizeof(buf)));
352 }
353
354 static void get_threshold(void *dev_data)
355 {
356         char buf[16] = { 0 };
357         int threshold;
358         u32 *cfg_buf;
359
360         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
361         struct sec_factory *sec = (struct sec_factory *)&data->sec;
362
363         set_default_result(sec);
364
365         ist30xx_get_update_info(data, data->fw.buf, data->fw.buf_size);
366         cfg_buf = (u32 *)&data->fw.buf[data->tags.cfg_addr];
367
368         threshold = (int)(cfg_buf[0x2C / IST30XX_DATA_LEN] & 0xFFFF);
369
370         snprintf(buf, sizeof(buf), "%d", threshold);
371         tsp_info("%s(), %s\n", __func__, buf);
372
373         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
374         sec->cmd_state = CMD_STATE_OK;
375         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__,
376                  buf, strnlen(buf, sizeof(buf)));
377 }
378
379 static void get_x_num(void *dev_data)
380 {
381         int val = ist30xx_tsp_info.width;
382         char buf[16] = { 0 };
383
384         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
385         struct sec_factory *sec = (struct sec_factory *)&data->sec;
386
387         set_default_result(sec);
388
389         if (val >= 0) {
390                 snprintf(buf, sizeof(buf), "%u", val);
391                 sec->cmd_state = CMD_STATE_OK;
392                 dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, buf,
393                          strnlen(buf, sizeof(buf)));
394         } else {
395                 snprintf(buf, sizeof(buf), "%s", "NG");
396                 sec->cmd_state = CMD_STATE_FAIL;
397                 dev_info(&data->client->dev,
398                          "%s: fail to read num of x (%d).\n", __func__, val);
399         }
400         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
401         tsp_info("%s(), %s\n", __func__, buf);
402 }
403
404 static void get_y_num(void *dev_data)
405 {
406         int val = ist30xx_tsp_info.height;
407         char buf[16] = { 0 };
408
409         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
410         struct sec_factory *sec = (struct sec_factory *)&data->sec;
411
412         set_default_result(sec);
413
414         if (val >= 0) {
415                 snprintf(buf, sizeof(buf), "%u", val);
416                 sec->cmd_state = CMD_STATE_OK;
417                 dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, buf,
418                          strnlen(buf, sizeof(buf)));
419         } else {
420                 snprintf(buf, sizeof(buf), "%s", "NG");
421                 sec->cmd_state = CMD_STATE_FAIL;
422                 dev_info(&data->client->dev,
423                          "%s: fail to read num of x (%d).\n", __func__, val);
424         }
425         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
426         tsp_info("%s(), %s\n", __func__, buf);
427 }
428
429 int check_tsp_channel(void *dev_data)
430 {
431         int node = -EPERM;
432
433         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
434         struct sec_factory *sec = (struct sec_factory *)&data->sec;
435         TSP_INFO *tsp = &ist30xx_tsp_info;
436
437         if ((sec->cmd_param[0] < 0) || (sec->cmd_param[0] >= tsp->width) ||
438             (sec->cmd_param[1] < 0) || (sec->cmd_param[1] >= tsp->height)) {
439                 dev_info(&data->client->dev, "%s: parameter error: %u,%u\n",
440                          __func__, sec->cmd_param[0], sec->cmd_param[1]);
441         } else {
442                 node = sec->cmd_param[0] + sec->cmd_param[1] * tsp->width;
443                 dev_info(&data->client->dev, "%s: node = %d\n", __func__, node);
444         }
445
446         return node;
447 }
448
449
450 extern int parse_tsp_node(u8 flag, struct TSP_NODE_BUF *node, s16 *buf16);
451 void run_raw_read(void *dev_data)
452 {
453         int i, ret;
454         int min_val, max_val;
455         char buf[16] = { 0 };
456         u8 flag = NODE_FLAG_RAW;
457
458         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
459         struct sec_factory *sec = (struct sec_factory *)&data->sec;
460         TSP_INFO *tsp = &ist30xx_tsp_info;
461
462         set_default_result(sec);
463
464         ret = ist30xx_read_touch_node(flag, &tsp->node);
465         if (ret) {
466                 sec->cmd_state = CMD_STATE_FAIL;
467                 tsp_warn("%s(), tsp node read fail!\n", __func__);
468                 return;
469         }
470         ist30xx_parse_touch_node(flag, &tsp->node);
471
472         ret = parse_tsp_node(flag, &tsp->node, node_value);
473         if (ret) {
474                 sec->cmd_state = CMD_STATE_FAIL;
475                 tsp_warn("%s(), tsp node parse fail - flag: %d\n", __func__, flag);
476                 return;
477         }
478
479         min_val = max_val = node_value[0];
480         for (i = 0; i < tsp->width * tsp->height; i++) {
481 #if TSP_NODE_DEBUG
482                 if ((i % tsp->width) == 0)
483                         printk("\n%s %4d: ", IST30XX_DEBUG_TAG, i);
484
485                 printk("%4d ", node_value[i]);
486 #endif
487
488                 max_val = max(max_val, (int)node_value[i]);
489                 min_val = min(min_val, (int)node_value[i]);
490         }
491
492         snprintf(buf, sizeof(buf), "%d,%d", min_val, max_val);
493         tsp_info("%s(), %s\n", __func__, buf);
494
495         sec->cmd_state = CMD_STATE_OK;
496         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
497         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, buf,
498                  strnlen(buf, sizeof(buf)));
499 }
500
501 void get_raw_value(void *dev_data)
502 {
503         int idx = 0;
504         char buf[16] = { 0 };
505
506         struct ist30xx_data *data = (struct ist30xx_data *)dev_data;
507         struct sec_factory *sec = (struct sec_factory *)&data->sec;
508
509         set_default_result(sec);
510
511         idx = check_tsp_channel(data);
512         if (idx < 0) { // Parameter parsing fail
513                 snprintf(buf, sizeof(buf), "%s", "NG");
514                 sec->cmd_state = CMD_STATE_FAIL;
515         } else {
516                 snprintf(buf, sizeof(buf), "%d", node_value[idx]);
517                 sec->cmd_state = CMD_STATE_OK;
518         }
519
520         set_cmd_result(sec, buf, strnlen(buf, sizeof(buf)));
521         tsp_info("%s(), [%d][%d]: %s\n", __func__,
522                  sec->cmd_param[0], sec->cmd_param[1], buf);
523         dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, buf,
524                  strnlen(buf, sizeof(buf)));
525 }
526
527
528
529 /* sysfs: /sys/class/sec/tsp/close_tsp_test */
530 static ssize_t show_close_tsp_test(struct device *dev,
531                                    struct device_attribute *attr, char *buf)
532 {
533         return snprintf(buf, FACTORY_BUF_SIZE, "%u\n", 0);
534 }
535
536 /* sysfs: /sys/class/sec/tsp/cmd */
537 static ssize_t store_cmd(struct device *dev, struct device_attribute
538                          *devattr, const char *buf, size_t count)
539 {
540         struct ist30xx_data *data = dev_get_drvdata(dev);
541         struct sec_factory *sec = (struct sec_factory *)&data->sec;
542         struct i2c_client *client = data->client;
543
544         char *cur, *start, *end;
545         char msg[SEC_CMD_STR_LEN] = { 0 };
546         int len, i;
547         struct tsp_cmd *tsp_cmd_ptr = NULL;
548         char delim = ',';
549         bool cmd_found = false;
550         int param_cnt = 0;
551         int ret;
552
553         if (sec->cmd_is_running == true) {
554                 dev_err(&client->dev, "tsp_cmd: other cmd is running.\n");
555                 tsp_err("tsp_cmd: other cmd is running.\n");
556                 goto err_out;
557         }
558
559         /* check lock  */
560         mutex_lock(&sec->cmd_lock);
561         sec->cmd_is_running = true;
562         mutex_unlock(&sec->cmd_lock);
563
564         sec->cmd_state = CMD_STATE_RUNNING;
565
566         for (i = 0; i < ARRAY_SIZE(sec->cmd_param); i++)
567                 sec->cmd_param[i] = 0;
568
569         len = (int)count;
570         if (*(buf + len - 1) == '\n')
571                 len--;
572         memset(sec->cmd, 0, ARRAY_SIZE(sec->cmd));
573         memcpy(sec->cmd, buf, len);
574
575         cur = strchr(buf, (int)delim);
576         if (cur)
577                 memcpy(msg, buf, cur - buf);
578         else
579                 memcpy(msg, buf, len);
580         /* find command */
581         list_for_each_entry(tsp_cmd_ptr, &sec->cmd_list_head, list) {
582                 if (!strcmp(msg, tsp_cmd_ptr->cmd_name)) {
583                         cmd_found = true;
584                         break;
585                 }
586         }
587
588         /* set not_support_cmd */
589         if (!cmd_found) {
590                 list_for_each_entry(tsp_cmd_ptr, &sec->cmd_list_head, list) {
591                         if (!strcmp("not_support_cmd", tsp_cmd_ptr->cmd_name))
592                                 break;
593                 }
594         }
595
596         /* parsing parameters */
597         if (cur && cmd_found) {
598                 cur++;
599                 start = cur;
600                 memset(msg, 0, ARRAY_SIZE(msg));
601                 do {
602                         if (*cur == delim || cur - buf == len) {
603                                 end = cur;
604                                 memcpy(msg, start, end - start);
605                                 *(msg + strlen(msg)) = '\0';
606                                 ret = kstrtoint(msg, 10, \
607                                                 sec->cmd_param + param_cnt);
608                                 start = cur + 1;
609                                 memset(msg, 0, ARRAY_SIZE(msg));
610                                 param_cnt++;
611                         }
612                         cur++;
613                 } while (cur - buf <= len);
614         }
615         dev_info(&client->dev, "cmd = %s\n", tsp_cmd_ptr->cmd_name);
616         tsp_info("SEC CMD = %s\n", tsp_cmd_ptr->cmd_name);
617
618         for (i = 0; i < param_cnt; i++)
619                 dev_info(&client->dev, "cmd param %d= %d\n", i, sec->cmd_param[i]);
620
621         tsp_cmd_ptr->cmd_func(data);
622
623 err_out:
624         return count;
625 }
626
627 /* sysfs: /sys/class/sec/tsp/cmd_status */
628 static ssize_t show_cmd_status(struct device *dev,
629                                struct device_attribute *devattr, char *buf)
630 {
631         struct ist30xx_data *data = dev_get_drvdata(dev);
632         struct sec_factory *sec = (struct sec_factory *)&data->sec;
633         char msg[16] = { 0 };
634
635         dev_info(&data->client->dev, "tsp cmd: status:%d\n", sec->cmd_state);
636
637         if (sec->cmd_state == CMD_STATE_WAITING)
638                 snprintf(msg, sizeof(msg), "WAITING");
639         else if (sec->cmd_state == CMD_STATE_RUNNING)
640                 snprintf(msg, sizeof(msg), "RUNNING");
641         else if (sec->cmd_state == CMD_STATE_OK)
642                 snprintf(msg, sizeof(msg), "OK");
643         else if (sec->cmd_state == CMD_STATE_FAIL)
644                 snprintf(msg, sizeof(msg), "FAIL");
645         else if (sec->cmd_state == CMD_STATE_NA)
646                 snprintf(msg, sizeof(msg), "NOT_APPLICABLE");
647
648         return snprintf(buf, FACTORY_BUF_SIZE, "%s\n", msg);
649 }
650
651 /* sysfs: /sys/class/sec/tsp/result */
652 static ssize_t show_cmd_result(struct device *dev, struct device_attribute
653                                *devattr, char *buf)
654 {
655         struct ist30xx_data *data = dev_get_drvdata(dev);
656         struct sec_factory *sec = (struct sec_factory *)&data->sec;
657
658         dev_info(&data->client->dev, "tsp cmd: result: %s\n", sec->cmd_result);
659
660         mutex_lock(&sec->cmd_lock);
661         sec->cmd_is_running = false;
662         mutex_unlock(&sec->cmd_lock);
663
664         sec->cmd_state = CMD_STATE_WAITING;
665
666         return snprintf(buf, FACTORY_BUF_SIZE, "%s\n", sec->cmd_result);
667 }
668
669
670
671 /* sysfs: /sys/class/sec/sec_touchscreen/tsp_firm_version_phone */
672 static ssize_t phone_firmware_show(struct device *dev,
673                                    struct device_attribute *attr, char *buf)
674 {
675         u32 ver = ist30xx_parse_ver(FLAG_PARAM, ts_data->fw.buf);
676
677         tsp_info("%s(), IM00%04x\n", __func__, ver);
678
679         return sprintf(buf, "IM00%04x", ver);
680 }
681
682 /* sysfs: /sys/class/sec/sec_touchscreen/tsp_firm_version_panel */
683 static ssize_t part_firmware_show(struct device *dev,
684                                   struct device_attribute *attr, char *buf)
685 {
686         u32 ver = 0;
687
688         if (ts_data->status.power == 1)
689                 ver = ist30xxb_get_fw_ver(ts_data);
690
691         tsp_info("%s(), IM00%04x\n", __func__, ver);
692
693         return sprintf(buf, "IM00%04x", ver);
694 }
695
696 /* sysfs: /sys/class/sec/sec_touchscreen/tsp_threshold */
697 static ssize_t threshold_firmware_show(struct device *dev,
698                                        struct device_attribute *attr, char *buf)
699 {
700         int threshold;
701         u32 *cfg_buf;
702
703         ist30xx_get_update_info(ts_data, ts_data->fw.buf, ts_data->fw.buf_size);
704         cfg_buf = (u32 *)&ts_data->fw.buf[ts_data->tags.cfg_addr];
705
706         threshold = (int)(cfg_buf[0x2C / IST30XX_DATA_LEN] & 0xFFFF);
707
708         tsp_info("%s(), %d\n", __func__, threshold);
709
710         return sprintf(buf, "%d", threshold);
711 }
712
713 /* sysfs: /sys/class/sec/sec_touchscreen/tsp_firm_update */
714 static ssize_t firmware_update(struct device *dev,
715                                struct device_attribute *attr, char *buf)
716 {
717         bool ret;
718
719         sprintf(IsfwUpdate, "%s\n", FW_DOWNLOADING);
720         tsp_info("%s(), %s\n", __func__, IsfwUpdate);
721
722         ret = ist30xx_fw_recovery(ts_data);
723         ret = (ret == 0 ? 1 : -1);
724
725         sprintf(IsfwUpdate, "%s\n",
726                 (ret > 0 ? FW_DOWNLOAD_COMPLETE : FW_DOWNLOAD_FAIL));
727         tsp_info("%s(), %s\n", __func__, IsfwUpdate);
728
729         return sprintf(buf, "%d", ret);
730 }
731
732 /* sysfs: /sys/class/sec/sec_touchscreen/tsp_firm_update_status */
733 static ssize_t firmware_update_status(struct device *dev,
734                                       struct device_attribute *attr, char *buf)
735 {
736         tsp_info("%s(), %s\n", __func__, IsfwUpdate);
737
738         return sprintf(buf, "%s\n", IsfwUpdate);
739 }
740
741 /* sysfs: /sys/class/sec/sec_touchkey/touchkey_recent */
742 static ssize_t recent_sensitivity_show(struct device *dev,
743                                        struct device_attribute *attr, char *buf)
744 {
745         int sensitivity = ist30xxb_get_key_sensitivity(ts_data, 0);
746
747         tsp_info("%s(), %d\n", __func__, sensitivity);
748
749         return sprintf(buf, "%d", sensitivity);
750 }
751
752 /* sysfs: /sys/class/sec/sec_touchkey/touchkey_back */
753 static ssize_t back_sensitivity_show(struct device *dev,
754                                      struct device_attribute *attr, char *buf)
755 {
756         int sensitivity = ist30xxb_get_key_sensitivity(ts_data, 1);
757
758         tsp_info("%s(), %d\n", __func__, sensitivity);
759
760         return sprintf(buf, "%d", sensitivity);
761 }
762
763 /* sysfs: /sys/class/sec/sec_touchkey/touchkey_threshold */
764 static ssize_t touchkey_threshold_show(struct device *dev,
765                                        struct device_attribute *attr, char *buf)
766 {
767         int threshold;
768         u32 *cfg_buf;
769
770         ist30xx_get_update_info(ts_data, ts_data->fw.buf, ts_data->fw.buf_size);
771         cfg_buf = (u32 *)&ts_data->fw.buf[ts_data->tags.cfg_addr];
772
773         threshold = (int)(cfg_buf[0x30 / IST30XX_DATA_LEN] & 0xFFFF);
774
775         tsp_info("%s(), %d\n", __func__, threshold);
776
777         return snprintf(buf, sizeof(int), "%d\n", threshold);
778 }
779
780 struct tsp_cmd tsp_cmds[] = {
781         { TSP_CMD("get_chip_vendor", get_chip_vendor), },
782         { TSP_CMD("get_chip_name",   get_chip_name),   },
783         { TSP_CMD("get_chip_id",     get_chip_id),     },
784         { TSP_CMD("fw_update",       fw_update),       },
785         { TSP_CMD("get_fw_ver_bin",  get_fw_ver_bin),  },
786         { TSP_CMD("get_fw_ver_ic",   get_fw_ver_ic),   },
787         { TSP_CMD("get_threshold",   get_threshold),   },
788         { TSP_CMD("get_x_num",       get_x_num),       },
789         { TSP_CMD("get_y_num",       get_y_num),       },
790         { TSP_CMD("run_raw_read",    run_raw_read),    },
791         { TSP_CMD("get_raw_value",   get_raw_value),   },
792         { TSP_CMD("not_support_cmd", not_support_cmd), },
793 };
794
795 #define SEC_DEFAULT_ATTR    (S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH)
796 /* sysfs - touchscreen */
797 static DEVICE_ATTR(tsp_firm_version_phone, SEC_DEFAULT_ATTR,
798                    phone_firmware_show, NULL);
799 static DEVICE_ATTR(tsp_firm_version_panel, SEC_DEFAULT_ATTR,
800                    part_firmware_show, NULL);
801 static DEVICE_ATTR(tsp_threshold, SEC_DEFAULT_ATTR,
802                    threshold_firmware_show, NULL);
803 static DEVICE_ATTR(tsp_firm_update, SEC_DEFAULT_ATTR,
804                    firmware_update, NULL);
805 static DEVICE_ATTR(tsp_firm_update_status, SEC_DEFAULT_ATTR,
806                    firmware_update_status, NULL);
807
808 /* sysfs - touchkey */
809 static DEVICE_ATTR(touchkey_recent, SEC_DEFAULT_ATTR,
810                    recent_sensitivity_show, NULL);
811 static DEVICE_ATTR(touchkey_back, SEC_DEFAULT_ATTR,
812                    back_sensitivity_show, NULL);
813 static DEVICE_ATTR(touchkey_threshold, SEC_DEFAULT_ATTR,
814                    touchkey_threshold_show, NULL);
815
816 /* sysfs - tsp */
817 static DEVICE_ATTR(close_tsp_test, S_IRUGO, show_close_tsp_test, NULL);
818 static DEVICE_ATTR(cmd, S_IWUSR | S_IWGRP, NULL, store_cmd);
819 static DEVICE_ATTR(cmd_status, S_IRUGO, show_cmd_status, NULL);
820 static DEVICE_ATTR(cmd_result, S_IRUGO, show_cmd_result, NULL);
821
822 static struct attribute *sec_tsp_attributes[] = {
823         &dev_attr_tsp_firm_version_phone.attr,
824         &dev_attr_tsp_firm_version_panel.attr,
825         &dev_attr_tsp_threshold.attr,
826         &dev_attr_tsp_firm_update.attr,
827         &dev_attr_tsp_firm_update_status.attr,
828         NULL,
829 };
830
831 static struct attribute *sec_tkey_attributes[] = {
832         &dev_attr_touchkey_recent.attr,
833         &dev_attr_touchkey_back.attr,
834         &dev_attr_touchkey_threshold.attr,
835         NULL,
836 };
837
838 static struct attribute *sec_touch_facotry_attributes[] = {
839         &dev_attr_close_tsp_test.attr,
840         &dev_attr_cmd.attr,
841         &dev_attr_cmd_status.attr,
842         &dev_attr_cmd_result.attr,
843         NULL,
844 };
845
846 static struct attribute_group sec_tsp_attr_group = {
847         .attrs  = sec_tsp_attributes,
848 };
849
850 static struct attribute_group sec_tkey_attr_group = {
851         .attrs  = sec_tkey_attributes,
852 };
853
854 static struct attribute_group sec_touch_factory_attr_group = {
855         .attrs  = sec_touch_facotry_attributes,
856 };
857
858 extern struct class *sec_class;
859 struct device *sec_touchscreen;
860 EXPORT_SYMBOL(sec_touchscreen);
861 struct device *sec_touchkey;
862 EXPORT_SYMBOL(sec_touchkey);
863 struct device *sec_fac_dev;
864
865
866 int sec_touch_sysfs(struct ist30xx_data *data)
867 {
868         /* /sys/class/sec/sec_touchscreen */
869         sec_touchscreen = device_create(sec_class, NULL, 0, NULL,
870                                         "sec_touchscreen");
871         if (IS_ERR(sec_touchscreen)) {
872                 tsp_err("Failed to create device (%s)!\n", "sec_touchscreen");
873                 return -ENODEV;
874         }
875         /* /sys/class/sec/sec_touchscreen/... */
876         if (sysfs_create_group(&sec_touchscreen->kobj, &sec_tsp_attr_group))
877                 tsp_err("Failed to create sysfs group(%s)!\n", "sec_touchscreen");
878
879         /* /sys/class/sec/sec_touchkey */
880         sec_touchkey = device_create(sec_class, NULL, 0, NULL, "sec_touchkey");
881         if (IS_ERR(sec_touchkey)) {
882                 tsp_err("Failed to create device (%s)!\n", "sec_touchkey");
883                 return -ENODEV;
884         }
885         /* /sys/class/sec/sec_touchkey/... */
886         if (sysfs_create_group(&sec_touchkey->kobj, &sec_tkey_attr_group))
887                 tsp_err("Failed to create sysfs group(%s)!\n", "sec_touchkey");
888
889         /* /sys/class/sec/tsp */
890         sec_fac_dev = device_create(sec_class, NULL, 0, data, "tsp");
891         if (IS_ERR(sec_fac_dev)) {
892                 tsp_err("Failed to create device (%s)!\n", "tsp");
893                 return -ENODEV;
894         }
895         /* /sys/class/sec/tsp/... */
896         if (sysfs_create_group(&sec_fac_dev->kobj, &sec_touch_factory_attr_group))
897                 tsp_err("Failed to create sysfs group(%s)!\n", "tsp");
898
899         return 0;
900 }
901 EXPORT_SYMBOL(sec_touch_sysfs);
902 int sec_fac_cmd_init(struct ist30xx_data *data)
903 {
904         int i;
905         struct sec_factory *sec = (struct sec_factory *)&data->sec;
906
907         INIT_LIST_HEAD(&sec->cmd_list_head);
908         for (i = 0; i < ARRAY_SIZE(tsp_cmds); i++)
909                 list_add_tail(&tsp_cmds[i].list, &sec->cmd_list_head);
910
911         mutex_init(&sec->cmd_lock);
912         sec->cmd_is_running = false;
913
914         return 0;
915 }
916 EXPORT_SYMBOL(sec_fac_cmd_init);