import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / input / touchscreen / mediatek / cy8ctma / cyttsp4_device_access.c
1 /* BEGIN PN:DTS2013051703879 ,Added by l00184147, 2013/5/17*/
2 //add Touch driver for G610-T11
3 /* BEGIN PN:DTS2013012601133 ,Modified by l00184147, 2013/1/26*/
4 /* BEGIN PN:SPBB-1218 ,Added by l00184147, 2012/12/20*/
5 /*
6 * cyttsp4_device_access.c
7 * Cypress TrueTouch(TM) Standard Product V4 Device Access module.
8 * Configuration and Test command/status user interface.
9 * For use with Cypress Txx4xx parts.
10 * Supported parts include:
11 * TMA4XX
12 * TMA1036
13 *
14 * Copyright (C) 2012 Cypress Semiconductor
15 * Copyright (C) 2011 Sony Ericsson Mobile Communications AB.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * version 2, and only version 2, as published by the
20 * Free Software Foundation.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 *
31 * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
32 *
33 */
34
35 #include "cyttsp4_bus.h"
36 #include "cyttsp4_core.h"
37 #include "cyttsp4_mt.h"
38
39 #include <linux/delay.h>
40 #include <linux/gpio.h>
41 #include <linux/input.h>
42 #include <linux/interrupt.h>
43 #include <linux/irq.h>
44 #include <linux/limits.h>
45 #include <linux/module.h>
46 #include <linux/pm_runtime.h>
47 #include <linux/sched.h>
48 #include <linux/slab.h>
49 #include <linux/wait.h>
50 #include <linux/workqueue.h>
51 #include "cyttsp4_device_access.h"
52 #include "cyttsp4_regs.h"
53 /* BEGIN PN:DTS2013061703557 ,Added by l00184147, 2013/6/17*/
54 //#include <linux/hardware_self_adapt.h>
55 /* END PN:DTS2013061703557 ,Added by l00184147, 2013/6/17*/
56
57 #define CY_MAX_CONFIG_BYTES 256
58 #define CY_CMD_INDEX 0
59 #define CY_NULL_CMD_INDEX 1
60 #define CY_NULL_CMD_MODE_INDEX 2
61 #define CY_NULL_CMD_SIZE_INDEX 3
62 #define CY_NULL_CMD_SIZEL_INDEX 2
63 #define CY_NULL_CMD_SIZEH_INDEX 3
64
65 #define HI_BYTE(x) (u8)(((x) >> 8) & 0xFF)
66 #define LOW_BYTE(x) (u8)((x) & 0xFF)
67
68 struct heatmap_param {
69 bool scan_start;
70 enum scanDataTypeList dataType; /* raw, base, diff */
71 int numElement;
72 };
73
74 struct cyttsp4_device_access_data {
75 struct cyttsp4_device *ttsp;
76 struct cyttsp4_device_access_platform_data *pdata;
77 struct cyttsp4_sysinfo *si;
78 struct cyttsp4_test_mode_params test;
79 struct mutex sysfs_lock;
80 uint32_t ic_grpnum;
81 uint32_t ic_grpoffset;
82 bool own_exclusive;
83 uint32_t ebid_row_size;
84 bool sysfs_nodes_created;
85 #ifdef VERBOSE_DEBUG
86 u8 pr_buf[CY_MAX_PRBUF_SIZE];
87 #endif
88 wait_queue_head_t wait_q;
89 u8 ic_buf[CY_MAX_PRBUF_SIZE];
90 u8 return_buf[CY_MAX_PRBUF_SIZE];
91 struct heatmap_param heatmap;
92 };
93
94 /*
95 * cyttsp4_is_awakening_grpnum
96 * Returns true if a grpnum requires being awake
97 */
98 static bool cyttsp4_is_awakening_grpnum(int grpnum)
99 {
100 int i;
101
102 /* Array that lists which grpnums require being awake */
103 static const int awakening_grpnums[] = {
104 CY_IC_GRPNUM_CMD_REGS,
105 CY_IC_GRPNUM_TEST_REGS,
106 };
107
108 for (i = 0; i < ARRAY_SIZE(awakening_grpnums); i++)
109 if (awakening_grpnums[i] == grpnum)
110 return true;
111
112 return false;
113 }
114
115 /*
116 * Show function prototype.
117 * Returns response length or Linux error code on error.
118 */
119 typedef int (*cyttsp4_show_function) (struct device *dev, u8 *ic_buf,
120 size_t length);
121
122 /*
123 * Store function prototype.
124 * Returns Linux error code on error.
125 */
126 typedef int (*cyttsp4_store_function) (struct device *dev, u8 *ic_buf,
127 size_t length);
128
129 /*
130 * grpdata show function to be used by
131 * reserved and not implemented ic group numbers.
132 */
133 int cyttsp4_grpdata_show_void (struct device *dev, u8 *ic_buf, size_t length)
134 {
135 return -ENOSYS;
136 }
137
138 /*
139 * grpdata store function to be used by
140 * reserved and not implemented ic group numbers.
141 */
142 int cyttsp4_grpdata_store_void (struct device *dev, u8 *ic_buf, size_t length)
143 {
144 return -ENOSYS;
145 }
146
147 /*
148 * SysFs group number entry show function.
149 */
150 static ssize_t cyttsp4_ic_grpnum_show(struct device *dev,
151 struct device_attribute *attr, char *buf)
152 {
153 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
154 int val = 0;
155
156 mutex_lock(&dad->sysfs_lock);
157 val = dad->ic_grpnum;
158 mutex_unlock(&dad->sysfs_lock);
159
160 return scnprintf(buf, CY_MAX_PRBUF_SIZE, "Current Group: %d\n", val);
161 }
162
163 /*
164 * SysFs group number entry store function.
165 */
166 static ssize_t cyttsp4_ic_grpnum_store(struct device *dev,
167 struct device_attribute *attr, const char *buf, size_t size)
168 {
169 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
170 unsigned long value;
171 int prev_grpnum;
172 int rc;
173
174 rc = kstrtoul(buf, 10, &value);
175 if (rc < 0) {
176 dev_err(dev, "%s: Invalid value\n", __func__);
177 return size;
178 }
179
180 if (value >= CY_IC_GRPNUM_NUM) {
181 dev_err(dev, "%s: Group %lu does not exist.\n",
182 __func__, value);
183 return size;
184 }
185
186 if (value > 0xFF)
187 value = 0xFF;
188
189 mutex_lock(&dad->sysfs_lock);
190 /*
191 * Block grpnum change when own_exclusive flag is set
192 * which means the current grpnum implementation requires
193 * running exclusively on some consecutive grpdata operations
194 */
195 if (dad->own_exclusive) {
196 mutex_unlock(&dad->sysfs_lock);
197 dev_err(dev, "%s: own_exclusive\n", __func__);
198 return -EBUSY;
199 }
200 prev_grpnum = dad->ic_grpnum;
201 dad->ic_grpnum = (int) value;
202 mutex_unlock(&dad->sysfs_lock);
203
204 /* Check whether the new grpnum requires being awake */
205 if (cyttsp4_is_awakening_grpnum(prev_grpnum) !=
206 cyttsp4_is_awakening_grpnum(value)) {
207 if (cyttsp4_is_awakening_grpnum(value))
208 pm_runtime_get(dev);
209 else
210 pm_runtime_put(dev);
211 }
212
213 dev_vdbg(dev, "%s: ic_grpnum=%d, return size=%d\n",
214 __func__, (int)value, (int)size);
215 return size;
216 }
217
218 static DEVICE_ATTR(ic_grpnum, S_IRUSR | S_IWUSR,
219 cyttsp4_ic_grpnum_show, cyttsp4_ic_grpnum_store);
220
221 /*
222 * SysFs group offset entry show function.
223 */
224 static ssize_t cyttsp4_ic_grpoffset_show(struct device *dev,
225 struct device_attribute *attr, char *buf)
226 {
227 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
228 int val = 0;
229
230 mutex_lock(&dad->sysfs_lock);
231 val = dad->ic_grpoffset;
232 mutex_unlock(&dad->sysfs_lock);
233
234 return scnprintf(buf, CY_MAX_PRBUF_SIZE, "Current Offset: %d\n", val);
235 }
236
237 /*
238 * SysFs group offset entry store function.
239 */
240 static ssize_t cyttsp4_ic_grpoffset_store(struct device *dev,
241 struct device_attribute *attr, const char *buf, size_t size)
242 {
243 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
244 unsigned long value;
245 int ret;
246
247 ret = kstrtoul(buf, 10, &value);
248 if (ret < 0) {
249 dev_err(dev, "%s: Invalid value\n", __func__);
250 return size;
251 }
252
253 if (value > 0xFFFF)
254 value = 0xFFFF;
255
256 mutex_lock(&dad->sysfs_lock);
257 dad->ic_grpoffset = (int)value;
258 mutex_unlock(&dad->sysfs_lock);
259
260 dev_vdbg(dev, "%s: ic_grpoffset=%d, return size=%d\n", __func__,
261 (int)value, (int)size);
262 return size;
263 }
264
265 static DEVICE_ATTR(ic_grpoffset, S_IRUSR | S_IWUSR,
266 cyttsp4_ic_grpoffset_show, cyttsp4_ic_grpoffset_store);
267
268 /*
269 * Prints part of communication registers.
270 */
271 static int cyttsp4_grpdata_show_registers(struct device *dev, u8 *ic_buf,
272 size_t length, int num_read, int offset, int mode)
273 {
274 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
275 int rc;
276
277 if (dad->ic_grpoffset >= num_read)
278 return -EINVAL;
279
280 num_read -= dad->ic_grpoffset;
281
282 if (length < num_read) {
283 dev_err(dev, "%s: not sufficient buffer req_bug_len=%d, length=%d\n",
284 __func__, num_read, length);
285 return -EINVAL;
286 }
287
288 rc = cyttsp4_read(dad->ttsp, mode, offset + dad->ic_grpoffset, ic_buf,
289 num_read);
290 if (rc < 0)
291 return rc;
292
293 return num_read;
294 }
295
296 /*
297 * SysFs grpdata show function implementation of group 1.
298 * Prints status register contents of Operational mode registers.
299 */
300 static int cyttsp4_grpdata_show_operational_regs(struct device *dev, u8 *ic_buf,
301 size_t length)
302 {
303 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
304 int num_read = dad->si->si_ofs.rep_ofs - dad->si->si_ofs.cmd_ofs;
305 int i;
306
307 if (dad->ic_grpoffset >= num_read) {
308 dev_err(dev,
309 "%s: ic_grpoffset bigger than command registers, cmd_registers=%d\n",
310 __func__, num_read);
311 return -EINVAL;
312 }
313
314 num_read -= dad->ic_grpoffset;
315
316 if (length < num_read) {
317 dev_err(dev,
318 "%s: not sufficient buffer req_bug_len=%d, length=%d\n",
319 __func__, num_read, length);
320 return -EINVAL;
321 }
322
323 if (dad->ic_grpoffset + num_read > CY_MAX_PRBUF_SIZE) {
324 dev_err(dev,
325 "%s: not sufficient source buffer req_bug_len=%d, length=%d\n",
326 __func__, dad->ic_grpoffset + num_read,
327 CY_MAX_PRBUF_SIZE);
328 return -EINVAL;
329 }
330
331
332 /* cmd result already put into dad->return_buf */
333 for (i = 0; i < num_read; i++)
334 ic_buf[i] = dad->return_buf[dad->ic_grpoffset + i];
335
336 return num_read;
337 }
338
339 /*
340 * SysFs grpdata show function implementation of group 2.
341 * Prints current contents of the touch registers (full set).
342 */
343 static int cyttsp4_grpdata_show_touch_regs(struct device *dev, u8 *ic_buf,
344 size_t length)
345 {
346 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
347 int num_read = dad->si->si_ofs.rep_sz;
348 int offset = dad->si->si_ofs.rep_ofs;
349
350 return cyttsp4_grpdata_show_registers(dev, ic_buf, length, num_read,
351 offset, CY_MODE_OPERATIONAL);
352 }
353
354 /*
355 * Prints some content of the system information
356 */
357 static int cyttsp4_grpdata_show_sysinfo(struct device *dev, u8 *ic_buf,
358 size_t length, int num_read, int offset)
359 {
360 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
361 int rc = 0, rc2 = 0, rc3 = 0;
362
363 if (dad->ic_grpoffset >= num_read)
364 return -EINVAL;
365
366 num_read -= dad->ic_grpoffset;
367
368 if (length < num_read) {
369 dev_err(dev, "%s: not sufficient buffer req_bug_len=%d, length=%d\n",
370 __func__, num_read, length);
371 return -EINVAL;
372 }
373
374 rc = cyttsp4_request_exclusive(dad->ttsp,
375 CY_DA_REQUEST_EXCLUSIVE_TIMEOUT);
376 if (rc < 0) {
377 dev_err(dev, "%s: Error on request exclusive r=%d\n",
378 __func__, rc);
379 return rc;
380 }
381
382 rc = cyttsp4_request_set_mode(dad->ttsp, CY_MODE_SYSINFO);
383 if (rc < 0) {
384 dev_err(dev, "%s: Error on request set mode r=%d\n",
385 __func__, rc);
386 goto cyttsp4_grpdata_show_sysinfo_err_release;
387 }
388
389 rc = cyttsp4_read(dad->ttsp, CY_MODE_SYSINFO,
390 offset + dad->ic_grpoffset,
391 ic_buf, num_read);
392 if (rc < 0)
393 dev_err(dev, "%s: Fail read cmd regs r=%d\n",
394 __func__, rc);
395
396 rc2 = cyttsp4_request_set_mode(dad->ttsp, CY_MODE_OPERATIONAL);
397 if (rc2 < 0)
398 dev_err(dev, "%s: Error on request set mode 2 r=%d\n",
399 __func__, rc2);
400
401 cyttsp4_grpdata_show_sysinfo_err_release:
402 rc3 = cyttsp4_release_exclusive(dad->ttsp);
403 if (rc3 < 0) {
404 dev_err(dev, "%s: Error on release exclusive r=%d\n",
405 __func__, rc3);
406 return rc3;
407 }
408
409 if (rc < 0)
410 return rc;
411 if (rc2 < 0)
412 return rc2;
413
414 return num_read;
415 }
416
417 /*
418 * SysFs grpdata show function implementation of group 3.
419 * Prints content of the system information DATA record.
420 */
421 static int cyttsp4_grpdata_show_sysinfo_data_rec(struct device *dev, u8 *ic_buf,
422 size_t length)
423 {
424 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
425 int num_read = dad->si->si_ofs.cydata_size;
426 int offset = dad->si->si_ofs.cydata_ofs;
427
428 return cyttsp4_grpdata_show_sysinfo(dev, ic_buf, length, num_read,
429 offset);
430 }
431
432 /*
433 * SysFs grpdata show function implementation of group 4.
434 * Prints content of the system information TEST record.
435 */
436 static int cyttsp4_grpdata_show_sysinfo_test_rec(struct device *dev, u8 *ic_buf,
437 size_t length)
438 {
439 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
440 int num_read = dad->si->si_ofs.test_size;
441 int offset = dad->si->si_ofs.test_ofs;
442
443 return cyttsp4_grpdata_show_sysinfo(dev, ic_buf, length, num_read,
444 offset);
445 }
446
447 /*
448 * SysFs grpdata show function implementation of group 5.
449 * Prints content of the system information PANEL data.
450 */
451 static int cyttsp4_grpdata_show_sysinfo_panel(struct device *dev, u8 *ic_buf,
452 size_t length)
453 {
454 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
455 int num_read = dad->si->si_ofs.pcfg_size;
456 int offset = dad->si->si_ofs.pcfg_ofs;
457
458 return cyttsp4_grpdata_show_sysinfo(dev, ic_buf, length, num_read,
459 offset);
460 }
461
462 /*
463 * Get EBID Row Size is a Config mode command
464 */
465 static int _cyttsp4_get_ebid_row_size(struct device *dev)
466 {
467 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
468 u8 cmd_buf[CY_CMD_CAT_GET_CFG_ROW_SZ_CMD_SZ];
469 u8 return_buf[CY_CMD_CAT_GET_CFG_ROW_SZ_RET_SZ];
470 int rc;
471
472 cmd_buf[0] = CY_CMD_CAT_GET_CFG_ROW_SZ;
473 rc = cyttsp4_request_exec_cmd(dad->ttsp, CY_MODE_CAT,
474 cmd_buf, CY_CMD_CAT_GET_CFG_ROW_SZ_CMD_SZ,
475 return_buf, CY_CMD_CAT_GET_CFG_ROW_SZ_RET_SZ,
476 CY_COMMAND_COMPLETE_TIMEOUT);
477 if (rc < 0) {
478 dev_err(dev, "%s: Unable to read EBID row size.\n", __func__);
479 return rc;
480 }
481
482 dad->ebid_row_size = (return_buf[0] << 8) + return_buf[1];
483 return rc;
484 }
485
486 /*
487 * SysFs grpdata show function implementation of group 6.
488 * Prints contents of the touch parameters a row at a time.
489 */
490 static int cyttsp4_grpdata_show_touch_params(struct device *dev, u8 *ic_buf,
491 size_t length)
492 {
493 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
494 u8 cmd_buf[CY_CMD_CAT_READ_CFG_BLK_CMD_SZ];
495 int return_buf_size = CY_CMD_CAT_READ_CFG_BLK_RET_SZ;
496 int row_offset;
497 int offset_in_single_row = 0;
498 int rc;
499 int rc2 = 0;
500 int rc3;
501 int i, j;
502
503 rc = cyttsp4_request_exclusive(dad->ttsp,
504 CY_DA_REQUEST_EXCLUSIVE_TIMEOUT);
505 if (rc < 0) {
506 dev_err(dev, "%s: Error on request exclusive r=%d\n",
507 __func__, rc);
508 return rc;
509 }
510
511 rc = cyttsp4_request_set_mode(dad->ttsp, CY_MODE_CAT);
512 if (rc < 0) {
513 dev_err(dev, "%s: Error on request set mode r=%d\n",
514 __func__, rc);
515 goto cyttsp4_grpdata_show_touch_params_err_release;
516 }
517
518 if (dad->ebid_row_size == 0) {
519 rc = _cyttsp4_get_ebid_row_size(dev);
520 if (rc < 0)
521 goto cyttsp4_grpdata_show_touch_params_err_change_mode;
522 }
523
524 /* Perform buffer size check since we have just acquired row size */
525 return_buf_size += dad->ebid_row_size;
526
527 if (length < return_buf_size) {
528 dev_err(dev, "%s: not sufficient buffer "
529 "req_buf_len=%d, length=%d\n",
530 __func__, return_buf_size, length);
531 rc = -EINVAL;
532 goto cyttsp4_grpdata_show_touch_params_err_change_mode;
533 }
534
535 row_offset = dad->ic_grpoffset / dad->ebid_row_size;
536
537 cmd_buf[0] = CY_CMD_CAT_READ_CFG_BLK;
538 cmd_buf[1] = HI_BYTE(row_offset);
539 cmd_buf[2] = LOW_BYTE(row_offset);
540 cmd_buf[3] = HI_BYTE(dad->ebid_row_size);
541 cmd_buf[4] = LOW_BYTE(dad->ebid_row_size);
542 cmd_buf[5] = CY_TCH_PARM_EBID;
543 rc = cyttsp4_request_exec_cmd(dad->ttsp, CY_MODE_CAT,
544 cmd_buf, CY_CMD_CAT_READ_CFG_BLK_CMD_SZ,
545 ic_buf, return_buf_size,
546 CY_COMMAND_COMPLETE_TIMEOUT);
547
548 offset_in_single_row = dad->ic_grpoffset % dad->ebid_row_size;
549
550 /* Remove Header data from return buffer */
551 for (i = 0, j = CY_CMD_CAT_READ_CFG_BLK_RET_HDR_SZ
552 + offset_in_single_row;
553 i < (dad->ebid_row_size - offset_in_single_row);
554 i++, j++)
555 ic_buf[i] = ic_buf[j];
556
557 cyttsp4_grpdata_show_touch_params_err_change_mode:
558 rc2 = cyttsp4_request_set_mode(dad->ttsp, CY_MODE_OPERATIONAL);
559 if (rc2 < 0)
560 dev_err(dev, "%s: Error on request set mode r=%d\n",
561 __func__, rc2);
562
563 cyttsp4_grpdata_show_touch_params_err_release:
564 rc3 = cyttsp4_release_exclusive(dad->ttsp);
565 if (rc3 < 0) {
566 dev_err(dev, "%s: Error on release exclusive r=%d\n",
567 __func__, rc3);
568 return rc3;
569 }
570
571 if (rc < 0)
572 return rc;
573 if (rc2 < 0)
574 return rc2;
575
576 return dad->ebid_row_size - offset_in_single_row;
577 }
578
579 /*
580 * SysFs grpdata show function implementation of group 7.
581 * Prints contents of the touch parameters sizes.
582 */
583 static int cyttsp4_grpdata_show_touch_params_sizes(struct device *dev,
584 u8 *ic_buf, size_t length)
585 {
586 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
587 struct cyttsp4_core_platform_data *pdata =
588 dev_get_platdata(&dad->ttsp->core->dev);
589 int max_size;
590 int block_start;
591 int block_end;
592 int num_read;
593
594 if (pdata->sett[CY_IC_GRPNUM_TCH_PARM_SIZE] == NULL) {
595 dev_err(dev, "%s: Missing platform data Touch Parameters Sizes"
596 " table\n", __func__);
597 return -EINVAL;
598 }
599
600 if (pdata->sett[CY_IC_GRPNUM_TCH_PARM_SIZE]->data == NULL) {
601 dev_err(dev, "%s: Missing platform data Touch Parameters Sizes"
602 " table data\n", __func__);
603 return -EINVAL;
604 }
605
606 max_size = pdata->sett[CY_IC_GRPNUM_TCH_PARM_SIZE]->size;
607 max_size *= sizeof(uint16_t);
608 if (dad->ic_grpoffset >= max_size)
609 return -EINVAL;
610
611 block_start = (dad->ic_grpoffset / CYTTSP4_TCH_PARAM_SIZE_BLK_SZ)
612 * CYTTSP4_TCH_PARAM_SIZE_BLK_SZ;
613 block_end = CYTTSP4_TCH_PARAM_SIZE_BLK_SZ + block_start;
614 if (block_end > max_size)
615 block_end = max_size;
616 num_read = block_end - dad->ic_grpoffset;
617 if (length < num_read) {
618 dev_err(dev, "%s: not sufficient buffer %s=%d, %s=%d\n",
619 __func__, "req_buf_len", num_read, "length",
620 length);
621 return -EINVAL;
622 }
623
624 memcpy(ic_buf, (u8 *)pdata->sett[CY_IC_GRPNUM_TCH_PARM_SIZE]->data
625 + dad->ic_grpoffset, num_read);
626
627 return num_read;
628 }
629
630 /*
631 * SysFs grpdata show function implementation of group 10.
632 * Prints content of the system information Operational Configuration data.
633 */
634 static int cyttsp4_grpdata_show_sysinfo_opcfg(struct device *dev, u8 *ic_buf,
635 size_t length)
636 {
637 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
638 int num_read = dad->si->si_ofs.opcfg_size;
639 int offset = dad->si->si_ofs.opcfg_ofs;
640
641 return cyttsp4_grpdata_show_sysinfo(dev, ic_buf, length, num_read,
642 offset);
643 }
644
645 /*
646 * SysFs grpdata show function implementation of group 11.
647 * Prints content of the system information Design data.
648 */
649 static int cyttsp4_grpdata_show_sysinfo_design(struct device *dev, u8 *ic_buf,
650 size_t length)
651 {
652 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
653 int num_read = dad->si->si_ofs.ddata_size;
654 int offset = dad->si->si_ofs.ddata_ofs;
655
656 return cyttsp4_grpdata_show_sysinfo(dev, ic_buf, length, num_read,
657 offset);
658 }
659
660 /*
661 * SysFs grpdata show function implementation of group 12.
662 * Prints content of the system information Manufacturing data.
663 */
664 static int cyttsp4_grpdata_show_sysinfo_manufacturing(struct device *dev,
665 u8 *ic_buf, size_t length)
666 {
667 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
668 int num_read = dad->si->si_ofs.mdata_size;
669 int offset = dad->si->si_ofs.mdata_ofs;
670
671 return cyttsp4_grpdata_show_sysinfo(dev, ic_buf, length, num_read,
672 offset);
673 }
674
675 /*
676 * SysFs grpdata show function implementation of group 13.
677 * Prints status register contents of Configuration and
678 * Test registers.
679 */
680 static int cyttsp4_grpdata_show_test_regs(struct device *dev, u8 *ic_buf,
681 size_t length)
682 {
683 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
684 u8 mode;
685 int rc = 0;
686 int num_read = 0;
687 int i;
688
689 dev_vdbg(dev, "%s: test.cur_cmd=%d test.cur_mode=%d\n",
690 __func__, dad->test.cur_cmd, dad->test.cur_mode);
691
692 if (dad->test.cur_cmd == CY_CMD_CAT_NULL) {
693 num_read = 1;
694 if (length < num_read) {
695 dev_err(dev, "%s: not sufficient buffer %s=%d, %s=%d\n",
696 __func__, "req_buf_len", num_read,
697 "length", length);
698 return -EINVAL;
699 }
700
701 dev_vdbg(dev, "%s: GRP=TEST_REGS: NULL CMD: host_mode=%02X\n",
702 __func__, ic_buf[0]);
703 rc = cyttsp4_read(dad->ttsp,
704 dad->test.cur_mode == CY_TEST_MODE_CAT ?
705 CY_MODE_CAT : CY_MODE_OPERATIONAL,
706 CY_REG_BASE, &mode, sizeof(mode));
707 if (rc < 0) {
708 ic_buf[0] = 0xFF;
709 dev_err(dev, "%s: failed to read host mode r=%d\n",
710 __func__, rc);
711 } else {
712 ic_buf[0] = mode;
713 }
714 } else if (dad->test.cur_mode == CY_TEST_MODE_CAT) {
715 num_read = dad->test.cur_status_size;
716 if (length < num_read) {
717 dev_err(dev, "%s: not sufficient buffer %s=%d, %s=%d\n",
718 __func__, "req_buf_len", num_read,
719 "length", length);
720 return -EINVAL;
721 }
722 if (dad->ic_grpoffset + num_read > CY_MAX_PRBUF_SIZE) {
723 dev_err(dev,
724 "%s: not sufficient source buffer req_bug_len=%d, length=%d\n",
725 __func__, dad->ic_grpoffset + num_read,
726 CY_MAX_PRBUF_SIZE);
727 return -EINVAL;
728 }
729
730 dev_vdbg(dev, "%s: GRP=TEST_REGS: num_rd=%d at ofs=%d + "
731 "grpofs=%d\n", __func__, num_read,
732 dad->si->si_ofs.cmd_ofs, dad->ic_grpoffset);
733
734 /* cmd result already put into dad->return_buf */
735 for (i = 0; i < num_read; i++)
736 ic_buf[i] = dad->return_buf[dad->ic_grpoffset + i];
737 } else {
738 dev_err(dev, "%s: Not in Config/Test mode\n", __func__);
739 }
740
741 return num_read;
742 }
743
744 /*
745 * SysFs grpdata show function implementation of group 14.
746 * Prints CapSense button keycodes.
747 */
748 static int cyttsp4_grpdata_show_btn_keycodes(struct device *dev, u8 *ic_buf,
749 size_t length)
750 {
751 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
752 struct cyttsp4_btn *btn = dad->si->btn;
753 int num_btns = dad->si->si_ofs.num_btns - dad->ic_grpoffset;
754 int n;
755
756 if (num_btns <= 0 || btn == NULL || length < num_btns)
757 return -EINVAL;
758
759 for (n = 0; n < num_btns; n++)
760 ic_buf[n] = (u8) btn[dad->ic_grpoffset + n].key_code;
761
762 return n;
763 }
764
765 /*
766 * SysFs grpdata show function implementation of group 15.
767 * Prints status register contents of Configuration and
768 * Test registers.
769 */
770 static int cyttsp4_grpdata_show_tthe_test_regs(struct device *dev, u8 *ic_buf,
771 size_t length)
772 {
773 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
774 int rc = 0;
775 int num_read = 0;
776
777 dev_vdbg(dev, "%s: test.cur_cmd=%d test.cur_mode=%d\n",
778 __func__, dad->test.cur_cmd, dad->test.cur_mode);
779
780 if (dad->test.cur_cmd == CY_CMD_CAT_NULL) {
781 num_read = dad->test.cur_status_size;
782 if (length < num_read) {
783 dev_err(dev, "%s: not sufficient buffer %s=%d, %s=%d\n",
784 __func__, "req_buf_len", num_read,
785 "length", length);
786 return -EINVAL;
787 }
788
789 dev_vdbg(dev, "%s: GRP=TEST_REGS: NULL CMD: host_mode=%02X\n",
790 __func__, ic_buf[0]);
791 rc = cyttsp4_read(dad->ttsp,
792 (dad->test.cur_mode == CY_TEST_MODE_CAT)
793 ? CY_MODE_CAT :
794 (dad->test.cur_mode == CY_TEST_MODE_SYSINFO)
795 ? CY_MODE_SYSINFO : CY_MODE_OPERATIONAL,
796 CY_REG_BASE, ic_buf, num_read);
797 if (rc < 0) {
798 ic_buf[0] = 0xFF;
799 dev_err(dev, "%s: failed to read host mode r=%d\n",
800 __func__, rc);
801 }
802 } else if (dad->test.cur_mode == CY_TEST_MODE_CAT
803 || dad->test.cur_mode == CY_TEST_MODE_SYSINFO) {
804 num_read = dad->test.cur_status_size;
805 if (length < num_read) {
806 dev_err(dev, "%s: not sufficient buffer %s=%d, %s=%d\n",
807 __func__, "req_buf_len", num_read,
808 "length", length);
809 return -EINVAL;
810 }
811 dev_vdbg(dev, "%s: GRP=TEST_REGS: num_rd=%d at ofs=%d + "
812 "grpofs=%d\n", __func__, num_read,
813 dad->si->si_ofs.cmd_ofs, dad->ic_grpoffset);
814 rc = cyttsp4_read(dad->ttsp,
815 (dad->test.cur_mode == CY_TEST_MODE_CAT)
816 ? CY_MODE_CAT : CY_MODE_SYSINFO,
817 CY_REG_BASE, ic_buf, num_read);
818 if (rc < 0)
819 return rc;
820 } else {
821 dev_err(dev, "%s: In unsupported mode\n", __func__);
822 }
823
824 return num_read;
825 }
826
827 static cyttsp4_show_function
828 cyttsp4_grpdata_show_functions[CY_IC_GRPNUM_NUM] = {
829 [CY_IC_GRPNUM_RESERVED] = cyttsp4_grpdata_show_void,
830 [CY_IC_GRPNUM_CMD_REGS] = cyttsp4_grpdata_show_operational_regs,
831 [CY_IC_GRPNUM_TCH_REP] = cyttsp4_grpdata_show_touch_regs,
832 [CY_IC_GRPNUM_DATA_REC] = cyttsp4_grpdata_show_sysinfo_data_rec,
833 [CY_IC_GRPNUM_TEST_REC] = cyttsp4_grpdata_show_sysinfo_test_rec,
834 [CY_IC_GRPNUM_PCFG_REC] = cyttsp4_grpdata_show_sysinfo_panel,
835 [CY_IC_GRPNUM_TCH_PARM_VAL] = cyttsp4_grpdata_show_touch_params,
836 [CY_IC_GRPNUM_TCH_PARM_SIZE] = cyttsp4_grpdata_show_touch_params_sizes,
837 [CY_IC_GRPNUM_RESERVED1] = cyttsp4_grpdata_show_void,
838 [CY_IC_GRPNUM_RESERVED2] = cyttsp4_grpdata_show_void,
839 [CY_IC_GRPNUM_OPCFG_REC] = cyttsp4_grpdata_show_sysinfo_opcfg,
840 [CY_IC_GRPNUM_DDATA_REC] = cyttsp4_grpdata_show_sysinfo_design,
841 [CY_IC_GRPNUM_MDATA_REC] = cyttsp4_grpdata_show_sysinfo_manufacturing,
842 [CY_IC_GRPNUM_TEST_REGS] = cyttsp4_grpdata_show_test_regs,
843 [CY_IC_GRPNUM_BTN_KEYS] = cyttsp4_grpdata_show_btn_keycodes,
844 [CY_IC_GRPNUM_TTHE_REGS] = cyttsp4_grpdata_show_tthe_test_regs,
845 };
846
847 static ssize_t cyttsp4_ic_grpdata_show(struct device *dev,
848 struct device_attribute *attr, char *buf)
849 {
850 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
851 int i;
852 ssize_t num_read;
853 int index;
854
855 mutex_lock(&dad->sysfs_lock);
856 dev_vdbg(dev, "%s: grpnum=%d grpoffset=%u\n",
857 __func__, dad->ic_grpnum, dad->ic_grpoffset);
858
859 index = scnprintf(buf, CY_MAX_PRBUF_SIZE,
860 "Group %d, Offset %u:\n", dad->ic_grpnum,
861 dad->ic_grpoffset);
862
863 pm_runtime_get_sync(dev);
864 num_read = cyttsp4_grpdata_show_functions[dad->ic_grpnum] (dev,
865 dad->ic_buf, CY_MAX_PRBUF_SIZE);
866 pm_runtime_put(dev);
867 if (num_read < 0) {
868 index = num_read;
869 if (num_read == -ENOSYS) {
870 dev_err(dev, "%s: Group %d is not implemented.\n",
871 __func__, dad->ic_grpnum);
872 goto cyttsp4_ic_grpdata_show_error;
873 }
874 dev_err(dev, "%s: Cannot read Group %d Data.\n",
875 __func__, dad->ic_grpnum);
876 goto cyttsp4_ic_grpdata_show_error;
877 }
878
879 for (i = 0; i < num_read; i++) {
880 index += scnprintf(buf + index, CY_MAX_PRBUF_SIZE - index,
881 "0x%02X\n", dad->ic_buf[i]);
882 }
883
884 index += scnprintf(buf + index, CY_MAX_PRBUF_SIZE - index,
885 "(%d bytes)\n", num_read);
886
887 cyttsp4_ic_grpdata_show_error:
888 mutex_unlock(&dad->sysfs_lock);
889 return index;
890 }
891
892 static int _cyttsp4_cmd_handshake(struct cyttsp4_device_access_data *dad)
893 {
894 struct device *dev = &dad->ttsp->dev;
895 u8 mode;
896 int rc;
897
898 rc = cyttsp4_read(dad->ttsp, CY_MODE_CAT,
899 CY_REG_BASE, &mode, sizeof(mode));
900 if (rc < 0) {
901 dev_err(dev, "%s: Fail read host mode r=%d\n", __func__, rc);
902 return rc;
903 }
904
905 rc = cyttsp4_request_handshake(dad->ttsp, mode);
906 if (rc < 0)
907 dev_err(dev, "%s: Fail cmd handshake r=%d\n", __func__, rc);
908
909 return rc;
910 }
911
912 static int _cyttsp4_cmd_toggle_lowpower(struct cyttsp4_device_access_data *dad)
913 {
914 struct device *dev = &dad->ttsp->dev;
915 u8 mode;
916 int rc = cyttsp4_read(dad->ttsp,
917 (dad->test.cur_mode == CY_TEST_MODE_CAT)
918 ? CY_MODE_CAT : CY_MODE_OPERATIONAL,
919 CY_REG_BASE, &mode, sizeof(mode));
920 if (rc < 0) {
921 dev_err(dev, "%s: Fail read host mode r=%d\n",
922 __func__, rc);
923 return rc;
924 }
925
926 rc = cyttsp4_request_toggle_lowpower(dad->ttsp, mode);
927 if (rc < 0)
928 dev_err(dev, "%s: Fail cmd handshake r=%d\n",
929 __func__, rc);
930 return rc;
931 }
932
933 static int cyttsp4_test_cmd_mode(struct cyttsp4_device_access_data *dad,
934 u8 *ic_buf, size_t length)
935 {
936 struct device *dev = &dad->ttsp->dev;
937 int rc = -ENOSYS;
938 u8 mode;
939
940 if (length < CY_NULL_CMD_MODE_INDEX + 1) {
941 dev_err(dev, "%s: %s length=%d\n", __func__,
942 "Buffer length is not valid", length);
943 return -EINVAL;
944 }
945 mode = ic_buf[CY_NULL_CMD_MODE_INDEX];
946
947 if (mode == CY_HST_CAT) {
948 rc = cyttsp4_request_exclusive(dad->ttsp,
949 CY_DA_REQUEST_EXCLUSIVE_TIMEOUT);
950 if (rc < 0) {
951 dev_err(dev, "%s: Fail rqst exclusive r=%d\n",
952 __func__, rc);
953 goto cyttsp4_test_cmd_mode_exit;
954 }
955 rc = cyttsp4_request_set_mode(dad->ttsp, CY_MODE_CAT);
956 if (rc < 0) {
957 dev_err(dev, "%s: Fail rqst set mode=%02X r=%d\n",
958 __func__, mode, rc);
959 rc = cyttsp4_release_exclusive(dad->ttsp);
960 if (rc < 0)
961 dev_err(dev, "%s: %s r=%d\n", __func__,
962 "Fail release exclusive", rc);
963 goto cyttsp4_test_cmd_mode_exit;
964 }
965 dad->test.cur_mode = CY_TEST_MODE_CAT;
966 dad->own_exclusive = true;
967 dev_vdbg(dev, "%s: %s=%d %s=%02X %s=%d(CaT)\n", __func__,
968 "own_exclusive", dad->own_exclusive == true,
969 "mode", mode, "test.cur_mode",
970 dad->test.cur_mode);
971 } else if (mode == CY_HST_OPERATE) {
972 if (dad->own_exclusive) {
973 rc = cyttsp4_request_set_mode(dad->ttsp,
974 CY_MODE_OPERATIONAL);
975 if (rc < 0)
976 dev_err(dev, "%s: %s=%02X r=%d\n", __func__,
977 "Fail rqst set mode", mode, rc);
978 /* continue anyway */
979
980 rc = cyttsp4_release_exclusive(dad->ttsp);
981 if (rc < 0) {
982 dev_err(dev, "%s: %s r=%d\n", __func__,
983 "Fail release exclusive", rc);
984 /* continue anyway */
985 rc = 0;
986 }
987 dad->test.cur_mode = CY_TEST_MODE_NORMAL_OP;
988 dad->own_exclusive = false;
989 dev_vdbg(dev, "%s: %s=%d %s=%02X %s=%d(Operate)\n",
990 __func__, "own_exclusive",
991 dad->own_exclusive == true,
992 "mode", mode,
993 "test.cur_mode", dad->test.cur_mode);
994 } else
995 dev_vdbg(dev, "%s: %s mode=%02X(Operate)\n", __func__,
996 "do not own exclusive; cannot switch",
997 mode);
998 } else
999 dev_vdbg(dev, "%s: unsupported mode switch=%02X\n",
1000 __func__, mode);
1001
1002 cyttsp4_test_cmd_mode_exit:
1003 return rc;
1004 }
1005
1006 static int cyttsp4_test_tthe_cmd_mode(struct cyttsp4_device_access_data *dad,
1007 u8 *ic_buf, size_t length)
1008 {
1009 struct device *dev = &dad->ttsp->dev;
1010 int rc = -ENOSYS;
1011 u8 mode;
1012 enum cyttsp4_test_mode test_mode;
1013 int new_mode;
1014
1015 if (length < CY_NULL_CMD_MODE_INDEX + 1) {
1016 dev_err(dev, "%s: %s length=%d\n", __func__,
1017 "Buffer length is not valid", length);
1018 return -EINVAL;
1019 }
1020 mode = ic_buf[CY_NULL_CMD_MODE_INDEX];
1021
1022 switch (mode) {
1023 case CY_HST_CAT:
1024 new_mode = CY_MODE_CAT;
1025 test_mode = CY_TEST_MODE_CAT;
1026 break;
1027 case CY_HST_OPERATE:
1028 new_mode = CY_MODE_OPERATIONAL;
1029 test_mode = CY_TEST_MODE_NORMAL_OP;
1030 break;
1031 case CY_HST_SYSINFO:
1032 new_mode = CY_MODE_SYSINFO;
1033 test_mode = CY_TEST_MODE_SYSINFO;
1034 break;
1035 default:
1036 dev_vdbg(dev, "%s: unsupported mode switch=%02X\n",
1037 __func__, mode);
1038 goto cyttsp4_test_tthe_cmd_mode_exit;
1039 }
1040
1041 rc = cyttsp4_request_exclusive(dad->ttsp,
1042 CY_DA_REQUEST_EXCLUSIVE_TIMEOUT);
1043 if (rc < 0) {
1044 dev_err(dev, "%s: Fail rqst exclusive r=%d\n", __func__, rc);
1045 goto cyttsp4_test_tthe_cmd_mode_exit;
1046 }
1047 rc = cyttsp4_request_set_mode(dad->ttsp, new_mode);
1048 if (rc < 0)
1049 dev_err(dev, "%s: Fail rqst set mode=%02X r=%d\n",
1050 __func__, mode, rc);
1051 rc = cyttsp4_release_exclusive(dad->ttsp);
1052 if (rc < 0) {
1053 dev_err(dev, "%s: %s r=%d\n", __func__,
1054 "Fail release exclusive", rc);
1055 if (mode == CY_HST_OPERATE)
1056 rc = 0;
1057 else
1058 goto cyttsp4_test_tthe_cmd_mode_exit;
1059 }
1060 dad->test.cur_mode = test_mode;
1061 dev_vdbg(dev, "%s: %s=%d %s=%02X %s=%d\n", __func__,
1062 "own_exclusive", dad->own_exclusive == true,
1063 "mode", mode,
1064 "test.cur_mode", dad->test.cur_mode);
1065
1066 cyttsp4_test_tthe_cmd_mode_exit:
1067 return rc;
1068 }
1069
1070 /*
1071 * SysFs grpdata store function implementation of group 1.
1072 * Stores to command and parameter registers of Operational mode.
1073 */
1074 static int cyttsp4_grpdata_store_operational_regs(struct device *dev,
1075 u8 *ic_buf, size_t length)
1076 {
1077 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
1078 size_t cmd_ofs = dad->si->si_ofs.cmd_ofs;
1079 int num_read = dad->si->si_ofs.rep_ofs - dad->si->si_ofs.cmd_ofs;
1080 u8 *return_buf = dad->return_buf;
1081 int rc;
1082
1083 if ((cmd_ofs + length) > dad->si->si_ofs.rep_ofs) {
1084 dev_err(dev, "%s: %s length=%d\n", __func__,
1085 "Buffer length is not valid", length);
1086 return -EINVAL;
1087 }
1088
1089 return_buf[0] = ic_buf[0];
1090 rc = cyttsp4_request_exec_cmd(dad->ttsp, CY_MODE_OPERATIONAL,
1091 ic_buf, length,
1092 return_buf + 1, num_read,
1093 CY_COMMAND_COMPLETE_TIMEOUT);
1094 if (rc < 0)
1095 dev_err(dev, "%s: Fail to execute cmd r=%d\n", __func__, rc);
1096
1097 return rc;
1098 }
1099
1100 /*
1101 * SysFs store function of Test Regs group.
1102 */
1103 static int cyttsp4_grpdata_store_test_regs(struct device *dev, u8 *ic_buf,
1104 size_t length)
1105 {
1106 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
1107 int rc;
1108 u8 *return_buf = dad->return_buf;
1109
1110 /* Caller function guaranties, length is not bigger than ic_buf size */
1111 if (length < CY_CMD_INDEX + 1) {
1112 dev_err(dev, "%s: %s length=%d\n", __func__,
1113 "Buffer length is not valid", length);
1114 return -EINVAL;
1115 }
1116
1117 dad->test.cur_cmd = ic_buf[CY_CMD_INDEX];
1118 if (dad->test.cur_cmd == CY_CMD_CAT_NULL) {
1119 if (length < CY_NULL_CMD_INDEX + 1) {
1120 dev_err(dev, "%s: %s length=%d\n", __func__,
1121 "Buffer length is not valid", length);
1122 return -EINVAL;
1123 }
1124 dev_vdbg(dev, "%s: test-cur_cmd=%d null-cmd=%d\n", __func__,
1125 dad->test.cur_cmd, ic_buf[CY_NULL_CMD_INDEX]);
1126 switch (ic_buf[CY_NULL_CMD_INDEX]) {
1127 case CY_NULL_CMD_NULL:
1128 dev_err(dev, "%s: empty NULL cmd\n", __func__);
1129 break;
1130 case CY_NULL_CMD_MODE:
1131 if (length < CY_NULL_CMD_MODE_INDEX + 1) {
1132 dev_err(dev, "%s: %s length=%d\n", __func__,
1133 "Buffer length is not valid",
1134 length);
1135 return -EINVAL;
1136 }
1137 dev_vdbg(dev, "%s: Set cmd mode=%02X\n", __func__,
1138 ic_buf[CY_NULL_CMD_MODE_INDEX]);
1139 cyttsp4_test_cmd_mode(dad, ic_buf, length);
1140 break;
1141 case CY_NULL_CMD_STATUS_SIZE:
1142 if (length < CY_NULL_CMD_SIZE_INDEX + 1) {
1143 dev_err(dev, "%s: %s length=%d\n", __func__,
1144 "Buffer length is not valid",
1145 length);
1146 return -EINVAL;
1147 }
1148 dad->test.cur_status_size =
1149 ic_buf[CY_NULL_CMD_SIZEL_INDEX]
1150 + (ic_buf[CY_NULL_CMD_SIZEH_INDEX] << 8);
1151 dev_vdbg(dev, "%s: test-cur_status_size=%d\n",
1152 __func__, dad->test.cur_status_size);
1153 break;
1154 case CY_NULL_CMD_HANDSHAKE:
1155 dev_vdbg(dev, "%s: try null cmd handshake\n",
1156 __func__);
1157 rc = _cyttsp4_cmd_handshake(dad);
1158 if (rc < 0)
1159 dev_err(dev, "%s: %s r=%d\n", __func__,
1160 "Fail test cmd handshake", rc);
1161 default:
1162 break;
1163 }
1164 } else {
1165 dev_dbg(dev, "%s: TEST CMD=0x%02X length=%d %s%d\n",
1166 __func__, ic_buf[0], length, "cmd_ofs+grpofs=",
1167 dad->ic_grpoffset + dad->si->si_ofs.cmd_ofs);
1168 cyttsp4_pr_buf(dev, dad->pr_buf, ic_buf, length, "test_cmd");
1169 return_buf[0] = ic_buf[0]; /* Save cmd byte to return_buf */
1170 rc = cyttsp4_request_exec_cmd(dad->ttsp, CY_MODE_CAT,
1171 ic_buf, length,
1172 return_buf + 1, dad->test.cur_status_size,
1173 CY_DA_COMMAND_COMPLETE_TIMEOUT);
1174 if (rc < 0)
1175 dev_err(dev, "%s: Fail to execute cmd r=%d\n",
1176 __func__, rc);
1177 }
1178 return 0;
1179 }
1180
1181 /*
1182 * SysFs store function of Test Regs group.
1183 */
1184 static int cyttsp4_grpdata_store_tthe_test_regs(struct device *dev, u8 *ic_buf,
1185 size_t length)
1186 {
1187 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
1188 int rc;
1189
1190 /* Caller function guaranties, length is not bigger than ic_buf size */
1191 if (length < CY_CMD_INDEX + 1) {
1192 dev_err(dev, "%s: %s length=%d\n", __func__,
1193 "Buffer length is not valid", length);
1194 return -EINVAL;
1195 }
1196
1197 dad->test.cur_cmd = ic_buf[CY_CMD_INDEX];
1198 if (dad->test.cur_cmd == CY_CMD_CAT_NULL) {
1199 if (length < CY_NULL_CMD_INDEX + 1) {
1200 dev_err(dev, "%s: %s length=%d\n", __func__,
1201 "Buffer length is not valid", length);
1202 return -EINVAL;
1203 }
1204 dev_vdbg(dev, "%s: test-cur_cmd=%d null-cmd=%d\n", __func__,
1205 dad->test.cur_cmd, ic_buf[CY_NULL_CMD_INDEX]);
1206 switch (ic_buf[CY_NULL_CMD_INDEX]) {
1207 case CY_NULL_CMD_NULL:
1208 dev_err(dev, "%s: empty NULL cmd\n", __func__);
1209 break;
1210 case CY_NULL_CMD_MODE:
1211 if (length < CY_NULL_CMD_MODE_INDEX + 1) {
1212 dev_err(dev, "%s: %s length=%d\n", __func__,
1213 "Buffer length is not valid",
1214 length);
1215 return -EINVAL;
1216 }
1217 dev_vdbg(dev, "%s: Set cmd mode=%02X\n", __func__,
1218 ic_buf[CY_NULL_CMD_MODE_INDEX]);
1219 cyttsp4_test_tthe_cmd_mode(dad, ic_buf, length);
1220 break;
1221 case CY_NULL_CMD_STATUS_SIZE:
1222 if (length < CY_NULL_CMD_SIZE_INDEX + 1) {
1223 dev_err(dev, "%s: %s length=%d\n", __func__,
1224 "Buffer length is not valid",
1225 length);
1226 return -EINVAL;
1227 }
1228 dad->test.cur_status_size =
1229 ic_buf[CY_NULL_CMD_SIZEL_INDEX]
1230 + (ic_buf[CY_NULL_CMD_SIZEH_INDEX] << 8);
1231 dev_vdbg(dev, "%s: test-cur_status_size=%d\n",
1232 __func__, dad->test.cur_status_size);
1233 break;
1234 case CY_NULL_CMD_HANDSHAKE:
1235 dev_vdbg(dev, "%s: try null cmd handshake\n",
1236 __func__);
1237 rc = _cyttsp4_cmd_handshake(dad);
1238 if (rc < 0)
1239 dev_err(dev, "%s: %s r=%d\n", __func__,
1240 "Fail test cmd handshake", rc);
1241 case CY_NULL_CMD_LOW_POWER:
1242 dev_vdbg(dev, "%s: try null cmd low power\n", __func__);
1243 rc = _cyttsp4_cmd_toggle_lowpower(dad);
1244 if (rc < 0)
1245 dev_err(dev, "%s: %s r=%d\n", __func__,
1246 "Fail test cmd toggle low power", rc);
1247 default:
1248 break;
1249 }
1250 } else {
1251 dev_dbg(dev, "%s: TEST CMD=0x%02X length=%d %s%d\n",
1252 __func__, ic_buf[0], length, "cmd_ofs+grpofs=",
1253 dad->ic_grpoffset + dad->si->si_ofs.cmd_ofs);
1254 cyttsp4_pr_buf(dev, dad->pr_buf, ic_buf, length, "test_cmd");
1255 /* Support Operating mode command. */
1256 rc = cyttsp4_write(dad->ttsp,
1257 (dad->test.cur_mode == CY_TEST_MODE_CAT)
1258 ? CY_MODE_CAT : CY_MODE_OPERATIONAL,
1259 dad->ic_grpoffset + dad->si->si_ofs.cmd_ofs,
1260 ic_buf, length);
1261 if (rc < 0)
1262 dev_err(dev, "%s: Fail write cmd regs r=%d\n",
1263 __func__, rc);
1264 }
1265 return 0;
1266 }
1267
1268 /*
1269 * Gets user input from sysfs and parse it
1270 * return size of parsed output buffer
1271 */
1272 static int cyttsp4_ic_parse_input(struct device *dev, const char *buf,
1273 size_t buf_size, u8 *ic_buf, size_t ic_buf_size)
1274 {
1275 const char *pbuf = buf;
1276 unsigned long value;
1277 char scan_buf[CYTTSP4_INPUT_ELEM_SZ];
1278 int i = 0;
1279 int j;
1280 int last = 0;
1281 int ret;
1282
1283 dev_dbg(dev, "%s: pbuf=%p buf=%p size=%d %s=%d buf=%s\n", __func__,
1284 pbuf, buf, (int) buf_size, "scan buf size",
1285 CYTTSP4_INPUT_ELEM_SZ, buf);
1286
1287 while (pbuf <= (buf + buf_size)) {
1288 if (i >= CY_MAX_CONFIG_BYTES) {
1289 dev_err(dev, "%s: %s size=%d max=%d\n", __func__,
1290 "Max cmd size exceeded", i,
1291 CY_MAX_CONFIG_BYTES);
1292 return -EINVAL;
1293 }
1294 if (i >= ic_buf_size) {
1295 dev_err(dev, "%s: %s size=%d buf_size=%d\n", __func__,
1296 "Buffer size exceeded", i, ic_buf_size);
1297 return -EINVAL;
1298 }
1299 while (((*pbuf == ' ') || (*pbuf == ','))
1300 && (pbuf < (buf + buf_size))) {
1301 last = *pbuf;
1302 pbuf++;
1303 }
1304
1305 if (pbuf >= (buf + buf_size))
1306 break;
1307
1308 memset(scan_buf, 0, CYTTSP4_INPUT_ELEM_SZ);
1309 if ((last == ',') && (*pbuf == ',')) {
1310 dev_err(dev, "%s: %s \",,\" not allowed.\n", __func__,
1311 "Invalid data format.");
1312 return -EINVAL;
1313 }
1314 for (j = 0; j < (CYTTSP4_INPUT_ELEM_SZ - 1)
1315 && (pbuf < (buf + buf_size))
1316 && (*pbuf != ' ')
1317 && (*pbuf != ','); j++) {
1318 last = *pbuf;
1319 scan_buf[j] = *pbuf++;
1320 }
1321
1322 ret = kstrtoul(scan_buf, 16, &value);
1323 if (ret < 0) {
1324 dev_err(dev, "%s: %s '%s' %s%s i=%d r=%d\n", __func__,
1325 "Invalid data format. ", scan_buf,
1326 "Use \"0xHH,...,0xHH\"", " instead.",
1327 i, ret);
1328 return ret;
1329 }
1330
1331 ic_buf[i] = value;
1332 i++;
1333 }
1334
1335 return i;
1336 }
1337
1338 /*
1339 * SysFs store functions of each group member.
1340 */
1341 static cyttsp4_store_function
1342 cyttsp4_grpdata_store_functions[CY_IC_GRPNUM_NUM] = {
1343 [CY_IC_GRPNUM_RESERVED] = cyttsp4_grpdata_store_void,
1344 [CY_IC_GRPNUM_CMD_REGS] = cyttsp4_grpdata_store_operational_regs,
1345 [CY_IC_GRPNUM_TCH_REP] = cyttsp4_grpdata_store_void,
1346 [CY_IC_GRPNUM_DATA_REC] = cyttsp4_grpdata_store_void,
1347 [CY_IC_GRPNUM_TEST_REC] = cyttsp4_grpdata_store_void,
1348 [CY_IC_GRPNUM_PCFG_REC] = cyttsp4_grpdata_store_void,
1349 [CY_IC_GRPNUM_TCH_PARM_VAL] = cyttsp4_grpdata_store_void,
1350 [CY_IC_GRPNUM_TCH_PARM_SIZE] = cyttsp4_grpdata_store_void,
1351 [CY_IC_GRPNUM_RESERVED1] = cyttsp4_grpdata_store_void,
1352 [CY_IC_GRPNUM_RESERVED2] = cyttsp4_grpdata_store_void,
1353 [CY_IC_GRPNUM_OPCFG_REC] = cyttsp4_grpdata_store_void,
1354 [CY_IC_GRPNUM_DDATA_REC] = cyttsp4_grpdata_store_void,
1355 [CY_IC_GRPNUM_MDATA_REC] = cyttsp4_grpdata_store_void,
1356 [CY_IC_GRPNUM_TEST_REGS] = cyttsp4_grpdata_store_test_regs,
1357 [CY_IC_GRPNUM_BTN_KEYS] = cyttsp4_grpdata_store_void,
1358 [CY_IC_GRPNUM_TTHE_REGS] = cyttsp4_grpdata_store_tthe_test_regs,
1359 };
1360
1361 static ssize_t cyttsp4_ic_grpdata_store(struct device *dev,
1362 struct device_attribute *attr, const char *buf, size_t size)
1363 {
1364 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
1365 ssize_t length;
1366 int rc;
1367
1368 mutex_lock(&dad->sysfs_lock);
1369 length = cyttsp4_ic_parse_input(dev, buf, size, dad->ic_buf,
1370 CY_MAX_PRBUF_SIZE);
1371 if (length <= 0) {
1372 dev_err(dev, "%s: %s Group Data store\n", __func__,
1373 "Malformed input for");
1374 goto cyttsp4_ic_grpdata_store_exit;
1375 }
1376
1377 dev_vdbg(dev, "%s: grpnum=%d grpoffset=%u\n",
1378 __func__, dad->ic_grpnum, dad->ic_grpoffset);
1379
1380 if (dad->ic_grpnum >= CY_IC_GRPNUM_NUM) {
1381 dev_err(dev, "%s: Group %d does not exist.\n",
1382 __func__, dad->ic_grpnum);
1383 goto cyttsp4_ic_grpdata_store_exit;
1384 }
1385
1386 /* write ic_buf to log */
1387 cyttsp4_pr_buf(dev, dad->pr_buf, dad->ic_buf, length, "ic_buf");
1388
1389 pm_runtime_get_sync(dev);
1390 /* Call relevant store handler. */
1391 rc = cyttsp4_grpdata_store_functions[dad->ic_grpnum] (dev, dad->ic_buf,
1392 length);
1393 pm_runtime_put(dev);
1394 if (rc < 0)
1395 dev_err(dev, "%s: Failed to store for grpmun=%d.\n",
1396 __func__, dad->ic_grpnum);
1397
1398 cyttsp4_ic_grpdata_store_exit:
1399 mutex_unlock(&dad->sysfs_lock);
1400 dev_vdbg(dev, "%s: return size=%d\n", __func__, size);
1401 return size;
1402 }
1403
1404 static DEVICE_ATTR(ic_grpdata, S_IRUSR | S_IWUSR,
1405 cyttsp4_ic_grpdata_show, cyttsp4_ic_grpdata_store);
1406
1407 /*
1408 * Execute scan command
1409 */
1410 static int _cyttsp4_exec_scan_cmd(struct device *dev)
1411 {
1412 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
1413 u8 cmd_buf[CY_CMD_CAT_EXEC_SCAN_CMD_SZ];
1414 u8 return_buf[CY_CMD_CAT_EXEC_SCAN_RET_SZ];
1415 int rc;
1416
1417 cmd_buf[0] = CY_CMD_CAT_EXEC_PANEL_SCAN;
1418 rc = cyttsp4_request_exec_cmd(dad->ttsp, CY_MODE_CAT,
1419 cmd_buf, CY_CMD_CAT_EXEC_SCAN_CMD_SZ,
1420 return_buf, CY_CMD_CAT_EXEC_SCAN_RET_SZ,
1421 CY_COMMAND_COMPLETE_TIMEOUT);
1422 if (rc < 0) {
1423 dev_err(dev, "%s: Unable to send execute panel scan command.\n",
1424 __func__);
1425 return rc;
1426 }
1427
1428 if (return_buf[0] != 0)
1429 return -EINVAL;
1430 return rc;
1431 }
1432
1433 /*
1434 * Retrieve panel data command
1435 */
1436 static int _cyttsp4_ret_scan_data_cmd(struct device *dev, int readOffset,
1437 int numElement, u8 dataType, u8 *return_buf)
1438 {
1439 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
1440 u8 cmd_buf[CY_CMD_CAT_READ_CFG_BLK_CMD_SZ];
1441 int rc;
1442
1443 cmd_buf[0] = CY_CMD_CAT_RETRIEVE_PANEL_SCAN;
1444 cmd_buf[1] = HI_BYTE(readOffset);
1445 cmd_buf[2] = LOW_BYTE(readOffset);
1446 cmd_buf[3] = HI_BYTE(numElement);
1447 cmd_buf[4] = LOW_BYTE(numElement);
1448 cmd_buf[5] = dataType;
1449 rc = cyttsp4_request_exec_cmd(dad->ttsp, CY_MODE_CAT,
1450 cmd_buf, CY_CMD_CAT_RET_PANEL_DATA_CMD_SZ,
1451 return_buf, CY_CMD_CAT_RET_PANEL_DATA_RET_SZ,
1452 CY_COMMAND_COMPLETE_TIMEOUT);
1453 if (rc < 0)
1454 return rc;
1455
1456 if (return_buf[0] != 0)
1457 return -EINVAL;
1458 return rc;
1459 }
1460
1461 /* BEGIN PN:SPBB-1276 ,Modified by l00184147, 2013/3/7*/
1462 /*
1463 * SysFs grpdata show function implementation of group 6.
1464 * Prints contents of the touch parameters a row at a time.
1465 */
1466 static ssize_t cyttsp4_get_panel_data_show(struct device *dev,
1467 struct device_attribute *attr, char *buf)
1468 {
1469 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
1470 u8 return_buf[CY_CMD_CAT_RET_PANEL_DATA_RET_SZ];
1471
1472 int rc = 0;
1473 int rc1 = 0;
1474 int dataIdx = -1;
1475 int i = 0;
1476 int printIdx = -1;
1477 u8 cmdParam_ofs = dad->si->si_ofs.cmd_ofs + 1;
1478 int readByte = CY_CMD_CAT_RET_PANEL_DATA_RET_SZ
1479 + (dad->si->si_ofs.cmd_ofs + 1);
1480 int leftOverElement = 0;
1481 int returnedElement = 0;
1482 int readElementOffset = 0;
1483 u8 elementStartOffset = dad->si->si_ofs.cmd_ofs + 1
1484 + CY_CMD_CAT_RET_PANEL_DATA_RET_SZ;
1485 u8 elementSize = 1;
1486 int maxElmtSize = I2C_BUF_MAX_SIZE - elementStartOffset;
1487
1488 rc = cyttsp4_request_exclusive(dad->ttsp,
1489 CY_DA_REQUEST_EXCLUSIVE_TIMEOUT);
1490 if (rc < 0) {
1491 dev_err(dev, "%s: Error on request exclusive r=%d\n",
1492 __func__, rc);
1493 goto cyttsp4_get_panel_data_show_err_release;
1494 }
1495
1496 if (dad->heatmap.scan_start) {
1497 /* Start scan */
1498 rc = _cyttsp4_exec_scan_cmd(dev);
1499 if (rc < 0)
1500 goto cyttsp4_get_panel_data_show_err_release;
1501 }
1502 /* retrieve scan data */
1503 rc = _cyttsp4_ret_scan_data_cmd(dev, CY_CMD_IN_DATA_OFFSET_VALUE,
1504 dad->heatmap.numElement, dad->heatmap.dataType,
1505 return_buf);
1506
1507 if (rc < 0)
1508 goto cyttsp4_get_panel_data_show_err_release;
1509 if (return_buf[CY_CMD_OUT_STATUS_OFFSET] != CY_CMD_STATUS_SUCCESS)
1510 goto cyttsp4_get_panel_data_show_err_release;
1511
1512 /* read data */
1513 elementSize = (return_buf[CY_CMD_RET_PNL_OUT_DATA_FORMAT_OFFS] &
1514 CY_CMD_RET_PANEL_ELMNT_SZ_MASK);
1515 readByte += (dad->heatmap.numElement *
1516 elementSize);
1517
1518 if (readByte >= I2C_BUF_MAX_SIZE) {
1519 rc = cyttsp4_read(dad->ttsp, CY_MODE_CAT, 0, dad->ic_buf,
1520 I2C_BUF_MAX_SIZE);
1521 dataIdx = I2C_BUF_MAX_SIZE;
1522 } else {
1523 rc = cyttsp4_read(dad->ttsp, CY_MODE_CAT, 0, dad->ic_buf,
1524 readByte);
1525 dataIdx = readByte;
1526 }
1527 if (rc < 0) {
1528 dev_err(dev, "%s: Error on read r=%d\n", __func__, dataIdx);
1529 goto cyttsp4_get_panel_data_show_err_release;
1530 }
1531
1532 if (readByte < I2C_BUF_MAX_SIZE)
1533 goto cyttsp4_get_panel_data_show_err_release;
1534
1535 dev_err(dev, "%s: _cyttsp4_ret_scan_data_cmd(): elementStartOffset:%d, maxElmtSize:%d\n",
1536 __func__, elementStartOffset, maxElmtSize);
1537 dev_err(dev, "%s:_cyttsp4_ret_scan_data_cmd(): return_buf: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
1538 __func__, return_buf[0], return_buf[1], return_buf[2], return_buf[3], return_buf[4]);
1539 dev_err(dev, "%s: dad->heatmap.numElement: 0x%x\n", __func__, dad->heatmap.numElement);
1540
1541
1542 maxElmtSize = maxElmtSize / elementSize;
1543 leftOverElement = dad->heatmap.numElement;
1544
1545 returnedElement =
1546 return_buf[CY_CMD_RET_PNL_OUT_ELMNT_SZ_OFFS_H] * 256
1547 + return_buf[CY_CMD_RET_PNL_OUT_ELMNT_SZ_OFFS_L];
1548 returnedElement = (returnedElement > maxElmtSize) ?
1549 maxElmtSize : returnedElement;
1550
1551 leftOverElement -= returnedElement;
1552 readElementOffset += returnedElement;
1553
1554
1555 do {
1556 /* get the data */
1557 rc = _cyttsp4_ret_scan_data_cmd(dev, readElementOffset,
1558 leftOverElement, dad->heatmap.dataType,
1559 return_buf);
1560 if (rc < 0)
1561 {
1562 dev_err(dev, "%s: Error on reading scanData r=%d\n", __func__, rc);
1563 goto cyttsp4_get_panel_data_show_err_release;
1564 }
1565
1566 dev_err(dev, "%s:_cyttsp4_ret_scan_data_cmd()2: return_buf: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
1567 __func__, return_buf[0], return_buf[1], return_buf[2], return_buf[3], return_buf[4]);
1568
1569 if (return_buf[CY_CMD_OUT_STATUS_OFFSET]
1570 != CY_CMD_STATUS_SUCCESS)
1571 goto cyttsp4_get_panel_data_show_err_release;
1572
1573 /* DO read */
1574 readByte = leftOverElement *
1575 (elementSize);
1576
1577 dev_err(dev, "%s:_cyttsp4_ret_scan_data_cmd()2: readByte: 0x%x\n", __func__, readByte);
1578
1579 if (readByte >= (I2C_BUF_MAX_SIZE - elementStartOffset)) {
1580 rc = cyttsp4_read(dad->ttsp, CY_MODE_CAT,
1581 elementStartOffset,
1582 dad->ic_buf + dataIdx,
1583 I2C_BUF_MAX_SIZE - elementStartOffset);
1584 dataIdx += (I2C_BUF_MAX_SIZE - elementStartOffset);
1585 } else {
1586 rc = cyttsp4_read(dad->ttsp, CY_MODE_CAT,
1587 elementStartOffset,
1588 dad->ic_buf + dataIdx, readByte);
1589 dataIdx += readByte;
1590 }
1591 if (rc < 0) {
1592 dev_err(dev, "%s: Error on read r=%d\n", __func__, rc);
1593 goto cyttsp4_get_panel_data_show_err_release;
1594 }
1595 returnedElement =
1596 return_buf[CY_CMD_RET_PNL_OUT_ELMNT_SZ_OFFS_H] * 256
1597 + return_buf[CY_CMD_RET_PNL_OUT_ELMNT_SZ_OFFS_L];
1598 returnedElement = (returnedElement > maxElmtSize) ?
1599 maxElmtSize : returnedElement;
1600 /* Update element status */
1601 leftOverElement -= returnedElement;
1602 readElementOffset += returnedElement;
1603 } while (leftOverElement > 0);
1604 /* update on the buffer */
1605 dad->ic_buf[CY_CMD_RET_PNL_OUT_ELMNT_SZ_OFFS_H + cmdParam_ofs] =
1606 HI_BYTE(readElementOffset);
1607 dad->ic_buf[CY_CMD_RET_PNL_OUT_ELMNT_SZ_OFFS_L + cmdParam_ofs] =
1608 LOW_BYTE(readElementOffset);
1609
1610 cyttsp4_get_panel_data_show_err_release:
1611 rc1 = cyttsp4_release_exclusive(dad->ttsp);
1612 if (rc1 < 0) {
1613 dev_err(dev, "%s: Error on release exclusive r=%d\n",
1614 __func__, rc1);
1615 goto cyttsp4_get_panel_data_show_err_sysfs;
1616 }
1617
1618 if (rc < 0)
1619 goto cyttsp4_get_panel_data_show_err_sysfs;
1620
1621 printIdx = 0;
1622 printIdx += scnprintf(buf, CY_MAX_PRBUF_SIZE, "CY_DATA:");
1623 for (i = 0; i < dataIdx; i++) {
1624 printIdx += scnprintf(buf + printIdx,
1625 CY_MAX_PRBUF_SIZE - printIdx,
1626 "%02X ", dad->ic_buf[i]);
1627 }
1628 printIdx += scnprintf(buf + printIdx, CY_MAX_PRBUF_SIZE - printIdx,
1629 ":(%d bytes)\n", dataIdx);
1630
1631 cyttsp4_get_panel_data_show_err_sysfs:
1632 return printIdx;
1633 }
1634 /* END PN:SPBB-1276 ,Modified by l00184147, 2013/3/7*/
1635
1636 /*
1637 * SysFs grpdata show function implementation of group 6.
1638 * Prints contents of the touch parameters a row at a time.
1639 */
1640 static int cyttsp4_get_panel_data_store(struct device *dev,
1641 struct device_attribute *attr, const char *buf, size_t size)
1642 {
1643 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
1644 ssize_t length;
1645
1646 mutex_lock(&dad->sysfs_lock);
1647
1648 length = cyttsp4_ic_parse_input(dev, buf, size, dad->ic_buf,
1649 CY_MAX_PRBUF_SIZE);
1650 if (length <= 0) {
1651 dev_err(dev, "%s: %s Group Data store\n", __func__,
1652 "Malformed input for");
1653 goto cyttsp4_get_panel_data_store_exit;
1654 }
1655
1656 dev_vdbg(dev, "%s: grpnum=%d grpoffset=%u\n",
1657 __func__, dad->ic_grpnum, dad->ic_grpoffset);
1658
1659 if (dad->ic_grpnum >= CY_IC_GRPNUM_NUM) {
1660 dev_err(dev, "%s: Group %d does not exist.\n",
1661 __func__, dad->ic_grpnum);
1662 goto cyttsp4_get_panel_data_store_exit;
1663 }
1664
1665 pm_runtime_get_sync(dev);
1666 /*update parameter value */
1667 dad->heatmap.numElement = dad->ic_buf[4] + (dad->ic_buf[3] * 256);
1668 dad->heatmap.dataType = dad->ic_buf[5];
1669
1670 if (dad->ic_buf[6] > 0)
1671 dad->heatmap.scan_start = true;
1672 else
1673 dad->heatmap.scan_start = false;
1674 pm_runtime_put(dev);
1675
1676 cyttsp4_get_panel_data_store_exit:
1677 mutex_unlock(&dad->sysfs_lock);
1678 dev_vdbg(dev, "%s: return size=%d\n", __func__, size);
1679 return size;
1680 }
1681
1682 static DEVICE_ATTR(get_panel_data, S_IRUSR | S_IWUSR,
1683 cyttsp4_get_panel_data_show, cyttsp4_get_panel_data_store);
1684
1685 /* BEGIN PN:DTS2013061703557 ,Added by l00184147, 2013/6/17*/
1686 static struct device * access_dev = NULL;
1687
1688 static int getHighPart(int num)
1689 {
1690 switch(num)
1691 {
1692 case 1:
1693 return 0xFF000000;
1694 case 2:
1695 return 0xFFFF0000;
1696 case 3:
1697 return 0xFFFFFF00;
1698 default:
1699 return 0x0;
1700
1701 }
1702
1703 }
1704 /* BEGIN PN:DTS2013062405322 ,Added by l00184147, 2013/6/24*/
1705 #define MAX_CAPACITANCE_LEN 4096
1706 static int g_capacitance_count = 0;
1707 static char *g_touch_capacitance = NULL;
1708 static void record_tp_capacitance(enum check_data_type type, int value)
1709 {
1710 char buf[7] = {0};
1711 sprintf(buf, "%d\t", value);
1712 strcat(g_touch_capacitance, buf);
1713 g_capacitance_count++;
1714 if(0 == g_capacitance_count % 13)
1715 {
1716 strcat(g_touch_capacitance, "\n");
1717 }
1718
1719 return;
1720 }
1721 /* END PN:DTS2013062405322 ,Added by l00184147, 2013/6/24*/
1722 static int out_of_range(enum check_data_type type, int value)
1723 {
1724 //hw_product_type board_id;
1725 //board_id=get_hardware_product_version();
1726 /* BEGIN PN:DTS2013062405322 ,Added by l00184147, 2013/6/24*/
1727 record_tp_capacitance(type, value);
1728 /* END PN:DTS2013062405322 ,Added by l00184147, 2013/6/24*/
1729 if(1/*(board_id & HW_VER_MAIN_MASK) == HW_G750_VER*/)
1730 {
1731 switch(type)
1732 {
1733 case CY_CHK_MUT_RAW:
1734 /* BEGIN PN:DTS2013071007839 ,Modified by l00184147, 2013/7/11*/
1735 if(value < -1900 || value > -300)
1736 /* END PN:DTS2013071007839 ,Modified by l00184147, 2013/7/11*/
1737 {
1738 return 1;
1739 }
1740 break;
1741 case CY_CHK_SELF_RAW:
1742 /* BEGIN PN:DTS2013071007839 ,Modified by l00184147, 2013/7/11*/
1743 if(value < -500 || value > 1300)
1744 /* END PN:DTS2013071007839 ,Modified by l00184147, 2013/7/11*/
1745 {
1746 return 1;
1747 }
1748 break;
1749 default:
1750 return 0;
1751 }
1752 }
1753 return 0;
1754 }
1755
1756
1757 #define B_ENDIAN 0
1758 #define L_ENDIAN 0x10
1759 static int cyttsp4_check_range(enum check_data_type type, int endian, int elementSize,
1760 struct cyttsp4_device_access_data* dad, int size)
1761 {
1762 static int temp = 0;
1763 int index;
1764 int rc = 0;
1765
1766 for(index = 8; index < size; ++index){
1767 if(endian ==B_ENDIAN)
1768 {
1769 printk("%s index = %d data = %#x\n", __func__, index, dad->ic_buf[index]);
1770 if(0 == index%elementSize) //high byte
1771 {
1772 if(dad->ic_buf[index]&0x80) //extend
1773 {
1774 temp |= getHighPart(4 -elementSize);
1775
1776 }
1777 temp |= dad->ic_buf[index] << 8*(elementSize -1);
1778 if(elementSize ==1){
1779 printk("%s: temp = %d\n", __func__, temp);
1780 if(out_of_range(type, temp))
1781 {
1782 //return -1; modified for show all data 0315
1783 rc = -1;
1784 }
1785 temp = 0;
1786 }
1787
1788 }else
1789 {
1790 temp |= dad->ic_buf[index] << 8*(elementSize - index%elementSize - 1);
1791 if(index%elementSize == elementSize -1) //low byte
1792 {
1793 printk("%s: temp = %d\n", __func__, temp);
1794 if(out_of_range(type, temp))
1795 {
1796 //return -1; modified for show all data 0315
1797 rc = -1;
1798 }
1799 temp = 0;
1800 }
1801 }
1802 }else {//little endian
1803 if( index%elementSize == elementSize -1)
1804 {
1805 printk("%s index = %d data = %#x\n", __func__, index, dad->ic_buf[index]);
1806 if(dad->ic_buf[index]&0x80)
1807 {
1808 temp |= getHighPart(4 -elementSize);
1809 }
1810 temp |= dad->ic_buf[index] << 8*(elementSize -1);
1811 printk("%s: temp = %d\n", __func__, temp);
1812 if(out_of_range(type, temp))
1813 {
1814 //return -1; modified for show all data 0315
1815 rc = -1;
1816 }
1817 temp = 0;
1818 }else
1819 {
1820 printk("%s index = %d data = %#x\n", __func__, index, dad->ic_buf[index]);
1821 temp |= dad->ic_buf[index] << 8*( index%elementSize);
1822 }
1823 }
1824 }
1825
1826 return rc;
1827 }
1828
1829 typedef int (* retrieve_func)(struct device *dev, int readOffset,int numElement, u8 dataType, u8 *return_buf);
1830 /*return value: >0 means success; <0 means failed; =0 means unknown*/
1831 static int cyttsp4_get_data_and_check(struct device* dev, retrieve_func ret_func,
1832 enum check_data_type type, int offset)
1833 {
1834 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
1835 u8 return_buf[CY_CMD_CAT_RET_PANEL_DATA_RET_SZ];
1836 int rc = 0;
1837 int dataIdx = 0;
1838 u8 cmdParam_ofs = dad->si->si_ofs.cmd_ofs + 1;
1839 int leftOverElement = 0;
1840 int returnedElement = 0;
1841 int readElementOffset = 0;
1842 u8 elementStartOffset = cmdParam_ofs + CY_CMD_CAT_RET_PANEL_DATA_RET_SZ;
1843 u8 elementSize = 0;
1844 int endian = 0;
1845 int readByte =cmdParam_ofs+ CY_CMD_CAT_RET_PANEL_DATA_RET_SZ;
1846 int maxElmtSize = I2C_BUF_MAX_SIZE - elementStartOffset;
1847
1848 printk("%s:cmdParam_ofs = %d, elementStartOffset = %d\n", __func__, cmdParam_ofs, elementStartOffset);
1849
1850 /* retrieve scan data */
1851 rc = ret_func(dev, offset,
1852 dad->heatmap.numElement, dad->heatmap.dataType,
1853 return_buf);
1854 if (rc < 0){
1855 dev_err(dev, "%s: Error on reading scanData r=%d\n", __func__, rc);
1856 return 0;
1857 }
1858 if (return_buf[CY_CMD_OUT_STATUS_OFFSET] != CY_CMD_STATUS_SUCCESS)
1859 return 0;
1860
1861 elementSize = return_buf[CY_CMD_RET_PNL_OUT_DATA_FORMAT_OFFS] &
1862 CY_CMD_RET_PANEL_ELMNT_SZ_MASK;
1863 endian = return_buf[CY_CMD_RET_PNL_OUT_DATA_FORMAT_OFFS]&0x10;
1864
1865 /* read data */
1866 readByte +=(dad->heatmap.numElement *elementSize);
1867 printk("%s:elementSize = %d, readByte = %d\n", __func__, elementSize, readByte);
1868
1869 if (readByte >= I2C_BUF_MAX_SIZE) {
1870 rc = cyttsp4_read(dad->ttsp, CY_MODE_CAT, 0, dad->ic_buf,I2C_BUF_MAX_SIZE);
1871 dataIdx= I2C_BUF_MAX_SIZE;
1872 }else {
1873 rc = cyttsp4_read(dad->ttsp, CY_MODE_CAT, 0, dad->ic_buf,
1874 readByte);
1875 dataIdx = readByte;
1876 }
1877 if (rc < 0) {
1878 dev_err(dev, "%s: Error on read r=%d\n", __func__, readByte);
1879 return 0;
1880 }
1881 dev_err(dev, "%s: _cyttsp4_ret_scan_data_cmd(): elementStartOffset:%d, maxElmtSize:%d\n",
1882 __func__, elementStartOffset, maxElmtSize);
1883 dev_err(dev, "%s:_cyttsp4_ret_scan_data_cmd(): return_buf: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
1884 __func__, return_buf[0], return_buf[1], return_buf[2], return_buf[3], return_buf[4]);
1885 dev_err(dev, "%s: dad->heatmap.numElement: 0x%x\n", __func__, dad->heatmap.numElement);
1886
1887 maxElmtSize = maxElmtSize / elementSize;
1888 leftOverElement = dad->heatmap.numElement;
1889
1890 returnedElement =
1891 return_buf[CY_CMD_RET_PNL_OUT_ELMNT_SZ_OFFS_H] * 256
1892 + return_buf[CY_CMD_RET_PNL_OUT_ELMNT_SZ_OFFS_L];
1893 returnedElement = (returnedElement > maxElmtSize) ?
1894 maxElmtSize : returnedElement;
1895
1896 leftOverElement -= returnedElement;
1897 readElementOffset += returnedElement;
1898
1899 printk("%s:leftOverElement = %d,readElementOffset=%d", __func__,leftOverElement,readElementOffset);
1900
1901 while (leftOverElement > 0){
1902 /* get the data */
1903 rc = ret_func(dev, readElementOffset,
1904 leftOverElement, dad->heatmap.dataType,
1905 return_buf);
1906 if (rc < 0){
1907 dev_err(dev, "%s: Error on reading scanData r=%d\n", __func__, rc);
1908 return 0;
1909 }
1910
1911 if (return_buf[CY_CMD_OUT_STATUS_OFFSET]
1912 != CY_CMD_STATUS_SUCCESS)
1913 return 0;
1914
1915 dev_err(dev, "%s:_cyttsp4_ret_scan_data_cmd()2: return_buf: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
1916 __func__, return_buf[0], return_buf[1], return_buf[2], return_buf[3], return_buf[4]);
1917
1918 /* DO read */
1919 readByte = leftOverElement *elementSize;
1920
1921 printk("%s:_cyttsp4_ret_scan_data_cmd()2:leftOverElement = %d, readByte = %d\n", __func__, leftOverElement, readByte);
1922
1923 if (readByte >= (I2C_BUF_MAX_SIZE - elementStartOffset)) {
1924 rc = cyttsp4_read(dad->ttsp, CY_MODE_CAT,
1925 elementStartOffset,
1926 dad->ic_buf + dataIdx,
1927 I2C_BUF_MAX_SIZE - elementStartOffset);
1928 dataIdx += (I2C_BUF_MAX_SIZE - elementStartOffset);
1929 } else {
1930 rc = cyttsp4_read(dad->ttsp, CY_MODE_CAT,
1931 elementStartOffset,
1932 dad->ic_buf + dataIdx, readByte);
1933 dataIdx += readByte;
1934 }
1935 if (rc < 0) {
1936 dev_err(dev, "%s: Error on read r=%d\n", __func__, rc);
1937 return 0;
1938 }
1939 returnedElement =
1940 return_buf[CY_CMD_RET_PNL_OUT_ELMNT_SZ_OFFS_H] * 256
1941 + return_buf[CY_CMD_RET_PNL_OUT_ELMNT_SZ_OFFS_L];
1942 returnedElement = (returnedElement > maxElmtSize) ?
1943 maxElmtSize : returnedElement;
1944 /* Update element status */
1945 leftOverElement -= returnedElement;
1946 readElementOffset += returnedElement;
1947
1948 printk("%s:---2----returnedElement = %d, leftOverElement = %d,readElementOffset=%d\n",
1949 __func__, returnedElement, leftOverElement,readElementOffset);
1950
1951 }
1952 /* update on the buffer */
1953 dad->ic_buf[CY_CMD_RET_PNL_OUT_ELMNT_SZ_OFFS_H + cmdParam_ofs] =
1954 HI_BYTE(readElementOffset);
1955 dad->ic_buf[CY_CMD_RET_PNL_OUT_ELMNT_SZ_OFFS_L + cmdParam_ofs] =
1956 LOW_BYTE(readElementOffset);
1957
1958 if (rc < 0)
1959 goto cyttsp4_get_panel_data_show_err_sysfs;
1960
1961
1962 rc = cyttsp4_check_range(type, endian, elementSize, dad, dataIdx);
1963 if(rc < 0)
1964 {
1965 dev_err(dev, "%s cyttsp4_check_range failed\n", __func__);
1966 return -1;
1967 }
1968 printk("%s:dataIdx = %d\n", __func__, dataIdx);
1969
1970 /*printIdx += scnprintf(buf + printIdx, CY_MAX_PRBUF_SIZE - printIdx,
1971 ":(%d bytes)\n", dataIdx);*/
1972 cyttsp4_get_panel_data_show_err_sysfs:
1973 return dataIdx;
1974 }
1975
1976
1977 /*return value: >0 means success; <0 means failed; =0 means unknown*/
1978 static int cyttsp4_check_raw_data(struct device *dev)
1979 {
1980 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
1981 int rc = 0;
1982 int i = 0;
1983 enum check_data_type type;
1984 //hw_product_type board_id;
1985 //board_id=get_hardware_product_version();
1986
1987 if(1/*(board_id & HW_VER_MAIN_MASK) == HW_G750_VER*/)
1988 {
1989 for(i = 0; i < 2; ++i){
1990 if(0 == i)
1991 {
1992 type = CY_CHK_MUT_RAW;
1993 dad->heatmap.numElement = 448;
1994 dad->heatmap.dataType = CY_MUT_RAW;
1995 }
1996 else if(1==i)
1997 {
1998 type = CY_CHK_SELF_RAW;
1999 dad->heatmap.numElement = 16;
2000 dad->heatmap.dataType = CY_SELF_RAW;
2001 }
2002 /* Start scan */
2003 rc = _cyttsp4_exec_scan_cmd(dev);
2004 if (rc < 0){
2005 return 0;
2006 }
2007 /* retrieve scan data */
2008 rc = cyttsp4_get_data_and_check(dev, _cyttsp4_ret_scan_data_cmd, type, CY_CMD_IN_DATA_OFFSET_VALUE);
2009 if(rc < 0)
2010 {
2011 return -1;
2012 }
2013 }
2014 }
2015 printk("%s:rc = %d\n", __func__, rc);
2016 return rc;
2017 }
2018
2019 static inline void cyttsp4_out_to_buf(int ret, char ** buf)
2020 {
2021 if(ret <0)
2022 {
2023 *buf = "Fail";
2024 printk("%s:the test result is %s\n", __func__,*buf);
2025 }else if(ret > 0){
2026 *buf = "Pass";
2027 printk("%s:the test result is %s\n", __func__,*buf);
2028 }else
2029 {
2030 *buf = "unknown";
2031 printk("%s:the test result is %s\n", __func__,*buf);
2032 }
2033 }
2034
2035 /* BEGIN PN:DTS2013062405322 ,Added by l00184147, 2013/6/24*/
2036 static int cyttsp4_check_short_data(struct device *dev)
2037 {
2038 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
2039 int i;
2040 int num_read;
2041 int rc=1;
2042
2043 mutex_lock(&dad->sysfs_lock);
2044 dev_vdbg(dev, "%s: grpnum=%d grpoffset=%u\n",
2045 __func__, dad->ic_grpnum, dad->ic_grpoffset);
2046
2047 num_read = cyttsp4_grpdata_show_functions[dad->ic_grpnum] (dev,
2048 dad->ic_buf, CY_MAX_PRBUF_SIZE);
2049
2050 if (num_read < 0) {
2051 rc = num_read;
2052 if (num_read == -ENOSYS) {
2053 dev_err(dev, "%s: Group %d is not implemented.\n",
2054 __func__, dad->ic_grpnum);
2055 goto cyttsp4_check_short_data_error;
2056 }
2057 dev_err(dev, "%s: Cannot read Group %d Data.\n",
2058 __func__, dad->ic_grpnum);
2059 goto cyttsp4_check_short_data_error;
2060 }
2061
2062 for (i = 0; i < num_read; i++)
2063 printk("buf[%d]=0x%X\n",i,dad->ic_buf[i]);
2064
2065 if (1==dad->ic_buf[2])
2066 rc=-1;
2067
2068 cyttsp4_check_short_data_error:
2069 mutex_unlock(&dad->sysfs_lock);
2070 return rc;
2071 }
2072 /* END PN:DTS2013062405322 ,Added by l00184147, 2013/6/24*/
2073 /* BEGIN PN:DTS2013062405322 ,Modified by l00184147, 2013/6/24*/
2074 int cyttsp4_get_panel_data_check(char **buf)
2075 {
2076 int rc = 0;
2077 bool need_output = true;
2078 char * grpnum = "15";
2079 char * grpdata = "0x00,0x01,0x20";
2080 char * back_to_op = "0,1,0";
2081 char* grpnum_selftest = "13";
2082 char* status_size_selftest = "0x00,0x02,0x04,0x00";
2083 char* grpdata_shorttest = "0x07,0x04";
2084 char* grpdata_handshake = "0x00,0x03";
2085 char* status_size_normal = "0x00,0x02,0x01,0x00";
2086 struct cyttsp4_device_access_data *dad = dev_get_drvdata(access_dev);
2087 struct device * dev = access_dev;
2088
2089 rc = cyttsp4_ic_grpnum_store(dev, NULL, grpnum, strlen(grpnum));
2090 if (rc < 0) {
2091 rc = 0;//use this to justify what to output to the user-space buf
2092 dev_err(dev, "%s: Error on cyttsp4_ic_grpnum_store r=%d\n",
2093 __func__, rc);
2094 goto exit;
2095 }
2096 rc = cyttsp4_ic_grpdata_store(dev, NULL, grpdata, strlen(grpdata));
2097 if (rc < 0) {
2098 rc = 0;//use this to justify what to output to the user-space buf
2099 dev_err(dev, "%s: Error on cyttsp4_ic_grpdata_store r=%d\n",
2100 __func__, rc);
2101 goto exit;
2102 }
2103
2104 rc = cyttsp4_request_exclusive(dad->ttsp,
2105 CY_DA_REQUEST_EXCLUSIVE_TIMEOUT);
2106 if (rc < 0) {
2107 rc = 0;//use this to justify what to output to the user-space buf
2108 dev_err(dev, "%s: Error on request exclusive r=%d\n",
2109 __func__, rc);
2110 goto exit;
2111 }
2112 rc = cyttsp4_check_raw_data(dev);
2113 if(rc <= 0){
2114 goto cyttsp4_get_panel_data_show_err_release;
2115 }
2116
2117 rc= cyttsp4_release_exclusive(dad->ttsp);
2118 if (rc< 0) {
2119 rc = 0;//use this to justify what to output to the user-space buf
2120 dev_err(dev, "%s: Error on release exclusive r=%d\n",
2121 __func__, rc);
2122 goto exit;
2123 }
2124
2125 /*set group number to 13*/
2126 rc = cyttsp4_ic_grpnum_store(dev, NULL, grpnum_selftest, strlen(grpnum_selftest));
2127 if (rc < 0) {
2128 rc = 0;//use this to justify what to output to the user-space buf
2129 dev_err(dev, "%s: Error on cyttsp4_ic_grpnum_store r=%d\n",
2130 __func__, rc);
2131 goto exit;
2132 }
2133
2134 /*Send Null command to set status size to 4*/
2135 rc = cyttsp4_ic_grpdata_store(dev, NULL, status_size_selftest, strlen(status_size_selftest));
2136 if (rc < 0) {
2137 rc = 0;//use this to justify what to output to the user-space buf
2138 dev_err(dev, "%s: Error on cyttsp4_ic_grpdata_store r=%d\n",
2139 __func__, rc);
2140 goto exit;
2141 }
2142
2143 /*Send CAT command for short test*/
2144 rc = cyttsp4_ic_grpdata_store(dev, NULL, grpdata_shorttest, strlen(grpdata_shorttest));
2145 if (rc < 0) {
2146 rc = 0;//use this to justify what to output to the user-space buf
2147 dev_err(dev, "%s: Error on cyttsp4_ic_grpdata_store r=%d\n",
2148 __func__, rc);
2149 goto exit;
2150 }
2151
2152 rc=cyttsp4_check_short_data(dev);
2153 if(rc < 0){
2154 goto cyttsp4_check_short_data_err_release;
2155 }
2156 printk("%s:rc_short = %d\n", __func__, rc);
2157
2158 cyttsp4_out_to_buf(rc, buf);
2159 need_output = false;
2160 cyttsp4_get_panel_data_show_err_release:
2161 if(need_output){
2162 cyttsp4_out_to_buf(rc, buf);
2163 need_output = false;
2164 rc= cyttsp4_release_exclusive(dad->ttsp);
2165 if (rc< 0) {
2166 rc = 0;//use this to justify what to output to the user-space buf
2167 dev_err(dev, "%s: Error on release exclusive r=%d\n",
2168 __func__, rc);
2169 goto exit;
2170 }
2171 }
2172 cyttsp4_check_short_data_err_release:
2173 if(need_output){
2174 cyttsp4_out_to_buf(rc, buf);
2175 }
2176
2177 /*Send Null command to do command handshake*/
2178 rc = cyttsp4_ic_grpdata_store(dev, NULL, grpdata_handshake, strlen(grpdata_handshake));
2179 if (rc < 0) {
2180 rc = 0;//use this to justify what to output to the user-space buf
2181 dev_err(dev, "%s: Error on cyttsp4_ic_grpdata_store r=%d\n",
2182 __func__, rc);
2183 goto exit;
2184 }
2185
2186 /*Send Null command to set status size to 1*/
2187 rc = cyttsp4_ic_grpdata_store(dev, NULL, status_size_normal, strlen(status_size_normal));
2188 if (rc < 0) {
2189 rc = 0;//use this to justify what to output to the user-space buf
2190 dev_err(dev, "%s: Error on cyttsp4_ic_grpdata_store r=%d\n",
2191 __func__, rc);
2192 goto exit;
2193 }
2194
2195 /*set group number to 15*/
2196 rc = cyttsp4_ic_grpnum_store(dev, NULL, grpnum, strlen(grpnum));
2197 if (rc < 0) {
2198 rc = 0;//use this to justify what to output to the user-space buf
2199 dev_err(dev, "%s: Error on cyttsp4_ic_grpnum_store r=%d\n",
2200 __func__, rc);
2201 goto exit;
2202 }
2203
2204 /*back to operational*/
2205 rc = cyttsp4_ic_grpdata_store(dev, NULL, back_to_op, strlen(back_to_op));
2206
2207 if (rc < 0) {
2208 dev_err(dev, "%s: Error on cyttsp4_ic_grpdata_store r=%d\n",
2209 __func__, rc);
2210 goto exit;
2211 }
2212 exit:
2213 return rc;
2214 }
2215 /* END PN:DTS2013062405322 ,Modified by l00184147, 2013/6/24*/
2216 /* BEGIN PN:DTS2013071007839 ,Added by l00184147, 2013/7/11*/
2217 static void cyttsp4_fw_calibrate(struct cyttsp4_device *ttsp)
2218 {
2219 struct device *dev = &ttsp->dev;
2220 u8 cmd_buf[4], return_buf[2];
2221 int rc, rc2, rc3;
2222
2223 dev_vdbg(dev, "%s\n", __func__);
2224
2225 pm_runtime_get_sync(dev);
2226
2227 dev_vdbg(dev, "%s: Requesting exclusive\n", __func__);
2228 rc = cyttsp4_request_exclusive(ttsp, CY_DA_REQUEST_EXCLUSIVE_TIMEOUT);
2229 if (rc < 0) {
2230 dev_err(dev, "%s: Error on request exclusive r=%d\n",
2231 __func__, rc);
2232 goto exit;
2233 }
2234
2235 dev_vdbg(dev, "%s: Requesting mode change to CAT\n", __func__);
2236 rc = cyttsp4_request_set_mode(ttsp, CY_MODE_CAT);
2237 if (rc < 0) {
2238 dev_err(dev, "%s: Error on request set mode r=%d\n",
2239 __func__, rc);
2240 goto exit_release;
2241 }
2242
2243 dev_vdbg(dev, "%s: Calibrating for Mutual Capacitance Screen\n", __func__);
2244 cmd_buf[0] = CY_CMD_CAT_CALIBRATE_IDACS;
2245 cmd_buf[1] = 0x00; /* Mutual Capacitance Screen */
2246 rc = cyttsp4_request_exec_cmd(ttsp, CY_MODE_CAT,
2247 cmd_buf, 2, return_buf, 1,
2248 CY_DA_REQUEST_EXCLUSIVE_TIMEOUT);
2249 if (rc < 0) {
2250 dev_err(dev, "%s: Unable to execute calibrate command.\n",
2251 __func__);
2252 goto exit_setmode;
2253 }
2254 if (return_buf[0] != 0) {
2255 dev_err(dev, "%s: calibrate command unsuccessful\n", __func__);
2256 goto exit_setmode;
2257 }
2258
2259 dev_vdbg(dev, "%s: Calibrating for Mutual Capacitance Button\n", __func__);
2260 cmd_buf[1] = 0x01; /* Mutual Capacitance Button */
2261 rc = cyttsp4_request_exec_cmd(ttsp, CY_MODE_CAT,
2262 cmd_buf, 2, return_buf, 1,
2263 CY_DA_REQUEST_EXCLUSIVE_TIMEOUT);
2264 if (rc < 0) {
2265 dev_err(dev, "%s: Unable to execute calibrate command.\n",
2266 __func__);
2267 goto exit_setmode;
2268 }
2269 if (return_buf[0] != 0) {
2270 dev_err(dev, "%s: calibrate command unsuccessful\n", __func__);
2271 goto exit_setmode;
2272 }
2273
2274 dev_vdbg(dev, "%s: Calibrating for Self Capacitance Screen\n", __func__);
2275 cmd_buf[1] = 0x02; /* Self Capacitance */
2276 rc = cyttsp4_request_exec_cmd(ttsp, CY_MODE_CAT,
2277 cmd_buf, 2, return_buf, 1,
2278 CY_DA_REQUEST_EXCLUSIVE_TIMEOUT);
2279 if (rc < 0) {
2280 dev_err(dev, "%s: Unable to execute calibrate command.\n",
2281 __func__);
2282 goto exit_setmode;
2283 }
2284 if (return_buf[0] != 0) {
2285 dev_err(dev, "%s: calibrate command unsuccessful\n", __func__);
2286 goto exit_setmode;
2287 }
2288
2289 exit_setmode:
2290 dev_vdbg(dev, "%s: Requesting mode change to Operational\n", __func__);
2291 rc2 = cyttsp4_request_set_mode(ttsp, CY_MODE_OPERATIONAL);
2292 if (rc2 < 0)
2293 dev_err(dev, "%s: Error on request set mode 2 r=%d\n",
2294 __func__, rc2);
2295 else
2296 dev_vdbg(dev, "%s: Mode changed to Operational\n", __func__);
2297
2298 exit_release:
2299 rc3 = cyttsp4_release_exclusive(ttsp);
2300 if (rc3 < 0)
2301 dev_err(dev, "%s: Error on release exclusive r=%d\n",
2302 __func__, rc3);
2303
2304 exit:
2305 dev_info(dev, "%s\n", __func__);
2306 pm_runtime_put(dev);
2307 }
2308 /* END PN:DTS2013071007839 ,Added by l00184147, 2013/7/11*/
2309 /*touchpanel mmi test begin*/
2310 static char *touch_mmi_test_result = NULL;
2311 static ssize_t cyttsp4_touch_mmi_test_show(struct device *dev,
2312 struct device_attribute *attr, char *buf)
2313 {
2314 int rc = 0;
2315 if (dev == NULL) {
2316 pr_err("touch_mmi_test dev is null\n");
2317 return -EINVAL;
2318 }
2319 /* BEGIN PN:DTS2013071007839 ,Added by l00184147, 2013/7/11*/
2320 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
2321 /* END PN:DTS2013071007839 ,Added by l00184147, 2013/7/11*/
2322
2323 /* BEGIN PN:DTS2013062405322 ,Added by l00184147, 2013/6/24*/
2324 /* if g_touch_capacitance is null, alloc memory for it*/
2325 if(NULL == g_touch_capacitance)
2326 {
2327 g_touch_capacitance = kzalloc(sizeof(char) * MAX_CAPACITANCE_LEN, GFP_KERNEL);
2328 if(NULL == g_touch_capacitance)
2329 {
2330 return -EINVAL;
2331 }
2332 }
2333
2334 /*reset the g_capacitance_count and g_touch_capacitance */
2335 g_capacitance_count= 0;
2336 memset(g_touch_capacitance, 0, MAX_CAPACITANCE_LEN);
2337 /* END PN:DTS2013062405322 ,Added by l00184147, 2013/6/24*/
2338
2339 rc = cyttsp4_get_panel_data_check(&touch_mmi_test_result);
2340 if(rc < 0){
2341 pr_err("cyttsp4_get_panel_data_check error\n");
2342 }
2343 /* BEGIN PN:DTS2013071007839 ,Added by l00184147, 2013/7/11*/
2344 if(0==strcmp(touch_mmi_test_result,"Fail")){
2345 pr_err("cyttsp4_get_panel_data_check Fail,calibrate and attempt to test again\n");
2346
2347 //do once calibration and then attempt to test again
2348 g_capacitance_count= 0;
2349 memset(g_touch_capacitance, 0, MAX_CAPACITANCE_LEN);
2350
2351 cyttsp4_fw_calibrate(dad->ttsp);
2352
2353 rc = cyttsp4_get_panel_data_check(&touch_mmi_test_result);
2354 if(rc < 0){
2355 pr_err("cyttsp4_get_panel_data_check error\n");
2356 }
2357 }
2358 /* END PN:DTS2013071007839 ,Added by l00184147, 2013/7/11*/
2359 printk("touch_mmi_test_result : %d\n", rc);
2360 printk("touch_mmi_test_result : %s\n", touch_mmi_test_result);
2361
2362 /* BEGIN PN:DTS2013062405322 ,Added by l00184147, 2013/6/24*/
2363 /*if someting is error, we still want to report info, because it is useful for debugging*/
2364 rc = sprintf(buf, "%s\n%s", touch_mmi_test_result,g_touch_capacitance);
2365 kfree(g_touch_capacitance);
2366 g_touch_capacitance = NULL;
2367 return rc;
2368 /* END PN:DTS2013062405322 ,Added by l00184147, 2013/6/24*/
2369 }
2370 static DEVICE_ATTR(touch_mmi_test, 0664,
2371 cyttsp4_touch_mmi_test_show, NULL);
2372 /* END PN:DTS2013061703557 ,Added by l00184147, 2013/6/17*/
2373
2374 #ifdef CONFIG_PM_SLEEP
2375 static int cyttsp4_device_access_suspend(struct device *dev)
2376 {
2377 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
2378
2379 dev_dbg(dev, "%s\n", __func__);
2380
2381 if (!mutex_trylock(&dad->sysfs_lock))
2382 return -EBUSY;
2383
2384 mutex_unlock(&dad->sysfs_lock);
2385 return 0;
2386 }
2387
2388 static int cyttsp4_device_access_resume(struct device *dev)
2389 {
2390 dev_dbg(dev, "%s\n", __func__);
2391
2392 return 0;
2393 }
2394 #endif
2395
2396 /* BEGIN PN:SPBB-1257 ,Deteled by l00184147, 2013/2/21*/
2397 //Don't use the pm operation with PM sleep
2398 //static const struct dev_pm_ops cyttsp4_device_access_pm_ops = {
2399 // SET_SYSTEM_SLEEP_PM_OPS(cyttsp4_device_access_suspend,
2400 // cyttsp4_device_access_resume)
2401 //};
2402 /* END PN:SPBB-1257 ,Deteled by l00184147, 2013/2/21*/
2403
2404 static int cyttsp4_setup_sysfs(struct cyttsp4_device *ttsp)
2405 {
2406 struct device *dev = &ttsp->dev;
2407 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
2408 int rc = 0;
2409
2410 rc = device_create_file(dev, &dev_attr_ic_grpnum);
2411 if (rc) {
2412 dev_err(dev, "%s: Error, could not create ic_grpnum\n",
2413 __func__);
2414 goto exit;
2415 }
2416
2417 rc = device_create_file(dev, &dev_attr_ic_grpoffset);
2418 if (rc) {
2419 dev_err(dev, "%s: Error, could not create ic_grpoffset\n",
2420 __func__);
2421 goto unregister_grpnum;
2422 }
2423
2424 rc = device_create_file(dev, &dev_attr_ic_grpdata);
2425 if (rc) {
2426 dev_err(dev, "%s: Error, could not create ic_grpdata\n",
2427 __func__);
2428 goto unregister_grpoffset;
2429 }
2430
2431 rc = device_create_file(dev, &dev_attr_get_panel_data);
2432 if (rc) {
2433 dev_err(dev, "%s: Error, could not create get_panel_data\n",
2434 __func__);
2435 goto unregister_grpdata;
2436 }
2437
2438 dad->sysfs_nodes_created = true;
2439 return rc;
2440
2441 unregister_grpdata:
2442 device_remove_file(dev, &dev_attr_get_panel_data);
2443 unregister_grpoffset:
2444 device_remove_file(dev, &dev_attr_ic_grpoffset);
2445 unregister_grpnum:
2446 device_remove_file(dev, &dev_attr_ic_grpnum);
2447 exit:
2448 return rc;
2449 }
2450
2451 static int cyttsp4_setup_sysfs_attention(struct cyttsp4_device *ttsp)
2452 {
2453 struct device *dev = &ttsp->dev;
2454 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
2455 int rc = 0;
2456
2457 dev_vdbg(dev, "%s\n", __func__);
2458
2459 dad->si = cyttsp4_request_sysinfo(ttsp);
2460 if (!dad->si)
2461 return -1;
2462
2463 rc = cyttsp4_setup_sysfs(ttsp);
2464
2465 cyttsp4_unsubscribe_attention(ttsp, CY_ATTEN_STARTUP,
2466 cyttsp4_setup_sysfs_attention, 0);
2467
2468 return rc;
2469
2470 }
2471
2472 static int cyttsp4_device_access_probe(struct cyttsp4_device *ttsp)
2473 {
2474 struct device *dev = &ttsp->dev;
2475 struct cyttsp4_device_access_data *dad;
2476 struct cyttsp4_device_access_platform_data *pdata =
2477 dev_get_platdata(dev);
2478 int rc = 0;
2479
2480 dev_info(dev, "%s\n", __func__);
2481 dev_dbg(dev, "%s: debug on\n", __func__);
2482 dev_vdbg(dev, "%s: verbose debug on\n", __func__);
2483
2484 dad = kzalloc(sizeof(*dad), GFP_KERNEL);
2485 if (dad == NULL) {
2486 dev_err(dev, "%s: Error, kzalloc\n", __func__);
2487 rc = -ENOMEM;
2488 goto cyttsp4_device_access_probe_data_failed;
2489 }
2490
2491 /* BEGIN PN:DTS2013061703557 ,Added by l00184147, 2013/6/17*/
2492 access_dev = dev;
2493 rc = device_create_file(dev, &dev_attr_touch_mmi_test);
2494 if (rc) {
2495 dev_err(dev, "%s: Error, could not create fw_calibration\n",
2496 __func__);
2497 goto cyttsp4_create_touch_mmi_test_failed;
2498 }
2499 /* END PN:DTS2013061703557 ,Added by l00184147, 2013/6/17*/
2500
2501 mutex_init(&dad->sysfs_lock);
2502 init_waitqueue_head(&dad->wait_q);
2503 dad->ttsp = ttsp;
2504 dad->pdata = pdata;
2505 dad->ic_grpnum = CY_IC_GRPNUM_TCH_REP;
2506 dad->test.cur_cmd = -1;
2507 dad->heatmap.numElement = 200;
2508 dev_set_drvdata(dev, dad);
2509
2510 pm_runtime_enable(dev);
2511
2512 pm_runtime_get_sync(dev);
2513 /* get sysinfo */
2514 dad->si = cyttsp4_request_sysinfo(ttsp);
2515 pm_runtime_put(dev);
2516 if (dad->si) {
2517 rc = cyttsp4_setup_sysfs(ttsp);
2518 if (rc)
2519 goto cyttsp4_device_access_setup_sysfs_failed;
2520 } else {
2521 dev_err(dev, "%s: Fail get sysinfo pointer from core p=%p\n",
2522 __func__, dad->si);
2523 cyttsp4_subscribe_attention(ttsp, CY_ATTEN_STARTUP,
2524 cyttsp4_setup_sysfs_attention, 0);
2525 }
2526
2527 /* Stay awake if the current grpnum requires */
2528 if (cyttsp4_is_awakening_grpnum(dad->ic_grpnum))
2529 pm_runtime_get(dev);
2530
2531 dev_dbg(dev, "%s: ok\n", __func__);
2532 return 0;
2533
2534 cyttsp4_device_access_setup_sysfs_failed:
2535 pm_runtime_suspend(dev);
2536 pm_runtime_disable(dev);
2537 dev_set_drvdata(dev, NULL);
2538 kfree(dad);
2539 /* BEGIN PN:DTS2013061703557 ,Added by l00184147, 2013/6/17*/
2540 cyttsp4_create_touch_mmi_test_failed:
2541 /* END PN:DTS2013061703557 ,Added by l00184147, 2013/6/17*/
2542 cyttsp4_device_access_probe_data_failed:
2543 dev_err(dev, "%s failed.\n", __func__);
2544 return rc;
2545 }
2546
2547 static int cyttsp4_device_access_release(struct cyttsp4_device *ttsp)
2548 {
2549 struct device *dev = &ttsp->dev;
2550 struct cyttsp4_device_access_data *dad = dev_get_drvdata(dev);
2551 u8 ic_buf[CY_NULL_CMD_MODE_INDEX + 1];
2552 dev_dbg(dev, "%s\n", __func__);
2553
2554 /* If the current grpnum required being awake, release it */
2555 mutex_lock(&dad->sysfs_lock);
2556 if (cyttsp4_is_awakening_grpnum(dad->ic_grpnum))
2557 pm_runtime_put(dev);
2558 mutex_unlock(&dad->sysfs_lock);
2559
2560 if (dad->own_exclusive) {
2561 dev_err(dev, "%s: Can't unload in CAT mode. "
2562 "First switch back to Operational mode\n"
2563 , __func__);
2564 ic_buf[CY_NULL_CMD_MODE_INDEX] = CY_HST_OPERATE;
2565 cyttsp4_test_cmd_mode(dad, ic_buf, CY_NULL_CMD_MODE_INDEX + 1);
2566 }
2567
2568 pm_runtime_suspend(dev);
2569 pm_runtime_disable(dev);
2570
2571 if (dad->sysfs_nodes_created) {
2572 device_remove_file(dev, &dev_attr_ic_grpnum);
2573 device_remove_file(dev, &dev_attr_ic_grpoffset);
2574 device_remove_file(dev, &dev_attr_ic_grpdata);
2575 device_remove_file(dev, &dev_attr_get_panel_data);
2576 } else {
2577 cyttsp4_unsubscribe_attention(ttsp, CY_ATTEN_STARTUP,
2578 cyttsp4_setup_sysfs_attention, 0);
2579 }
2580
2581 dev_set_drvdata(dev, NULL);
2582 kfree(dad);
2583 return 0;
2584 }
2585
2586 static struct cyttsp4_driver cyttsp4_device_access_driver = {
2587 .probe = cyttsp4_device_access_probe,
2588 .remove = cyttsp4_device_access_release,
2589 .driver = {
2590 .name = CYTTSP4_DEVICE_ACCESS_NAME,
2591 .bus = &cyttsp4_bus_type,
2592 .owner = THIS_MODULE,
2593 /* BEGIN PN:SPBB-1257 ,Deteled by l00184147, 2013/2/21*/
2594 //no longer to use pm operation
2595 //.pm = &cyttsp4_device_access_pm_ops,
2596 /* END PN:SPBB-1257 ,Deteled by l00184147, 2013/2/21*/
2597 },
2598 };
2599
2600 static struct cyttsp4_device_access_platform_data
2601 _cyttsp4_device_access_platform_data = {
2602 .device_access_dev_name = CYTTSP4_DEVICE_ACCESS_NAME,
2603 };
2604
2605 static const char cyttsp4_device_access_name[] = CYTTSP4_DEVICE_ACCESS_NAME;
2606 static struct cyttsp4_device_info
2607 cyttsp4_device_access_infos[CY_MAX_NUM_CORE_DEVS];
2608
2609 static const char *core_ids[CY_MAX_NUM_CORE_DEVS] = {
2610 CY_DEFAULT_CORE_ID,
2611 NULL,
2612 NULL,
2613 NULL,
2614 NULL
2615 };
2616
2617 static int num_core_ids = 1;
2618
2619 module_param_array(core_ids, charp, &num_core_ids, 0);
2620 MODULE_PARM_DESC(core_ids,
2621 "Core id list of cyttsp4 core devices for device access module");
2622
2623 static int __init cyttsp4_device_access_init(void)
2624 {
2625 int rc = 0;
2626 int i, j;
2627
2628 /* Check for invalid or duplicate core_ids */
2629 for (i = 0; i < num_core_ids; i++) {
2630 if (!strlen(core_ids[i])) {
2631 pr_err("%s: core_id %d is empty\n",
2632 __func__, i+1);
2633 return -EINVAL;
2634 }
2635 for (j = i+1; j < num_core_ids; j++)
2636 if (!strcmp(core_ids[i], core_ids[j])) {
2637 pr_err("%s: core_ids %d and %d are same\n",
2638 __func__, i+1, j+1);
2639 return -EINVAL;
2640 }
2641 }
2642
2643 for (i = 0; i < num_core_ids; i++) {
2644 cyttsp4_device_access_infos[i].name =
2645 cyttsp4_device_access_name;
2646 cyttsp4_device_access_infos[i].core_id = core_ids[i];
2647 cyttsp4_device_access_infos[i].platform_data =
2648 &_cyttsp4_device_access_platform_data;
2649 pr_info("%s: Registering device access device for core_id: %s\n",
2650 __func__, cyttsp4_device_access_infos[i].core_id);
2651 rc = cyttsp4_register_device(&cyttsp4_device_access_infos[i]);
2652 if (rc < 0) {
2653 pr_err("%s: Error, failed registering device\n",
2654 __func__);
2655 goto fail_unregister_devices;
2656 }
2657 }
2658 rc = cyttsp4_register_driver(&cyttsp4_device_access_driver);
2659 if (rc) {
2660 pr_err("%s: Error, failed registering driver\n", __func__);
2661 goto fail_unregister_devices;
2662 }
2663
2664 pr_info("%s: Cypress TTSP Device Access (Built %s) rc=%d\n",
2665 __func__, CY_DRIVER_DATE, rc);
2666 return 0;
2667
2668 fail_unregister_devices:
2669 /* BEGIN PN:DTS2013033006231 ,Modified by l00184147, 2013/3/27*/
2670 for (i--; i >= 0; i--) {
2671 /* END PN:DTS2013033006231 ,Modified by l00184147, 2013/3/27*/
2672 cyttsp4_unregister_device(cyttsp4_device_access_infos[i].name,
2673 cyttsp4_device_access_infos[i].core_id);
2674 pr_info("%s: Unregistering device access device for core_id: %s\n",
2675 __func__, cyttsp4_device_access_infos[i].core_id);
2676 }
2677 return rc;
2678 }
2679 module_init(cyttsp4_device_access_init);
2680
2681 static void __exit cyttsp4_device_access_exit(void)
2682 {
2683 int i;
2684
2685 cyttsp4_unregister_driver(&cyttsp4_device_access_driver);
2686 for (i = 0; i < num_core_ids; i++) {
2687 cyttsp4_unregister_device(cyttsp4_device_access_infos[i].name,
2688 cyttsp4_device_access_infos[i].core_id);
2689 pr_info("%s: Unregistering device access device for core_id: %s\n",
2690 __func__, cyttsp4_device_access_infos[i].core_id);
2691 }
2692 pr_info("%s: module exit\n", __func__);
2693 }
2694 module_exit(cyttsp4_device_access_exit);
2695
2696 MODULE_LICENSE("GPL");
2697 MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product Device Access Driver");
2698 MODULE_AUTHOR("Cypress Semiconductor");
2699 /* END PN:SPBB-1218 ,Added by l00184147, 2012/12/20*/
2700 /* END PN:DTS2013012601133 ,Modified by l00184147, 2013/1/26*/
2701 /* END PN:DTS2013051703879 ,Added by l00184147, 2013/5/17*/