1 /*
2 * cyttsp5_core.c
3 * Parade TrueTouch(TM) Standard Product V5 Core Module.
4 * For use with Parade touchscreen controllers.
5 * Supported parts include:
6 * CYTMA5XX
7 * CYTMA448
8 * CYTMA445A
9 * CYTT21XXX
10 * CYTT31XXX
11 *
12 * Copyright (C) 2015 Parade Technologies
13 * Copyright (C) 2012-2015 Cypress Semiconductor
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2, and only version 2, as published by the
18 * Free Software Foundation.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * Contact Parade Technologies at www.paradetech.com <ttdrivers@paradetech.com>
26 *
27 */
28
29 #include "cyttsp5_regs.h"
30 #include <linux/kthread.h>
31
32 #include <linux/notifier.h>
33 #include <linux/regulator/driver.h>
34 #include <linux/regulator/consumer.h>
35
36 static struct cyttsp5_core_data *priv_data;
37 #define CY_CORE_STARTUP_RETRY_COUNT 3
38
39 MODULE_FIRMWARE(CY_FW_FILE_NAME);
40
41 static const char *cy_driver_core_name = CYTTSP5_CORE_NAME;
42 static const char *cy_driver_core_version = CY_DRIVER_VERSION;
43 static const char *cy_driver_core_date = CY_DRIVER_DATE;
44 static bool cyttsp5_first_probe = true;
45 static bool is_cyttsp5_probe_success;
46 static const struct cyttsp5_bus_ops *cyttsp5_bus_ops_save;
47
48 struct cyttsp5_hid_field {
49 int report_count;
50 int report_size;
51 int size; /* report_count * report_size */
52 int offset;
53 int data_type;
54 int logical_min;
55 int logical_max;
56 /* Usage Page (Hi 16 bit) + Usage (Lo 16 bit) */
57 u32 usage_page;
58 u32 collection_usage_pages[CY_HID_MAX_COLLECTIONS];
59 struct cyttsp5_hid_report *report;
60 bool record_field;
61 };
62
63 struct cyttsp5_hid_report {
64 u8 id;
65 u8 type;
66 int size;
67 struct cyttsp5_hid_field *fields[CY_HID_MAX_FIELDS];
68 int num_fields;
69 int record_field_index;
70 int header_size;
71 int record_size;
72 u32 usage_page;
73 };
74
75 struct atten_node {
76 struct list_head node;
77 char *id;
78 struct device *dev;
79
80 int (*func)(struct device *);
81 int mode;
82 };
83
84 struct param_node {
85 struct list_head node;
86 u8 id;
87 u32 value;
88 u8 size;
89 };
90
91 struct module_node {
92 struct list_head node;
93 struct cyttsp5_module *module;
94 void *data;
95 };
96
97 struct cyttsp5_hid_cmd {
98 u8 opcode;
99 u8 report_type;
100 union {
101 u8 report_id;
102 u8 power_state;
103 };
104 u8 has_data_register;
105 size_t write_length;
106 u8 *write_buf;
107 u8 *read_buf;
108 u8 wait_interrupt;
109 u8 reset_cmd;
110 u16 timeout_ms;
111 };
112
113 struct cyttsp5_hid_output {
114 u8 cmd_type;
115 u16 length;
116 u8 command_code;
117 size_t write_length;
118 u8 *write_buf;
119 u8 novalidate;
120 u8 reset_expected;
121 u16 timeout_ms;
122 };
123
124 #define SET_CMD_OPCODE(byte, opcode) SET_CMD_LOW(byte, opcode)
125 #define SET_CMD_REPORT_TYPE(byte, type) SET_CMD_HIGH(byte, ((type) << 4))
126 #define SET_CMD_REPORT_ID(byte, id) SET_CMD_LOW(byte, id)
127
128 #define HID_OUTPUT_APP_COMMAND(command) \
129 .cmd_type = HID_OUTPUT_CMD_APP, \
130 .command_code = command
131
132 #define HID_OUTPUT_BL_COMMAND(command) \
133 .cmd_type = HID_OUTPUT_CMD_BL, \
134 .command_code = command
135
136 #ifdef VERBOSE_DEBUG
cyttsp5_pr_buf(struct device * dev,u8 * dptr,int size,const char * data_name)137 void cyttsp5_pr_buf(struct device *dev, u8 *dptr, int size,
138 const char *data_name)
139 {
140 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
141 u8 *pr_buf = cd->pr_buf;
142 int i, k;
143 const char fmt[] = "%02X ";
144 int max;
145
146 if (!size)
147 return;
148
149 max = (CY_MAX_PRBUF_SIZE - 1) - sizeof(CY_PR_TRUNCATED);
150
151 pr_buf[0] = 0;
152 for (i = k = 0; i < size && k < max; i++, k += 3)
153 scnprintf(pr_buf + k, CY_MAX_PRBUF_SIZE, fmt, dptr[i]);
154
155 if (size) {
156 parade_debug(dev, DEBUG_LEVEL_2, "%s: %s[0..%d]=%s%s\n",
157 __func__, data_name,
158 size - 1, pr_buf, size <= max ? "" : CY_PR_TRUNCATED);
159 } else {
160 parade_debug(dev, DEBUG_LEVEL_2, "%s: %s[]\n",
161 __func__, data_name);
162 }
163 }
164 EXPORT_SYMBOL_GPL(cyttsp5_pr_buf);
165 #endif
166
167 #ifdef TTHE_TUNER_SUPPORT
tthe_print(struct cyttsp5_core_data * cd,u8 * buf,int buf_len,const u8 * data_name)168 static int tthe_print(struct cyttsp5_core_data *cd, u8 *buf, int buf_len,
169 const u8 *data_name)
170 {
171 int len = strlen(data_name);
172 int i, n;
173 u8 *p;
174 int remain;
175 u8 data_name_with_time_stamp[100];
176
177 if (cd->show_timestamp) {
178 sprintf(data_name_with_time_stamp, "[%u] %s",
179 jiffies_to_msecs(jiffies), data_name);
180 data_name = data_name_with_time_stamp;
181 len = strlen(data_name);
182 }
183
184 mutex_lock(&cd->tthe_lock);
185 if (!cd->tthe_buf)
186 goto exit;
187
188 if (cd->tthe_buf_len + (len + buf_len) > CY_MAX_PRBUF_SIZE)
189 goto exit;
190
191 if (len + buf_len == 0)
192 goto exit;
193
194 remain = CY_MAX_PRBUF_SIZE - cd->tthe_buf_len;
195 if (remain < len)
196 len = remain;
197
198 p = cd->tthe_buf + cd->tthe_buf_len;
199 memcpy(p, data_name, len);
200 cd->tthe_buf_len += len;
201 p += len;
202 remain -= len;
203
204 *p = 0;
205 for (i = 0; i < buf_len; i++) {
206 n = scnprintf(p, remain, "%02X ", buf[i]);
207 if (!n)
208 break;
209 p += n;
210 remain -= n;
211 cd->tthe_buf_len += n;
212 }
213
214 n = scnprintf(p, remain, "\n");
215 if (!n)
216 cd->tthe_buf[cd->tthe_buf_len] = 0;
217 cd->tthe_buf_len += n;
218 wake_up(&cd->wait_q);
219 exit:
220 mutex_unlock(&cd->tthe_lock);
221 return 0;
222 }
223
_cyttsp5_request_tthe_print(struct device * dev,u8 * buf,int buf_len,const u8 * data_name)224 static int _cyttsp5_request_tthe_print(struct device *dev, u8 *buf,
225 int buf_len, const u8 *data_name)
226 {
227 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
228
229 return tthe_print(cd, buf, buf_len, data_name);
230 }
231 #endif
232
233 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
watchdog_delay_enable(struct work_struct * work)234 static void watchdog_delay_enable(struct work_struct *work)
235 {
236 struct cyttsp5_core_data *cd;
237
238 cd = container_of(work, struct cyttsp5_core_data, watchdog_enable_work.work);
239 cd->watchdog_interval = CY_WATCHDOG_TIMEOUT;
240 printk("++++++watchdog_delay_enable\n");
241 }
242 #endif
243
244 /*
245 * cyttsp5_platform_detect_read()
246 *
247 * This function is passed to platform detect
248 * function to perform a read operation
249 */
cyttsp5_platform_detect_read(struct device * dev,void * buf,int size)250 static int cyttsp5_platform_detect_read(struct device *dev, void *buf, int size)
251 {
252 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
253
254 return cyttsp5_adap_read_default(cd, buf, size);
255 }
256
257 /* Must be called with cd->hid_report_lock acquired */
cyttsp5_get_hid_report_(struct cyttsp5_core_data * cd,u8 report_type,u8 report_id,bool create)258 static struct cyttsp5_hid_report *cyttsp5_get_hid_report_(
259 struct cyttsp5_core_data *cd, u8 report_type, u8 report_id,
260 bool create)
261 {
262 struct cyttsp5_hid_report *report = NULL;
263 int i;
264
265 /* Look for created reports */
266 for (i = 0; i < cd->num_hid_reports; i++) {
267 if (cd->hid_reports[i]->type == report_type
268 && cd->hid_reports[i]->id == report_id) {
269 return cd->hid_reports[i];
270 }
271 }
272
273 /* Create a new report */
274 if (create && cd->num_hid_reports < CY_HID_MAX_REPORTS) {
275 report = kzalloc(sizeof(struct cyttsp5_hid_report),
276 GFP_KERNEL);
277 if (!report)
278 return NULL;
279
280 report->type = report_type;
281 report->id = report_id;
282 cd->hid_reports[cd->num_hid_reports++] = report;
283 }
284
285 return report;
286 }
287
288 /* Must be called with cd->hid_report_lock acquired */
cyttsp5_free_hid_reports_(struct cyttsp5_core_data * cd)289 static void cyttsp5_free_hid_reports_(struct cyttsp5_core_data *cd)
290 {
291 struct cyttsp5_hid_report *report;
292 int i, j;
293
294 for (i = 0; i < cd->num_hid_reports; i++) {
295 report = cd->hid_reports[i];
296 for (j = 0; j < report->num_fields; j++)
297 kfree(report->fields[j]);
298 kfree(report);
299 cd->hid_reports[i] = NULL;
300 }
301
302 cd->num_hid_reports = 0;
303 }
304
cyttsp5_free_hid_reports(struct cyttsp5_core_data * cd)305 static void cyttsp5_free_hid_reports(struct cyttsp5_core_data *cd)
306 {
307 mutex_lock(&cd->hid_report_lock);
308 cyttsp5_free_hid_reports_(cd);
309 mutex_unlock(&cd->hid_report_lock);
310 }
311
312 /* Must be called with cd->hid_report_lock acquired */
cyttsp5_create_hid_field_(struct cyttsp5_hid_report * report)313 static struct cyttsp5_hid_field *cyttsp5_create_hid_field_(
314 struct cyttsp5_hid_report *report)
315 {
316 struct cyttsp5_hid_field *field;
317
318 if (!report)
319 return NULL;
320
321 if (report->num_fields == CY_HID_MAX_FIELDS)
322 return NULL;
323
324 field = kzalloc(sizeof(struct cyttsp5_hid_field), GFP_KERNEL);
325 if (!field)
326 return NULL;
327
328 field->report = report;
329
330 report->fields[report->num_fields++] = field;
331
332 return field;
333 }
334
cyttsp5_add_parameter(struct cyttsp5_core_data * cd,u8 param_id,u32 param_value,u8 param_size)335 static int cyttsp5_add_parameter(struct cyttsp5_core_data *cd,
336 u8 param_id, u32 param_value, u8 param_size)
337 {
338 struct param_node *param, *param_new;
339
340 /* Check if parameter exists */
341 spin_lock(&cd->spinlock);
342 list_for_each_entry(param, &cd->param_list, node) {
343 if (param->id == param_id) {
344 /* Update parameter */
345 param->value = param_value;
346 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: Update parameter id:%d value:%d size:%d\n",
347 __func__, param_id, param_value, param_size);
348 goto exit_unlock;
349 }
350 }
351 spin_unlock(&cd->spinlock);
352
353 param_new = kzalloc(sizeof(*param_new), GFP_KERNEL);
354 if (!param_new)
355 return -ENOMEM;
356
357 param_new->id = param_id;
358 param_new->value = param_value;
359 param_new->size = param_size;
360
361 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: Add parameter id:%d value:%d size:%d\n",
362 __func__, param_id, param_value, param_size);
363
364 spin_lock(&cd->spinlock);
365 list_add(¶m_new->node, &cd->param_list);
366 exit_unlock:
367 spin_unlock(&cd->spinlock);
368
369 return 0;
370 }
371
request_exclusive(struct cyttsp5_core_data * cd,void * ownptr,int timeout_ms)372 int request_exclusive(struct cyttsp5_core_data *cd, void *ownptr,
373 int timeout_ms)
374 {
375 int t = msecs_to_jiffies(timeout_ms);
376 bool with_timeout = (timeout_ms != 0);
377
378 mutex_lock(&cd->system_lock);
379 if (!cd->exclusive_dev && cd->exclusive_waits == 0) {
380 cd->exclusive_dev = ownptr;
381 goto exit;
382 }
383
384 cd->exclusive_waits++;
385 wait:
386 mutex_unlock(&cd->system_lock);
387 if (with_timeout) {
388 t = wait_event_timeout(cd->wait_q, !cd->exclusive_dev, t);
389 if (IS_TMO(t)) {
390 dev_err(cd->dev, "%s: tmo waiting exclusive access\n",
391 __func__);
392 return -ETIME;
393 }
394 } else {
395 wait_event(cd->wait_q, !cd->exclusive_dev);
396 }
397 mutex_lock(&cd->system_lock);
398 if (cd->exclusive_dev)
399 goto wait;
400 cd->exclusive_dev = ownptr;
401 cd->exclusive_waits--;
402 exit:
403 mutex_unlock(&cd->system_lock);
404 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: request_exclusive ok=%p\n",
405 __func__, ownptr);
406
407 return 0;
408 }
409
release_exclusive_(struct cyttsp5_core_data * cd,void * ownptr)410 static int release_exclusive_(struct cyttsp5_core_data *cd, void *ownptr)
411 {
412 if (cd->exclusive_dev != ownptr)
413 return -EINVAL;
414
415 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: exclusive_dev %p freed\n",
416 __func__, cd->exclusive_dev);
417 cd->exclusive_dev = NULL;
418 wake_up(&cd->wait_q);
419 return 0;
420 }
421
422 /*
423 * returns error if was not owned
424 */
release_exclusive(struct cyttsp5_core_data * cd,void * ownptr)425 int release_exclusive(struct cyttsp5_core_data *cd, void *ownptr)
426 {
427 int rc;
428
429 mutex_lock(&cd->system_lock);
430 rc = release_exclusive_(cd, ownptr);
431 mutex_unlock(&cd->system_lock);
432
433 return rc;
434 }
435
cyttsp5_hid_exec_cmd_(struct cyttsp5_core_data * cd,struct cyttsp5_hid_cmd * hid_cmd)436 static int cyttsp5_hid_exec_cmd_(struct cyttsp5_core_data *cd,
437 struct cyttsp5_hid_cmd *hid_cmd)
438 {
439 int rc;
440 u8 *cmd;
441 u8 cmd_length;
442 u8 cmd_offset = 0;
443
444 cmd_length = 2 /* command register */
445 + 2 /* command */
446 + (hid_cmd->report_id >= 0XF ? 1 : 0) /* Report ID */
447 + (hid_cmd->has_data_register ? 2 : 0) /* Data register */
448 + hid_cmd->write_length; /* Data length */
449
450 cmd = kzalloc(cmd_length, GFP_KERNEL);
451 if (!cmd)
452 return -ENOMEM;
453
454 /* Set Command register */
455 memcpy(&cmd[cmd_offset], &cd->hid_desc.command_register,
456 sizeof(cd->hid_desc.command_register));
457 cmd_offset += sizeof(cd->hid_desc.command_register);
458
459 /* Set Command */
460 SET_CMD_REPORT_TYPE(cmd[cmd_offset], hid_cmd->report_type);
461
462 if (hid_cmd->report_id >= 0XF)
463 SET_CMD_REPORT_ID(cmd[cmd_offset], 0xF);
464 else
465 SET_CMD_REPORT_ID(cmd[cmd_offset], hid_cmd->report_id);
466 cmd_offset++;
467
468 SET_CMD_OPCODE(cmd[cmd_offset], hid_cmd->opcode);
469 cmd_offset++;
470
471 if (hid_cmd->report_id >= 0XF) {
472 cmd[cmd_offset] = hid_cmd->report_id;
473 cmd_offset++;
474 }
475
476 /* Set Data register */
477 if (hid_cmd->has_data_register) {
478 memcpy(&cmd[cmd_offset], &cd->hid_desc.data_register,
479 sizeof(cd->hid_desc.data_register));
480 cmd_offset += sizeof(cd->hid_desc.data_register);
481 }
482
483 /* Set Data */
484 if (hid_cmd->write_length && hid_cmd->write_buf) {
485 memcpy(&cmd[cmd_offset], hid_cmd->write_buf,
486 hid_cmd->write_length);
487 cmd_offset += hid_cmd->write_length;
488 }
489
490 rc = cyttsp5_adap_write_read_specific(cd, cmd_length, cmd,
491 hid_cmd->read_buf);
492 if (rc)
493 dev_err(cd->dev, "%s: Fail cyttsp5_adap_transfer\n", __func__);
494
495 kfree(cmd);
496 return rc;
497 }
498
cyttsp5_hid_exec_cmd_and_wait_(struct cyttsp5_core_data * cd,struct cyttsp5_hid_cmd * hid_cmd)499 static int cyttsp5_hid_exec_cmd_and_wait_(struct cyttsp5_core_data *cd,
500 struct cyttsp5_hid_cmd *hid_cmd)
501 {
502 int rc;
503 int t;
504 u16 timeout_ms;
505 int *cmd_state;
506
507 if (hid_cmd->reset_cmd)
508 cmd_state = &cd->hid_reset_cmd_state;
509 else
510 cmd_state = &cd->hid_cmd_state;
511
512 if (hid_cmd->wait_interrupt) {
513 mutex_lock(&cd->system_lock);
514 *cmd_state = 1;
515 mutex_unlock(&cd->system_lock);
516 }
517
518 rc = cyttsp5_hid_exec_cmd_(cd, hid_cmd);
519 if (rc) {
520 if (hid_cmd->wait_interrupt)
521 goto error;
522
523 goto exit;
524 }
525
526 if (!hid_cmd->wait_interrupt)
527 goto exit;
528
529 if (hid_cmd->timeout_ms)
530 timeout_ms = hid_cmd->timeout_ms;
531 else
532 timeout_ms = CY_HID_RESET_TIMEOUT;
533 //printk("****%s timeout_ms=%d, rc=%d\n", __func__, timeout_ms, rc);
534
535 t = wait_event_timeout(cd->wait_q, (*cmd_state == 0),
536 msecs_to_jiffies(timeout_ms));
537 if (IS_TMO(t)) {
538 dev_err(cd->dev, "%s: HID output cmd execution timed out %d\n",
539 __func__, timeout_ms);
540 rc = -ETIME;
541 goto error;
542 }
543
544 goto exit;
545
546 error:
547 mutex_lock(&cd->system_lock);
548 *cmd_state = 0;
549 mutex_unlock(&cd->system_lock);
550
551 exit:
552 return rc;
553 }
554
cyttsp5_hid_cmd_reset_(struct cyttsp5_core_data * cd)555 static int cyttsp5_hid_cmd_reset_(struct cyttsp5_core_data *cd)
556 {
557 struct cyttsp5_hid_cmd hid_cmd = {
558 .opcode = HID_CMD_RESET,
559 .wait_interrupt = 1,
560 .reset_cmd = 1,
561 .timeout_ms = CY_HID_RESET_TIMEOUT,
562 };
563
564 return cyttsp5_hid_exec_cmd_and_wait_(cd, &hid_cmd);
565 }
566
cyttsp5_hid_cmd_reset(struct cyttsp5_core_data * cd)567 static int cyttsp5_hid_cmd_reset(struct cyttsp5_core_data *cd)
568 {
569 int rc;
570
571 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
572 if (rc < 0) {
573 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
574 __func__, cd->exclusive_dev, cd->dev);
575 return rc;
576 }
577
578 rc = cyttsp5_hid_cmd_reset_(cd);
579
580 if (release_exclusive(cd, cd->dev) < 0)
581 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
582
583 return rc;
584 }
585
cyttsp5_hid_cmd_set_power_(struct cyttsp5_core_data * cd,u8 power_state)586 static int cyttsp5_hid_cmd_set_power_(struct cyttsp5_core_data *cd,
587 u8 power_state)
588 {
589 int rc;
590 struct cyttsp5_hid_cmd hid_cmd = {
591 .opcode = HID_CMD_SET_POWER,
592 .wait_interrupt = 1,
593 .timeout_ms = CY_HID_SET_POWER_TIMEOUT,
594 };
595 hid_cmd.power_state = power_state;
596
597 rc = cyttsp5_hid_exec_cmd_and_wait_(cd, &hid_cmd);
598 if (rc) {
599 dev_err(cd->dev, "%s: Failed to set power to state:%d\n",
600 __func__, power_state);
601 return rc;
602 }
603
604 /* validate */
605 if ((cd->response_buf[2] != HID_RESPONSE_REPORT_ID)
606 || ((cd->response_buf[3] & 0x3) != power_state)
607 || ((cd->response_buf[4] & 0xF) != HID_CMD_SET_POWER))
608 rc = -EINVAL;
609
610 return rc;
611 }
612
cyttsp5_hid_cmd_set_power(struct cyttsp5_core_data * cd,u8 power_state)613 static int cyttsp5_hid_cmd_set_power(struct cyttsp5_core_data *cd,
614 u8 power_state)
615 {
616 int rc;
617
618 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
619 if (rc < 0) {
620 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
621 __func__, cd->exclusive_dev, cd->dev);
622 return rc;
623 }
624
625 rc = cyttsp5_hid_cmd_set_power_(cd, power_state);
626
627 if (release_exclusive(cd, cd->dev) < 0)
628 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
629
630 return rc;
631 }
632
633 static const u16 crc_table[16] = {
634 0x0000, 0x1021, 0x2042, 0x3063,
635 0x4084, 0x50a5, 0x60c6, 0x70e7,
636 0x8108, 0x9129, 0xa14a, 0xb16b,
637 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
638 };
639
_cyttsp5_compute_crc(u8 * buf,u32 size)640 static u16 _cyttsp5_compute_crc(u8 *buf, u32 size)
641 {
642 u16 remainder = 0xFFFF;
643 u16 xor_mask = 0x0000;
644 u32 index;
645 u32 byte_value;
646 u32 table_index;
647 u32 crc_bit_width = sizeof(u16) * 8;
648
649 /* Divide the message by polynomial, via the table. */
650 for (index = 0; index < size; index++) {
651 byte_value = buf[index];
652 table_index = ((byte_value >> 4) & 0x0F)
653 ^ (remainder >> (crc_bit_width - 4));
654 remainder = crc_table[table_index] ^ (remainder << 4);
655 table_index = (byte_value & 0x0F)
656 ^ (remainder >> (crc_bit_width - 4));
657 remainder = crc_table[table_index] ^ (remainder << 4);
658 }
659
660 /* Perform the final remainder CRC. */
661 return remainder ^ xor_mask;
662 }
663
cyttsp5_hid_output_validate_bl_response(struct cyttsp5_core_data * cd,struct cyttsp5_hid_output * hid_output)664 static int cyttsp5_hid_output_validate_bl_response(
665 struct cyttsp5_core_data *cd,
666 struct cyttsp5_hid_output *hid_output)
667 {
668 u16 size;
669 u16 crc;
670 u8 status;
671
672 size = get_unaligned_le16(&cd->response_buf[0]);
673
674 if (hid_output->reset_expected && !size)
675 return 0;
676
677 if (cd->response_buf[HID_OUTPUT_RESPONSE_REPORT_OFFSET]
678 != HID_BL_RESPONSE_REPORT_ID) {
679 dev_err(cd->dev, "%s: HID output response, wrong report_id\n",
680 __func__);
681 return -EPROTO;
682 }
683
684 if (cd->response_buf[4] != HID_OUTPUT_BL_SOP) {
685 dev_err(cd->dev, "%s: HID output response, wrong SOP\n",
686 __func__);
687 return -EPROTO;
688 }
689
690 if (cd->response_buf[size - 1] != HID_OUTPUT_BL_EOP) {
691 dev_err(cd->dev, "%s: HID output response, wrong EOP\n",
692 __func__);
693 return -EPROTO;
694 }
695
696 crc = _cyttsp5_compute_crc(&cd->response_buf[4], size - 7);
697 if (cd->response_buf[size - 3] != LOW_BYTE(crc)
698 || cd->response_buf[size - 2] != HI_BYTE(crc)) {
699 dev_err(cd->dev, "%s: HID output response, wrong CRC 0x%X\n",
700 __func__, crc);
701 return -EPROTO;
702 }
703
704 status = cd->response_buf[5];
705 if (status) {
706 dev_err(cd->dev, "%s: HID output response, ERROR:%d\n",
707 __func__, status);
708 return -EPROTO;
709 }
710
711 return 0;
712 }
713
cyttsp5_hid_output_validate_app_response(struct cyttsp5_core_data * cd,struct cyttsp5_hid_output * hid_output)714 static int cyttsp5_hid_output_validate_app_response(
715 struct cyttsp5_core_data *cd,
716 struct cyttsp5_hid_output *hid_output)
717 {
718 int command_code;
719 u16 size;
720
721 size = get_unaligned_le16(&cd->response_buf[0]);
722
723 if (hid_output->reset_expected && !size)
724 return 0;
725
726 if (cd->response_buf[HID_OUTPUT_RESPONSE_REPORT_OFFSET]
727 != HID_APP_RESPONSE_REPORT_ID) {
728 dev_err(cd->dev, "%s: HID output response, wrong report_id\n",
729 __func__);
730 return -EPROTO;
731 }
732
733 command_code = cd->response_buf[HID_OUTPUT_RESPONSE_CMD_OFFSET]
734 & HID_OUTPUT_RESPONSE_CMD_MASK;
735 if (command_code != hid_output->command_code) {
736 dev_err(cd->dev,
737 "%s: HID output response, wrong command_code:%X\n",
738 __func__, command_code);
739 return -EPROTO;
740 }
741
742 return 0;
743 }
744
cyttsp5_check_set_parameter(struct cyttsp5_core_data * cd,struct cyttsp5_hid_output * hid_output,bool raw)745 static void cyttsp5_check_set_parameter(struct cyttsp5_core_data *cd,
746 struct cyttsp5_hid_output *hid_output, bool raw)
747 {
748 u8 *param_buf;
749 u32 param_value = 0;
750 u8 param_size;
751 u8 param_id;
752 int i = 0;
753
754 if (!(cd->cpdata->flags & CY_CORE_FLAG_RESTORE_PARAMETERS))
755 return;
756
757 /* Check command input for Set Parameter command */
758 if (raw && hid_output->length >= 10 && hid_output->length <= 13
759 && !memcmp(&hid_output->write_buf[0],
760 &cd->hid_desc.output_register,
761 sizeof(cd->hid_desc.output_register))
762 && hid_output->write_buf[4] ==
763 HID_APP_OUTPUT_REPORT_ID
764 && hid_output->write_buf[6] ==
765 HID_OUTPUT_SET_PARAM)
766 param_buf = &hid_output->write_buf[7];
767 else if (!raw && hid_output->cmd_type == HID_OUTPUT_CMD_APP
768 && hid_output->command_code == HID_OUTPUT_SET_PARAM
769 && hid_output->write_length >= 3
770 && hid_output->write_length <= 6)
771 param_buf = &hid_output->write_buf[0];
772 else
773 return;
774
775 /* Get parameter ID, size and value */
776 param_id = param_buf[0];
777 param_size = param_buf[1];
778 if (param_size > 4) {
779 dev_err(cd->dev, "%s: Invalid parameter size\n", __func__);
780 return;
781 }
782
783 param_buf = ¶m_buf[2];
784 while (i < param_size)
785 param_value += *(param_buf++) << (8 * i++);
786
787 /* Check command response for Set Parameter command */
788 if (cd->response_buf[2] != HID_APP_RESPONSE_REPORT_ID
789 || (cd->response_buf[4] & HID_OUTPUT_CMD_MASK) !=
790 HID_OUTPUT_SET_PARAM
791 || cd->response_buf[5] != param_id
792 || cd->response_buf[6] != param_size) {
793 dev_err(cd->dev, "%s: Set Parameter command not successful\n",
794 __func__);
795 return;
796 }
797
798 cyttsp5_add_parameter(cd, param_id, param_value, param_size);
799 }
800
cyttsp5_check_command(struct cyttsp5_core_data * cd,struct cyttsp5_hid_output * hid_output,bool raw)801 static void cyttsp5_check_command(struct cyttsp5_core_data *cd,
802 struct cyttsp5_hid_output *hid_output, bool raw)
803 {
804 cyttsp5_check_set_parameter(cd, hid_output, raw);
805 }
806
cyttsp5_hid_output_validate_response(struct cyttsp5_core_data * cd,struct cyttsp5_hid_output * hid_output)807 static int cyttsp5_hid_output_validate_response(struct cyttsp5_core_data *cd,
808 struct cyttsp5_hid_output *hid_output)
809 {
810 if (hid_output->cmd_type == HID_OUTPUT_CMD_BL)
811 return cyttsp5_hid_output_validate_bl_response(cd, hid_output);
812
813 return cyttsp5_hid_output_validate_app_response(cd, hid_output);
814
815 }
816
cyttsp5_hid_send_output_user_(struct cyttsp5_core_data * cd,struct cyttsp5_hid_output * hid_output)817 static int cyttsp5_hid_send_output_user_(struct cyttsp5_core_data *cd,
818 struct cyttsp5_hid_output *hid_output)
819 {
820 int rc;
821
822 if (!hid_output->length || !hid_output->write_buf)
823 return -EINVAL;
824
825 rc = cyttsp5_adap_write_read_specific(cd, hid_output->length,
826 hid_output->write_buf, NULL);
827 if (rc)
828 dev_err(cd->dev, "%s: Fail cyttsp5_adap_transfer\n", __func__);
829
830 return rc;
831 }
832
cyttsp5_hid_send_output_user_and_wait_(struct cyttsp5_core_data * cd,struct cyttsp5_hid_output * hid_output)833 static int cyttsp5_hid_send_output_user_and_wait_(struct cyttsp5_core_data *cd,
834 struct cyttsp5_hid_output *hid_output)
835 {
836 int rc;
837 int t;
838
839 mutex_lock(&cd->system_lock);
840 cd->hid_cmd_state = HID_OUTPUT_USER_CMD + 1;
841 mutex_unlock(&cd->system_lock);
842
843 rc = cyttsp5_hid_send_output_user_(cd, hid_output);
844 if (rc)
845 goto error;
846
847 t = wait_event_timeout(cd->wait_q, (cd->hid_cmd_state == 0),
848 msecs_to_jiffies(CY_HID_OUTPUT_USER_TIMEOUT));
849 if (IS_TMO(t)) {
850 dev_err(cd->dev, "%s: HID output cmd execution timed out\n",
851 __func__);
852 rc = -ETIME;
853 goto error;
854 }
855
856 cyttsp5_check_command(cd, hid_output, true);
857
858 goto exit;
859
860 error:
861 mutex_lock(&cd->system_lock);
862 cd->hid_cmd_state = 0;
863 mutex_unlock(&cd->system_lock);
864
865 exit:
866 return rc;
867 }
868
cyttsp5_hid_send_output_(struct cyttsp5_core_data * cd,struct cyttsp5_hid_output * hid_output)869 static int cyttsp5_hid_send_output_(struct cyttsp5_core_data *cd,
870 struct cyttsp5_hid_output *hid_output)
871 {
872 int rc;
873 u8 *cmd;
874 u16 length;
875 u8 report_id;
876 u8 cmd_offset = 0;
877 u16 crc;
878 u8 cmd_allocated = 0;
879
880 switch (hid_output->cmd_type) {
881 case HID_OUTPUT_CMD_APP:
882 report_id = HID_APP_OUTPUT_REPORT_ID;
883 length = 5;
884 break;
885 case HID_OUTPUT_CMD_BL:
886 report_id = HID_BL_OUTPUT_REPORT_ID;
887 length = 11 /* 5 + SOP + LEN(2) + CRC(2) + EOP */;
888 break;
889 default:
890 return -EINVAL;
891 }
892
893 length += hid_output->write_length;
894
895 if (length + 2 > CYTTSP5_PREALLOCATED_CMD_BUFFER) {
896 cmd = kzalloc(length + 2, GFP_KERNEL);
897 if (!cmd)
898 return -ENOMEM;
899 cmd_allocated = 1;
900 } else {
901 cmd = cd->cmd_buf;
902 }
903
904 /* Set Output register */
905 memcpy(&cmd[cmd_offset], &cd->hid_desc.output_register,
906 sizeof(cd->hid_desc.output_register));
907 cmd_offset += sizeof(cd->hid_desc.output_register);
908
909 cmd[cmd_offset++] = LOW_BYTE(length);
910 cmd[cmd_offset++] = HI_BYTE(length);
911 cmd[cmd_offset++] = report_id;
912 cmd[cmd_offset++] = 0x0; /* reserved */
913 if (hid_output->cmd_type == HID_OUTPUT_CMD_BL)
914 cmd[cmd_offset++] = HID_OUTPUT_BL_SOP;
915 cmd[cmd_offset++] = hid_output->command_code;
916
917 /* Set Data Length for bootloader */
918 if (hid_output->cmd_type == HID_OUTPUT_CMD_BL) {
919 cmd[cmd_offset++] = LOW_BYTE(hid_output->write_length);
920 cmd[cmd_offset++] = HI_BYTE(hid_output->write_length);
921 }
922 /* Set Data */
923 if (hid_output->write_length && hid_output->write_buf) {
924 memcpy(&cmd[cmd_offset], hid_output->write_buf,
925 hid_output->write_length);
926 cmd_offset += hid_output->write_length;
927 }
928 if (hid_output->cmd_type == HID_OUTPUT_CMD_BL) {
929 crc = _cyttsp5_compute_crc(&cmd[6],
930 hid_output->write_length + 4);
931 cmd[cmd_offset++] = LOW_BYTE(crc);
932 cmd[cmd_offset++] = HI_BYTE(crc);
933 cmd[cmd_offset++] = HID_OUTPUT_BL_EOP;
934 }
935
936 cyttsp5_pr_buf(cd->dev, cmd, length + 2, "command");
937 rc = cyttsp5_adap_write_read_specific(cd, length + 2, cmd, NULL);
938 if (rc)
939 dev_err(cd->dev, "%s: Fail cyttsp5_adap_transfer\n", __func__);
940
941 if (cmd_allocated)
942 kfree(cmd);
943 return rc;
944 }
945
cyttsp5_hid_send_output_and_wait_(struct cyttsp5_core_data * cd,struct cyttsp5_hid_output * hid_output)946 static int cyttsp5_hid_send_output_and_wait_(struct cyttsp5_core_data *cd,
947 struct cyttsp5_hid_output *hid_output)
948 {
949 int rc;
950 int t;
951 #ifdef VERBOSE_DEBUG
952 u16 size;
953 #endif
954 u16 timeout_ms;
955
956 mutex_lock(&cd->system_lock);
957 cd->hid_cmd_state = hid_output->command_code + 1;
958 mutex_unlock(&cd->system_lock);
959
960 if (hid_output->timeout_ms)
961 timeout_ms = hid_output->timeout_ms;
962 else
963 timeout_ms = CY_HID_OUTPUT_TIMEOUT;
964
965 rc = cyttsp5_hid_send_output_(cd, hid_output);
966 if (rc)
967 goto error;
968
969 //printk("%s time=%d\n", __func__, timeout_ms);
970 t = wait_event_timeout(cd->wait_q, (cd->hid_cmd_state == 0),
971 msecs_to_jiffies(timeout_ms));
972 if (IS_TMO(t)) {
973 dev_err(cd->dev, "%s: HID output cmd execution timed out\n",
974 __func__);
975 rc = -ETIME;
976 goto error;
977 }
978
979 if (!hid_output->novalidate)
980 rc = cyttsp5_hid_output_validate_response(cd, hid_output);
981
982 cyttsp5_check_command(cd, hid_output, false);
983
984 #ifdef VERBOSE_DEBUG
985 size = get_unaligned_le16(&cd->response_buf[0]);
986 cyttsp5_pr_buf(cd->dev, cd->response_buf, size, "return_buf");
987 #endif
988
989 goto exit;
990
991 error:
992 mutex_lock(&cd->system_lock);
993 cd->hid_cmd_state = 0;
994 mutex_unlock(&cd->system_lock);
995 exit:
996 return rc;
997 }
998
cyttsp5_hid_output_null_(struct cyttsp5_core_data * cd)999 static int cyttsp5_hid_output_null_(struct cyttsp5_core_data *cd)
1000 {
1001 struct cyttsp5_hid_output hid_output = {
1002 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_NULL),
1003 };
1004
1005 return cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1006 }
1007
cyttsp5_hid_output_null(struct cyttsp5_core_data * cd)1008 static int cyttsp5_hid_output_null(struct cyttsp5_core_data *cd)
1009 {
1010 int rc;
1011
1012 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
1013 if (rc < 0) {
1014 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
1015 __func__, cd->exclusive_dev, cd->dev);
1016 return rc;
1017 }
1018
1019 rc = cyttsp5_hid_output_null_(cd);
1020
1021 if (release_exclusive(cd, cd->dev) < 0)
1022 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
1023
1024 return rc;
1025 }
1026
cyttsp5_hid_output_start_bootloader_(struct cyttsp5_core_data * cd)1027 static int cyttsp5_hid_output_start_bootloader_(struct cyttsp5_core_data *cd)
1028 {
1029 struct cyttsp5_hid_output hid_output = {
1030 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_START_BOOTLOADER),
1031 .timeout_ms = CY_HID_OUTPUT_START_BOOTLOADER_TIMEOUT,
1032 .reset_expected = 1,
1033 };
1034
1035 return cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1036 }
1037
cyttsp5_hid_output_start_bootloader(struct cyttsp5_core_data * cd)1038 static int cyttsp5_hid_output_start_bootloader(struct cyttsp5_core_data *cd)
1039 {
1040 int rc;
1041
1042 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
1043 if (rc < 0) {
1044 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
1045 __func__, cd->exclusive_dev, cd->dev);
1046 return rc;
1047 }
1048
1049 rc = cyttsp5_hid_output_start_bootloader_(cd);
1050
1051 if (release_exclusive(cd, cd->dev) < 0)
1052 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
1053
1054 return rc;
1055 }
1056
_cyttsp5_request_hid_output_start_bl(struct device * dev,int protect)1057 static int _cyttsp5_request_hid_output_start_bl(struct device *dev, int protect)
1058 {
1059 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
1060
1061 if (protect)
1062 return cyttsp5_hid_output_start_bootloader(cd);
1063
1064 return cyttsp5_hid_output_start_bootloader_(cd);
1065 }
1066
cyttsp5_si_get_cydata(struct cyttsp5_core_data * cd)1067 static void cyttsp5_si_get_cydata(struct cyttsp5_core_data *cd)
1068 {
1069 struct cyttsp5_cydata *cydata = &cd->sysinfo.cydata;
1070 struct cyttsp5_cydata_dev *cydata_dev =
1071 (struct cyttsp5_cydata_dev *)
1072 &cd->response_buf[HID_SYSINFO_CYDATA_OFFSET];
1073
1074 cydata->pip_ver_major = cydata_dev->pip_ver_major;
1075 cydata->pip_ver_minor = cydata_dev->pip_ver_minor;
1076 cydata->bl_ver_major = cydata_dev->bl_ver_major;
1077 cydata->bl_ver_minor = cydata_dev->bl_ver_minor;
1078 cydata->fw_ver_major = cydata_dev->fw_ver_major;
1079 cydata->fw_ver_minor = cydata_dev->fw_ver_minor;
1080
1081 cydata->fw_pid = get_unaligned_le16(&cydata_dev->fw_pid);
1082 cydata->fw_ver_conf = get_unaligned_le16(&cydata_dev->fw_ver_conf);
1083 cydata->post_code = get_unaligned_le16(&cydata_dev->post_code);
1084 cydata->revctrl = get_unaligned_le32(&cydata_dev->revctrl);
1085 cydata->jtag_id_l = get_unaligned_le16(&cydata_dev->jtag_si_id_l);
1086 cydata->jtag_id_h = get_unaligned_le16(&cydata_dev->jtag_si_id_h);
1087
1088 memcpy(cydata->mfg_id, cydata_dev->mfg_id, CY_NUM_MFGID);
1089
1090 cyttsp5_pr_buf(cd->dev, (u8 *)cydata_dev,
1091 sizeof(struct cyttsp5_cydata_dev), "sysinfo_cydata");
1092 }
1093
cyttsp5_si_get_sensing_conf_data(struct cyttsp5_core_data * cd)1094 static void cyttsp5_si_get_sensing_conf_data(struct cyttsp5_core_data *cd)
1095 {
1096 struct cyttsp5_sensing_conf_data *scd = &cd->sysinfo.sensing_conf_data;
1097 struct cyttsp5_sensing_conf_data_dev *scd_dev =
1098 (struct cyttsp5_sensing_conf_data_dev *)
1099 &cd->response_buf[HID_SYSINFO_SENSING_OFFSET];
1100
1101 scd->electrodes_x = scd_dev->electrodes_x;
1102 scd->electrodes_y = scd_dev->electrodes_y;
1103 scd->origin_x = scd_dev->origin_x;
1104 scd->origin_y = scd_dev->origin_y;
1105
1106 /* PIP 1.4 (001-82649 *Q) add X_IS_TX bit in X_ORG */
1107 if (scd->origin_x & 0x02) {
1108 scd->tx_num = scd->electrodes_x;
1109 scd->rx_num = scd->electrodes_y;
1110 } else {
1111 scd->tx_num = scd->electrodes_y;
1112 scd->rx_num = scd->electrodes_x;
1113 }
1114
1115 scd->panel_id = scd_dev->panel_id;
1116 scd->btn = scd_dev->btn;
1117 scd->scan_mode = scd_dev->scan_mode;
1118 scd->max_tch = scd_dev->max_num_of_tch_per_refresh_cycle;
1119
1120 scd->res_x = get_unaligned_le16(&scd_dev->res_x);
1121 scd->res_y = get_unaligned_le16(&scd_dev->res_y);
1122 scd->max_z = get_unaligned_le16(&scd_dev->max_z);
1123 scd->len_x = get_unaligned_le16(&scd_dev->len_x);
1124 scd->len_y = get_unaligned_le16(&scd_dev->len_y);
1125
1126 cyttsp5_pr_buf(cd->dev, (u8 *)scd_dev,
1127 sizeof(struct cyttsp5_sensing_conf_data_dev),
1128 "sensing_conf_data");
1129 }
1130
cyttsp5_si_setup(struct cyttsp5_core_data * cd)1131 static int cyttsp5_si_setup(struct cyttsp5_core_data *cd)
1132 {
1133 struct cyttsp5_sysinfo *si = &cd->sysinfo;
1134 int max_tch = si->sensing_conf_data.max_tch;
1135
1136 if (!si->xy_data)
1137 si->xy_data = kzalloc(max_tch * si->desc.tch_record_size,
1138 GFP_KERNEL);
1139 if (!si->xy_data)
1140 return -ENOMEM;
1141
1142 if (!si->xy_mode)
1143 si->xy_mode = kzalloc(si->desc.tch_header_size, GFP_KERNEL);
1144 if (!si->xy_mode) {
1145 kfree(si->xy_data);
1146 return -ENOMEM;
1147 }
1148
1149 return 0;
1150 }
1151
cyttsp5_si_get_btn_data(struct cyttsp5_core_data * cd)1152 static int cyttsp5_si_get_btn_data(struct cyttsp5_core_data *cd)
1153 {
1154 struct cyttsp5_sysinfo *si = &cd->sysinfo;
1155 int num_btns = 0;
1156 int num_defined_keys;
1157 u16 *key_table;
1158 int btn;
1159 int i;
1160 int rc = 0;
1161 unsigned int btns = cd->response_buf[HID_SYSINFO_BTN_OFFSET]
1162 & HID_SYSINFO_BTN_MASK;
1163 size_t btn_keys_size;
1164
1165 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: get btn data\n", __func__);
1166
1167 for (i = 0; i < HID_SYSINFO_MAX_BTN; i++) {
1168 if (btns & (1 << i))
1169 num_btns++;
1170 }
1171 si->num_btns = num_btns;
1172
1173 if (num_btns) {
1174 btn_keys_size = num_btns * sizeof(struct cyttsp5_btn);
1175 if (!si->btn)
1176 si->btn = kzalloc(btn_keys_size, GFP_KERNEL);
1177 if (!si->btn)
1178 return -ENOMEM;
1179
1180 if (cd->cpdata->sett[CY_IC_GRPNUM_BTN_KEYS] == NULL)
1181 num_defined_keys = 0;
1182 else if (cd->cpdata->sett[CY_IC_GRPNUM_BTN_KEYS]->data == NULL)
1183 num_defined_keys = 0;
1184 else
1185 num_defined_keys = cd->cpdata->sett
1186 [CY_IC_GRPNUM_BTN_KEYS]->size;
1187
1188 for (btn = 0; btn < num_btns && btn < num_defined_keys; btn++) {
1189 key_table = (u16 *)cd->cpdata->sett
1190 [CY_IC_GRPNUM_BTN_KEYS]->data;
1191 si->btn[btn].key_code = key_table[btn];
1192 si->btn[btn].enabled = true;
1193 }
1194 for (; btn < num_btns; btn++) {
1195 si->btn[btn].key_code = KEY_RESERVED;
1196 si->btn[btn].enabled = true;
1197 }
1198
1199 return rc;
1200 }
1201
1202 kfree(si->btn);
1203 si->btn = NULL;
1204 return rc;
1205 }
1206
cyttsp5_si_put_log_data(struct cyttsp5_core_data * cd)1207 static void cyttsp5_si_put_log_data(struct cyttsp5_core_data *cd)
1208 {
1209 struct cyttsp5_sysinfo *si = &cd->sysinfo;
1210 struct cyttsp5_cydata *cydata = &si->cydata;
1211 struct cyttsp5_sensing_conf_data *scd = &si->sensing_conf_data;
1212 int i;
1213
1214 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: pip_ver_major =0x%02X (%d)\n",
1215 __func__, cydata->pip_ver_major, cydata->pip_ver_major);
1216 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: pip_ver_minor =0x%02X (%d)\n",
1217 __func__, cydata->pip_ver_minor, cydata->pip_ver_minor);
1218 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: fw_pid =0x%04X (%d)\n",
1219 __func__, cydata->fw_pid, cydata->fw_pid);
1220 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: fw_ver_major =0x%02X (%d)\n",
1221 __func__, cydata->fw_ver_major, cydata->fw_ver_major);
1222 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: fw_ver_minor =0x%02X (%d)\n",
1223 __func__, cydata->fw_ver_minor, cydata->fw_ver_minor);
1224 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: revctrl =0x%08X (%d)\n",
1225 __func__, cydata->revctrl, cydata->revctrl);
1226 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: fw_ver_conf =0x%04X (%d)\n",
1227 __func__, cydata->fw_ver_conf, cydata->fw_ver_conf);
1228 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: bl_ver_major =0x%02X (%d)\n",
1229 __func__, cydata->bl_ver_major, cydata->bl_ver_major);
1230 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: bl_ver_minor =0x%02X (%d)\n",
1231 __func__, cydata->bl_ver_minor, cydata->bl_ver_minor);
1232 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: jtag_id_h =0x%04X (%d)\n",
1233 __func__, cydata->jtag_id_h, cydata->jtag_id_h);
1234 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: jtag_id_l =0x%04X (%d)\n",
1235 __func__, cydata->jtag_id_l, cydata->jtag_id_l);
1236 for (i = 0; i < CY_NUM_MFGID; i++)
1237 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: mfg_id[%d] =0x%02X (%d)\n",
1238 __func__, i, cydata->mfg_id[i], cydata->mfg_id[i]);
1239 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: post_code =0x%04X (%d)\n",
1240 __func__, cydata->post_code, cydata->post_code);
1241
1242 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: electrodes_x =0x%02X (%d)\n",
1243 __func__, scd->electrodes_x, scd->electrodes_x);
1244 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: electrodes_y =0x%02X (%d)\n",
1245 __func__, scd->electrodes_y, scd->electrodes_y);
1246 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: len_x =0x%04X (%d)\n",
1247 __func__, scd->len_x, scd->len_x);
1248 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: len_y =0x%04X (%d)\n",
1249 __func__, scd->len_y, scd->len_y);
1250 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: res_x =0x%04X (%d)\n",
1251 __func__, scd->res_x, scd->res_x);
1252 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: res_y =0x%04X (%d)\n",
1253 __func__, scd->res_y, scd->res_y);
1254 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: max_z =0x%04X (%d)\n",
1255 __func__, scd->max_z, scd->max_z);
1256 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: origin_x =0x%02X (%d)\n",
1257 __func__, scd->origin_x, scd->origin_x);
1258 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: origin_y =0x%02X (%d)\n",
1259 __func__, scd->origin_y, scd->origin_y);
1260 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: panel_id =0x%02X (%d)\n",
1261 __func__, scd->panel_id, scd->panel_id);
1262 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: btn =0x%02X (%d)\n",
1263 __func__, scd->btn, scd->btn);
1264 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: scan_mode =0x%02X (%d)\n",
1265 __func__, scd->scan_mode, scd->scan_mode);
1266 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: max_num_of_tch_per_refresh_cycle =0x%02X (%d)\n",
1267 __func__, scd->max_tch, scd->max_tch);
1268 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: xy_mode =%p\n",
1269 __func__, si->xy_mode);
1270 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: xy_data =%p\n",
1271 __func__, si->xy_data);
1272 }
1273
cyttsp5_get_sysinfo_regs(struct cyttsp5_core_data * cd)1274 static int cyttsp5_get_sysinfo_regs(struct cyttsp5_core_data *cd)
1275 {
1276 struct cyttsp5_sysinfo *si = &cd->sysinfo;
1277 int rc;
1278
1279 rc = cyttsp5_si_get_btn_data(cd);
1280 if (rc < 0)
1281 return rc;
1282
1283 cyttsp5_si_get_cydata(cd);
1284
1285 cyttsp5_si_get_sensing_conf_data(cd);
1286
1287 cyttsp5_si_setup(cd);
1288
1289 cyttsp5_si_put_log_data(cd);
1290
1291 si->ready = true;
1292 return rc;
1293 }
1294
cyttsp5_free_si_ptrs(struct cyttsp5_core_data * cd)1295 static void cyttsp5_free_si_ptrs(struct cyttsp5_core_data *cd)
1296 {
1297 struct cyttsp5_sysinfo *si = &cd->sysinfo;
1298
1299 kfree(si->btn);
1300 kfree(si->xy_mode);
1301 kfree(si->xy_data);
1302 }
1303
cyttsp5_hid_output_get_sysinfo_(struct cyttsp5_core_data * cd)1304 static int cyttsp5_hid_output_get_sysinfo_(struct cyttsp5_core_data *cd)
1305 {
1306 int rc;
1307 struct cyttsp5_hid_output hid_output = {
1308 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_GET_SYSINFO),
1309 .timeout_ms = CY_HID_OUTPUT_GET_SYSINFO_TIMEOUT,
1310 };
1311
1312 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1313 if (rc)
1314 return rc;
1315
1316 rc = cyttsp5_get_sysinfo_regs(cd);
1317 if (rc)
1318 cyttsp5_free_si_ptrs(cd);
1319
1320 return rc;
1321 }
1322
cyttsp5_hid_output_get_sysinfo(struct cyttsp5_core_data * cd)1323 static int cyttsp5_hid_output_get_sysinfo(struct cyttsp5_core_data *cd)
1324 {
1325 int rc;
1326
1327 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
1328 if (rc < 0) {
1329 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
1330 __func__, cd->exclusive_dev, cd->dev);
1331 return rc;
1332 }
1333
1334 rc = cyttsp5_hid_output_get_sysinfo_(cd);
1335
1336 if (release_exclusive(cd, cd->dev) < 0)
1337 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
1338
1339 return rc;
1340 }
1341
cyttsp5_hid_output_suspend_scanning_(struct cyttsp5_core_data * cd)1342 static int cyttsp5_hid_output_suspend_scanning_(struct cyttsp5_core_data *cd)
1343 {
1344 struct cyttsp5_hid_output hid_output = {
1345 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_SUSPEND_SCANNING),
1346 .timeout_ms = 1000,
1347 };
1348
1349 return cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1350 }
1351
cyttsp5_hid_output_suspend_scanning(struct cyttsp5_core_data * cd)1352 static int cyttsp5_hid_output_suspend_scanning(struct cyttsp5_core_data *cd)
1353 {
1354 int rc;
1355
1356 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
1357 if (rc < 0) {
1358 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
1359 __func__, cd->exclusive_dev, cd->dev);
1360 return rc;
1361 }
1362
1363 rc = cyttsp5_hid_output_suspend_scanning_(cd);
1364
1365 if (release_exclusive(cd, cd->dev) < 0)
1366 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
1367
1368 return rc;
1369 }
1370
_cyttsp5_request_hid_output_suspend_scanning(struct device * dev,int protect)1371 static int _cyttsp5_request_hid_output_suspend_scanning(struct device *dev,
1372 int protect)
1373 {
1374 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
1375
1376 if (protect)
1377 return cyttsp5_hid_output_suspend_scanning(cd);
1378
1379 return cyttsp5_hid_output_suspend_scanning_(cd);
1380 }
1381
cyttsp5_hid_output_resume_scanning_(struct cyttsp5_core_data * cd)1382 static int cyttsp5_hid_output_resume_scanning_(struct cyttsp5_core_data *cd)
1383 {
1384 struct cyttsp5_hid_output hid_output = {
1385 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_RESUME_SCANNING),
1386 };
1387
1388 return cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1389 }
1390
cyttsp5_hid_output_resume_scanning(struct cyttsp5_core_data * cd)1391 static int cyttsp5_hid_output_resume_scanning(struct cyttsp5_core_data *cd)
1392 {
1393 int rc;
1394
1395 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
1396 if (rc < 0) {
1397 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
1398 __func__, cd->exclusive_dev, cd->dev);
1399 return rc;
1400 }
1401
1402 rc = cyttsp5_hid_output_resume_scanning_(cd);
1403
1404 if (release_exclusive(cd, cd->dev) < 0)
1405 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
1406
1407 return rc;
1408 }
1409
_cyttsp5_request_hid_output_resume_scanning(struct device * dev,int protect)1410 static int _cyttsp5_request_hid_output_resume_scanning(struct device *dev,
1411 int protect)
1412 {
1413 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
1414
1415 if (protect)
1416 return cyttsp5_hid_output_resume_scanning(cd);
1417
1418 return cyttsp5_hid_output_resume_scanning_(cd);
1419 }
1420
cyttsp5_hid_output_get_param_(struct cyttsp5_core_data * cd,u8 param_id,u32 * value)1421 static int cyttsp5_hid_output_get_param_(struct cyttsp5_core_data *cd,
1422 u8 param_id, u32 *value)
1423 {
1424 int write_length = 1;
1425 u8 param[1] = { param_id };
1426 u8 read_param_id;
1427 int param_size;
1428 u8 *ptr;
1429 int rc;
1430 int i;
1431 struct cyttsp5_hid_output hid_output = {
1432 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_GET_PARAM),
1433 .write_length = write_length,
1434 .write_buf = param,
1435 };
1436
1437 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1438 if (rc)
1439 return rc;
1440
1441 read_param_id = cd->response_buf[5];
1442 if (read_param_id != param_id)
1443 return -EPROTO;
1444
1445 param_size = cd->response_buf[6];
1446 ptr = &cd->response_buf[7];
1447 *value = 0;
1448 for (i = 0; i < param_size; i++)
1449 *value += ptr[i] << (i * 8);
1450 return 0;
1451 }
1452
cyttsp5_hid_output_get_param(struct cyttsp5_core_data * cd,u8 param_id,u32 * value)1453 static int cyttsp5_hid_output_get_param(struct cyttsp5_core_data *cd,
1454 u8 param_id, u32 *value)
1455 {
1456 int rc;
1457
1458 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
1459 if (rc < 0) {
1460 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
1461 __func__, cd->exclusive_dev, cd->dev);
1462 return rc;
1463 }
1464
1465 rc = cyttsp5_hid_output_get_param_(cd, param_id, value);
1466
1467 if (release_exclusive(cd, cd->dev) < 0)
1468 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
1469
1470 return rc;
1471 }
1472
_cyttsp5_request_hid_output_get_param(struct device * dev,int protect,u8 param_id,u32 * value)1473 int _cyttsp5_request_hid_output_get_param(struct device *dev,
1474 int protect, u8 param_id, u32 *value)
1475 {
1476 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
1477
1478 if (protect)
1479 return cyttsp5_hid_output_get_param(cd, param_id, value);
1480
1481 return cyttsp5_hid_output_get_param_(cd, param_id, value);
1482 }
1483
cyttsp5_hid_output_set_param_(struct cyttsp5_core_data * cd,u8 param_id,u32 value,u8 size)1484 static int cyttsp5_hid_output_set_param_(struct cyttsp5_core_data *cd,
1485 u8 param_id, u32 value, u8 size)
1486 {
1487 u8 write_buf[6];
1488 u8 *ptr = &write_buf[2];
1489 int rc;
1490 int i;
1491 struct cyttsp5_hid_output hid_output = {
1492 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_SET_PARAM),
1493 .write_buf = write_buf,
1494 };
1495
1496 write_buf[0] = param_id;
1497 write_buf[1] = size;
1498 for (i = 0; i < size; i++) {
1499 ptr[i] = value & 0xFF;
1500 value = value >> 8;
1501 }
1502
1503 hid_output.write_length = 2 + size;
1504
1505 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1506 if (rc)
1507 return rc;
1508
1509 if (param_id != cd->response_buf[5] || size != cd->response_buf[6])
1510 return -EPROTO;
1511
1512 return 0;
1513 }
1514
cyttsp5_hid_output_set_param(struct cyttsp5_core_data * cd,u8 param_id,u32 value,u8 size)1515 static int cyttsp5_hid_output_set_param(struct cyttsp5_core_data *cd,
1516 u8 param_id, u32 value, u8 size)
1517 {
1518 int rc;
1519
1520 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
1521 if (rc < 0) {
1522 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
1523 __func__, cd->exclusive_dev, cd->dev);
1524 return rc;
1525 }
1526
1527 rc = cyttsp5_hid_output_set_param_(cd, param_id, value, size);
1528
1529 if (release_exclusive(cd, cd->dev) < 0)
1530 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
1531
1532 return rc;
1533 }
1534
_cyttsp5_request_hid_output_set_param(struct device * dev,int protect,u8 param_id,u32 value,u8 size)1535 int _cyttsp5_request_hid_output_set_param(struct device *dev,
1536 int protect, u8 param_id, u32 value, u8 size)
1537 {
1538 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
1539
1540 if (protect)
1541 return cyttsp5_hid_output_set_param(cd, param_id, value, size);
1542
1543 return cyttsp5_hid_output_set_param_(cd, param_id, value, size);
1544 }
1545
cyttsp5_hid_output_enter_easywake_state_(struct cyttsp5_core_data * cd,u8 data,u8 * return_data)1546 static int cyttsp5_hid_output_enter_easywake_state_(
1547 struct cyttsp5_core_data *cd, u8 data, u8 *return_data)
1548 {
1549 int write_length = 1;
1550 u8 param[1] = { data };
1551 int rc;
1552 struct cyttsp5_hid_output hid_output = {
1553 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_ENTER_EASYWAKE_STATE),
1554 .write_length = write_length,
1555 .write_buf = param,
1556 };
1557
1558 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1559 if (rc)
1560 return rc;
1561
1562 *return_data = cd->response_buf[5];
1563 return rc;
1564 }
1565
cyttsp5_hid_output_verify_config_block_crc_(struct cyttsp5_core_data * cd,u8 ebid,u8 * status,u16 * calculated_crc,u16 * stored_crc)1566 static int cyttsp5_hid_output_verify_config_block_crc_(
1567 struct cyttsp5_core_data *cd, u8 ebid, u8 *status,
1568 u16 *calculated_crc, u16 *stored_crc)
1569 {
1570 int write_length = 1;
1571 u8 param[1] = { ebid };
1572 u8 *ptr;
1573 int rc;
1574 struct cyttsp5_hid_output hid_output = {
1575 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_VERIFY_CONFIG_BLOCK_CRC),
1576 .write_length = write_length,
1577 .write_buf = param,
1578 .timeout_ms = 1000,
1579 };
1580
1581 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1582 if (rc)
1583 return rc;
1584
1585 ptr = &cd->response_buf[5];
1586 *status = ptr[0];
1587 *calculated_crc = get_unaligned_le16(&ptr[1]);
1588 *stored_crc = get_unaligned_le16(&ptr[3]);
1589 return 0;
1590 }
1591
cyttsp5_hid_output_verify_config_block_crc(struct cyttsp5_core_data * cd,u8 ebid,u8 * status,u16 * calculated_crc,u16 * stored_crc)1592 static int cyttsp5_hid_output_verify_config_block_crc(
1593 struct cyttsp5_core_data *cd, u8 ebid, u8 *status,
1594 u16 *calculated_crc, u16 *stored_crc)
1595 {
1596 int rc;
1597
1598 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
1599 if (rc < 0) {
1600 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
1601 __func__, cd->exclusive_dev, cd->dev);
1602 return rc;
1603 }
1604
1605 rc = cyttsp5_hid_output_verify_config_block_crc_(cd, ebid, status,
1606 calculated_crc, stored_crc);
1607
1608 if (release_exclusive(cd, cd->dev) < 0)
1609 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
1610
1611 return rc;
1612 }
1613
_cyttsp5_request_hid_output_verify_config_block_crc(struct device * dev,int protect,u8 ebid,u8 * status,u16 * calculated_crc,u16 * stored_crc)1614 static int _cyttsp5_request_hid_output_verify_config_block_crc(
1615 struct device *dev, int protect, u8 ebid, u8 *status,
1616 u16 *calculated_crc, u16 *stored_crc)
1617 {
1618 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
1619
1620 if (protect)
1621 return cyttsp5_hid_output_verify_config_block_crc(cd, ebid,
1622 status, calculated_crc, stored_crc);
1623
1624 return cyttsp5_hid_output_verify_config_block_crc_(cd, ebid,
1625 status, calculated_crc, stored_crc);
1626 }
1627
cyttsp5_hid_output_get_config_row_size_(struct cyttsp5_core_data * cd,u16 * row_size)1628 static int cyttsp5_hid_output_get_config_row_size_(struct cyttsp5_core_data *cd,
1629 u16 *row_size)
1630 {
1631 int rc;
1632 struct cyttsp5_hid_output hid_output = {
1633 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_GET_CONFIG_ROW_SIZE),
1634 };
1635
1636 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1637 if (rc)
1638 return rc;
1639
1640 *row_size = get_unaligned_le16(&cd->response_buf[5]);
1641 return 0;
1642 }
1643
cyttsp5_hid_output_get_config_row_size(struct cyttsp5_core_data * cd,u16 * row_size)1644 static int cyttsp5_hid_output_get_config_row_size(struct cyttsp5_core_data *cd,
1645 u16 *row_size)
1646 {
1647 int rc;
1648
1649 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
1650 if (rc < 0) {
1651 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
1652 __func__, cd->exclusive_dev, cd->dev);
1653 return rc;
1654 }
1655
1656 rc = cyttsp5_hid_output_get_config_row_size_(cd, row_size);
1657
1658 if (release_exclusive(cd, cd->dev) < 0)
1659 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
1660
1661 return rc;
1662 }
1663
_cyttsp5_request_hid_output_get_config_row_size(struct device * dev,int protect,u16 * row_size)1664 static int _cyttsp5_request_hid_output_get_config_row_size(struct device *dev,
1665 int protect, u16 *row_size)
1666 {
1667 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
1668
1669 if (protect)
1670 return cyttsp5_hid_output_get_config_row_size(cd, row_size);
1671
1672 return cyttsp5_hid_output_get_config_row_size_(cd, row_size);
1673 }
1674
cyttsp5_hid_output_read_conf_block_(struct cyttsp5_core_data * cd,u16 row_number,u16 length,u8 ebid,u8 * read_buf,u16 * crc)1675 static int cyttsp5_hid_output_read_conf_block_(struct cyttsp5_core_data *cd,
1676 u16 row_number, u16 length, u8 ebid, u8 *read_buf, u16 *crc)
1677 {
1678 int read_ebid;
1679 int read_length;
1680 int status;
1681 int rc;
1682 int write_length = 5;
1683 u8 write_buf[5];
1684 u8 cmd_offset = 0;
1685 struct cyttsp5_hid_output hid_output = {
1686 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_READ_CONF_BLOCK),
1687 .write_length = write_length,
1688 .write_buf = write_buf,
1689 };
1690
1691 write_buf[cmd_offset++] = LOW_BYTE(row_number);
1692 write_buf[cmd_offset++] = HI_BYTE(row_number);
1693 write_buf[cmd_offset++] = LOW_BYTE(length);
1694 write_buf[cmd_offset++] = HI_BYTE(length);
1695 write_buf[cmd_offset++] = ebid;
1696
1697 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1698 if (rc)
1699 return rc;
1700
1701 status = cd->response_buf[5];
1702 if (status)
1703 return -EINVAL;
1704
1705 read_ebid = cd->response_buf[6];
1706 if ((read_ebid != ebid) || (cd->response_buf[9] != 0))
1707 return -EPROTO;
1708
1709 read_length = get_unaligned_le16(&cd->response_buf[7]);
1710 if (length < read_length)
1711 length = read_length;
1712
1713 memcpy(read_buf, &cd->response_buf[10], length);
1714 *crc = get_unaligned_le16(&cd->response_buf[read_length + 10]);
1715
1716 return 0;
1717 }
1718
cyttsp5_hid_output_read_conf_ver_(struct cyttsp5_core_data * cd,u16 * config_ver)1719 static int cyttsp5_hid_output_read_conf_ver_(struct cyttsp5_core_data *cd,
1720 u16 *config_ver)
1721 {
1722 int rc;
1723 u8 read_buf[CY_TTCONFIG_VERSION_OFFSET + CY_TTCONFIG_VERSION_SIZE];
1724 u16 crc;
1725
1726 rc = cyttsp5_hid_output_read_conf_block_(cd, CY_TTCONFIG_VERSION_ROW,
1727 CY_TTCONFIG_VERSION_OFFSET + CY_TTCONFIG_VERSION_SIZE,
1728 CY_TCH_PARM_EBID, read_buf, &crc);
1729 if (rc)
1730 return rc;
1731
1732 *config_ver = get_unaligned_le16(
1733 &read_buf[CY_TTCONFIG_VERSION_OFFSET]);
1734
1735 return 0;
1736 }
1737
cyttsp5_hid_output_write_conf_block_(struct cyttsp5_core_data * cd,u16 row_number,u16 write_length,u8 ebid,u8 * write_buf,u8 * security_key,u16 * actual_write_len)1738 static int cyttsp5_hid_output_write_conf_block_(struct cyttsp5_core_data *cd,
1739 u16 row_number, u16 write_length, u8 ebid, u8 *write_buf,
1740 u8 *security_key, u16 *actual_write_len)
1741 {
1742 /* row_number + write_len + ebid + security_key + crc */
1743 int full_write_length = 2 + 2 + 1 + write_length + 8 + 2;
1744 u8 *full_write_buf;
1745 u8 cmd_offset = 0;
1746 u16 crc;
1747 int status;
1748 int rc;
1749 int read_ebid;
1750 u8 *data;
1751 struct cyttsp5_hid_output hid_output = {
1752 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_WRITE_CONF_BLOCK),
1753 .write_length = full_write_length,
1754 .timeout_ms = CY_HID_OUTPUT_WRITE_CONF_BLOCK_TIMEOUT,
1755 };
1756
1757 full_write_buf = kzalloc(full_write_length, GFP_KERNEL);
1758 if (!full_write_buf)
1759 return -ENOMEM;
1760
1761 hid_output.write_buf = full_write_buf;
1762 full_write_buf[cmd_offset++] = LOW_BYTE(row_number);
1763 full_write_buf[cmd_offset++] = HI_BYTE(row_number);
1764 full_write_buf[cmd_offset++] = LOW_BYTE(write_length);
1765 full_write_buf[cmd_offset++] = HI_BYTE(write_length);
1766 full_write_buf[cmd_offset++] = ebid;
1767 data = &full_write_buf[cmd_offset];
1768 memcpy(data, write_buf, write_length);
1769 cmd_offset += write_length;
1770 memcpy(&full_write_buf[cmd_offset], security_key, 8);
1771 cmd_offset += 8;
1772 crc = _cyttsp5_compute_crc(data, write_length);
1773 full_write_buf[cmd_offset++] = LOW_BYTE(crc);
1774 full_write_buf[cmd_offset++] = HI_BYTE(crc);
1775
1776 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1777 if (rc)
1778 goto exit;
1779
1780 status = cd->response_buf[5];
1781 if (status) {
1782 rc = -EINVAL;
1783 goto exit;
1784 }
1785
1786 read_ebid = cd->response_buf[6];
1787 if (read_ebid != ebid) {
1788 rc = -EPROTO;
1789 goto exit;
1790 }
1791
1792 *actual_write_len = get_unaligned_le16(&cd->response_buf[7]);
1793
1794 exit:
1795 kfree(full_write_buf);
1796 return rc;
1797 }
1798
cyttsp5_hid_output_write_conf_block(struct cyttsp5_core_data * cd,u16 row_number,u16 write_length,u8 ebid,u8 * write_buf,u8 * security_key,u16 * actual_write_len)1799 static int cyttsp5_hid_output_write_conf_block(struct cyttsp5_core_data *cd,
1800 u16 row_number, u16 write_length, u8 ebid, u8 *write_buf,
1801 u8 *security_key, u16 *actual_write_len)
1802 {
1803 int rc;
1804
1805 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
1806 if (rc < 0) {
1807 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
1808 __func__, cd->exclusive_dev, cd->dev);
1809 return rc;
1810 }
1811
1812 rc = cyttsp5_hid_output_write_conf_block_(cd, row_number, write_length,
1813 ebid, write_buf, security_key, actual_write_len);
1814
1815 if (release_exclusive(cd, cd->dev) < 0)
1816 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
1817
1818 return rc;
1819 }
1820
_cyttsp5_request_hid_output_write_conf_block(struct device * dev,int protect,u16 row_number,u16 write_length,u8 ebid,u8 * write_buf,u8 * security_key,u16 * actual_write_len)1821 static int _cyttsp5_request_hid_output_write_conf_block(struct device *dev,
1822 int protect, u16 row_number, u16 write_length, u8 ebid,
1823 u8 *write_buf, u8 *security_key, u16 *actual_write_len)
1824 {
1825 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
1826
1827 if (protect)
1828 return cyttsp5_hid_output_write_conf_block(cd, row_number,
1829 write_length, ebid, write_buf, security_key,
1830 actual_write_len);
1831
1832 return cyttsp5_hid_output_write_conf_block_(cd, row_number,
1833 write_length, ebid, write_buf, security_key,
1834 actual_write_len);
1835 }
1836
cyttsp5_hid_output_get_data_structure_(struct cyttsp5_core_data * cd,u16 read_offset,u16 read_length,u8 data_id,u8 * status,u8 * data_format,u16 * actual_read_len,u8 * data)1837 static int cyttsp5_hid_output_get_data_structure_(
1838 struct cyttsp5_core_data *cd, u16 read_offset, u16 read_length,
1839 u8 data_id, u8 *status, u8 *data_format, u16 *actual_read_len,
1840 u8 *data)
1841 {
1842 int rc;
1843 u16 total_read_len = 0;
1844 u16 read_len;
1845 u16 off_buf = 0;
1846 u8 write_buf[5];
1847 u8 read_data_id;
1848 struct cyttsp5_hid_output hid_output = {
1849 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_GET_DATA_STRUCTURE),
1850 .write_length = 5,
1851 .write_buf = write_buf,
1852 };
1853
1854 again:
1855 write_buf[0] = LOW_BYTE(read_offset);
1856 write_buf[1] = HI_BYTE(read_offset);
1857 write_buf[2] = LOW_BYTE(read_length);
1858 write_buf[3] = HI_BYTE(read_length);
1859 write_buf[4] = data_id;
1860
1861 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1862 if (rc)
1863 return rc;
1864
1865 if (cd->response_buf[5] != CY_CMD_STATUS_SUCCESS)
1866 goto set_status;
1867
1868 read_data_id = cd->response_buf[6];
1869 if (read_data_id != data_id)
1870 return -EPROTO;
1871
1872 read_len = get_unaligned_le16(&cd->response_buf[7]);
1873 if (read_len && data) {
1874 memcpy(&data[off_buf], &cd->response_buf[10], read_len);
1875
1876 total_read_len += read_len;
1877
1878 if (read_len < read_length) {
1879 read_offset += read_len;
1880 off_buf += read_len;
1881 read_length -= read_len;
1882 goto again;
1883 }
1884 }
1885
1886 if (data_format)
1887 *data_format = cd->response_buf[9];
1888 if (actual_read_len)
1889 *actual_read_len = total_read_len;
1890 set_status:
1891 if (status)
1892 *status = cd->response_buf[5];
1893
1894 return rc;
1895 }
1896
cyttsp5_hid_output_get_data_structure(struct cyttsp5_core_data * cd,u16 read_offset,u16 read_length,u8 data_id,u8 * status,u8 * data_format,u16 * actual_read_len,u8 * data)1897 static int cyttsp5_hid_output_get_data_structure(
1898 struct cyttsp5_core_data *cd, u16 read_offset, u16 read_length,
1899 u8 data_id, u8 *status, u8 *data_format, u16 *actual_read_len,
1900 u8 *data)
1901 {
1902 int rc;
1903
1904 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
1905 if (rc < 0) {
1906 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
1907 __func__, cd->exclusive_dev, cd->dev);
1908 return rc;
1909 }
1910
1911 rc = cyttsp5_hid_output_get_data_structure_(cd, read_offset,
1912 read_length, data_id, status, data_format,
1913 actual_read_len, data);
1914
1915 if (release_exclusive(cd, cd->dev) < 0)
1916 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
1917
1918 return rc;
1919 }
1920
_cyttsp5_request_hid_output_get_data_structure(struct device * dev,int protect,u16 read_offset,u16 read_length,u8 data_id,u8 * status,u8 * data_format,u16 * actual_read_len,u8 * data)1921 static int _cyttsp5_request_hid_output_get_data_structure(struct device *dev,
1922 int protect, u16 read_offset, u16 read_length, u8 data_id,
1923 u8 *status, u8 *data_format, u16 *actual_read_len, u8 *data)
1924 {
1925 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
1926
1927 if (protect)
1928 return cyttsp5_hid_output_get_data_structure(cd,
1929 read_offset, read_length, data_id, status,
1930 data_format, actual_read_len, data);
1931
1932 return cyttsp5_hid_output_get_data_structure_(cd,
1933 read_offset, read_length, data_id, status,
1934 data_format, actual_read_len, data);
1935 }
1936
cyttsp5_hid_output_run_selftest_(struct cyttsp5_core_data * cd,u8 test_id,u8 write_idacs_to_flash,u8 * status,u8 * summary_result,u8 * results_available)1937 static int cyttsp5_hid_output_run_selftest_(
1938 struct cyttsp5_core_data *cd, u8 test_id,
1939 u8 write_idacs_to_flash, u8 *status, u8 *summary_result,
1940 u8 *results_available)
1941 {
1942 int rc;
1943 u8 write_buf[2];
1944 struct cyttsp5_hid_output hid_output = {
1945 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_RUN_SELF_TEST),
1946 .write_length = 2,
1947 .write_buf = write_buf,
1948 .timeout_ms = CY_HID_OUTPUT_RUN_SELF_TEST_TIMEOUT,
1949 };
1950
1951 write_buf[0] = test_id;
1952 write_buf[1] = write_idacs_to_flash;
1953
1954 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
1955 if (rc)
1956 return rc;
1957
1958 if (status)
1959 *status = cd->response_buf[5];
1960 if (summary_result)
1961 *summary_result = cd->response_buf[6];
1962 if (results_available)
1963 *results_available = cd->response_buf[7];
1964
1965 return rc;
1966 }
1967
cyttsp5_hid_output_run_selftest(struct cyttsp5_core_data * cd,u8 test_id,u8 write_idacs_to_flash,u8 * status,u8 * summary_result,u8 * results_available)1968 static int cyttsp5_hid_output_run_selftest(
1969 struct cyttsp5_core_data *cd, u8 test_id,
1970 u8 write_idacs_to_flash, u8 *status, u8 *summary_result,
1971 u8 *results_available)
1972 {
1973 int rc;
1974
1975 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
1976 if (rc < 0) {
1977 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
1978 __func__, cd->exclusive_dev, cd->dev);
1979 return rc;
1980 }
1981
1982 rc = cyttsp5_hid_output_run_selftest_(cd, test_id,
1983 write_idacs_to_flash, status, summary_result,
1984 results_available);
1985
1986 if (release_exclusive(cd, cd->dev) < 0)
1987 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
1988
1989 return rc;
1990 }
1991
_cyttsp5_request_hid_output_run_selftest(struct device * dev,int protect,u8 test_id,u8 write_idacs_to_flash,u8 * status,u8 * summary_result,u8 * results_available)1992 static int _cyttsp5_request_hid_output_run_selftest(struct device *dev,
1993 int protect, u8 test_id, u8 write_idacs_to_flash, u8 *status,
1994 u8 *summary_result, u8 *results_available)
1995 {
1996 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
1997
1998 if (protect)
1999 return cyttsp5_hid_output_run_selftest(cd, test_id,
2000 write_idacs_to_flash, status, summary_result,
2001 results_available);
2002
2003 return cyttsp5_hid_output_run_selftest_(cd, test_id,
2004 write_idacs_to_flash, status, summary_result,
2005 results_available);
2006 }
2007
cyttsp5_hid_output_get_selftest_result_(struct cyttsp5_core_data * cd,u16 read_offset,u16 read_length,u8 test_id,u8 * status,u16 * actual_read_len,u8 * data)2008 static int cyttsp5_hid_output_get_selftest_result_(
2009 struct cyttsp5_core_data *cd, u16 read_offset, u16 read_length,
2010 u8 test_id, u8 *status, u16 *actual_read_len, u8 *data)
2011 {
2012 int rc;
2013 u16 total_read_len = 0;
2014 u16 read_len;
2015 u16 off_buf = 0;
2016 u8 write_buf[5];
2017 u8 read_test_id;
2018 bool repeat;
2019 struct cyttsp5_hid_output hid_output = {
2020 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_GET_SELF_TEST_RESULT),
2021 .write_length = 5,
2022 .write_buf = write_buf,
2023 };
2024
2025 /*
2026 * Do not repeat reading for Auto Shorts test
2027 * when PIP version < 1.3
2028 */
2029 repeat = IS_PIP_VER_GE(&cd->sysinfo, 1, 3)
2030 || test_id != CY_ST_ID_AUTOSHORTS;
2031
2032 again:
2033 write_buf[0] = LOW_BYTE(read_offset);
2034 write_buf[1] = HI_BYTE(read_offset);
2035 write_buf[2] = LOW_BYTE(read_length);
2036 write_buf[3] = HI_BYTE(read_length);
2037 write_buf[4] = test_id;
2038
2039 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
2040 if (rc)
2041 return rc;
2042
2043 if (cd->response_buf[5] != CY_CMD_STATUS_SUCCESS)
2044 goto set_status;
2045
2046 read_test_id = cd->response_buf[6];
2047 if (read_test_id != test_id)
2048 return -EPROTO;
2049
2050 read_len = get_unaligned_le16(&cd->response_buf[7]);
2051 if (read_len && data) {
2052 memcpy(&data[off_buf], &cd->response_buf[10], read_len);
2053
2054 total_read_len += read_len;
2055
2056 if (repeat && read_len < read_length) {
2057 read_offset += read_len;
2058 off_buf += read_len;
2059 read_length -= read_len;
2060 goto again;
2061 }
2062 }
2063
2064 if (actual_read_len)
2065 *actual_read_len = total_read_len;
2066 set_status:
2067 if (status)
2068 *status = cd->response_buf[5];
2069
2070 return rc;
2071 }
2072
cyttsp5_hid_output_get_selftest_result(struct cyttsp5_core_data * cd,u16 read_offset,u16 read_length,u8 test_id,u8 * status,u16 * actual_read_len,u8 * data)2073 static int cyttsp5_hid_output_get_selftest_result(
2074 struct cyttsp5_core_data *cd, u16 read_offset, u16 read_length,
2075 u8 test_id, u8 *status, u16 *actual_read_len, u8 *data)
2076 {
2077 int rc;
2078
2079 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2080 if (rc < 0) {
2081 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2082 __func__, cd->exclusive_dev, cd->dev);
2083 return rc;
2084 }
2085
2086 rc = cyttsp5_hid_output_get_selftest_result_(cd, read_offset,
2087 read_length, test_id, status, actual_read_len, data);
2088
2089 if (release_exclusive(cd, cd->dev) < 0)
2090 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2091
2092 return rc;
2093 }
2094
_cyttsp5_request_hid_output_get_selftest_result(struct device * dev,int protect,u16 read_offset,u16 read_length,u8 test_id,u8 * status,u16 * actual_read_len,u8 * data)2095 static int _cyttsp5_request_hid_output_get_selftest_result(struct device *dev,
2096 int protect, u16 read_offset, u16 read_length, u8 test_id,
2097 u8 *status, u16 *actual_read_len, u8 *data)
2098 {
2099 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2100
2101 if (protect)
2102 return cyttsp5_hid_output_get_selftest_result(cd, read_offset,
2103 read_length, test_id, status, actual_read_len,
2104 data);
2105
2106 return cyttsp5_hid_output_get_selftest_result_(cd, read_offset,
2107 read_length, test_id, status, actual_read_len,
2108 data);
2109 }
2110
cyttsp5_hid_output_calibrate_idacs_(struct cyttsp5_core_data * cd,u8 mode,u8 * status)2111 static int cyttsp5_hid_output_calibrate_idacs_(struct cyttsp5_core_data *cd,
2112 u8 mode, u8 *status)
2113 {
2114 int rc;
2115 int write_length = 1;
2116 u8 write_buf[1];
2117 u8 cmd_offset = 0;
2118 struct cyttsp5_hid_output hid_output = {
2119 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_CALIBRATE_IDACS),
2120 .write_length = write_length,
2121 .write_buf = write_buf,
2122 .timeout_ms = CY_HID_OUTPUT_CALIBRATE_IDAC_TIMEOUT,
2123 };
2124
2125 write_buf[cmd_offset++] = mode;
2126 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
2127 if (rc)
2128 return rc;
2129
2130 *status = cd->response_buf[5];
2131 if (*status)
2132 return -EINVAL;
2133
2134 return 0;
2135 }
2136
cyttsp5_hid_output_calibrate_idacs(struct cyttsp5_core_data * cd,u8 mode,u8 * status)2137 static int cyttsp5_hid_output_calibrate_idacs(struct cyttsp5_core_data *cd,
2138 u8 mode, u8 *status)
2139 {
2140 int rc;
2141
2142 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2143 if (rc < 0) {
2144 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2145 __func__, cd->exclusive_dev, cd->dev);
2146 return rc;
2147 }
2148
2149 rc = cyttsp5_hid_output_calibrate_idacs_(cd, mode, status);
2150
2151 if (release_exclusive(cd, cd->dev) < 0)
2152 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2153
2154 return rc;
2155 }
2156
_cyttsp5_request_hid_output_calibrate_idacs(struct device * dev,int protect,u8 mode,u8 * status)2157 static int _cyttsp5_request_hid_output_calibrate_idacs(struct device *dev,
2158 int protect, u8 mode, u8 *status)
2159 {
2160 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2161
2162 if (protect)
2163 return cyttsp5_hid_output_calibrate_idacs(cd, mode, status);
2164
2165 return cyttsp5_hid_output_calibrate_idacs_(cd, mode, status);
2166 }
2167
cyttsp5_hid_output_initialize_baselines_(struct cyttsp5_core_data * cd,u8 test_id,u8 * status)2168 static int cyttsp5_hid_output_initialize_baselines_(
2169 struct cyttsp5_core_data *cd, u8 test_id, u8 *status)
2170 {
2171 int rc;
2172 int write_length = 1;
2173 u8 write_buf[1];
2174 u8 cmd_offset = 0;
2175 struct cyttsp5_hid_output hid_output = {
2176 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_INITIALIZE_BASELINES),
2177 .write_length = write_length,
2178 .write_buf = write_buf,
2179 };
2180
2181 write_buf[cmd_offset++] = test_id;
2182
2183 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
2184 if (rc)
2185 return rc;
2186
2187 *status = cd->response_buf[5];
2188 if (*status)
2189 return -EINVAL;
2190
2191 return rc;
2192 }
2193
cyttsp5_hid_output_initialize_baselines(struct cyttsp5_core_data * cd,u8 test_id,u8 * status)2194 static int cyttsp5_hid_output_initialize_baselines(struct cyttsp5_core_data *cd,
2195 u8 test_id, u8 *status)
2196 {
2197 int rc;
2198
2199 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2200 if (rc < 0) {
2201 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2202 __func__, cd->exclusive_dev, cd->dev);
2203 return rc;
2204 }
2205
2206 rc = cyttsp5_hid_output_initialize_baselines_(cd, test_id, status);
2207
2208 if (release_exclusive(cd, cd->dev) < 0)
2209 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2210
2211 return rc;
2212 }
2213
_cyttsp5_request_hid_output_initialize_baselines(struct device * dev,int protect,u8 test_id,u8 * status)2214 static int _cyttsp5_request_hid_output_initialize_baselines(struct device *dev,
2215 int protect, u8 test_id, u8 *status)
2216 {
2217 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2218
2219 if (protect)
2220 return cyttsp5_hid_output_initialize_baselines(cd, test_id,
2221 status);
2222
2223 return cyttsp5_hid_output_initialize_baselines_(cd, test_id, status);
2224 }
2225
cyttsp5_hid_output_exec_panel_scan_(struct cyttsp5_core_data * cd)2226 static int cyttsp5_hid_output_exec_panel_scan_(struct cyttsp5_core_data *cd)
2227 {
2228 struct cyttsp5_hid_output hid_output = {
2229 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_EXEC_PANEL_SCAN),
2230 };
2231
2232 return cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
2233 }
2234
cyttsp5_hid_output_exec_panel_scan(struct cyttsp5_core_data * cd)2235 static int cyttsp5_hid_output_exec_panel_scan(struct cyttsp5_core_data *cd)
2236 {
2237 int rc;
2238
2239 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2240 if (rc < 0) {
2241 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2242 __func__, cd->exclusive_dev, cd->dev);
2243 return rc;
2244 }
2245
2246 rc = cyttsp5_hid_output_exec_panel_scan_(cd);
2247
2248 if (release_exclusive(cd, cd->dev) < 0)
2249 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2250
2251 return rc;
2252 }
2253
_cyttsp5_request_hid_output_exec_panel_scan(struct device * dev,int protect)2254 static int _cyttsp5_request_hid_output_exec_panel_scan(struct device *dev,
2255 int protect)
2256 {
2257 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2258
2259 if (protect)
2260 return cyttsp5_hid_output_exec_panel_scan(cd);
2261
2262 return cyttsp5_hid_output_exec_panel_scan_(cd);
2263 }
2264
2265 /* @response: set none NULL only if all response required including header */
cyttsp5_hid_output_retrieve_panel_scan_(struct cyttsp5_core_data * cd,u16 read_offset,u16 read_count,u8 data_id,u8 * response,u8 * config,u16 * actual_read_len,u8 * read_buf)2266 static int cyttsp5_hid_output_retrieve_panel_scan_(
2267 struct cyttsp5_core_data *cd, u16 read_offset, u16 read_count,
2268 u8 data_id, u8 *response, u8 *config, u16 *actual_read_len,
2269 u8 *read_buf)
2270 {
2271 int status;
2272 u8 read_data_id;
2273 int rc;
2274 int write_length = 5;
2275 u8 write_buf[5];
2276 u8 cmd_offset = 0;
2277 u8 data_elem_size;
2278 int size;
2279 int data_size;
2280 struct cyttsp5_hid_output hid_output = {
2281 HID_OUTPUT_APP_COMMAND(HID_OUTPUT_RETRIEVE_PANEL_SCAN),
2282 .write_length = write_length,
2283 .write_buf = write_buf,
2284 };
2285
2286 write_buf[cmd_offset++] = LOW_BYTE(read_offset);
2287 write_buf[cmd_offset++] = HI_BYTE(read_offset);
2288 write_buf[cmd_offset++] = LOW_BYTE(read_count);
2289 write_buf[cmd_offset++] = HI_BYTE(read_count);
2290 write_buf[cmd_offset++] = data_id;
2291
2292 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
2293 if (rc)
2294 return rc;
2295
2296 status = cd->response_buf[5];
2297 if (status)
2298 return -EINVAL;
2299
2300 read_data_id = cd->response_buf[6];
2301 if (read_data_id != data_id)
2302 return -EPROTO;
2303
2304 size = get_unaligned_le16(&cd->response_buf[0]);
2305 *actual_read_len = get_unaligned_le16(&cd->response_buf[7]);
2306 *config = cd->response_buf[9];
2307
2308 data_elem_size = *config & 0x07;
2309 data_size = *actual_read_len * data_elem_size;
2310
2311 if (read_buf)
2312 memcpy(read_buf, &cd->response_buf[10], data_size);
2313 if (response)
2314 memcpy(response, cd->response_buf, size);
2315 return rc;
2316 }
2317
cyttsp5_hid_output_retrieve_panel_scan(struct cyttsp5_core_data * cd,u16 read_offset,u16 read_count,u8 data_id,u8 * response,u8 * config,u16 * actual_read_len,u8 * read_buf)2318 static int cyttsp5_hid_output_retrieve_panel_scan(
2319 struct cyttsp5_core_data *cd, u16 read_offset, u16 read_count,
2320 u8 data_id, u8 *response, u8 *config, u16 *actual_read_len,
2321 u8 *read_buf)
2322 {
2323 int rc;
2324
2325 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2326 if (rc < 0) {
2327 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2328 __func__, cd->exclusive_dev, cd->dev);
2329 return rc;
2330 }
2331
2332 rc = cyttsp5_hid_output_retrieve_panel_scan_(cd, read_offset,
2333 read_count, data_id, response, config,
2334 actual_read_len, read_buf);
2335
2336 if (release_exclusive(cd, cd->dev) < 0)
2337 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2338
2339 return rc;
2340 }
2341
_cyttsp5_request_hid_output_retrieve_panel_scan(struct device * dev,int protect,u16 read_offset,u16 read_count,u8 data_id,u8 * response,u8 * config,u16 * actual_read_len,u8 * read_buf)2342 static int _cyttsp5_request_hid_output_retrieve_panel_scan(struct device *dev,
2343 int protect, u16 read_offset, u16 read_count, u8 data_id,
2344 u8 *response, u8 *config, u16 *actual_read_len, u8 *read_buf)
2345 {
2346 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2347
2348 if (protect)
2349 return cyttsp5_hid_output_retrieve_panel_scan(cd,
2350 read_offset, read_count, data_id, response,
2351 config, actual_read_len, read_buf);
2352
2353 return cyttsp5_hid_output_retrieve_panel_scan_(cd,
2354 read_offset, read_count, data_id, response,
2355 config, actual_read_len, read_buf);
2356 }
2357
cyttsp5_hid_output_user_cmd_(struct cyttsp5_core_data * cd,u16 read_len,u8 * read_buf,u16 write_len,u8 * write_buf,u16 * actual_read_len)2358 static int cyttsp5_hid_output_user_cmd_(struct cyttsp5_core_data *cd,
2359 u16 read_len, u8 *read_buf, u16 write_len, u8 *write_buf,
2360 u16 *actual_read_len)
2361 {
2362 int rc;
2363 u16 size;
2364 #ifdef TTHE_TUNER_SUPPORT
2365 int command_code = 0;
2366 int len;
2367 #endif
2368 struct cyttsp5_hid_output hid_output = {
2369 .length = write_len,
2370 .write_buf = write_buf,
2371 };
2372
2373 rc = cyttsp5_hid_send_output_user_and_wait_(cd, &hid_output);
2374 if (rc)
2375 return rc;
2376
2377 size = get_unaligned_le16(&cd->response_buf[0]);
2378 if (size == 0)
2379 size = 2;
2380
2381 if (size > read_len) {
2382 *actual_read_len = 0;
2383 return -EINVAL;
2384 }
2385
2386 memcpy(read_buf, cd->response_buf, size);
2387 *actual_read_len = size;
2388
2389 #ifdef TTHE_TUNER_SUPPORT
2390 /* print up to cmd code */
2391 len = HID_OUTPUT_CMD_OFFSET + 1;
2392 if (write_len < len)
2393 len = write_len;
2394 else
2395 command_code = write_buf[HID_OUTPUT_CMD_OFFSET]
2396 & HID_OUTPUT_CMD_MASK;
2397
2398 /* Do not print for EXEC_PANEL_SCAN & RETRIEVE_PANEL_SCAN commands */
2399 if (command_code != HID_OUTPUT_EXEC_PANEL_SCAN
2400 && command_code != HID_OUTPUT_RETRIEVE_PANEL_SCAN)
2401 tthe_print(cd, write_buf, len, "CMD=");
2402 #endif
2403
2404 return 0;
2405 }
2406
cyttsp5_get_config_ver_(struct cyttsp5_core_data * cd)2407 static int cyttsp5_get_config_ver_(struct cyttsp5_core_data *cd)
2408 {
2409 struct cyttsp5_sysinfo *si = &cd->sysinfo;
2410 int rc;
2411 u16 config_ver = 0;
2412
2413 rc = cyttsp5_hid_output_suspend_scanning_(cd);
2414 if (rc)
2415 goto error;
2416
2417 rc = cyttsp5_hid_output_read_conf_ver_(cd, &config_ver);
2418 if (rc)
2419 goto exit;
2420
2421 si->cydata.fw_ver_conf = config_ver;
2422
2423 exit:
2424 cyttsp5_hid_output_resume_scanning_(cd);
2425 error:
2426 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: CONFIG_VER:%04X\n",
2427 __func__, config_ver);
2428 return rc;
2429 }
2430
cyttsp5_hid_output_user_cmd(struct cyttsp5_core_data * cd,u16 read_len,u8 * read_buf,u16 write_len,u8 * write_buf,u16 * actual_read_len)2431 static int cyttsp5_hid_output_user_cmd(struct cyttsp5_core_data *cd,
2432 u16 read_len, u8 *read_buf, u16 write_len, u8 *write_buf,
2433 u16 *actual_read_len)
2434 {
2435 int rc;
2436
2437 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2438 if (rc < 0) {
2439 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2440 __func__, cd->exclusive_dev, cd->dev);
2441 return rc;
2442 }
2443
2444 rc = cyttsp5_hid_output_user_cmd_(cd, read_len, read_buf,
2445 write_len, write_buf, actual_read_len);
2446
2447 if (release_exclusive(cd, cd->dev) < 0)
2448 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2449
2450 return rc;
2451 }
2452
_cyttsp5_request_hid_output_user_cmd(struct device * dev,int protect,u16 read_len,u8 * read_buf,u16 write_len,u8 * write_buf,u16 * actual_read_len)2453 static int _cyttsp5_request_hid_output_user_cmd(struct device *dev,
2454 int protect, u16 read_len, u8 *read_buf, u16 write_len,
2455 u8 *write_buf, u16 *actual_read_len)
2456 {
2457 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2458
2459 if (protect)
2460 return cyttsp5_hid_output_user_cmd(cd, read_len, read_buf,
2461 write_len, write_buf, actual_read_len);
2462
2463 return cyttsp5_hid_output_user_cmd_(cd, read_len, read_buf,
2464 write_len, write_buf, actual_read_len);
2465 }
2466
cyttsp5_hid_output_bl_get_information_(struct cyttsp5_core_data * cd,u8 * return_data)2467 static int cyttsp5_hid_output_bl_get_information_(struct cyttsp5_core_data *cd,
2468 u8 *return_data)
2469 {
2470 int rc;
2471 int data_len;
2472 struct cyttsp5_hid_output hid_output = {
2473 HID_OUTPUT_BL_COMMAND(HID_OUTPUT_BL_GET_INFO),
2474 };
2475
2476 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
2477 if (rc)
2478 return rc;
2479
2480 data_len = get_unaligned_le16(&cd->input_buf[6]);
2481 if (!data_len)
2482 return -EPROTO;
2483
2484 memcpy(return_data, &cd->response_buf[8], data_len);
2485
2486 return 0;
2487 }
2488
cyttsp5_hid_output_bl_get_information(struct cyttsp5_core_data * cd,u8 * return_data)2489 static int cyttsp5_hid_output_bl_get_information(struct cyttsp5_core_data *cd,
2490 u8 *return_data)
2491 {
2492 int rc;
2493
2494 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2495 if (rc < 0) {
2496 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2497 __func__, cd->exclusive_dev, cd->dev);
2498 return rc;
2499 }
2500
2501 rc = cyttsp5_hid_output_bl_get_information_(cd, return_data);
2502
2503 if (release_exclusive(cd, cd->dev) < 0)
2504 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2505
2506 return rc;
2507 }
2508
_cyttsp5_request_hid_output_bl_get_information(struct device * dev,int protect,u8 * return_data)2509 static int _cyttsp5_request_hid_output_bl_get_information(struct device *dev,
2510 int protect, u8 *return_data)
2511 {
2512 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2513
2514 if (protect)
2515 return cyttsp5_hid_output_bl_get_information(cd, return_data);
2516
2517 return cyttsp5_hid_output_bl_get_information_(cd, return_data);
2518 }
2519
cyttsp5_hid_output_bl_initiate_bl_(struct cyttsp5_core_data * cd,u16 key_size,u8 * key_buf,u16 row_size,u8 * metadata_row_buf)2520 static int cyttsp5_hid_output_bl_initiate_bl_(struct cyttsp5_core_data *cd,
2521 u16 key_size, u8 *key_buf, u16 row_size, u8 *metadata_row_buf)
2522 {
2523 u16 write_length = key_size + row_size;
2524 u8 *write_buf;
2525 int rc;
2526 struct cyttsp5_hid_output hid_output = {
2527 HID_OUTPUT_BL_COMMAND(HID_OUTPUT_BL_INITIATE_BL),
2528 .write_length = write_length,
2529 .timeout_ms = CY_HID_OUTPUT_BL_INITIATE_BL_TIMEOUT,
2530 };
2531
2532 write_buf = kzalloc(write_length, GFP_KERNEL);
2533 if (!write_buf)
2534 return -ENOMEM;
2535
2536 hid_output.write_buf = write_buf;
2537
2538 if (key_size)
2539 memcpy(write_buf, key_buf, key_size);
2540
2541 if (row_size)
2542 memcpy(&write_buf[key_size], metadata_row_buf, row_size);
2543
2544 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
2545
2546 kfree(write_buf);
2547 return rc;
2548 }
2549
cyttsp5_hid_output_bl_initiate_bl(struct cyttsp5_core_data * cd,u16 key_size,u8 * key_buf,u16 row_size,u8 * metadata_row_buf)2550 static int cyttsp5_hid_output_bl_initiate_bl(struct cyttsp5_core_data *cd,
2551 u16 key_size, u8 *key_buf, u16 row_size, u8 *metadata_row_buf)
2552 {
2553 int rc;
2554
2555 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2556 if (rc < 0) {
2557 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2558 __func__, cd->exclusive_dev, cd->dev);
2559 return rc;
2560 }
2561
2562 rc = cyttsp5_hid_output_bl_initiate_bl_(cd, key_size, key_buf,
2563 row_size, metadata_row_buf);
2564
2565 if (release_exclusive(cd, cd->dev) < 0)
2566 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2567
2568 return rc;
2569 }
2570
_cyttsp5_request_hid_output_bl_initiate_bl(struct device * dev,int protect,u16 key_size,u8 * key_buf,u16 row_size,u8 * metadata_row_buf)2571 static int _cyttsp5_request_hid_output_bl_initiate_bl(struct device *dev,
2572 int protect, u16 key_size, u8 *key_buf, u16 row_size,
2573 u8 *metadata_row_buf)
2574 {
2575 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2576
2577 if (protect)
2578 return cyttsp5_hid_output_bl_initiate_bl(cd, key_size, key_buf,
2579 row_size, metadata_row_buf);
2580
2581 return cyttsp5_hid_output_bl_initiate_bl_(cd, key_size, key_buf,
2582 row_size, metadata_row_buf);
2583 }
2584
cyttsp5_hid_output_bl_program_and_verify_(struct cyttsp5_core_data * cd,u16 data_len,u8 * data_buf)2585 static int cyttsp5_hid_output_bl_program_and_verify_(
2586 struct cyttsp5_core_data *cd, u16 data_len, u8 *data_buf)
2587 {
2588 struct cyttsp5_hid_output hid_output = {
2589 HID_OUTPUT_BL_COMMAND(HID_OUTPUT_BL_PROGRAM_AND_VERIFY),
2590 .write_length = data_len,
2591 .write_buf = data_buf,
2592 .timeout_ms = CY_HID_OUTPUT_BL_PROGRAM_AND_VERIFY_TIMEOUT,
2593 };
2594
2595 return cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
2596 }
2597
cyttsp5_hid_output_bl_program_and_verify(struct cyttsp5_core_data * cd,u16 data_len,u8 * data_buf)2598 static int cyttsp5_hid_output_bl_program_and_verify(
2599 struct cyttsp5_core_data *cd, u16 data_len, u8 *data_buf)
2600 {
2601 int rc;
2602
2603 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2604 if (rc < 0) {
2605 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2606 __func__, cd->exclusive_dev, cd->dev);
2607 return rc;
2608 }
2609
2610 rc = cyttsp5_hid_output_bl_program_and_verify_(cd, data_len, data_buf);
2611
2612 if (release_exclusive(cd, cd->dev) < 0)
2613 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2614
2615 return rc;
2616 }
2617
_cyttsp5_request_hid_output_bl_program_and_verify(struct device * dev,int protect,u16 data_len,u8 * data_buf)2618 static int _cyttsp5_request_hid_output_bl_program_and_verify(
2619 struct device *dev, int protect, u16 data_len, u8 *data_buf)
2620 {
2621 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2622
2623 if (protect)
2624 return cyttsp5_hid_output_bl_program_and_verify(cd, data_len,
2625 data_buf);
2626
2627 return cyttsp5_hid_output_bl_program_and_verify_(cd, data_len,
2628 data_buf);
2629 }
2630
cyttsp5_hid_output_bl_verify_app_integrity_(struct cyttsp5_core_data * cd,u8 * result)2631 static int cyttsp5_hid_output_bl_verify_app_integrity_(
2632 struct cyttsp5_core_data *cd, u8 *result)
2633 {
2634 int rc;
2635 struct cyttsp5_hid_output hid_output = {
2636 HID_OUTPUT_BL_COMMAND(HID_OUTPUT_BL_VERIFY_APP_INTEGRITY),
2637 };
2638
2639 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
2640 if (rc) {
2641 *result = 0;
2642 return rc;
2643 }
2644
2645 *result = cd->response_buf[8];
2646 return 0;
2647 }
2648
cyttsp5_hid_output_bl_verify_app_integrity(struct cyttsp5_core_data * cd,u8 * result)2649 static int cyttsp5_hid_output_bl_verify_app_integrity(
2650 struct cyttsp5_core_data *cd, u8 *result)
2651 {
2652 int rc;
2653
2654 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2655 if (rc < 0) {
2656 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2657 __func__, cd->exclusive_dev, cd->dev);
2658 return rc;
2659 }
2660
2661 rc = cyttsp5_hid_output_bl_verify_app_integrity_(cd, result);
2662
2663 if (release_exclusive(cd, cd->dev) < 0)
2664 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2665
2666 return rc;
2667 }
2668
_cyttsp5_request_hid_output_bl_verify_app_integrity(struct device * dev,int protect,u8 * result)2669 static int _cyttsp5_request_hid_output_bl_verify_app_integrity(
2670 struct device *dev, int protect, u8 *result)
2671 {
2672 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2673
2674 if (protect)
2675 return cyttsp5_hid_output_bl_verify_app_integrity(cd, result);
2676
2677 return cyttsp5_hid_output_bl_verify_app_integrity_(cd, result);
2678 }
2679
cyttsp5_hid_output_bl_launch_app_(struct cyttsp5_core_data * cd)2680 static int cyttsp5_hid_output_bl_launch_app_(struct cyttsp5_core_data *cd)
2681 {
2682 struct cyttsp5_hid_output hid_output = {
2683 HID_OUTPUT_BL_COMMAND(HID_OUTPUT_BL_LAUNCH_APP),
2684 .reset_expected = 1,
2685 };
2686
2687 return cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
2688 }
2689
cyttsp5_hid_output_bl_launch_app(struct cyttsp5_core_data * cd)2690 static int cyttsp5_hid_output_bl_launch_app(struct cyttsp5_core_data *cd)
2691 {
2692 int rc;
2693
2694 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2695 if (rc < 0) {
2696 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2697 __func__, cd->exclusive_dev, cd->dev);
2698 return rc;
2699 }
2700
2701 rc = cyttsp5_hid_output_bl_launch_app_(cd);
2702
2703 if (release_exclusive(cd, cd->dev) < 0)
2704 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2705
2706 return rc;
2707 }
2708
_cyttsp5_request_hid_output_launch_app(struct device * dev,int protect)2709 static int _cyttsp5_request_hid_output_launch_app(struct device *dev,
2710 int protect)
2711 {
2712 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2713
2714 if (protect)
2715 return cyttsp5_hid_output_bl_launch_app(cd);
2716
2717 return cyttsp5_hid_output_bl_launch_app_(cd);
2718 }
2719
cyttsp5_hid_output_bl_get_panel_id_(struct cyttsp5_core_data * cd,u8 * panel_id)2720 static int cyttsp5_hid_output_bl_get_panel_id_(
2721 struct cyttsp5_core_data *cd, u8 *panel_id)
2722 {
2723 int rc;
2724 struct cyttsp5_hid_output hid_output = {
2725 HID_OUTPUT_BL_COMMAND(HID_OUTPUT_BL_GET_PANEL_ID),
2726 };
2727
2728 rc = cyttsp5_hid_send_output_and_wait_(cd, &hid_output);
2729 if (rc == -EPROTO && cd->response_buf[5] == ERROR_COMMAND) {
2730 parade_debug(cd->dev, DEBUG_LEVEL_1,
2731 "%s: Get Panel ID command not supported\n",
2732 __func__);
2733 *panel_id = PANEL_ID_NOT_ENABLED;
2734 return 0;
2735 } else if (rc < 0) {
2736 dev_err(cd->dev, "%s: Error on Get Panel ID command\n",
2737 __func__);
2738 return rc;
2739 }
2740
2741 *panel_id = cd->response_buf[8];
2742 return 0;
2743 }
2744
cyttsp5_hid_output_bl_get_panel_id(struct cyttsp5_core_data * cd,u8 * panel_id)2745 static int cyttsp5_hid_output_bl_get_panel_id(
2746 struct cyttsp5_core_data *cd, u8 *panel_id)
2747 {
2748 int rc;
2749
2750 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2751 if (rc < 0) {
2752 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2753 __func__, cd->exclusive_dev, cd->dev);
2754 return rc;
2755 }
2756
2757 rc = cyttsp5_hid_output_bl_get_panel_id_(cd, panel_id);
2758
2759 if (release_exclusive(cd, cd->dev) < 0)
2760 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2761
2762 return rc;
2763 }
2764
_cyttsp5_request_hid_output_bl_get_panel_id(struct device * dev,int protect,u8 * panel_id)2765 static int _cyttsp5_request_hid_output_bl_get_panel_id(
2766 struct device *dev, int protect, u8 *panel_id)
2767 {
2768 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2769
2770 if (protect)
2771 return cyttsp5_hid_output_bl_get_panel_id(cd, panel_id);
2772
2773 return cyttsp5_hid_output_bl_get_panel_id_(cd, panel_id);
2774 }
2775
cyttsp5_get_hid_descriptor_(struct cyttsp5_core_data * cd,struct cyttsp5_hid_desc * desc)2776 static int cyttsp5_get_hid_descriptor_(struct cyttsp5_core_data *cd,
2777 struct cyttsp5_hid_desc *desc)
2778 {
2779 struct device *dev = cd->dev;
2780 int rc;
2781 int t;
2782 u8 cmd[2];
2783
2784 /* Read HID descriptor length and version */
2785 mutex_lock(&cd->system_lock);
2786 cd->hid_cmd_state = 1;
2787 mutex_unlock(&cd->system_lock);
2788
2789 /* Set HID descriptor register */
2790 memcpy(cmd, &cd->hid_core.hid_desc_register,
2791 sizeof(cd->hid_core.hid_desc_register));
2792
2793 rc = cyttsp5_adap_write_read_specific(cd, 2, cmd, NULL);
2794 if (rc) {
2795 dev_err(dev, "%s: failed to get HID descriptor length and version, rc=%d\n",
2796 __func__, rc);
2797 goto error;
2798 }
2799
2800 t = wait_event_timeout(cd->wait_q, (cd->hid_cmd_state == 0),
2801 msecs_to_jiffies(CY_HID_GET_HID_DESCRIPTOR_TIMEOUT));
2802 if (IS_TMO(t)) {
2803 dev_err(cd->dev, "%s: HID get descriptor timed out\n",
2804 __func__);
2805 rc = -ETIME;
2806 goto error;
2807 }
2808
2809 memcpy((u8 *)desc, cd->response_buf, sizeof(struct cyttsp5_hid_desc));
2810
2811 /* Check HID descriptor length and version */
2812 parade_debug(dev, DEBUG_LEVEL_2, "%s: HID len:%X HID ver:%X\n",
2813 __func__,
2814 le16_to_cpu(desc->hid_desc_len),
2815 le16_to_cpu(desc->bcd_version));
2816
2817 if (le16_to_cpu(desc->hid_desc_len) != sizeof(*desc) ||
2818 le16_to_cpu(desc->bcd_version) != CY_HID_VERSION) {
2819 dev_err(dev, "%s: Unsupported HID version\n", __func__);
2820 return -ENODEV;
2821 }
2822
2823 goto exit;
2824
2825 error:
2826 mutex_lock(&cd->system_lock);
2827 cd->hid_cmd_state = 0;
2828 mutex_unlock(&cd->system_lock);
2829 exit:
2830 return rc;
2831 }
2832
cyttsp5_get_hid_descriptor(struct cyttsp5_core_data * cd,struct cyttsp5_hid_desc * desc)2833 static int cyttsp5_get_hid_descriptor(struct cyttsp5_core_data *cd,
2834 struct cyttsp5_hid_desc *desc)
2835 {
2836 int rc;
2837
2838 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
2839 if (rc < 0) {
2840 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
2841 __func__, cd->exclusive_dev, cd->dev);
2842 return rc;
2843 }
2844
2845 rc = cyttsp5_get_hid_descriptor_(cd, desc);
2846
2847 if (release_exclusive(cd, cd->dev) < 0)
2848 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
2849
2850 return rc;
2851 }
2852
_cyttsp5_request_get_hid_desc(struct device * dev,int protect)2853 static int _cyttsp5_request_get_hid_desc(struct device *dev, int protect)
2854 {
2855 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
2856
2857 if (protect)
2858 return cyttsp5_get_hid_descriptor(cd, &cd->hid_desc);
2859
2860 return cyttsp5_get_hid_descriptor_(cd, &cd->hid_desc);
2861 }
2862
cyttsp5_hw_soft_reset(struct cyttsp5_core_data * cd)2863 static int cyttsp5_hw_soft_reset(struct cyttsp5_core_data *cd)
2864 {
2865 int rc;
2866
2867 if (cd->hid_desc.hid_desc_len == 0) {
2868 rc = cyttsp5_get_hid_descriptor_(cd, &cd->hid_desc);
2869 if (rc < 0)
2870 return rc;
2871 }
2872
2873 rc = cyttsp5_hid_cmd_reset_(cd);
2874 if (rc < 0) {
2875 dev_err(cd->dev, "%s: FAILED to execute SOFT reset\n",
2876 __func__);
2877 return rc;
2878 }
2879 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: execute SOFT reset\n",
2880 __func__);
2881 return 0;
2882 }
2883
cyttsp5_hw_hard_reset(struct cyttsp5_core_data * cd)2884 static int cyttsp5_hw_hard_reset(struct cyttsp5_core_data *cd)
2885 {
2886 if (cd->cpdata->xres) {
2887 cd->cpdata->xres(cd->cpdata, cd->dev);
2888 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: execute HARD reset\n",
2889 __func__);
2890 return 0;
2891 }
2892 dev_err(cd->dev, "%s: FAILED to execute HARD reset\n", __func__);
2893 return -ENODEV;
2894 }
2895
cyttsp5_hw_reset(struct cyttsp5_core_data * cd)2896 static int cyttsp5_hw_reset(struct cyttsp5_core_data *cd)
2897 {
2898 int rc;
2899
2900 mutex_lock(&cd->system_lock);
2901 rc = cyttsp5_hw_hard_reset(cd);
2902 //printk("======cyttsp5_hw_reset rc=%d \n", rc);
2903 mutex_unlock(&cd->system_lock);
2904 if (rc == -ENODEV)
2905 rc = cyttsp5_hw_soft_reset(cd);
2906 return rc;
2907 }
2908
get_hid_item_data(u8 * data,int item_size)2909 static inline int get_hid_item_data(u8 *data, int item_size)
2910 {
2911 if (item_size == 1)
2912 return (int)*data;
2913 else if (item_size == 2)
2914 return (int)get_unaligned_le16(data);
2915 else if (item_size == 4)
2916 return (int)get_unaligned_le32(data);
2917 return 0;
2918 }
2919
parse_report_descriptor(struct cyttsp5_core_data * cd,u8 * report_desc,size_t len)2920 static int parse_report_descriptor(struct cyttsp5_core_data *cd,
2921 u8 *report_desc, size_t len)
2922 {
2923 struct cyttsp5_hid_report *report;
2924 struct cyttsp5_hid_field *field;
2925 u8 *buf = report_desc;
2926 u8 *end = buf + len;
2927 int rc = 0;
2928 int offset = 0;
2929 int i;
2930 u8 report_type;
2931 u32 up_usage;
2932 /* Global items */
2933 u8 report_id = 0;
2934 u16 usage_page = 0;
2935 int report_count = 0;
2936 int report_size = 0;
2937 int logical_min = 0;
2938 int logical_max = 0;
2939 /* Local items */
2940 u16 usage = 0;
2941 /* Main items - Collection stack */
2942 u32 collection_usages[CY_HID_MAX_NESTED_COLLECTIONS] = {0};
2943 u8 collection_types[CY_HID_MAX_NESTED_COLLECTIONS] = {0};
2944 /* First collection for header, second for report */
2945 int logical_collection_count = 0;
2946 int collection_nest = 0;
2947
2948 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: Report descriptor length: %u\n",
2949 __func__, (u32)len);
2950
2951 mutex_lock(&cd->hid_report_lock);
2952 cyttsp5_free_hid_reports_(cd);
2953
2954 while (buf < end) {
2955 int item_type;
2956 int item_size;
2957 int item_tag;
2958 u8 *data;
2959
2960 /* Get Item */
2961 item_size = HID_GET_ITEM_SIZE(buf[0]);
2962 if (item_size == 3)
2963 item_size = 4;
2964 item_type = HID_GET_ITEM_TYPE(buf[0]);
2965 item_tag = HID_GET_ITEM_TAG(buf[0]);
2966
2967 data = ++buf;
2968 buf += item_size;
2969
2970 /* Process current item */
2971 switch (item_type) {
2972 case HID_ITEM_TYPE_GLOBAL:
2973 switch (item_tag) {
2974 case HID_GLOBAL_ITEM_TAG_REPORT_ID:
2975 if (item_size != 1) {
2976 rc = -EINVAL;
2977 goto exit;
2978 }
2979 report_id = get_hid_item_data(data, item_size);
2980 offset = 0;
2981 logical_collection_count = 0;
2982 break;
2983 case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
2984 if (item_size == 0 || item_size == 4) {
2985 rc = -EINVAL;
2986 goto exit;
2987 }
2988 usage_page = (u16)get_hid_item_data(data,
2989 item_size);
2990 break;
2991 case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM:
2992 if (item_size == 0) {
2993 rc = -EINVAL;
2994 goto exit;
2995 }
2996 logical_min = get_hid_item_data(data,
2997 item_size);
2998 break;
2999 case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
3000 if (item_size == 0) {
3001 rc = -EINVAL;
3002 goto exit;
3003 }
3004 logical_max = get_hid_item_data(data,
3005 item_size);
3006 break;
3007 case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
3008 if (item_size == 0) {
3009 rc = -EINVAL;
3010 goto exit;
3011 }
3012 report_count = get_hid_item_data(data,
3013 item_size);
3014 break;
3015 case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
3016 if (item_size == 0) {
3017 rc = -EINVAL;
3018 goto exit;
3019 }
3020 report_size = get_hid_item_data(data,
3021 item_size);
3022 break;
3023 default:
3024 dev_info(cd->dev,
3025 "%s: Unrecognized Global tag %d\n",
3026 __func__, item_tag);
3027 }
3028 break;
3029 case HID_ITEM_TYPE_LOCAL:
3030 switch (item_tag) {
3031 case HID_LOCAL_ITEM_TAG_USAGE:
3032 if (item_size == 0 || item_size == 4) {
3033 rc = -EINVAL;
3034 goto exit;
3035 }
3036 usage = (u16)get_hid_item_data(data,
3037 item_size);
3038 break;
3039 case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
3040 if (item_size == 0) {
3041 rc = -EINVAL;
3042 goto exit;
3043 }
3044 /* usage_min = */
3045 get_hid_item_data(data, item_size);
3046 break;
3047 case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
3048 if (item_size == 0) {
3049 rc = -EINVAL;
3050 goto exit;
3051 }
3052 /* usage_max = */
3053 get_hid_item_data(data, item_size);
3054 break;
3055 default:
3056 dev_info(cd->dev,
3057 "%s: Unrecognized Local tag %d\n",
3058 __func__, item_tag);
3059 }
3060 break;
3061 case HID_ITEM_TYPE_MAIN:
3062 switch (item_tag) {
3063 case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
3064 if (item_size != 1) {
3065 rc = -EINVAL;
3066 goto exit;
3067 }
3068 if (CY_HID_MAX_NESTED_COLLECTIONS ==
3069 collection_nest) {
3070 rc = -EINVAL;
3071 goto exit;
3072 }
3073
3074 up_usage = usage_page << 16 | usage;
3075
3076 /* Update collection stack */
3077 collection_usages[collection_nest] = up_usage;
3078 collection_types[collection_nest] =
3079 get_hid_item_data(data, item_size);
3080
3081 if (collection_types[collection_nest] ==
3082 HID_COLLECTION_LOGICAL)
3083 logical_collection_count++;
3084
3085 collection_nest++;
3086 break;
3087 case HID_MAIN_ITEM_TAG_END_COLLECTION:
3088 if (item_size != 0) {
3089 rc = -EINVAL;
3090 goto exit;
3091 }
3092 if (--collection_nest < 0) {
3093 rc = -EINVAL;
3094 goto exit;
3095 }
3096 break;
3097 case HID_MAIN_ITEM_TAG_INPUT:
3098 report_type = HID_INPUT_REPORT;
3099 goto continue_main_item;
3100 case HID_MAIN_ITEM_TAG_OUTPUT:
3101 report_type = HID_OUTPUT_REPORT;
3102 goto continue_main_item;
3103 case HID_MAIN_ITEM_TAG_FEATURE:
3104 report_type = HID_FEATURE_REPORT;
3105 continue_main_item:
3106 if (item_size != 1) {
3107 rc = -EINVAL;
3108 goto exit;
3109 }
3110
3111 up_usage = usage_page << 16 | usage;
3112
3113 /* Get or create report */
3114 report = cyttsp5_get_hid_report_(cd,
3115 report_type, report_id, true);
3116 if (!report) {
3117 rc = -ENOMEM;
3118 goto exit;
3119 }
3120 if (!report->usage_page && collection_nest > 0)
3121 report->usage_page =
3122 collection_usages
3123 [collection_nest - 1];
3124
3125 /* Create field */
3126 field = cyttsp5_create_hid_field_(report);
3127 if (!field) {
3128 rc = -ENOMEM;
3129 goto exit;
3130 }
3131
3132 field->report_count = report_count;
3133 field->report_size = report_size;
3134 field->size = report_count * report_size;
3135 field->offset = offset;
3136 field->data_type =
3137 get_hid_item_data(data, item_size);
3138 field->logical_min = logical_min;
3139 field->logical_max = logical_max;
3140 field->usage_page = up_usage;
3141
3142 for (i = 0; i < collection_nest; i++) {
3143 field->collection_usage_pages
3144 [collection_types[i]] =
3145 collection_usages[i];
3146 }
3147
3148 /* Update report's header or record size */
3149 if (logical_collection_count == 1) {
3150 report->header_size += field->size;
3151 } else if (logical_collection_count == 2) {
3152 field->record_field = true;
3153 field->offset -= report->header_size;
3154 /* Set record field index */
3155 if (report->record_field_index == 0)
3156 report->record_field_index =
3157 report->num_fields - 1;
3158 report->record_size += field->size;
3159 }
3160
3161 report->size += field->size;
3162
3163 offset += field->size;
3164 break;
3165 default:
3166 dev_info(cd->dev, "%s: Unrecognized Main tag %d\n",
3167 __func__, item_tag);
3168 }
3169
3170 /* Reset all local items */
3171 usage = 0;
3172 break;
3173 }
3174 }
3175
3176 if (buf != end) {
3177 dev_err(cd->dev, "%s: Report descriptor length invalid\n",
3178 __func__);
3179 rc = -EINVAL;
3180 goto exit;
3181 }
3182
3183 if (collection_nest) {
3184 dev_err(cd->dev, "%s: Unbalanced collection items (%d)\n",
3185 __func__, collection_nest);
3186 rc = -EINVAL;
3187 goto exit;
3188 }
3189
3190 exit:
3191 if (rc)
3192 cyttsp5_free_hid_reports_(cd);
3193 mutex_unlock(&cd->hid_report_lock);
3194 return rc;
3195 }
3196
find_report_desc_field(struct cyttsp5_core_data * cd,u32 usage_page,u32 collection_usage_page)3197 static struct cyttsp5_hid_field *find_report_desc_field(
3198 struct cyttsp5_core_data *cd, u32 usage_page,
3199 u32 collection_usage_page)
3200 {
3201 struct cyttsp5_hid_report *report = NULL;
3202 struct cyttsp5_hid_field *field = NULL;
3203 int i;
3204 int j;
3205 u32 field_cup;
3206 u32 field_up;
3207
3208 for (i = 0; i < cd->num_hid_reports; i++) {
3209 report = cd->hid_reports[i];
3210 for (j = 0; j < report->num_fields; j++) {
3211 field = report->fields[j];
3212 field_cup = field->collection_usage_pages
3213 [HID_COLLECTION_LOGICAL];
3214 field_up = field->usage_page;
3215 if (field_cup == collection_usage_page
3216 && field_up == usage_page) {
3217 return field;
3218 }
3219 }
3220 }
3221
3222 return NULL;
3223 }
3224
fill_tch_abs(struct cyttsp5_tch_abs_params * tch_abs,struct cyttsp5_hid_field * field)3225 static int fill_tch_abs(struct cyttsp5_tch_abs_params *tch_abs,
3226 struct cyttsp5_hid_field *field)
3227 {
3228 tch_abs->ofs = field->offset / 8;
3229 tch_abs->size = field->report_size / 8;
3230 if (field->report_size % 8)
3231 tch_abs->size += 1;
3232 tch_abs->min = 0;
3233 tch_abs->max = 1 << field->report_size;
3234 tch_abs->bofs = field->offset - (tch_abs->ofs << 3);
3235
3236 return 0;
3237 }
3238
find_report_desc(struct cyttsp5_core_data * cd,u32 usage_page)3239 static struct cyttsp5_hid_report *find_report_desc(struct cyttsp5_core_data *cd,
3240 u32 usage_page)
3241 {
3242 struct cyttsp5_hid_report *report = NULL;
3243 int i;
3244
3245 for (i = 0; i < cd->num_hid_reports; i++) {
3246 if (cd->hid_reports[i]->usage_page == usage_page) {
3247 report = cd->hid_reports[i];
3248 break;
3249 }
3250 }
3251
3252 return report;
3253 }
3254
setup_report_descriptor(struct cyttsp5_core_data * cd)3255 static int setup_report_descriptor(struct cyttsp5_core_data *cd)
3256 {
3257 struct cyttsp5_sysinfo *si = &cd->sysinfo;
3258 struct cyttsp5_hid_report *report;
3259 struct cyttsp5_hid_field *field;
3260 int i;
3261 u32 tch_collection_usage_page = HID_CY_TCH_COL_USAGE_PG;
3262 u32 btn_collection_usage_page = HID_CY_BTN_COL_USAGE_PG;
3263
3264 for (i = CY_TCH_X; i < CY_TCH_NUM_ABS; i++) {
3265 field = find_report_desc_field(cd,
3266 cyttsp5_tch_abs_field_map[i],
3267 tch_collection_usage_page);
3268 if (field) {
3269 parade_debug(cd->dev, DEBUG_LEVEL_2,
3270 " Field %p: rep_cnt:%d rep_sz:%d off:%d data:%02X min:%d max:%d usage_page:%08X\n",
3271 field, field->report_count, field->report_size,
3272 field->offset, field->data_type,
3273 field->logical_min, field->logical_max,
3274 field->usage_page);
3275 fill_tch_abs(&si->tch_abs[i], field);
3276 si->tch_abs[i].report = 1;
3277 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: ofs:%u size:%u min:%u max:%u bofs:%u report:%d",
3278 cyttsp5_tch_abs_string[i],
3279 (u32)si->tch_abs[i].ofs,
3280 (u32)si->tch_abs[i].size,
3281 (u32)si->tch_abs[i].min,
3282 (u32)si->tch_abs[i].max,
3283 (u32)si->tch_abs[i].bofs,
3284 si->tch_abs[i].report);
3285
3286 } else {
3287 si->tch_abs[i].report = 0;
3288 }
3289 }
3290 for (i = CY_TCH_TIME; i < CY_TCH_NUM_HDR; i++) {
3291 field = find_report_desc_field(cd,
3292 cyttsp5_tch_hdr_field_map[i],
3293 tch_collection_usage_page);
3294 if (field) {
3295 parade_debug(cd->dev, DEBUG_LEVEL_2,
3296 " Field %p: rep_cnt:%d rep_sz:%d off:%d data:%02X min:%d max:%d usage_page:%08X\n",
3297 field, field->report_count, field->report_size,
3298 field->offset, field->data_type,
3299 field->logical_min, field->logical_max,
3300 field->usage_page);
3301 fill_tch_abs(&si->tch_hdr[i], field);
3302 si->tch_hdr[i].report = 1;
3303 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: ofs:%u size:%u min:%u max:%u bofs:%u report:%d",
3304 cyttsp5_tch_hdr_string[i],
3305 (u32)si->tch_hdr[i].ofs,
3306 (u32)si->tch_hdr[i].size,
3307 (u32)si->tch_hdr[i].min,
3308 (u32)si->tch_hdr[i].max,
3309 (u32)si->tch_hdr[i].bofs,
3310 si->tch_hdr[i].report);
3311
3312 } else {
3313 si->tch_hdr[i].report = 0;
3314 }
3315 }
3316
3317 report = find_report_desc(cd, tch_collection_usage_page);
3318 if (report) {
3319 si->desc.tch_report_id = report->id;
3320 si->desc.tch_record_size = report->record_size / 8;
3321 si->desc.tch_header_size = (report->header_size / 8) + 3;
3322 } else {
3323 si->desc.tch_report_id = HID_TOUCH_REPORT_ID;
3324 si->desc.tch_record_size = TOUCH_REPORT_SIZE;
3325 si->desc.tch_header_size = TOUCH_INPUT_HEADER_SIZE;
3326 }
3327
3328 report = find_report_desc(cd, btn_collection_usage_page);
3329 if (report)
3330 si->desc.btn_report_id = report->id;
3331 else
3332 si->desc.btn_report_id = HID_BTN_REPORT_ID;
3333
3334 for (i = 0; i < cd->num_hid_reports; i++) {
3335 struct cyttsp5_hid_report *report = cd->hid_reports[i];
3336
3337 switch (report->id) {
3338 case HID_WAKEUP_REPORT_ID:
3339 cd->features.easywake = 1;
3340 break;
3341 case HID_NOISE_METRIC_REPORT_ID:
3342 cd->features.noise_metric = 1;
3343 break;
3344 case HID_TRACKING_HEATMAP_REPOR_ID:
3345 cd->features.tracking_heatmap = 1;
3346 break;
3347 case HID_SENSOR_DATA_REPORT_ID:
3348 cd->features.sensor_data = 1;
3349 break;
3350 default:
3351 break;
3352 }
3353 }
3354
3355 parade_debug(cd->dev, DEBUG_LEVEL_1, "Features: easywake:%d noise_metric:%d tracking_heatmap:%d sensor_data:%d\n",
3356 cd->features.easywake, cd->features.noise_metric,
3357 cd->features.tracking_heatmap,
3358 cd->features.sensor_data);
3359
3360 return 0;
3361 }
3362
cyttsp5_get_report_descriptor_(struct cyttsp5_core_data * cd)3363 static int cyttsp5_get_report_descriptor_(struct cyttsp5_core_data *cd)
3364 {
3365 struct device *dev = cd->dev;
3366 u8 cmd[2];
3367 int rc;
3368 int t;
3369
3370 /* Read report descriptor length and version */
3371 mutex_lock(&cd->system_lock);
3372 cd->hid_cmd_state = 1;
3373 mutex_unlock(&cd->system_lock);
3374
3375 /* Set report descriptor register */
3376 memcpy(cmd, &cd->hid_desc.report_desc_register,
3377 sizeof(cd->hid_desc.report_desc_register));
3378
3379 rc = cyttsp5_adap_write_read_specific(cd, 2, cmd, NULL);
3380 if (rc) {
3381 dev_err(dev, "%s: failed to get HID descriptor length and version, rc=%d\n",
3382 __func__, rc);
3383 goto error;
3384 }
3385
3386 t = wait_event_timeout(cd->wait_q, (cd->hid_cmd_state == 0),
3387 msecs_to_jiffies(CY_HID_GET_REPORT_DESCRIPTOR_TIMEOUT));
3388 if (IS_TMO(t)) {
3389 dev_err(cd->dev, "%s: HID get descriptor timed out\n",
3390 __func__);
3391 rc = -ETIME;
3392 goto error;
3393 }
3394
3395 cyttsp5_pr_buf(cd->dev, cd->response_buf,
3396 cd->hid_core.hid_report_desc_len, "Report Desc");
3397
3398 rc = parse_report_descriptor(cd, cd->response_buf + 3,
3399 get_unaligned_le16(&cd->response_buf[0]) - 3);
3400 if (rc) {
3401 dev_err(cd->dev, "%s: Error parsing report descriptor r=%d\n",
3402 __func__, rc);
3403 }
3404
3405 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: %d reports found in descriptor\n",
3406 __func__, cd->num_hid_reports);
3407
3408 for (t = 0; t < cd->num_hid_reports; t++) {
3409 struct cyttsp5_hid_report *report = cd->hid_reports[t];
3410 int j;
3411
3412 parade_debug(cd->dev, DEBUG_LEVEL_2,
3413 "Report %d: type:%d id:%02X size:%d fields:%d rec_fld_index:%d hdr_sz:%d rec_sz:%d usage_page:%08X\n",
3414 t, report->type, report->id,
3415 report->size, report->num_fields,
3416 report->record_field_index, report->header_size,
3417 report->record_size, report->usage_page);
3418
3419 for (j = 0; j < report->num_fields; j++) {
3420 struct cyttsp5_hid_field *field = report->fields[j];
3421
3422 parade_debug(cd->dev, DEBUG_LEVEL_2,
3423 " Field %d: rep_cnt:%d rep_sz:%d off:%d data:%02X min:%d max:%d usage_page:%08X\n",
3424 j, field->report_count, field->report_size,
3425 field->offset, field->data_type,
3426 field->logical_min, field->logical_max,
3427 field->usage_page);
3428
3429 parade_debug(cd->dev, DEBUG_LEVEL_2, " Collections Phys:%08X App:%08X Log:%08X\n",
3430 field->collection_usage_pages
3431 [HID_COLLECTION_PHYSICAL],
3432 field->collection_usage_pages
3433 [HID_COLLECTION_APPLICATION],
3434 field->collection_usage_pages
3435 [HID_COLLECTION_LOGICAL]);
3436 }
3437 }
3438
3439 rc = setup_report_descriptor(cd);
3440
3441 /* Free it for now */
3442 cyttsp5_free_hid_reports_(cd);
3443
3444 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: %d reports found in descriptor\n",
3445 __func__, cd->num_hid_reports);
3446
3447 goto exit;
3448
3449 error:
3450 mutex_lock(&cd->system_lock);
3451 cd->hid_cmd_state = 0;
3452 mutex_unlock(&cd->system_lock);
3453 exit:
3454 return rc;
3455 }
3456
cyttsp5_get_mode(struct cyttsp5_core_data * cd,struct cyttsp5_hid_desc * desc)3457 static int cyttsp5_get_mode(struct cyttsp5_core_data *cd,
3458 struct cyttsp5_hid_desc *desc)
3459 {
3460 if (desc->packet_id == CY_HID_APP_REPORT_ID)
3461 return CY_MODE_OPERATIONAL;
3462 else if (desc->packet_id == CY_HID_BL_REPORT_ID)
3463 return CY_MODE_BOOTLOADER;
3464
3465 return CY_MODE_UNKNOWN;
3466 }
3467
_cyttsp5_request_get_mode(struct device * dev,int protect,u8 * mode)3468 static int _cyttsp5_request_get_mode(struct device *dev, int protect, u8 *mode)
3469 {
3470 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
3471 int rc;
3472
3473 if (protect)
3474 rc = cyttsp5_get_hid_descriptor(cd, &cd->hid_desc);
3475 else
3476 rc = cyttsp5_get_hid_descriptor_(cd, &cd->hid_desc);
3477
3478 if (rc)
3479 *mode = CY_MODE_UNKNOWN;
3480 else
3481 *mode = cyttsp5_get_mode(cd, &cd->hid_desc);
3482
3483 return rc;
3484 }
3485
cyttsp5_queue_startup_(struct cyttsp5_core_data * cd)3486 static void cyttsp5_queue_startup_(struct cyttsp5_core_data *cd)
3487 {
3488 if (cd->startup_state == STARTUP_NONE) {
3489 cd->startup_state = STARTUP_QUEUED;
3490 schedule_work(&cd->startup_work);
3491 dev_info(cd->dev, "%s: cyttsp5_startup queued\n", __func__);
3492 } else {
3493 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: startup_state = %d\n",
3494 __func__, cd->startup_state);
3495 }
3496 }
3497
cyttsp5_queue_startup(struct cyttsp5_core_data * cd)3498 static void cyttsp5_queue_startup(struct cyttsp5_core_data *cd)
3499 {
3500 mutex_lock(&cd->system_lock);
3501 cyttsp5_queue_startup_(cd);
3502 mutex_unlock(&cd->system_lock);
3503 }
3504
call_atten_cb(struct cyttsp5_core_data * cd,enum cyttsp5_atten_type type,int mode)3505 static void call_atten_cb(struct cyttsp5_core_data *cd,
3506 enum cyttsp5_atten_type type, int mode)
3507 {
3508 struct atten_node *atten, *atten_n;
3509
3510 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: check list type=%d mode=%d\n",
3511 __func__, type, mode);
3512 spin_lock(&cd->spinlock);
3513 list_for_each_entry_safe(atten, atten_n,
3514 &cd->atten_list[type], node) {
3515 if (!mode || atten->mode & mode) {
3516 spin_unlock(&cd->spinlock);
3517 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: attention for '%s'",
3518 __func__, dev_name(atten->dev));
3519 atten->func(atten->dev);
3520 spin_lock(&cd->spinlock);
3521 }
3522 }
3523 spin_unlock(&cd->spinlock);
3524 }
3525
3526 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
cyttsp5_start_wd_timer(struct cyttsp5_core_data * cd)3527 static void cyttsp5_start_wd_timer(struct cyttsp5_core_data *cd)
3528 {
3529 if (!cd->watchdog_interval){
3530 //printk("++++++cyttsp5_start_wd_timer %d\n",cd->watchdog_interval);
3531 return;
3532 }
3533
3534 mod_timer(&cd->watchdog_timer, jiffies +
3535 msecs_to_jiffies(cd->watchdog_interval));
3536 }
3537
cyttsp5_stop_wd_timer(struct cyttsp5_core_data * cd)3538 static void cyttsp5_stop_wd_timer(struct cyttsp5_core_data *cd)
3539 {
3540 if (!cd->watchdog_interval)
3541 {
3542 //printk("++++++cyttsp5_stop_wd_timer %d\n",cd->watchdog_interval);
3543 return;
3544 }
3545
3546 /*
3547 * Ensure we wait until the watchdog timer
3548 * running on a different CPU finishes
3549 */
3550 del_timer_sync(&cd->watchdog_timer);
3551 cancel_work_sync(&cd->watchdog_work);
3552 del_timer_sync(&cd->watchdog_timer);
3553 }
3554
start_fw_upgrade(void * data)3555 static int start_fw_upgrade(void *data)
3556 {
3557 struct cyttsp5_core_data *cd = (struct cyttsp5_core_data *)data;
3558
3559 call_atten_cb(cd, CY_ATTEN_LOADER, 0);
3560 return 0;
3561 }
3562
cyttsp5_watchdog_work(struct work_struct * work)3563 static void cyttsp5_watchdog_work(struct work_struct *work)
3564 {
3565 struct cyttsp5_core_data *cd =
3566 container_of(work, struct cyttsp5_core_data,
3567 watchdog_work);
3568 int rc;
3569 /*fix CDT207254
3570 *if found the current sleep_state is SS_SLEEPING
3571 *then no need to request_exclusive, directly return
3572 */
3573 if (cd->sleep_state == SS_SLEEPING)
3574 return;
3575
3576 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
3577 if (rc < 0) {
3578 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
3579 __func__, cd->exclusive_dev, cd->dev);
3580 goto queue_startup;
3581 }
3582
3583 rc = cyttsp5_hid_output_null_(cd);
3584
3585 if (release_exclusive(cd, cd->dev) < 0)
3586 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
3587
3588 queue_startup:
3589 if (rc) {
3590 dev_err(cd->dev,
3591 "%s: failed to access device in watchdog timer r=%d\n",
3592 __func__, rc);
3593
3594 /* Already tried FW upgrade because of watchdog but failed */
3595 if (cd->startup_retry_count > CY_WATCHDOG_RETRY_COUNT)
3596 return;
3597
3598 if (cd->startup_retry_count++ < CY_WATCHDOG_RETRY_COUNT)
3599 cyttsp5_queue_startup(cd);
3600 else
3601 kthread_run(start_fw_upgrade, cd, "cyttp5_loader");
3602
3603 return;
3604 }
3605
3606 cyttsp5_start_wd_timer(cd);
3607 }
3608
cyttsp5_watchdog_timer(struct timer_list * t)3609 static void cyttsp5_watchdog_timer(struct timer_list *t)//(unsigned long handle)
3610 {
3611 struct cyttsp5_core_data *cd = from_timer(cd, t, watchdog_timer);
3612
3613 if (!cd)
3614 return;
3615
3616 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: Watchdog timer triggered\n",
3617 __func__);
3618
3619 if (!work_pending(&cd->watchdog_work))
3620 schedule_work(&cd->watchdog_work);
3621 }
3622 #endif
cyttsp5_put_device_into_easy_wakeup_(struct cyttsp5_core_data * cd)3623 static int cyttsp5_put_device_into_easy_wakeup_(struct cyttsp5_core_data *cd)
3624 {
3625 int rc;
3626 u8 status = 0;
3627
3628 mutex_lock(&cd->system_lock);
3629 cd->wait_until_wake = 0;
3630 mutex_unlock(&cd->system_lock);
3631
3632 rc = cyttsp5_hid_output_enter_easywake_state_(cd,
3633 cd->easy_wakeup_gesture, &status);
3634 if (rc || status == 0)
3635 return -EBUSY;
3636
3637 return rc;
3638 }
3639
cyttsp5_put_device_into_deep_sleep_(struct cyttsp5_core_data * cd)3640 static int cyttsp5_put_device_into_deep_sleep_(struct cyttsp5_core_data *cd)
3641 {
3642 int rc;
3643
3644 rc = cyttsp5_hid_cmd_set_power_(cd, HID_POWER_SLEEP);
3645 if (rc)
3646 rc = -EBUSY;
3647 return rc;
3648 }
3649
cyttsp5_put_device_into_sleep_(struct cyttsp5_core_data * cd)3650 static int cyttsp5_put_device_into_sleep_(struct cyttsp5_core_data *cd)
3651 {
3652 int rc;
3653
3654 //dev_err(cd->dev, "%s: \n",
3655 // __func__);
3656 if (IS_DEEP_SLEEP_CONFIGURED(cd->easy_wakeup_gesture))
3657 rc = cyttsp5_put_device_into_deep_sleep_(cd);
3658 else
3659 rc = cyttsp5_put_device_into_easy_wakeup_(cd);
3660
3661 return rc;
3662 }
3663
cyttsp5_core_poweroff_device_(struct cyttsp5_core_data * cd)3664 static int cyttsp5_core_poweroff_device_(struct cyttsp5_core_data *cd)
3665 {
3666 int rc;
3667
3668 //dev_err(cd->dev, "%s: irq_enabled=0x%x\n",
3669 // __func__, cd->irq_enabled);
3670 if (cd->irq_enabled) {
3671 cd->irq_enabled = false;
3672 disable_irq_nosync(cd->irq);
3673 }
3674
3675 rc = cd->cpdata->power(cd->cpdata, 0, cd->dev, 0);
3676 if (rc < 0)
3677 dev_err(cd->dev, "%s: HW Power down fails r=%d\n",
3678 __func__, rc);
3679 return rc;
3680 }
3681
cyttsp5_core_sleep_(struct cyttsp5_core_data * cd)3682 static int cyttsp5_core_sleep_(struct cyttsp5_core_data *cd)
3683 {
3684 int rc;
3685
3686 mutex_lock(&cd->system_lock);
3687 if (cd->sleep_state == SS_SLEEP_OFF) {
3688 cd->sleep_state = SS_SLEEPING;
3689 } else {
3690 mutex_unlock(&cd->system_lock);
3691 return 1;
3692 }
3693 mutex_unlock(&cd->system_lock);
3694
3695 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
3696 /* Ensure watchdog and startup works stopped */
3697 cyttsp5_stop_wd_timer(cd);
3698 #endif
3699 cancel_work_sync(&cd->startup_work);
3700 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
3701 cyttsp5_stop_wd_timer(cd);
3702 #endif
3703 //dev_err(cd->dev, "%s: flags=0x%x\n",
3704 // __func__, cd->cpdata->flags);
3705
3706 if (cd->cpdata->flags & CY_CORE_FLAG_POWEROFF_ON_SLEEP)
3707 rc = cyttsp5_core_poweroff_device_(cd);
3708 else
3709 rc = cyttsp5_put_device_into_sleep_(cd);
3710
3711 mutex_lock(&cd->system_lock);
3712 cd->sleep_state = SS_SLEEP_ON;
3713 mutex_unlock(&cd->system_lock);
3714
3715 return rc;
3716 }
3717
cyttsp5_core_sleep(struct cyttsp5_core_data * cd)3718 static int cyttsp5_core_sleep(struct cyttsp5_core_data *cd)
3719 {
3720 int rc;
3721
3722 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
3723 if (rc < 0) {
3724 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
3725 __func__, cd->exclusive_dev, cd->dev);
3726 return rc;
3727 }
3728
3729 rc = cyttsp5_core_sleep_(cd);
3730
3731 if (release_exclusive(cd, cd->dev) < 0)
3732 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
3733 else
3734 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: pass release exclusive\n",
3735 __func__);
3736
3737 return rc;
3738 }
3739
cyttsp5_wakeup_host(struct cyttsp5_core_data * cd)3740 static int cyttsp5_wakeup_host(struct cyttsp5_core_data *cd)
3741 {
3742 #ifndef EASYWAKE_TSG6
3743 /* TSG5 EasyWake */
3744 int rc = 0;
3745 int event_id;
3746 int size = get_unaligned_le16(&cd->input_buf[0]);
3747
3748 /* Validate report */
3749 if (size != 4 || cd->input_buf[2] != 4)
3750 rc = -EINVAL;
3751
3752 cd->wake_initiated_by_device = 1;
3753 event_id = cd->input_buf[3];
3754
3755 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: e=%d, rc=%d\n",
3756 __func__, event_id, rc);
3757
3758 if (rc) {
3759 cyttsp5_core_sleep_(cd);
3760 goto exit;
3761 }
3762
3763 /* attention WAKE */
3764 call_atten_cb(cd, CY_ATTEN_WAKE, 0);
3765 exit:
3766 return rc;
3767 #else
3768 /* TSG6 FW1.3 EasyWake */
3769 int rc = 0;
3770 int i = 0;
3771 int report_length;
3772
3773 /* Validate report */
3774 if (cd->input_buf[2] != 4)
3775 rc = -EINVAL;
3776
3777 cd->wake_initiated_by_device = 1;
3778
3779 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: rc=%d\n", __func__, rc);
3780
3781 if (rc) {
3782 cyttsp5_core_sleep_(cd);
3783 goto exit;
3784 }
3785
3786 /* Get gesture id and gesture data length */
3787 cd->gesture_id = cd->input_buf[3];
3788 report_length = (cd->input_buf[1] << 8) | (cd->input_buf[0]);
3789 cd->gesture_data_length = report_length - 4;
3790
3791 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: gesture_id = %d, gesture_data_length = %d\n",
3792 __func__, cd->gesture_id, cd->gesture_data_length);
3793
3794 for (i = 0; i < cd->gesture_data_length; i++)
3795 cd->gesture_data[i] = cd->input_buf[4 + i];
3796
3797 /* attention WAKE */
3798 call_atten_cb(cd, CY_ATTEN_WAKE, 0);
3799 exit:
3800 return rc;
3801 #endif
3802 }
3803
cyttsp5_get_touch_axis(struct cyttsp5_core_data * cd,int * axis,int size,int max,u8 * data,int bofs)3804 static void cyttsp5_get_touch_axis(struct cyttsp5_core_data *cd,
3805 int *axis, int size, int max, u8 *data, int bofs)
3806 {
3807 int nbyte;
3808 int next;
3809
3810 for (nbyte = 0, *axis = 0, next = 0; nbyte < size; nbyte++) {
3811 *axis = *axis + ((data[next] >> bofs) << (nbyte * 8));
3812 next++;
3813 }
3814
3815 *axis &= max - 1;
3816 }
3817
move_tracking_hetmap_data(struct cyttsp5_core_data * cd,struct cyttsp5_sysinfo * si)3818 static int move_tracking_hetmap_data(struct cyttsp5_core_data *cd,
3819 struct cyttsp5_sysinfo *si)
3820 {
3821 #ifdef TTHE_TUNER_SUPPORT
3822 int size = get_unaligned_le16(&cd->input_buf[0]);
3823
3824 if (size)
3825 tthe_print(cd, cd->input_buf, size, "THM=");
3826 #endif
3827 memcpy(si->xy_mode, cd->input_buf, SENSOR_HEADER_SIZE);
3828 return 0;
3829 }
3830
move_sensor_data(struct cyttsp5_core_data * cd,struct cyttsp5_sysinfo * si)3831 static int move_sensor_data(struct cyttsp5_core_data *cd,
3832 struct cyttsp5_sysinfo *si)
3833 {
3834 #ifdef TTHE_TUNER_SUPPORT
3835 int size = get_unaligned_le16(&cd->input_buf[0]);
3836
3837 if (size)
3838 tthe_print(cd, cd->input_buf, size, "sensor_monitor=");
3839 #endif
3840 memcpy(si->xy_mode, cd->input_buf, SENSOR_HEADER_SIZE);
3841 return 0;
3842 }
3843
move_button_data(struct cyttsp5_core_data * cd,struct cyttsp5_sysinfo * si)3844 static int move_button_data(struct cyttsp5_core_data *cd,
3845 struct cyttsp5_sysinfo *si)
3846 {
3847 #ifdef TTHE_TUNER_SUPPORT
3848 int size = get_unaligned_le16(&cd->input_buf[0]);
3849
3850 if (size)
3851 tthe_print(cd, cd->input_buf, size, "OpModeData=");
3852 #endif
3853 memcpy(si->xy_mode, cd->input_buf, BTN_INPUT_HEADER_SIZE);
3854 cyttsp5_pr_buf(cd->dev, (u8 *)si->xy_mode, BTN_INPUT_HEADER_SIZE,
3855 "xy_mode");
3856
3857 memcpy(si->xy_data, &cd->input_buf[BTN_INPUT_HEADER_SIZE],
3858 BTN_REPORT_SIZE);
3859 cyttsp5_pr_buf(cd->dev, (u8 *)si->xy_data, BTN_REPORT_SIZE, "xy_data");
3860 return 0;
3861 }
3862
move_touch_data(struct cyttsp5_core_data * cd,struct cyttsp5_sysinfo * si)3863 static int move_touch_data(struct cyttsp5_core_data *cd,
3864 struct cyttsp5_sysinfo *si)
3865 {
3866 int max_tch = si->sensing_conf_data.max_tch;
3867 int num_cur_tch;
3868 int length;
3869 struct cyttsp5_tch_abs_params *tch = &si->tch_hdr[CY_TCH_NUM];
3870 #ifdef TTHE_TUNER_SUPPORT
3871 int size = get_unaligned_le16(&cd->input_buf[0]);
3872
3873 if (size)
3874 tthe_print(cd, cd->input_buf, size, "OpModeData=");
3875 #endif
3876
3877 memcpy(si->xy_mode, cd->input_buf, si->desc.tch_header_size);
3878 cyttsp5_pr_buf(cd->dev, (u8 *)si->xy_mode, si->desc.tch_header_size,
3879 "xy_mode");
3880
3881 cyttsp5_get_touch_axis(cd, &num_cur_tch, tch->size,
3882 tch->max, si->xy_mode + 3 + tch->ofs, tch->bofs);
3883 if (unlikely(num_cur_tch > max_tch))
3884 num_cur_tch = max_tch;
3885
3886 length = num_cur_tch * si->desc.tch_record_size;
3887
3888 memcpy(si->xy_data, &cd->input_buf[si->desc.tch_header_size], length);
3889 cyttsp5_pr_buf(cd->dev, (u8 *)si->xy_data, length, "xy_data");
3890 return 0;
3891 }
3892
parse_touch_input(struct cyttsp5_core_data * cd,int size)3893 static int parse_touch_input(struct cyttsp5_core_data *cd, int size)
3894 {
3895 struct cyttsp5_sysinfo *si = &cd->sysinfo;
3896 int report_id = cd->input_buf[2];
3897 int rc = -EINVAL;
3898
3899 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: Received touch report\n",
3900 __func__);
3901 if (!si->ready) {
3902 dev_err(cd->dev,
3903 "%s: Need system information to parse touches\n",
3904 __func__);
3905 return 0;
3906 }
3907
3908 if (!si->xy_mode || !si->xy_data)
3909 return rc;
3910
3911 if (report_id == si->desc.tch_report_id)
3912 rc = move_touch_data(cd, si);
3913 else if (report_id == si->desc.btn_report_id)
3914 rc = move_button_data(cd, si);
3915 else if (report_id == HID_SENSOR_DATA_REPORT_ID)
3916 rc = move_sensor_data(cd, si);
3917 else if (report_id == HID_TRACKING_HEATMAP_REPOR_ID)
3918 rc = move_tracking_hetmap_data(cd, si);
3919
3920 if (rc)
3921 return rc;
3922
3923 /* attention IRQ */
3924 call_atten_cb(cd, CY_ATTEN_IRQ, cd->mode);
3925
3926 return 0;
3927 }
3928
parse_command_input(struct cyttsp5_core_data * cd,int size)3929 static int parse_command_input(struct cyttsp5_core_data *cd, int size)
3930 {
3931 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: Received cmd interrupt\n",
3932 __func__);
3933
3934 memcpy(cd->response_buf, cd->input_buf, size);
3935
3936 mutex_lock(&cd->system_lock);
3937 cd->hid_cmd_state = 0;
3938 mutex_unlock(&cd->system_lock);
3939 wake_up(&cd->wait_q);
3940
3941 return 0;
3942 }
3943
cyttsp5_parse_input(struct cyttsp5_core_data * cd)3944 static int cyttsp5_parse_input(struct cyttsp5_core_data *cd)
3945 {
3946 int report_id;
3947 int is_command = 0;
3948 int size;
3949
3950 //printk("*******cyttsp5_parse_input \n");
3951 size = get_unaligned_le16(&cd->input_buf[0]);
3952
3953 /* check reset */
3954 if (size == 0) {
3955 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: Reset complete\n",
3956 __func__);
3957 memcpy(cd->response_buf, cd->input_buf, 2);
3958 mutex_lock(&cd->system_lock);
3959 if (!cd->hid_reset_cmd_state && !cd->hid_cmd_state) {
3960 mutex_unlock(&cd->system_lock);
3961 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: Device Initiated Reset\n",
3962 __func__);
3963 return 0;
3964 }
3965
3966 cd->hid_reset_cmd_state = 0;
3967 if (cd->hid_cmd_state == HID_OUTPUT_START_BOOTLOADER + 1
3968 || cd->hid_cmd_state ==
3969 HID_OUTPUT_BL_LAUNCH_APP + 1
3970 || cd->hid_cmd_state ==
3971 HID_OUTPUT_USER_CMD + 1)
3972 cd->hid_cmd_state = 0;
3973 wake_up(&cd->wait_q);
3974 mutex_unlock(&cd->system_lock);
3975 return 0;
3976 } else if (size == 2 || size >= CY_PIP_1P7_EMPTY_BUF)
3977 /*
3978 * Before PIP 1.7, empty buffer is 0x0002;
3979 * From PIP 1.7, empty buffer is 0xFFXX
3980 */
3981 return 0;
3982
3983 report_id = cd->input_buf[2];
3984 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: report_id:%X\n",
3985 __func__, report_id);
3986
3987 /* Check wake-up report */
3988 if (report_id == HID_WAKEUP_REPORT_ID) {
3989 cyttsp5_wakeup_host(cd);
3990 return 0;
3991 }
3992 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
3993 /* update watchdog expire time */
3994 mod_timer_pending(&cd->watchdog_timer, jiffies +
3995 msecs_to_jiffies(cd->watchdog_interval));
3996 #endif
3997 if (report_id != cd->sysinfo.desc.tch_report_id
3998 && report_id != cd->sysinfo.desc.btn_report_id
3999 && report_id != HID_SENSOR_DATA_REPORT_ID
4000 && report_id != HID_TRACKING_HEATMAP_REPOR_ID)
4001 is_command = 1;
4002
4003 if (unlikely(is_command)) {
4004 parse_command_input(cd, size);
4005 return 0;
4006 }
4007 parse_touch_input(cd, size);
4008 return 0;
4009 }
4010
cyttsp5_read_input(struct cyttsp5_core_data * cd)4011 static int cyttsp5_read_input(struct cyttsp5_core_data *cd)
4012 {
4013 struct device *dev = cd->dev;
4014 int rc;
4015 int t;
4016
4017 //printk("**********cyttsp5_read_input \n");
4018 /* added as workaround to CDT170960: easywake failure */
4019 /* Interrupt for easywake, wait for bus controller to wake */
4020 mutex_lock(&cd->system_lock);
4021 if (!IS_DEEP_SLEEP_CONFIGURED(cd->easy_wakeup_gesture)) {
4022 if (cd->sleep_state == SS_SLEEP_ON) {
4023 mutex_unlock(&cd->system_lock);
4024 if (!dev->power.is_suspended)
4025 goto read;
4026 t = wait_event_timeout(cd->wait_q,
4027 (cd->wait_until_wake == 1),
4028 msecs_to_jiffies(2000));
4029 if (IS_TMO(t))
4030 cyttsp5_queue_startup(cd);
4031 goto read;
4032 }
4033 }
4034 mutex_unlock(&cd->system_lock);
4035
4036 read:
4037 rc = cyttsp5_adap_read_default_nosize(cd, cd->input_buf, CY_MAX_INPUT);
4038 if (rc) {
4039 dev_err(dev, "%s: Error getting report, r=%d\n",
4040 __func__, rc);
4041 return rc;
4042 }
4043 parade_debug(dev, DEBUG_LEVEL_2, "%s: Read input successfully\n",
4044 __func__);
4045 return rc;
4046 }
4047
cyttsp5_check_irq_asserted(struct cyttsp5_core_data * cd)4048 static bool cyttsp5_check_irq_asserted(struct cyttsp5_core_data *cd)
4049 {
4050 #ifdef ENABLE_WORKAROUND_FOR_GLITCH_AFTER_BL_LAUNCH_APP
4051 /*
4052 * Workaround for FW defect, CDT165308
4053 * bl_launch app creates a glitch in IRQ line
4054 */
4055 if (cd->hid_cmd_state == HID_OUTPUT_BL_LAUNCH_APP + 1
4056 && cd->cpdata->irq_stat){
4057 /*
4058 * in X1S panel and GC1546 panel, the width for the INT
4059 * glitch is about 4us,the normal INT width of response
4060 * will last more than 200us, so use 10us delay
4061 * for distinguish the glitch the normal INT is enough.
4062 */
4063 udelay(10);
4064 if (cd->cpdata->irq_stat(cd->cpdata, cd->dev)
4065 != CY_IRQ_ASSERTED_VALUE)
4066 return false;
4067 }
4068 #endif
4069 return true;
4070 }
4071
4072
cyttsp5_irq(int irq,void * handle)4073 static irqreturn_t cyttsp5_irq(int irq, void *handle)
4074 {
4075 struct cyttsp5_core_data *cd = handle;
4076 int rc;
4077 //printk("&&&&&&cyttsp5_irq \n");
4078 if (!cyttsp5_check_irq_asserted(cd))
4079 return IRQ_HANDLED;
4080
4081 pm_stay_awake(cd->dev);
4082
4083 rc = cyttsp5_read_input(cd);
4084 if (!rc)
4085 cyttsp5_parse_input(cd);
4086
4087 pm_relax(cd->dev);
4088
4089 return IRQ_HANDLED;
4090 }
4091
_cyttsp5_subscribe_attention(struct device * dev,enum cyttsp5_atten_type type,char * id,int (* func)(struct device *),int mode)4092 int _cyttsp5_subscribe_attention(struct device *dev,
4093 enum cyttsp5_atten_type type, char *id, int (*func)(struct device *),
4094 int mode)
4095 {
4096 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4097 struct atten_node *atten, *atten_new;
4098
4099 atten_new = kzalloc(sizeof(*atten_new), GFP_KERNEL);
4100 if (!atten_new)
4101 return -ENOMEM;
4102
4103 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s from '%s'\n", __func__,
4104 dev_name(cd->dev));
4105
4106 spin_lock(&cd->spinlock);
4107 list_for_each_entry(atten, &cd->atten_list[type], node) {
4108 if (atten->id == id && atten->mode == mode) {
4109 spin_unlock(&cd->spinlock);
4110 kfree(atten_new);
4111 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: %s=%p %s=%d\n",
4112 __func__,
4113 "already subscribed attention",
4114 dev, "mode", mode);
4115
4116 return 0;
4117 }
4118 }
4119
4120 atten_new->id = id;
4121 atten_new->dev = dev;
4122 atten_new->mode = mode;
4123 atten_new->func = func;
4124
4125 list_add(&atten_new->node, &cd->atten_list[type]);
4126 spin_unlock(&cd->spinlock);
4127
4128 return 0;
4129 }
4130
_cyttsp5_unsubscribe_attention(struct device * dev,enum cyttsp5_atten_type type,char * id,int (* func)(struct device *),int mode)4131 int _cyttsp5_unsubscribe_attention(struct device *dev,
4132 enum cyttsp5_atten_type type, char *id, int (*func)(struct device *),
4133 int mode)
4134 {
4135 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4136 struct atten_node *atten, *atten_n;
4137
4138 spin_lock(&cd->spinlock);
4139 list_for_each_entry_safe(atten, atten_n, &cd->atten_list[type], node) {
4140 if (atten->id == id && atten->mode == mode) {
4141 list_del(&atten->node);
4142 spin_unlock(&cd->spinlock);
4143 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: %s=%p %s=%d\n",
4144 __func__,
4145 "unsub for atten->dev", atten->dev,
4146 "atten->mode", atten->mode);
4147 kfree(atten);
4148 return 0;
4149 }
4150 }
4151 spin_unlock(&cd->spinlock);
4152
4153 return -ENODEV;
4154 }
4155
_cyttsp5_request_exclusive(struct device * dev,int timeout_ms)4156 static int _cyttsp5_request_exclusive(struct device *dev,
4157 int timeout_ms)
4158 {
4159 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4160
4161 return request_exclusive(cd, (void *)dev, timeout_ms);
4162 }
4163
_cyttsp5_release_exclusive(struct device * dev)4164 static int _cyttsp5_release_exclusive(struct device *dev)
4165 {
4166 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4167
4168 return release_exclusive(cd, (void *)dev);
4169 }
4170
cyttsp5_reset(struct cyttsp5_core_data * cd)4171 static int cyttsp5_reset(struct cyttsp5_core_data *cd)
4172 {
4173 int rc;
4174
4175 /* reset hardware */
4176 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: reset hw...\n", __func__);
4177 rc = cyttsp5_hw_reset(cd);
4178 if (rc < 0)
4179 dev_err(cd->dev, "%s: %s dev='%s' r=%d\n", __func__,
4180 "Fail hw reset", dev_name(cd->dev), rc);
4181 return rc;
4182 }
4183
cyttsp5_reset_and_wait(struct cyttsp5_core_data * cd)4184 static int cyttsp5_reset_and_wait(struct cyttsp5_core_data *cd)
4185 {
4186 int rc;
4187 int t;
4188
4189 mutex_lock(&cd->system_lock);
4190 cd->hid_reset_cmd_state = 1;
4191 mutex_unlock(&cd->system_lock);
4192
4193 rc = cyttsp5_reset(cd);
4194 if (rc < 0)
4195 goto error;
4196
4197 t = wait_event_timeout(cd->wait_q, (cd->hid_reset_cmd_state == 0),
4198 msecs_to_jiffies(CY_HID_RESET_TIMEOUT));
4199 if (IS_TMO(t)) {
4200 dev_err(cd->dev, "%s: reset timed out\n",
4201 __func__);
4202 rc = -ETIME;
4203 goto error;
4204 }
4205
4206 goto exit;
4207
4208 error:
4209 mutex_lock(&cd->system_lock);
4210 cd->hid_reset_cmd_state = 0;
4211 mutex_unlock(&cd->system_lock);
4212 exit:
4213 return rc;
4214 }
4215
4216 /*
4217 * returns err if refused or timeout(core uses fixed timeout period) occurs;
4218 * blocks until ISR occurs
4219 */
_cyttsp5_request_reset(struct device * dev)4220 static int _cyttsp5_request_reset(struct device *dev)
4221 {
4222 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4223 int rc;
4224
4225 mutex_lock(&cd->system_lock);
4226 cd->hid_reset_cmd_state = 1;
4227 mutex_unlock(&cd->system_lock);
4228
4229 rc = cyttsp5_reset(cd);
4230 if (rc < 0) {
4231 dev_err(cd->dev, "%s: Error on h/w reset r=%d\n",
4232 __func__, rc);
4233 mutex_lock(&cd->system_lock);
4234 cd->hid_reset_cmd_state = 0;
4235 mutex_unlock(&cd->system_lock);
4236 }
4237
4238 return rc;
4239 }
4240
4241 /*
4242 * returns err if refused ; if no error then restart has completed
4243 * and system is in normal operating mode
4244 */
_cyttsp5_request_restart(struct device * dev,bool wait)4245 static int _cyttsp5_request_restart(struct device *dev, bool wait)
4246 {
4247 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4248
4249 cyttsp5_queue_startup(cd);
4250
4251 if (wait)
4252 wait_event(cd->wait_q, cd->startup_state == STARTUP_NONE);
4253
4254 return 0;
4255 }
4256
4257 /*
4258 * returns NULL if sysinfo has not been acquired from the device yet
4259 */
_cyttsp5_request_sysinfo(struct device * dev)4260 struct cyttsp5_sysinfo *_cyttsp5_request_sysinfo(struct device *dev)
4261 {
4262 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4263
4264 if (cd->sysinfo.ready)
4265 return &cd->sysinfo;
4266
4267 return NULL;
4268 }
4269
_cyttsp5_request_loader_pdata(struct device * dev)4270 static struct cyttsp5_loader_platform_data *_cyttsp5_request_loader_pdata(
4271 struct device *dev)
4272 {
4273 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4274
4275 return cd->pdata->loader_pdata;
4276 }
4277
4278 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
_cyttsp5_request_start_wd(struct device * dev)4279 static int _cyttsp5_request_start_wd(struct device *dev)
4280 {
4281 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4282
4283 cyttsp5_start_wd_timer(cd);
4284 return 0;
4285 }
4286
_cyttsp5_request_stop_wd(struct device * dev)4287 static int _cyttsp5_request_stop_wd(struct device *dev)
4288 {
4289 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4290
4291 cyttsp5_stop_wd_timer(cd);
4292 return 0;
4293 }
4294 #endif
4295
cyttsp5_core_wake_device_from_deep_sleep_(struct cyttsp5_core_data * cd)4296 static int cyttsp5_core_wake_device_from_deep_sleep_(
4297 struct cyttsp5_core_data *cd)
4298 {
4299 int rc;
4300
4301 rc = cyttsp5_hid_cmd_set_power_(cd, HID_POWER_ON);
4302 if (rc)
4303 rc = -EAGAIN;
4304
4305 /* Prevent failure on sequential wake/sleep requests from OS */
4306 msleep(20);
4307
4308 return rc;
4309 }
4310
cyttsp5_core_wake_device_(struct cyttsp5_core_data * cd)4311 static int cyttsp5_core_wake_device_(struct cyttsp5_core_data *cd)
4312 {
4313 if (!IS_DEEP_SLEEP_CONFIGURED(cd->easy_wakeup_gesture)) {
4314 mutex_lock(&cd->system_lock);
4315 cd->wait_until_wake = 1;
4316 mutex_unlock(&cd->system_lock);
4317 wake_up(&cd->wait_q);
4318 msleep(20);
4319
4320 if (cd->wake_initiated_by_device) {
4321 cd->wake_initiated_by_device = 0;
4322 return 0;
4323 }
4324 }
4325
4326 return cyttsp5_core_wake_device_from_deep_sleep_(cd);
4327 }
4328
cyttsp5_restore_parameters_(struct cyttsp5_core_data * cd)4329 static int cyttsp5_restore_parameters_(struct cyttsp5_core_data *cd)
4330 {
4331 struct param_node *param;
4332 int rc = 0;
4333
4334 if (!(cd->cpdata->flags & CY_CORE_FLAG_RESTORE_PARAMETERS))
4335 goto exit;
4336
4337 spin_lock(&cd->spinlock);
4338 list_for_each_entry(param, &cd->param_list, node) {
4339 spin_unlock(&cd->spinlock);
4340 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: Parameter id:%d value:%d\n",
4341 __func__, param->id, param->value);
4342 rc = cyttsp5_hid_output_set_param_(cd, param->id,
4343 param->value, param->size);
4344 if (rc)
4345 goto exit;
4346 spin_lock(&cd->spinlock);
4347 }
4348 spin_unlock(&cd->spinlock);
4349 exit:
4350 return rc;
4351 }
4352
_fast_startup(struct cyttsp5_core_data * cd)4353 static int _fast_startup(struct cyttsp5_core_data *cd)
4354 {
4355 int retry = CY_CORE_STARTUP_RETRY_COUNT;
4356 int rc;
4357
4358 reset:
4359 if (retry != CY_CORE_STARTUP_RETRY_COUNT)
4360 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: Retry %d\n",
4361 __func__, CY_CORE_STARTUP_RETRY_COUNT - retry);
4362
4363 rc = cyttsp5_get_hid_descriptor_(cd, &cd->hid_desc);
4364 if (rc < 0) {
4365 dev_err(cd->dev, "%s: Error on getting HID descriptor r=%d\n",
4366 __func__, rc);
4367 if (retry--)
4368 goto reset;
4369 goto exit;
4370 }
4371 cd->mode = cyttsp5_get_mode(cd, &cd->hid_desc);
4372
4373 if (cd->mode == CY_MODE_BOOTLOADER) {
4374 dev_info(cd->dev, "%s: Bootloader mode\n", __func__);
4375 rc = cyttsp5_hid_output_bl_launch_app_(cd);
4376 if (rc < 0) {
4377 dev_err(cd->dev, "%s: Error on launch app r=%d\n",
4378 __func__, rc);
4379 if (retry--)
4380 goto reset;
4381 goto exit;
4382 }
4383 rc = cyttsp5_get_hid_descriptor_(cd, &cd->hid_desc);
4384 if (rc < 0) {
4385 dev_err(cd->dev,
4386 "%s: Error on getting HID descriptor r=%d\n",
4387 __func__, rc);
4388 if (retry--)
4389 goto reset;
4390 goto exit;
4391 }
4392 cd->mode = cyttsp5_get_mode(cd, &cd->hid_desc);
4393 if (cd->mode == CY_MODE_BOOTLOADER) {
4394 if (retry--)
4395 goto reset;
4396 goto exit;
4397 }
4398 }
4399
4400 rc = cyttsp5_restore_parameters_(cd);
4401 if (rc)
4402 dev_err(cd->dev, "%s: failed to restore parameters rc=%d\n",
4403 __func__, rc);
4404
4405 exit:
4406 return rc;
4407 }
4408
cyttsp5_core_poweron_device_(struct cyttsp5_core_data * cd)4409 static int cyttsp5_core_poweron_device_(struct cyttsp5_core_data *cd)
4410 {
4411 struct device *dev = cd->dev;
4412 int rc;
4413
4414 rc = cd->cpdata->power(cd->cpdata, 1, dev, 0);
4415 if (rc < 0) {
4416 dev_err(dev, "%s: HW Power up fails r=%d\n", __func__, rc);
4417 goto exit;
4418 }
4419
4420 if (!cd->irq_enabled) {
4421 cd->irq_enabled = true;
4422 enable_irq(cd->irq);
4423 }
4424
4425 rc = _fast_startup(cd);
4426 exit:
4427 return rc;
4428 }
4429
cyttsp5_core_wake_(struct cyttsp5_core_data * cd)4430 static int cyttsp5_core_wake_(struct cyttsp5_core_data *cd)
4431 {
4432 int rc;
4433
4434 mutex_lock(&cd->system_lock);
4435 if (cd->sleep_state == SS_SLEEP_ON) {
4436 cd->sleep_state = SS_WAKING;
4437 } else {
4438 mutex_unlock(&cd->system_lock);
4439 return 1;
4440 }
4441 mutex_unlock(&cd->system_lock);
4442
4443 if (cd->cpdata->flags & CY_CORE_FLAG_POWEROFF_ON_SLEEP)
4444 rc = cyttsp5_core_poweron_device_(cd);
4445 else
4446 rc = cyttsp5_core_wake_device_(cd);
4447
4448 mutex_lock(&cd->system_lock);
4449 cd->sleep_state = SS_SLEEP_OFF;
4450 mutex_unlock(&cd->system_lock);
4451
4452 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
4453 cyttsp5_start_wd_timer(cd);
4454 #endif
4455 return rc;
4456 }
4457
cyttsp5_core_wake(struct cyttsp5_core_data * cd)4458 static int cyttsp5_core_wake(struct cyttsp5_core_data *cd)
4459 {
4460 int rc;
4461
4462 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
4463 if (rc < 0) {
4464 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
4465 __func__, cd->exclusive_dev, cd->dev);
4466 return rc;
4467 }
4468
4469 rc = cyttsp5_core_wake_(cd);
4470
4471 if (release_exclusive(cd, cd->dev) < 0)
4472 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
4473 else
4474 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: pass release exclusive\n",
4475 __func__);
4476
4477 return rc;
4478 }
4479
cyttsp5_get_ic_crc_(struct cyttsp5_core_data * cd,u8 ebid)4480 static int cyttsp5_get_ic_crc_(struct cyttsp5_core_data *cd, u8 ebid)
4481 {
4482 struct cyttsp5_sysinfo *si = &cd->sysinfo;
4483 int rc;
4484 u8 status;
4485 u16 calculated_crc = 0;
4486 u16 stored_crc = 0;
4487
4488 rc = cyttsp5_hid_output_suspend_scanning_(cd);
4489 if (rc)
4490 goto error;
4491
4492 rc = cyttsp5_hid_output_verify_config_block_crc_(cd, ebid, &status,
4493 &calculated_crc, &stored_crc);
4494 if (rc)
4495 goto exit;
4496
4497 if (status) {
4498 rc = -EINVAL;
4499 goto exit;
4500 }
4501
4502 si->ttconfig.crc = stored_crc;
4503
4504 exit:
4505 cyttsp5_hid_output_resume_scanning_(cd);
4506 error:
4507 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: CRC: ebid:%d, crc:0x%04X\n",
4508 __func__, ebid, si->ttconfig.crc);
4509 return rc;
4510 }
4511
cyttsp5_check_and_deassert_int(struct cyttsp5_core_data * cd)4512 static int cyttsp5_check_and_deassert_int(struct cyttsp5_core_data *cd)
4513 {
4514 u16 size;
4515 u8 buf[2];
4516 u8 *p;
4517 u8 retry = 3;
4518 int rc;
4519
4520 do {
4521 rc = cyttsp5_adap_read_default(cd, buf, 2);
4522 if (rc < 0)
4523 return rc;
4524 size = get_unaligned_le16(&buf[0]);
4525
4526 if (size == 2 || size == 0 || size >= CY_PIP_1P7_EMPTY_BUF)
4527 return 0;
4528
4529 p = kzalloc(size, GFP_KERNEL);
4530 if (!p)
4531 return -ENOMEM;
4532
4533 rc = cyttsp5_adap_read_default(cd, p, size);
4534 kfree(p);
4535 if (rc < 0)
4536 return rc;
4537 } while (retry--);
4538
4539 return -EINVAL;
4540 }
4541
cyttsp5_startup_(struct cyttsp5_core_data * cd,bool reset)4542 static int cyttsp5_startup_(struct cyttsp5_core_data *cd, bool reset)
4543 {
4544 int retry = CY_CORE_STARTUP_RETRY_COUNT;
4545 int rc;
4546 bool detected = false;
4547
4548 #ifdef TTHE_TUNER_SUPPORT
4549 tthe_print(cd, NULL, 0, "enter startup");
4550 #endif
4551
4552 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
4553 cyttsp5_stop_wd_timer(cd);
4554 #endif
4555 //printk("++++++++++cyttsp5_startup_ start reset=%d\n", reset);
4556
4557 reset:
4558 if (retry != CY_CORE_STARTUP_RETRY_COUNT)
4559 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: Retry %d\n",
4560 __func__, CY_CORE_STARTUP_RETRY_COUNT - retry);
4561
4562 rc = cyttsp5_check_and_deassert_int(cd);
4563
4564 if (reset || retry != CY_CORE_STARTUP_RETRY_COUNT) {
4565 /* reset hardware */
4566 //printk("++++++++++cyttsp5_startup_ cyttsp5_reset_and_wait\n");
4567 rc = cyttsp5_reset_and_wait(cd);
4568 if (rc < 0) {
4569 dev_err(cd->dev, "%s: Error on h/w reset r=%d\n",
4570 __func__, rc);
4571 if (retry--)
4572 goto reset;
4573 //printk("++++++++++cyttsp5_startup_ goto exit\n");
4574 goto exit;
4575 }
4576 }
4577
4578 //printk("++++++++++cyttsp5_startup_ next\n");
4579 rc = cyttsp5_get_hid_descriptor_(cd, &cd->hid_desc);
4580 if (rc < 0) {
4581 dev_err(cd->dev, "%s: Error on getting HID descriptor r=%d\n",
4582 __func__, rc);
4583 if (retry--)
4584 goto reset;
4585 goto exit;
4586 }
4587 cd->mode = cyttsp5_get_mode(cd, &cd->hid_desc);
4588
4589 detected = true;
4590
4591 /* Switch to bootloader mode to get Panel ID */
4592 if (cd->mode == CY_MODE_OPERATIONAL) {
4593 rc = cyttsp5_hid_output_start_bootloader_(cd);
4594 if (rc < 0) {
4595 dev_err(cd->dev, "%s: Error on start bootloader r=%d\n",
4596 __func__, rc);
4597 if (retry--)
4598 goto reset;
4599 goto exit;
4600 }
4601 dev_info(cd->dev, "%s: Bootloader mode\n", __func__);
4602 }
4603
4604 cyttsp5_hid_output_bl_get_panel_id_(cd, &cd->panel_id);
4605
4606 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: Panel ID: 0x%02X\n",
4607 __func__, cd->panel_id);
4608
4609 rc = cyttsp5_hid_output_bl_launch_app_(cd);
4610 if (rc < 0) {
4611 dev_err(cd->dev, "%s: Error on launch app r=%d\n",
4612 __func__, rc);
4613 if (retry--)
4614 goto reset;
4615 goto exit;
4616 }
4617
4618 rc = cyttsp5_get_hid_descriptor_(cd, &cd->hid_desc);
4619 if (rc < 0) {
4620 dev_err(cd->dev,
4621 "%s: Error on getting HID descriptor r=%d\n",
4622 __func__, rc);
4623 if (retry--)
4624 goto reset;
4625 goto exit;
4626 }
4627 cd->mode = cyttsp5_get_mode(cd, &cd->hid_desc);
4628 if (cd->mode == CY_MODE_BOOTLOADER) {
4629 if (retry--)
4630 goto reset;
4631 goto exit;
4632 }
4633
4634 mutex_lock(&cd->system_lock);
4635 /* Read descriptor lengths */
4636 cd->hid_core.hid_report_desc_len =
4637 le16_to_cpu(cd->hid_desc.report_desc_len);
4638 cd->hid_core.hid_max_input_len =
4639 le16_to_cpu(cd->hid_desc.max_input_len);
4640 cd->hid_core.hid_max_output_len =
4641 le16_to_cpu(cd->hid_desc.max_output_len);
4642
4643 cd->mode = cyttsp5_get_mode(cd, &cd->hid_desc);
4644 if (cd->mode == CY_MODE_OPERATIONAL)
4645 dev_info(cd->dev, "%s: Operational mode\n", __func__);
4646 else if (cd->mode == CY_MODE_BOOTLOADER)
4647 dev_info(cd->dev, "%s: Bootloader mode\n", __func__);
4648 else if (cd->mode == CY_MODE_UNKNOWN) {
4649 dev_err(cd->dev, "%s: Unknown mode\n", __func__);
4650 rc = -ENODEV;
4651 mutex_unlock(&cd->system_lock);
4652 if (retry--)
4653 goto reset;
4654 goto exit;
4655 }
4656 mutex_unlock(&cd->system_lock);
4657
4658 dev_info(cd->dev, "%s: Reading report descriptor\n", __func__);
4659 rc = cyttsp5_get_report_descriptor_(cd);
4660 if (rc < 0) {
4661 dev_err(cd->dev, "%s: Error on getting report descriptor r=%d\n",
4662 __func__, rc);
4663 if (retry--)
4664 goto reset;
4665 goto exit;
4666 }
4667
4668 if (!cd->features.easywake)
4669 cd->easy_wakeup_gesture = CY_CORE_EWG_NONE;
4670
4671 rc = cyttsp5_hid_output_get_sysinfo_(cd);
4672 if (rc) {
4673 dev_err(cd->dev, "%s: Error on getting sysinfo r=%d\n",
4674 __func__, rc);
4675 if (retry--)
4676 goto reset;
4677 goto exit;
4678 }
4679
4680 dev_info(cd->dev, "cyttsp5 Protocol Version: %d.%d\n",
4681 cd->sysinfo.cydata.pip_ver_major,
4682 cd->sysinfo.cydata.pip_ver_minor);
4683
4684 /* Read config version directly if PIP version < 1.2 */
4685 if (!IS_PIP_VER_GE(&cd->sysinfo, 1, 2)) {
4686 rc = cyttsp5_get_config_ver_(cd);
4687 if (rc)
4688 dev_err(cd->dev, "%s: failed to read config version rc=%d\n",
4689 __func__, rc);
4690 }
4691
4692 rc = cyttsp5_get_ic_crc_(cd, CY_TCH_PARM_EBID);
4693 if (rc)
4694 dev_err(cd->dev, "%s: failed to crc data rc=%d\n",
4695 __func__, rc);
4696
4697 rc = cyttsp5_restore_parameters_(cd);
4698 if (rc)
4699 dev_err(cd->dev, "%s: failed to restore parameters rc=%d\n",
4700 __func__, rc);
4701
4702 /* attention startup */
4703 call_atten_cb(cd, CY_ATTEN_STARTUP, 0);
4704
4705 exit:
4706 if (!rc)
4707 cd->startup_retry_count = 0;
4708
4709 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
4710 cyttsp5_start_wd_timer(cd);
4711 #endif
4712 if (!detected)
4713 rc = -ENODEV;
4714
4715 #ifdef TTHE_TUNER_SUPPORT
4716 tthe_print(cd, NULL, 0, "exit startup");
4717 #endif
4718
4719 return rc;
4720 }
4721
cyttsp5_startup(struct cyttsp5_core_data * cd,bool reset)4722 static int cyttsp5_startup(struct cyttsp5_core_data *cd, bool reset)
4723 {
4724 int rc;
4725
4726 mutex_lock(&cd->system_lock);
4727 cd->startup_state = STARTUP_RUNNING;
4728 mutex_unlock(&cd->system_lock);
4729
4730 rc = request_exclusive(cd, cd->dev, CY_REQUEST_EXCLUSIVE_TIMEOUT);
4731 if (rc < 0) {
4732 dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
4733 __func__, cd->exclusive_dev, cd->dev);
4734 goto exit;
4735 }
4736
4737 rc = cyttsp5_startup_(cd, reset);
4738
4739 if (release_exclusive(cd, cd->dev) < 0)
4740 /* Don't return fail code, mode is already changed. */
4741 dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
4742 else
4743 parade_debug(cd->dev, DEBUG_LEVEL_2, "%s: pass release exclusive\n",
4744 __func__);
4745
4746 exit:
4747 mutex_lock(&cd->system_lock);
4748 cd->startup_state = STARTUP_NONE;
4749 mutex_unlock(&cd->system_lock);
4750
4751 /* Wake the waiters for end of startup */
4752 wake_up(&cd->wait_q);
4753
4754 return rc;
4755 }
4756
cyttsp5_startup_work_function(struct work_struct * work)4757 static void cyttsp5_startup_work_function(struct work_struct *work)
4758 {
4759 struct cyttsp5_core_data *cd = container_of(work,
4760 struct cyttsp5_core_data, startup_work);
4761 int rc;
4762
4763 rc = cyttsp5_startup(cd, true);
4764 if (rc < 0)
4765 dev_err(cd->dev, "%s: Fail queued startup r=%d\n",
4766 __func__, rc);
4767 }
4768
4769 /*
4770 * CONFIG_PM_RUNTIME option is removed in 3.19.0.
4771 */
4772 #if defined(CONFIG_PM_RUNTIME) || \
4773 (KERNEL_VERSION(3, 19, 0) <= LINUX_VERSION_CODE)
cyttsp5_core_rt_suspend(struct device * dev)4774 static int cyttsp5_core_rt_suspend(struct device *dev)
4775 {
4776 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4777 int rc;
4778 //printk("cyttsp5_core_rt_suspend\n");
4779 rc = cyttsp5_core_sleep(cd);
4780 if (rc < 0) {
4781 dev_err(dev, "%s: Error on sleep\n", __func__);
4782 return -EAGAIN;
4783 }
4784 return 0;
4785 }
4786
cyttsp5_core_rt_resume(struct device * dev)4787 static int cyttsp5_core_rt_resume(struct device *dev)
4788 {
4789 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4790 int rc;
4791
4792 //printk("cyttsp5_core_rt_resume\n");
4793 rc = cyttsp5_core_wake(cd);
4794 if (rc < 0) {
4795 dev_err(dev, "%s: Error on wake\n", __func__);
4796 return -EAGAIN;
4797 }
4798
4799 return 0;
4800 }
4801 #endif
4802
4803 #if defined(CONFIG_PM_SLEEP)
cyttsp5_core_suspend(struct device * dev)4804 static int cyttsp5_core_suspend(struct device *dev)
4805 {
4806 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4807
4808 if (cd->is_suspend)
4809 return 0;
4810 cyttsp5_core_sleep(cd);
4811
4812 return 0;
4813 }
4814
cyttsp5_core_resume(struct device * dev)4815 static int cyttsp5_core_resume(struct device *dev)
4816 {
4817 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4818
4819 if (cd->is_suspend)
4820 return 0;
4821 cyttsp5_core_wake(cd);
4822
4823 return 0;
4824 }
4825
cyttsp5_core_early_suspend(struct tp_device * tp_d)4826 static int cyttsp5_core_early_suspend(struct tp_device *tp_d)
4827 {
4828 struct cyttsp5_core_data *cd = container_of(tp_d, struct cyttsp5_core_data, tp);
4829
4830 cyttsp5_core_sleep(cd);
4831 if (!cd->irq_disabled) {
4832 disable_irq(cd->irq);
4833 cd->irq_disabled = 1;
4834 }
4835 gpio_direction_output(cd->cpdata->rst_gpio, 0);
4836 gpio_direction_output(cd->cpdata->irq_gpio, 0);
4837 if (cd->supply)
4838 regulator_disable(cd->supply);
4839 cd->is_suspend = 1;
4840
4841 return 0;
4842 }
4843
cyttsp5_core_late_resume(struct tp_device * tp_d)4844 static int cyttsp5_core_late_resume(struct tp_device *tp_d)
4845 {
4846 struct cyttsp5_core_data *cd = container_of(tp_d, struct cyttsp5_core_data, tp);
4847 int ret;
4848
4849 if (cd->supply) {
4850 ret = regulator_enable(cd->supply);
4851 if (ret < 0)
4852 dev_err(cd->dev, "failed to enable cyttsp5 power supply\n");
4853 }
4854 gpio_direction_input(cd->cpdata->irq_gpio);
4855 cyttsp5_hw_hard_reset(cd);
4856 if (cd->irq_disabled) {
4857 enable_irq(cd->irq);
4858 cd->irq_disabled = 0;
4859 }
4860 cyttsp5_core_wake(cd);
4861 cd->is_suspend = 0;
4862
4863 return 0;
4864 }
4865 #endif
4866
4867 #if NEED_SUSPEND_NOTIFIER
cyttsp5_pm_notifier(struct notifier_block * nb,unsigned long action,void * data)4868 static int cyttsp5_pm_notifier(struct notifier_block *nb,
4869 unsigned long action, void *data)
4870 {
4871 struct cyttsp5_core_data *cd = container_of(nb,
4872 struct cyttsp5_core_data, pm_notifier);
4873
4874 if (action == PM_SUSPEND_PREPARE) {
4875 parade_debug(cd->dev, DEBUG_LEVEL_1, "%s: Suspend prepare\n",
4876 __func__);
4877
4878 /*
4879 * If not runtime PM suspended, either call runtime
4880 * PM suspend callback or wait until it finishes
4881 */
4882 if (!pm_runtime_suspended(cd->dev))
4883 pm_runtime_suspend(cd->dev);
4884
4885 (void) cyttsp5_core_suspend(cd->dev);
4886 }
4887
4888 return NOTIFY_DONE;
4889 }
4890 #endif
4891
4892 const struct dev_pm_ops cyttsp5_pm_ops = {
4893 SET_LATE_SYSTEM_SLEEP_PM_OPS(cyttsp5_core_suspend, cyttsp5_core_resume)
4894 SET_RUNTIME_PM_OPS(cyttsp5_core_rt_suspend, cyttsp5_core_rt_resume,
4895 NULL)
4896 };
4897 EXPORT_SYMBOL_GPL(cyttsp5_pm_ops);
4898
4899 /*
4900 * Show Firmware version via sysfs
4901 */
cyttsp5_ic_ver_show(struct device * dev,struct device_attribute * attr,char * buf)4902 static ssize_t cyttsp5_ic_ver_show(struct device *dev,
4903 struct device_attribute *attr, char *buf)
4904 {
4905 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4906 struct cyttsp5_cydata *cydata = &cd->sysinfo.cydata;
4907
4908 return sprintf(buf,
4909 "%s: 0x%02X\n"
4910 "%s: 0x%02X\n"
4911 "%s: 0x%08X\n"
4912 "%s: 0x%04X\n"
4913 "%s: 0x%02X\n"
4914 "%s: 0x%02X\n"
4915 "%s: 0x%02X\n"
4916 "%s: 0x%02X\n",
4917 "Firmware Major Version", cydata->fw_ver_major,
4918 "Firmware Minor Version", cydata->fw_ver_minor,
4919 "Revision Control Number", cydata->revctrl,
4920 "Firmware Configuration Version", cydata->fw_ver_conf,
4921 "Bootloader Major Version", cydata->bl_ver_major,
4922 "Bootloader Minor Version", cydata->bl_ver_minor,
4923 "Protocol Major Version", cydata->pip_ver_major,
4924 "Protocol Minor Version", cydata->pip_ver_minor);
4925 }
4926
4927 /*
4928 * Show Driver version via sysfs
4929 */
cyttsp5_drv_ver_show(struct device * dev,struct device_attribute * attr,char * buf)4930 static ssize_t cyttsp5_drv_ver_show(struct device *dev,
4931 struct device_attribute *attr, char *buf)
4932 {
4933 return snprintf(buf, CY_MAX_PRBUF_SIZE,
4934 "Driver: %s\nVersion: %s\nDate: %s\n",
4935 cy_driver_core_name, cy_driver_core_version,
4936 cy_driver_core_date);
4937 }
4938
4939 /*
4940 * HW reset via sysfs
4941 */
cyttsp5_hw_reset_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)4942 static ssize_t cyttsp5_hw_reset_store(struct device *dev,
4943 struct device_attribute *attr, const char *buf, size_t size)
4944 {
4945 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4946 int rc;
4947
4948 rc = cyttsp5_startup(cd, true);
4949 if (rc < 0)
4950 dev_err(dev, "%s: HW reset failed r=%d\n",
4951 __func__, rc);
4952
4953 return size;
4954 }
4955
4956 /*
4957 * Show IRQ status via sysfs
4958 */
cyttsp5_hw_irq_stat_show(struct device * dev,struct device_attribute * attr,char * buf)4959 static ssize_t cyttsp5_hw_irq_stat_show(struct device *dev,
4960 struct device_attribute *attr, char *buf)
4961 {
4962 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4963 int retval;
4964
4965 if (cd->cpdata->irq_stat) {
4966 retval = cd->cpdata->irq_stat(cd->cpdata, dev);
4967 switch (retval) {
4968 case 0:
4969 return snprintf(buf, CY_MAX_PRBUF_SIZE,
4970 "Interrupt line is LOW.\n");
4971 case 1:
4972 return snprintf(buf, CY_MAX_PRBUF_SIZE,
4973 "Interrupt line is HIGH.\n");
4974 default:
4975 return snprintf(buf, CY_MAX_PRBUF_SIZE,
4976 "Function irq_stat() returned %d.\n", retval);
4977 }
4978 }
4979
4980 return snprintf(buf, CY_MAX_PRBUF_SIZE,
4981 "Function irq_stat() undefined.\n");
4982 }
4983
4984 /*
4985 * Show IRQ enable/disable status via sysfs
4986 */
cyttsp5_drv_irq_show(struct device * dev,struct device_attribute * attr,char * buf)4987 static ssize_t cyttsp5_drv_irq_show(struct device *dev,
4988 struct device_attribute *attr, char *buf)
4989 {
4990 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
4991 ssize_t ret;
4992
4993 mutex_lock(&cd->system_lock);
4994 if (cd->irq_enabled)
4995 ret = snprintf(buf, CY_MAX_PRBUF_SIZE,
4996 "Driver interrupt is ENABLED\n");
4997 else
4998 ret = snprintf(buf, CY_MAX_PRBUF_SIZE,
4999 "Driver interrupt is DISABLED\n");
5000 mutex_unlock(&cd->system_lock);
5001
5002 return ret;
5003 }
5004
5005 /*
5006 * Enable/disable IRQ via sysfs
5007 */
cyttsp5_drv_irq_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)5008 static ssize_t cyttsp5_drv_irq_store(struct device *dev,
5009 struct device_attribute *attr, const char *buf, size_t size)
5010 {
5011 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
5012 unsigned long value;
5013 int retval = 0;
5014
5015 retval = kstrtoul(buf, 10, &value);
5016 if (retval < 0) {
5017 dev_err(dev, "%s: Invalid value\n", __func__);
5018 goto cyttsp5_drv_irq_store_error_exit;
5019 }
5020
5021 mutex_lock(&cd->system_lock);
5022 switch (value) {
5023 case 0:
5024 if (cd->irq_enabled) {
5025 cd->irq_enabled = false;
5026 /* Disable IRQ */
5027 disable_irq_nosync(cd->irq);
5028 dev_info(dev, "%s: Driver IRQ now disabled\n",
5029 __func__);
5030 } else
5031 dev_info(dev, "%s: Driver IRQ already disabled\n",
5032 __func__);
5033 break;
5034
5035 case 1:
5036 if (cd->irq_enabled == false) {
5037 cd->irq_enabled = true;
5038 /* Enable IRQ */
5039 enable_irq(cd->irq);
5040 dev_info(dev, "%s: Driver IRQ now enabled\n",
5041 __func__);
5042 } else
5043 dev_info(dev, "%s: Driver IRQ already enabled\n",
5044 __func__);
5045 break;
5046
5047 default:
5048 dev_err(dev, "%s: Invalid value\n", __func__);
5049 }
5050 mutex_unlock(&(cd->system_lock));
5051
5052 cyttsp5_drv_irq_store_error_exit:
5053
5054 return size;
5055 }
5056
5057 /*
5058 * Gets user input from sysfs and parse it
5059 * return size of parsed output buffer
5060 */
5061
5062 #define CY_MAX_CONFIG_BYTES_DEC 256
5063 #define CYTTSP5_INPUT_ELEM_SZ_DEC 10
5064
cyttsp5_ic_parse_input_dec(struct device * dev,const char * buf,size_t buf_size,u32 * ic_buf,size_t ic_buf_size)5065 static int cyttsp5_ic_parse_input_dec(struct device *dev, const char *buf,
5066 size_t buf_size, u32 *ic_buf, size_t ic_buf_size)
5067 {
5068 const char *pbuf = buf;
5069 unsigned long value;
5070 char scan_buf[CYTTSP5_INPUT_ELEM_SZ_DEC];
5071 u32 i = 0;
5072 u32 j;
5073 int last = 0;
5074 int ret;
5075
5076 parade_debug(dev, DEBUG_LEVEL_1, "%s: pbuf=%p buf=%p size=%zu %s=%zu buf=%s\n",
5077 __func__, pbuf, buf, buf_size, "scan buf size",
5078 (size_t)CYTTSP5_INPUT_ELEM_SZ_DEC, buf);
5079
5080 while (pbuf <= (buf + buf_size)) {
5081 if (i >= CY_MAX_CONFIG_BYTES_DEC) {
5082 dev_err(dev, "%s: %s size=%d max=%d\n", __func__,
5083 "Max cmd size exceeded", i,
5084 CY_MAX_CONFIG_BYTES_DEC);
5085 return -EINVAL;
5086 }
5087 if (i >= ic_buf_size) {
5088 dev_err(dev, "%s: %s size=%d buf_size=%zu\n", __func__,
5089 "Buffer size exceeded", i, ic_buf_size);
5090 return -EINVAL;
5091 }
5092 while (((*pbuf == ' ') || (*pbuf == ','))
5093 && (pbuf < (buf + buf_size))) {
5094 last = *pbuf;
5095 pbuf++;
5096 }
5097
5098 if (pbuf >= (buf + buf_size))
5099 break;
5100
5101 memset(scan_buf, 0, CYTTSP5_INPUT_ELEM_SZ_DEC);
5102 if ((last == ',') && (*pbuf == ',')) {
5103 dev_err(dev, "%s: %s \",,\" not allowed.\n", __func__,
5104 "Invalid data format.");
5105 return -EINVAL;
5106 }
5107 for (j = 0; j < (CYTTSP5_INPUT_ELEM_SZ_DEC - 1)
5108 && (pbuf < (buf + buf_size))
5109 && (*pbuf != ' ')
5110 && (*pbuf != ','); j++) {
5111 last = *pbuf;
5112 scan_buf[j] = *pbuf++;
5113 }
5114 ret = kstrtoul(scan_buf, 10, &value);
5115 if (ret < 0) {
5116 dev_err(dev, "%s: Invalid data format.\n", __func__);
5117 return ret;
5118 }
5119
5120 ic_buf[i] = value;
5121 i++;
5122 }
5123
5124 return i;
5125 }
5126
5127 /*
5128 * Debugging options via sysfs
5129 */
cyttsp5_drv_debug_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)5130 static ssize_t cyttsp5_drv_debug_store(struct device *dev,
5131 struct device_attribute *attr, const char *buf, size_t size)
5132 {
5133 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
5134 unsigned long value;
5135 int rc;
5136 u8 return_data[8];
5137 static u8 wd_disabled;
5138 u32 input_data[2];
5139 int length;
5140
5141 /*maximal input two data*/
5142 length = cyttsp5_ic_parse_input_dec(dev, buf, size, input_data,
5143 3);
5144 if (length <= 0) {
5145 dev_err(dev, "%s: %s failed\n", __func__,
5146 "cyttsp5_ic_parse_input_dec");
5147 goto cyttsp5_drv_debug_store_exit;
5148 }
5149 value = input_data[0];
5150
5151
5152 /* Start watchdog timer command */
5153 if (value == CY_DBG_HID_START_WD) {
5154 dev_info(dev, "%s: start watchdog (cd=%p)\n", __func__, cd);
5155 wd_disabled = 0;
5156 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
5157 cyttsp5_start_wd_timer(cd);
5158 #endif
5159 goto cyttsp5_drv_debug_store_exit;
5160 }
5161
5162 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
5163 /* Stop watchdog timer temporarily */
5164 cyttsp5_stop_wd_timer(cd);
5165 #endif
5166 if (value == CY_DBG_HID_STOP_WD) {
5167 dev_info(dev, "%s: stop watchdog (cd=%p)\n", __func__, cd);
5168 wd_disabled = 1;
5169 goto cyttsp5_drv_debug_store_exit;
5170 }
5171
5172 switch (value) {
5173 case CY_DBG_SUSPEND:
5174 dev_info(dev, "%s: SUSPEND (cd=%p)\n", __func__, cd);
5175 rc = cyttsp5_core_sleep(cd);
5176 if (rc)
5177 dev_err(dev, "%s: Suspend failed rc=%d\n",
5178 __func__, rc);
5179 else
5180 dev_info(dev, "%s: Suspend succeeded\n", __func__);
5181 break;
5182
5183 case CY_DBG_RESUME:
5184 dev_info(dev, "%s: RESUME (cd=%p)\n", __func__, cd);
5185 rc = cyttsp5_core_wake(cd);
5186 if (rc)
5187 dev_err(dev, "%s: Resume failed rc=%d\n",
5188 __func__, rc);
5189 else
5190 dev_info(dev, "%s: Resume succeeded\n", __func__);
5191 break;
5192 case CY_DBG_SOFT_RESET:
5193 dev_info(dev, "%s: SOFT RESET (cd=%p)\n", __func__, cd);
5194 rc = cyttsp5_hw_soft_reset(cd);
5195 break;
5196 case CY_DBG_RESET:
5197 dev_info(dev, "%s: HARD RESET (cd=%p)\n", __func__, cd);
5198 rc = cyttsp5_hw_hard_reset(cd);
5199 break;
5200 case CY_DBG_HID_RESET:
5201 dev_info(dev, "%s: hid_reset (cd=%p)\n", __func__, cd);
5202 cyttsp5_hid_cmd_reset(cd);
5203 break;
5204 case CY_DBG_HID_SET_POWER_ON:
5205 dev_info(dev, "%s: hid_set_power_on (cd=%p)\n", __func__, cd);
5206 cyttsp5_hid_cmd_set_power(cd, HID_POWER_ON);
5207 wd_disabled = 0;
5208 break;
5209 case CY_DBG_HID_SET_POWER_SLEEP:
5210 dev_info(dev, "%s: hid_set_power_off (cd=%p)\n", __func__, cd);
5211 wd_disabled = 1;
5212 cyttsp5_hid_cmd_set_power(cd, HID_POWER_SLEEP);
5213 break;
5214 case CY_DBG_HID_NULL:
5215 dev_info(dev, "%s: hid_null (cd=%p)\n", __func__, cd);
5216 cyttsp5_hid_output_null(cd);
5217 break;
5218 case CY_DBG_HID_ENTER_BL:
5219 dev_info(dev, "%s: start_bootloader (cd=%p)\n", __func__, cd);
5220 cyttsp5_hid_output_start_bootloader(cd);
5221 break;
5222 case CY_DBG_HID_SYSINFO:
5223 dev_info(dev, "%s: get_sysinfo (cd=%p)\n", __func__, cd);
5224 cyttsp5_hid_output_get_sysinfo(cd);
5225 break;
5226 case CY_DBG_HID_SUSPEND_SCAN:
5227 dev_info(dev, "%s: suspend_scanning (cd=%p)\n", __func__, cd);
5228 cyttsp5_hid_output_suspend_scanning(cd);
5229 break;
5230 case CY_DBG_HID_RESUME_SCAN:
5231 dev_info(dev, "%s: resume_scanning (cd=%p)\n", __func__, cd);
5232 cyttsp5_hid_output_resume_scanning(cd);
5233 break;
5234 case HID_OUTPUT_BL_VERIFY_APP_INTEGRITY:
5235 dev_info(dev, "%s: verify app integ (cd=%p)\n", __func__, cd);
5236 cyttsp5_hid_output_bl_verify_app_integrity(cd, &return_data[0]);
5237 break;
5238 case HID_OUTPUT_BL_GET_INFO:
5239 dev_info(dev, "%s: bl get info (cd=%p)\n", __func__, cd);
5240 cyttsp5_hid_output_bl_get_information(cd, return_data);
5241 break;
5242 case HID_OUTPUT_BL_PROGRAM_AND_VERIFY:
5243 dev_info(dev, "%s: program and verify (cd=%p)\n", __func__, cd);
5244 cyttsp5_hid_output_bl_program_and_verify(cd, 0, NULL);
5245 break;
5246 case HID_OUTPUT_BL_LAUNCH_APP:
5247 dev_info(dev, "%s: launch app (cd=%p)\n", __func__, cd);
5248 cyttsp5_hid_output_bl_launch_app(cd);
5249 break;
5250 case HID_OUTPUT_BL_INITIATE_BL:
5251 dev_info(dev, "%s: initiate bl (cd=%p)\n", __func__, cd);
5252 cyttsp5_hid_output_bl_initiate_bl(cd, 0, NULL, 0, NULL);
5253 break;
5254 #ifdef TTHE_TUNER_SUPPORT
5255 case CY_TTHE_TUNER_EXIT:
5256 cd->tthe_exit = 1;
5257 wake_up(&cd->wait_q);
5258 kfree(cd->tthe_buf);
5259 cd->tthe_buf = NULL;
5260 cd->tthe_exit = 0;
5261 break;
5262 case CY_TTHE_BUF_CLEAN:
5263 if (cd->tthe_buf)
5264 memset(cd->tthe_buf, 0, CY_MAX_PRBUF_SIZE);
5265 else
5266 dev_info(dev, "%s : tthe_buf not existed\n", __func__);
5267 break;
5268 #endif
5269 case CY_DBG_REPORT_LEVEL:
5270 mutex_lock(&cd->system_lock);
5271 cd->debug_level = input_data[1];
5272 dev_info(dev, "%s: Set debug_level: %d\n",
5273 __func__, cd->debug_level);
5274 mutex_unlock(&(cd->system_lock));
5275 break;
5276 case CY_DBG_WATCHDOG_INTERVAL:
5277 mutex_lock(&cd->system_lock);
5278 if (input_data[1] > 0)
5279 cd->watchdog_interval = input_data[1];
5280 dev_info(dev, "%s: Set watchdog_interval: %d\n",
5281 __func__, cd->watchdog_interval);
5282 mutex_unlock(&(cd->system_lock));
5283 break;
5284 case CY_DBG_SHOW_TIMESTAMP:
5285 mutex_lock(&cd->system_lock);
5286 cd->show_timestamp = input_data[1];
5287 dev_info(dev, "%s: Set show_timestamp: %d\n",
5288 __func__, cd->show_timestamp);
5289 mutex_unlock(&(cd->system_lock));
5290 break;
5291
5292 default:
5293 dev_err(dev, "%s: Invalid value\n", __func__);
5294 }
5295
5296 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
5297 /* Enable watchdog timer */
5298 if (!wd_disabled)
5299 cyttsp5_start_wd_timer(cd);
5300 #endif
5301 cyttsp5_drv_debug_store_exit:
5302 return size;
5303 }
5304
5305 /*
5306 * Show system status on deep sleep status via sysfs
5307 */
cyttsp5_sleep_status_show(struct device * dev,struct device_attribute * attr,char * buf)5308 static ssize_t cyttsp5_sleep_status_show(struct device *dev,
5309 struct device_attribute *attr, char *buf)
5310 {
5311 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
5312 ssize_t ret;
5313
5314 mutex_lock(&cd->system_lock);
5315 if (cd->sleep_state == SS_SLEEP_ON)
5316 ret = snprintf(buf, CY_MAX_PRBUF_SIZE, "off\n");
5317 else
5318 ret = snprintf(buf, CY_MAX_PRBUF_SIZE, "on\n");
5319 mutex_unlock(&cd->system_lock);
5320
5321 return ret;
5322 }
5323
cyttsp5_easy_wakeup_gesture_show(struct device * dev,struct device_attribute * attr,char * buf)5324 static ssize_t cyttsp5_easy_wakeup_gesture_show(struct device *dev,
5325 struct device_attribute *attr, char *buf)
5326 {
5327 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
5328 ssize_t ret;
5329
5330 mutex_lock(&cd->system_lock);
5331 ret = snprintf(buf, CY_MAX_PRBUF_SIZE, "0x%02X\n",
5332 cd->easy_wakeup_gesture);
5333 mutex_unlock(&cd->system_lock);
5334 return ret;
5335 }
5336
cyttsp5_easy_wakeup_gesture_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)5337 static ssize_t cyttsp5_easy_wakeup_gesture_store(struct device *dev,
5338 struct device_attribute *attr, const char *buf, size_t size)
5339 {
5340 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
5341 unsigned long value;
5342 int ret;
5343
5344 if (!cd->features.easywake)
5345 return -EINVAL;
5346
5347 ret = kstrtoul(buf, 10, &value);
5348 if (ret < 0)
5349 return ret;
5350
5351 if (value > 0xFF)
5352 return -EINVAL;
5353
5354 pm_runtime_get_sync(dev);
5355
5356 mutex_lock(&cd->system_lock);
5357 if (cd->sysinfo.ready && IS_PIP_VER_GE(&cd->sysinfo, 1, 2))
5358 cd->easy_wakeup_gesture = (u8)value;
5359 else
5360 ret = -ENODEV;
5361 mutex_unlock(&cd->system_lock);
5362
5363 pm_runtime_put(dev);
5364
5365 if (ret)
5366 return ret;
5367
5368 return size;
5369 }
5370
5371 #ifdef EASYWAKE_TSG6
5372 /*
5373 * Show easywake gesture id via sysfs
5374 */
cyttsp5_easy_wakeup_gesture_id_show(struct device * dev,struct device_attribute * attr,char * buf)5375 static ssize_t cyttsp5_easy_wakeup_gesture_id_show(struct device *dev,
5376 struct device_attribute *attr, char *buf)
5377 {
5378 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
5379 ssize_t ret;
5380
5381 mutex_lock(&cd->system_lock);
5382 ret = snprintf(buf, CY_MAX_PRBUF_SIZE, "0x%02X\n",
5383 cd->gesture_id);
5384 mutex_unlock(&cd->system_lock);
5385 return ret;
5386 }
5387
5388 /*
5389 * Show easywake gesture data via sysfs
5390 * The format:
5391 * x1(LSB), x1(MSB),y1(LSB), y1(MSB),x2(LSB), x2(MSB),y2(LSB), y2(MSB),...
5392 */
cyttsp5_easy_wakeup_gesture_data_show(struct device * dev,struct device_attribute * attr,char * buf)5393 static ssize_t cyttsp5_easy_wakeup_gesture_data_show(struct device *dev,
5394 struct device_attribute *attr, char *buf)
5395 {
5396 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
5397 ssize_t ret = 0;
5398 int i;
5399
5400 mutex_lock(&cd->system_lock);
5401
5402 for (i = 0; i < cd->gesture_data_length; i++)
5403 ret += snprintf(buf + ret, CY_MAX_PRBUF_SIZE - ret,
5404 "0x%02X\n", cd->gesture_data[i]);
5405
5406 ret += snprintf(buf + ret, CY_MAX_PRBUF_SIZE - ret,
5407 "(%d bytes)\n", cd->gesture_data_length);
5408
5409 mutex_unlock(&cd->system_lock);
5410 return ret;
5411 }
5412 #endif
5413
5414 /* Show Panel ID via sysfs */
cyttsp5_panel_id_show(struct device * dev,struct device_attribute * attr,char * buf)5415 static ssize_t cyttsp5_panel_id_show(struct device *dev,
5416 struct device_attribute *attr, char *buf)
5417 {
5418 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
5419 ssize_t ret;
5420
5421 ret = snprintf(buf, CY_MAX_PRBUF_SIZE, "0x%02X\n",
5422 cd->panel_id);
5423 return ret;
5424 }
5425
5426 /* Show platform data via sysfs */
cyttsp5_platform_data_show(struct device * dev,struct device_attribute * attr,char * buf)5427 static ssize_t cyttsp5_platform_data_show(struct device *dev,
5428 struct device_attribute *attr, char *buf)
5429 {
5430 struct cyttsp5_platform_data *pdata = dev_get_platdata(dev);
5431 ssize_t ret;
5432
5433 ret = sprintf(buf,
5434 "%s: %d\n"
5435 "%s: %d\n"
5436 "%s: %d\n"
5437 "%s: %d\n"
5438 "%s: %d\n"
5439 "%s: %d\n"
5440 "%s: %d\n"
5441 "%s: %d\n"
5442 "%s: %d\n"
5443 "%s: %d\n"
5444 "%s: %d\n"
5445 "%s: %d\n",
5446 "Interrupt GPIO", pdata->core_pdata->irq_gpio,
5447 "Reset GPIO", pdata->core_pdata->rst_gpio,
5448 "Level trigger delay (us)", pdata->core_pdata->level_irq_udelay,
5449 "HID descriptor register", pdata->core_pdata->hid_desc_register,
5450 "Vendor ID", pdata->core_pdata->vendor_id,
5451 "Product ID", pdata->core_pdata->product_id,
5452 "Easy wakeup gesture", pdata->core_pdata->easy_wakeup_gesture,
5453 "Vkeys x", pdata->mt_pdata->vkeys_x,
5454 "Vkeys y", pdata->mt_pdata->vkeys_y,
5455 "Core data flags", pdata->core_pdata->flags,
5456 "MT data flags", pdata->mt_pdata->flags,
5457 "Loader data flags", pdata->loader_pdata->flags);
5458 return ret;
5459 }
5460
5461 static struct device_attribute attributes[] = {
5462 __ATTR(ic_ver, S_IRUGO, cyttsp5_ic_ver_show, NULL),
5463 __ATTR(drv_ver, S_IRUGO, cyttsp5_drv_ver_show, NULL),
5464 __ATTR(hw_reset, S_IWUSR, NULL, cyttsp5_hw_reset_store),
5465 __ATTR(hw_irq_stat, S_IRUSR, cyttsp5_hw_irq_stat_show, NULL),
5466 __ATTR(drv_irq, S_IRUSR | S_IWUSR, cyttsp5_drv_irq_show,
5467 cyttsp5_drv_irq_store),
5468 __ATTR(drv_debug, S_IWUSR, NULL, cyttsp5_drv_debug_store),
5469 __ATTR(sleep_status, S_IRUSR, cyttsp5_sleep_status_show, NULL),
5470 __ATTR(easy_wakeup_gesture, S_IRUSR | S_IWUSR,
5471 cyttsp5_easy_wakeup_gesture_show,
5472 cyttsp5_easy_wakeup_gesture_store),
5473 #ifdef EASYWAKE_TSG6
5474 __ATTR(easy_wakeup_gesture_id, S_IRUSR,
5475 cyttsp5_easy_wakeup_gesture_id_show, NULL),
5476 __ATTR(easy_wakeup_gesture_data, S_IRUSR,
5477 cyttsp5_easy_wakeup_gesture_data_show, NULL),
5478 #endif
5479 __ATTR(panel_id, S_IRUGO, cyttsp5_panel_id_show, NULL),
5480 __ATTR(platform_data, S_IRUGO, cyttsp5_platform_data_show, NULL),
5481 };
5482
add_sysfs_interfaces(struct device * dev)5483 static int add_sysfs_interfaces(struct device *dev)
5484 {
5485 int i;
5486
5487 for (i = 0; i < ARRAY_SIZE(attributes); i++)
5488 if (device_create_file(dev, attributes + i))
5489 goto undo;
5490 return 0;
5491 undo:
5492 for (i--; i >= 0; i--)
5493 device_remove_file(dev, attributes + i);
5494 dev_err(dev, "%s: failed to create sysfs interface\n", __func__);
5495 return -ENODEV;
5496 }
5497
remove_sysfs_interfaces(struct device * dev)5498 static void remove_sysfs_interfaces(struct device *dev)
5499 {
5500 u32 i;
5501
5502 for (i = 0; i < ARRAY_SIZE(attributes); i++)
5503 device_remove_file(dev, attributes + i);
5504 }
5505
5506 /*
5507 * ttdl_restart via sysfs
5508 */
cyttsp5_ttdl_restart_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)5509 static ssize_t cyttsp5_ttdl_restart_store(struct device *dev,
5510 struct device_attribute *attr, const char *buf, size_t size)
5511 {
5512 int rc;
5513 struct i2c_client *client =
5514 (struct i2c_client *)container_of(dev, struct i2c_client, dev);
5515
5516 if (is_cyttsp5_probe_success) {
5517 dev_err(dev, "%s: previous cyttsp5_probe is successful, do nothing\n",
5518 __func__);
5519 return size;
5520 }
5521
5522 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
5523 dev_err(dev, "%s I2C functionality not Supported\n", __func__);
5524 return -EIO;
5525 }
5526
5527 #ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
5528 rc = cyttsp5_devtree_create_and_get_pdata(dev);
5529 if (rc < 0)
5530 return rc;
5531 #endif
5532
5533 rc = cyttsp5_probe(cyttsp5_bus_ops_save, &client->dev, client->irq,
5534 512);
5535
5536 if (!rc) {
5537 is_cyttsp5_probe_success = true;
5538 dev_err(dev, "%s restart successful\n", __func__);
5539 } else {
5540 is_cyttsp5_probe_success = false;
5541 dev_err(dev, "%s: ttdl restart failed r=%d\n",
5542 __func__, rc);
5543 }
5544
5545 #ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
5546 if (rc)
5547 cyttsp5_devtree_clean_pdata(dev);
5548 #endif
5549
5550 return size;
5551
5552 }
5553 static DEVICE_ATTR(ttdl_restart, S_IWUSR, NULL, cyttsp5_ttdl_restart_store);
5554
5555
5556 #ifdef TTHE_TUNER_SUPPORT
tthe_debugfs_open(struct inode * inode,struct file * filp)5557 static int tthe_debugfs_open(struct inode *inode, struct file *filp)
5558 {
5559 struct cyttsp5_core_data *cd = inode->i_private;
5560
5561 filp->private_data = inode->i_private;
5562
5563 if (cd->tthe_buf)
5564 return -EBUSY;
5565
5566 cd->tthe_buf = kzalloc(CY_MAX_PRBUF_SIZE, GFP_KERNEL);
5567 if (!cd->tthe_buf)
5568 return -ENOMEM;
5569
5570 return 0;
5571 }
5572
tthe_debugfs_close(struct inode * inode,struct file * filp)5573 static int tthe_debugfs_close(struct inode *inode, struct file *filp)
5574 {
5575 struct cyttsp5_core_data *cd = filp->private_data;
5576
5577 filp->private_data = NULL;
5578
5579 kfree(cd->tthe_buf);
5580 cd->tthe_buf = NULL;
5581
5582 return 0;
5583 }
5584
tthe_debugfs_read(struct file * filp,char __user * buf,size_t count,loff_t * ppos)5585 static ssize_t tthe_debugfs_read(struct file *filp, char __user *buf,
5586 size_t count, loff_t *ppos)
5587 {
5588 struct cyttsp5_core_data *cd = filp->private_data;
5589 int size;
5590 int ret;
5591
5592 wait_event_interruptible(cd->wait_q,
5593 cd->tthe_buf_len != 0 || cd->tthe_exit);
5594 mutex_lock(&cd->tthe_lock);
5595 if (cd->tthe_exit) {
5596 mutex_unlock(&cd->tthe_lock);
5597 return 0;
5598 }
5599 if (count > cd->tthe_buf_len)
5600 size = cd->tthe_buf_len;
5601 else
5602 size = count;
5603 if (!size) {
5604 mutex_unlock(&cd->tthe_lock);
5605 return 0;
5606 }
5607
5608 ret = copy_to_user(buf, cd->tthe_buf, cd->tthe_buf_len);
5609 if (ret == size)
5610 return -EFAULT;
5611 size -= ret;
5612 cd->tthe_buf_len -= size;
5613 mutex_unlock(&cd->tthe_lock);
5614 *ppos += size;
5615 return size;
5616 }
5617
5618 static const struct file_operations tthe_debugfs_fops = {
5619 .open = tthe_debugfs_open,
5620 .release = tthe_debugfs_close,
5621 .read = tthe_debugfs_read,
5622 };
5623 #endif
5624
5625 static struct cyttsp5_core_nonhid_cmd _cyttsp5_core_nonhid_cmd = {
5626 .start_bl = _cyttsp5_request_hid_output_start_bl,
5627 .suspend_scanning = _cyttsp5_request_hid_output_suspend_scanning,
5628 .resume_scanning = _cyttsp5_request_hid_output_resume_scanning,
5629 .get_param = _cyttsp5_request_hid_output_get_param,
5630 .set_param = _cyttsp5_request_hid_output_set_param,
5631 .verify_config_block_crc =
5632 _cyttsp5_request_hid_output_verify_config_block_crc,
5633 .get_config_row_size = _cyttsp5_request_hid_output_get_config_row_size,
5634 .get_data_structure = _cyttsp5_request_hid_output_get_data_structure,
5635 .run_selftest = _cyttsp5_request_hid_output_run_selftest,
5636 .get_selftest_result = _cyttsp5_request_hid_output_get_selftest_result,
5637 .calibrate_idacs = _cyttsp5_request_hid_output_calibrate_idacs,
5638 .initialize_baselines =
5639 _cyttsp5_request_hid_output_initialize_baselines,
5640 .exec_panel_scan = _cyttsp5_request_hid_output_exec_panel_scan,
5641 .retrieve_panel_scan = _cyttsp5_request_hid_output_retrieve_panel_scan,
5642 .write_conf_block = _cyttsp5_request_hid_output_write_conf_block,
5643 .user_cmd = _cyttsp5_request_hid_output_user_cmd,
5644 .get_bl_info = _cyttsp5_request_hid_output_bl_get_information,
5645 .initiate_bl = _cyttsp5_request_hid_output_bl_initiate_bl,
5646 .launch_app = _cyttsp5_request_hid_output_launch_app,
5647 .prog_and_verify = _cyttsp5_request_hid_output_bl_program_and_verify,
5648 .verify_app_integrity =
5649 _cyttsp5_request_hid_output_bl_verify_app_integrity,
5650 .get_panel_id = _cyttsp5_request_hid_output_bl_get_panel_id,
5651 };
5652
5653 static struct cyttsp5_core_commands _cyttsp5_core_commands = {
5654 .subscribe_attention = _cyttsp5_subscribe_attention,
5655 .unsubscribe_attention = _cyttsp5_unsubscribe_attention,
5656 .request_exclusive = _cyttsp5_request_exclusive,
5657 .release_exclusive = _cyttsp5_release_exclusive,
5658 .request_reset = _cyttsp5_request_reset,
5659 .request_restart = _cyttsp5_request_restart,
5660 .request_sysinfo = _cyttsp5_request_sysinfo,
5661 .request_loader_pdata = _cyttsp5_request_loader_pdata,
5662 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
5663 .request_stop_wd = _cyttsp5_request_stop_wd,
5664 .request_start_wd = _cyttsp5_request_start_wd,
5665 #endif
5666 .request_get_hid_desc = _cyttsp5_request_get_hid_desc,
5667 .request_get_mode = _cyttsp5_request_get_mode,
5668 #ifdef TTHE_TUNER_SUPPORT
5669 .request_tthe_print = _cyttsp5_request_tthe_print,
5670 #endif
5671 .nonhid_cmd = &_cyttsp5_core_nonhid_cmd,
5672 };
5673
cyttsp5_get_commands(void)5674 struct cyttsp5_core_commands *cyttsp5_get_commands(void)
5675 {
5676 return &_cyttsp5_core_commands;
5677 }
5678 EXPORT_SYMBOL_GPL(cyttsp5_get_commands);
5679
5680 static DEFINE_MUTEX(core_list_lock);
5681 static LIST_HEAD(core_list);
5682 static DEFINE_MUTEX(module_list_lock);
5683 static LIST_HEAD(module_list);
5684 static int core_number;
5685
cyttsp5_probe_module(struct cyttsp5_core_data * cd,struct cyttsp5_module * module)5686 static int cyttsp5_probe_module(struct cyttsp5_core_data *cd,
5687 struct cyttsp5_module *module)
5688 {
5689 struct module_node *module_node;
5690 int rc = 0;
5691
5692 module_node = kzalloc(sizeof(*module_node), GFP_KERNEL);
5693 if (!module_node)
5694 return -ENOMEM;
5695
5696 module_node->module = module;
5697
5698 mutex_lock(&cd->module_list_lock);
5699 list_add(&module_node->node, &cd->module_list);
5700 mutex_unlock(&cd->module_list_lock);
5701
5702 rc = module->probe(cd->dev, &module_node->data);
5703 if (rc) {
5704 /*
5705 * Remove from the list when probe fails
5706 * in order not to call release
5707 */
5708 mutex_lock(&cd->module_list_lock);
5709 list_del(&module_node->node);
5710 mutex_unlock(&cd->module_list_lock);
5711 kfree(module_node);
5712 goto exit;
5713 }
5714
5715 exit:
5716 return rc;
5717 }
5718
cyttsp5_release_module(struct cyttsp5_core_data * cd,struct cyttsp5_module * module)5719 static void cyttsp5_release_module(struct cyttsp5_core_data *cd,
5720 struct cyttsp5_module *module)
5721 {
5722 struct module_node *m, *m_n;
5723
5724 mutex_lock(&cd->module_list_lock);
5725 list_for_each_entry_safe(m, m_n, &cd->module_list, node)
5726 if (m->module == module) {
5727 module->release(cd->dev, m->data);
5728 list_del(&m->node);
5729 kfree(m);
5730 break;
5731 }
5732 mutex_unlock(&cd->module_list_lock);
5733 }
5734
cyttsp5_probe_modules(struct cyttsp5_core_data * cd)5735 static void cyttsp5_probe_modules(struct cyttsp5_core_data *cd)
5736 {
5737 struct cyttsp5_module *m;
5738 int rc = 0;
5739
5740 mutex_lock(&module_list_lock);
5741 list_for_each_entry(m, &module_list, node) {
5742 rc = cyttsp5_probe_module(cd, m);
5743 if (rc)
5744 dev_err(cd->dev, "%s: Probe fails for module %s\n",
5745 __func__, m->name);
5746 }
5747 mutex_unlock(&module_list_lock);
5748 }
5749
cyttsp5_release_modules(struct cyttsp5_core_data * cd)5750 static void cyttsp5_release_modules(struct cyttsp5_core_data *cd)
5751 {
5752 struct cyttsp5_module *m;
5753
5754 mutex_lock(&module_list_lock);
5755 list_for_each_entry(m, &module_list, node)
5756 cyttsp5_release_module(cd, m);
5757 mutex_unlock(&module_list_lock);
5758 }
5759
cyttsp5_get_core_data(char * id)5760 struct cyttsp5_core_data *cyttsp5_get_core_data(char *id)
5761 {
5762 struct cyttsp5_core_data *d;
5763
5764 list_for_each_entry(d, &core_list, node)
5765 if (!strncmp(d->core_id, id, 20))
5766 return d;
5767 return NULL;
5768 }
5769 EXPORT_SYMBOL_GPL(cyttsp5_get_core_data);
5770
cyttsp5_add_core(struct device * dev)5771 static void cyttsp5_add_core(struct device *dev)
5772 {
5773 struct cyttsp5_core_data *d;
5774 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
5775
5776 mutex_lock(&core_list_lock);
5777 list_for_each_entry(d, &core_list, node)
5778 if (d->dev == dev)
5779 goto unlock;
5780
5781 list_add(&cd->node, &core_list);
5782 unlock:
5783 mutex_unlock(&core_list_lock);
5784 }
5785
cyttsp5_del_core(struct device * dev)5786 static void cyttsp5_del_core(struct device *dev)
5787 {
5788 struct cyttsp5_core_data *d, *d_n;
5789
5790 mutex_lock(&core_list_lock);
5791 list_for_each_entry_safe(d, d_n, &core_list, node)
5792 if (d->dev == dev) {
5793 list_del(&d->node);
5794 goto unlock;
5795 }
5796 unlock:
5797 mutex_unlock(&core_list_lock);
5798 }
5799
cyttsp5_register_module(struct cyttsp5_module * module)5800 int cyttsp5_register_module(struct cyttsp5_module *module)
5801 {
5802 struct cyttsp5_module *m;
5803 struct cyttsp5_core_data *cd;
5804
5805 int rc = 0;
5806
5807 if (!module || !module->probe || !module->release)
5808 return -EINVAL;
5809
5810 mutex_lock(&module_list_lock);
5811 list_for_each_entry(m, &module_list, node)
5812 if (m == module) {
5813 rc = -EEXIST;
5814 goto unlock;
5815 }
5816
5817 list_add(&module->node, &module_list);
5818
5819 /* Probe the module for each core */
5820 mutex_lock(&core_list_lock);
5821 list_for_each_entry(cd, &core_list, node)
5822 cyttsp5_probe_module(cd, module);
5823 mutex_unlock(&core_list_lock);
5824
5825 unlock:
5826 mutex_unlock(&module_list_lock);
5827 return rc;
5828 }
5829 EXPORT_SYMBOL_GPL(cyttsp5_register_module);
5830
cyttsp5_unregister_module(struct cyttsp5_module * module)5831 void cyttsp5_unregister_module(struct cyttsp5_module *module)
5832 {
5833 struct cyttsp5_module *m, *m_n;
5834 struct cyttsp5_core_data *cd;
5835
5836 if (!module)
5837 return;
5838
5839 mutex_lock(&module_list_lock);
5840
5841 /* Release the module for each core */
5842 mutex_lock(&core_list_lock);
5843 list_for_each_entry(cd, &core_list, node)
5844 cyttsp5_release_module(cd, module);
5845 mutex_unlock(&core_list_lock);
5846
5847 list_for_each_entry_safe(m, m_n, &module_list, node)
5848 if (m == module) {
5849 list_del(&m->node);
5850 break;
5851 }
5852
5853 mutex_unlock(&module_list_lock);
5854 }
5855 EXPORT_SYMBOL_GPL(cyttsp5_unregister_module);
5856
cyttsp5_get_module_data(struct device * dev,struct cyttsp5_module * module)5857 void *cyttsp5_get_module_data(struct device *dev, struct cyttsp5_module *module)
5858 {
5859 struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
5860 struct module_node *m;
5861 void *data = NULL;
5862
5863 mutex_lock(&cd->module_list_lock);
5864 list_for_each_entry(m, &cd->module_list, node)
5865 if (m->module == module) {
5866 data = m->data;
5867 break;
5868 }
5869 mutex_unlock(&cd->module_list_lock);
5870
5871 return data;
5872 }
5873 EXPORT_SYMBOL(cyttsp5_get_module_data);
5874
5875 #if 0 //def CONFIG_HAS_EARLYSUSPEND
5876 static void cyttsp5_early_suspend(struct early_suspend *h)
5877 {
5878 struct cyttsp5_core_data *cd =
5879 container_of(h, struct cyttsp5_core_data, es);
5880
5881 call_atten_cb(cd, CY_ATTEN_SUSPEND, 0);
5882 }
5883
5884 static void cyttsp5_late_resume(struct early_suspend *h)
5885 {
5886 struct cyttsp5_core_data *cd =
5887 container_of(h, struct cyttsp5_core_data, es);
5888
5889 call_atten_cb(cd, CY_ATTEN_RESUME, 0);
5890 }
5891
5892 static void cyttsp5_setup_early_suspend(struct cyttsp5_core_data *cd)
5893 {
5894 cd->es.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
5895 cd->es.suspend = cyttsp5_early_suspend;
5896 cd->es.resume = cyttsp5_late_resume;
5897
5898 register_early_suspend(&cd->es);
5899 }
5900 #endif
5901 #if 0 //defined(CONFIG_FB)
5902 static int fb_notifier_callback(struct notifier_block *self,
5903 unsigned long event, void *data)
5904 {
5905 struct cyttsp5_core_data *cd =
5906 container_of(self, struct cyttsp5_core_data, fb_notifier);
5907 struct fb_event *evdata = data;
5908 int *blank;
5909
5910 if (event != FB_EVENT_BLANK || !evdata)
5911 goto exit;
5912
5913 blank = evdata->data;
5914 if (*blank == FB_BLANK_UNBLANK) {
5915 dev_info(cd->dev, "%s: UNBLANK!\n", __func__);
5916 if (cd->fb_state != FB_ON) {
5917 call_atten_cb(cd, CY_ATTEN_RESUME, 0);
5918 cd->fb_state = FB_ON;
5919 }
5920 } else if (*blank == FB_BLANK_POWERDOWN) {
5921 dev_info(cd->dev, "%s: POWERDOWN!\n", __func__);
5922 if (cd->fb_state != FB_OFF) {
5923 call_atten_cb(cd, CY_ATTEN_SUSPEND, 0);
5924 cd->fb_state = FB_OFF;
5925 }
5926 }
5927
5928 exit:
5929 return 0;
5930 }
5931
5932 static void cyttsp5_setup_fb_notifier(struct cyttsp5_core_data *cd)
5933 {
5934 int rc;
5935
5936 cd->fb_state = FB_ON;
5937
5938 cd->fb_notifier.notifier_call = fb_notifier_callback;
5939
5940 rc = fb_register_client(&cd->fb_notifier);
5941 if (rc)
5942 dev_err(cd->dev, "Unable to register fb_notifier: %d\n", rc);
5943 }
5944 #endif
5945
cyttsp5_setup_irq_gpio(struct cyttsp5_core_data * cd)5946 static int cyttsp5_setup_irq_gpio(struct cyttsp5_core_data *cd)
5947 {
5948 struct device *dev = cd->dev;
5949 unsigned long irq_flags;
5950 int rc; //reg, val;
5951
5952 /* Initialize IRQ */
5953 cd->irq = gpio_to_irq(cd->cpdata->irq_gpio);
5954 //printk("%%%% cyttsp5_setup_irq_gpio irq=%d\n", cd->irq);
5955 if (cd->irq < 0)
5956 return -EINVAL;
5957
5958 cd->irq_enabled = true;
5959
5960 parade_debug(dev, DEBUG_LEVEL_1, "%s: initialize threaded irq=%d\n",
5961 __func__, cd->irq);
5962 if (cd->cpdata->level_irq_udelay > 0)
5963 /* use level triggered interrupts */
5964 irq_flags = IRQF_TRIGGER_LOW | IRQF_ONESHOT;
5965 else
5966 /* use edge triggered interrupts */
5967 irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT ;
5968
5969 rc = request_threaded_irq(cd->irq, NULL, cyttsp5_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_SUSPEND,
5970 dev_name(dev), cd);
5971 if (rc < 0)
5972 dev_err(dev, "%s: Error, could not request irq\n", __func__);
5973 return rc;
5974 }
5975
cyttsp5_probe(const struct cyttsp5_bus_ops * ops,struct device * dev,u16 irq,size_t xfer_buf_size)5976 int cyttsp5_probe(const struct cyttsp5_bus_ops *ops, struct device *dev,
5977 u16 irq, size_t xfer_buf_size)
5978 {
5979 struct cyttsp5_core_data *cd;
5980 struct cyttsp5_platform_data *pdata = dev_get_platdata(dev);
5981 enum cyttsp5_atten_type type;
5982 int rc = 0;
5983
5984 /* Set default values on first probe */
5985 if (cyttsp5_first_probe) {
5986 cyttsp5_first_probe = false;
5987 is_cyttsp5_probe_success = false;
5988 cyttsp5_bus_ops_save = NULL;
5989 }
5990
5991 if (!pdata || !pdata->core_pdata || !pdata->mt_pdata) {
5992 dev_err(dev, "%s: Missing platform data\n", __func__);
5993 rc = -ENODEV;
5994 goto error_no_pdata;
5995 }
5996
5997 if (pdata->core_pdata->flags & CY_CORE_FLAG_POWEROFF_ON_SLEEP) {
5998 if (!pdata->core_pdata->power) {
5999 dev_err(dev, "%s: Missing platform data function\n",
6000 __func__);
6001 rc = -ENODEV;
6002 goto error_no_pdata;
6003 }
6004 }
6005
6006 /* get context and debug print buffers */
6007 cd = kzalloc(sizeof(*cd), GFP_KERNEL);
6008 if (!cd) {
6009 rc = -ENOMEM;
6010 goto error_alloc_data;
6011 }
6012
6013 cd->supply = devm_regulator_get(dev, "cytp");
6014 if (cd->supply) {
6015 dev_info(dev, "cyttsp5 touch supply = %dmv\n", regulator_get_voltage(cd->supply));
6016 rc = regulator_enable(cd->supply);
6017 if (rc < 0)
6018 dev_err(dev, "failed to enable cyttsp5 power supply\n");
6019 }
6020
6021 /* Initialize device info */
6022 cd->dev = dev;
6023 cd->pdata = pdata;
6024 cd->cpdata = pdata->core_pdata;
6025 cd->bus_ops = ops;
6026 cd->debug_level = CY_INITIAL_DEBUG_LEVEL;
6027 //2019-03-22 interval is 0, solve reboot huge
6028 cd->watchdog_interval = 0;//CY_WATCHDOG_TIMEOUT;
6029 cd->show_timestamp = CY_INITIAL_SHOW_TIME_STAMP;
6030 scnprintf(cd->core_id, 20, "%s%d", CYTTSP5_CORE_NAME, core_number++);
6031
6032 /* Initialize mutexes and spinlocks */
6033 mutex_init(&cd->module_list_lock);
6034 mutex_init(&cd->system_lock);
6035 mutex_init(&cd->adap_lock);
6036 mutex_init(&cd->hid_report_lock);
6037 spin_lock_init(&cd->spinlock);
6038
6039 /* Initialize module list */
6040 INIT_LIST_HEAD(&cd->module_list);
6041
6042 /* Initialize attention lists */
6043 for (type = 0; type < CY_ATTEN_NUM_ATTEN; type++)
6044 INIT_LIST_HEAD(&cd->atten_list[type]);
6045
6046 /* Initialize parameter list */
6047 INIT_LIST_HEAD(&cd->param_list);
6048
6049 /* Initialize wait queue */
6050 init_waitqueue_head(&cd->wait_q);
6051
6052 /* Initialize works */
6053 INIT_WORK(&cd->startup_work, cyttsp5_startup_work_function);
6054 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
6055 INIT_WORK(&cd->watchdog_work, cyttsp5_watchdog_work);
6056 #endif
6057 /* Initialize HID specific data */
6058 cd->hid_core.hid_vendor_id = (cd->cpdata->vendor_id) ?
6059 cd->cpdata->vendor_id : CY_HID_VENDOR_ID;
6060 cd->hid_core.hid_product_id = (cd->cpdata->product_id) ?
6061 cd->cpdata->product_id : CY_HID_APP_PRODUCT_ID;
6062 cd->hid_core.hid_desc_register =
6063 cpu_to_le16(cd->cpdata->hid_desc_register);
6064
6065 /* Set platform easywake value */
6066 cd->easy_wakeup_gesture = cd->cpdata->easy_wakeup_gesture;
6067
6068 /* Set Panel ID to Not Enabled */
6069 cd->panel_id = PANEL_ID_NOT_ENABLED;
6070
6071 dev_set_drvdata(dev, cd);
6072 cyttsp5_add_core(dev);
6073
6074 /*create ttdl_restart sysfs node is probe failed*/
6075 if (!is_cyttsp5_probe_success)
6076 device_create_file(dev, &dev_attr_ttdl_restart);
6077
6078 /*
6079 * Save the pointer to a global value, which will be used
6080 * in ttdl_restart function
6081 */
6082 cyttsp5_bus_ops_save = ops;
6083
6084 /* Call platform detect function */
6085 if (cd->cpdata->detect) {
6086 dev_info(cd->dev, "%s: Detect HW\n", __func__);
6087 rc = cd->cpdata->detect(cd->cpdata, cd->dev,
6088 cyttsp5_platform_detect_read);
6089 if (rc) {
6090 dev_info(cd->dev, "%s: No HW detected\n", __func__);
6091 rc = -ENODEV;
6092 goto error_detect;
6093 }
6094 }
6095 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
6096 /* Setup watchdog timer */
6097 timer_setup(&cd->watchdog_timer, cyttsp5_watchdog_timer,
6098 (unsigned long)cd);
6099 #endif
6100 rc = cyttsp5_setup_irq_gpio(cd);
6101 if (rc < 0) {
6102 dev_err(dev, "%s: Error, could not setup IRQ\n", __func__);
6103 goto error_setup_irq;
6104 }
6105
6106 parade_debug(dev, DEBUG_LEVEL_1, "%s: add sysfs interfaces\n",
6107 __func__);
6108 rc = add_sysfs_interfaces(dev);
6109 if (rc < 0) {
6110 dev_err(dev, "%s: Error, fail sysfs init\n", __func__);
6111 goto error_attr_create;
6112 }
6113
6114 #ifdef TTHE_TUNER_SUPPORT
6115 mutex_init(&cd->tthe_lock);
6116 cd->tthe_debugfs = debugfs_create_file(CYTTSP5_TTHE_TUNER_FILE_NAME,
6117 0644, NULL, cd, &tthe_debugfs_fops);
6118 #endif
6119 rc = device_init_wakeup(dev, 1);
6120 if (rc < 0)
6121 dev_err(dev, "%s: Error, device_init_wakeup rc:%d\n",
6122 __func__, rc);
6123 enable_irq_wake(cd->irq);
6124 cd->irq_wake = 1;
6125
6126 pm_runtime_get_noresume(dev);
6127 pm_runtime_set_active(dev);
6128 pm_runtime_enable(dev);
6129
6130 /*
6131 * call startup directly to ensure that the device
6132 * is tested before leaving the probe
6133 */
6134 parade_debug(dev, DEBUG_LEVEL_1, "%s: call startup\n", __func__);
6135 rc = cyttsp5_startup(cd, false);
6136
6137 pm_runtime_put_sync(dev);
6138
6139 /* Do not fail probe if startup fails but the device is detected */
6140 if (rc == -ENODEV) {
6141 dev_err(cd->dev, "%s: Fail initial startup r=%d\n",
6142 __func__, rc);
6143 goto error_startup;
6144 }
6145
6146 rc = cyttsp5_mt_probe(dev);
6147 if (rc < 0) {
6148 dev_err(dev, "%s: Error, fail mt probe\n", __func__);
6149 goto error_startup;
6150 }
6151
6152 rc = cyttsp5_btn_probe(dev);
6153 if (rc < 0) {
6154 dev_err(dev, "%s: Error, fail btn probe\n", __func__);
6155 goto error_startup_mt;
6156 }
6157
6158 rc = cyttsp5_proximity_probe(dev);
6159 if (rc < 0) {
6160 dev_err(dev, "%s: Error, fail proximity probe\n", __func__);
6161 goto error_startup_btn;
6162 }
6163
6164 /* Probe registered modules */
6165 cyttsp5_probe_modules(cd);
6166
6167 //#ifdef CONFIG_HAS_EARLYSUSPEND
6168 // cyttsp5_setup_early_suspend(cd);
6169 //#elif defined(CONFIG_FB)
6170 // cyttsp5_setup_fb_notifier(cd);
6171 //#endif
6172
6173 #if NEED_SUSPEND_NOTIFIER
6174 cd->pm_notifier.notifier_call = cyttsp5_pm_notifier;
6175 register_pm_notifier(&cd->pm_notifier);
6176 #endif
6177
6178 cd->tp.tp_resume = cyttsp5_core_late_resume;
6179 cd->tp.tp_suspend = cyttsp5_core_early_suspend;
6180 tp_register_fb(&cd->tp);
6181
6182 if (!priv_data) {
6183 priv_data = cd;
6184 }
6185 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
6186 INIT_DELAYED_WORK(&cd->watchdog_enable_work, watchdog_delay_enable);
6187 schedule_delayed_work(&cd->watchdog_enable_work, msecs_to_jiffies(25 * 1000));
6188 #endif
6189 is_cyttsp5_probe_success = true;
6190 return 0;
6191
6192 error_startup_btn:
6193 cyttsp5_btn_release(dev);
6194 error_startup_mt:
6195 cyttsp5_mt_release(dev);
6196 error_startup:
6197 pm_runtime_disable(dev);
6198 #if (KERNEL_VERSION(3, 16, 0) > LINUX_VERSION_CODE)
6199 device_wakeup_disable(dev);
6200 #endif
6201 device_init_wakeup(dev, 0);
6202 cancel_work_sync(&cd->startup_work);
6203 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
6204 cyttsp5_stop_wd_timer(cd);
6205 #endif
6206 cyttsp5_free_si_ptrs(cd);
6207 remove_sysfs_interfaces(dev);
6208 error_attr_create:
6209 free_irq(cd->irq, cd);
6210 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
6211 del_timer(&cd->watchdog_timer);
6212 #endif
6213 error_setup_irq:
6214 error_detect:
6215 if (cd->cpdata->init)
6216 cd->cpdata->init(cd->cpdata, 0, dev);
6217 cyttsp5_del_core(dev);
6218 dev_set_drvdata(dev, NULL);
6219 kfree(cd);
6220 error_alloc_data:
6221 error_no_pdata:
6222 dev_err(dev, "%s failed.\n", __func__);
6223 is_cyttsp5_probe_success = false;
6224 return rc;
6225 }
6226 EXPORT_SYMBOL_GPL(cyttsp5_probe);
6227
cyttsp5_release(struct cyttsp5_core_data * cd)6228 int cyttsp5_release(struct cyttsp5_core_data *cd)
6229 {
6230 struct device *dev = cd->dev;
6231
6232 /* Release successfully probed modules */
6233 cyttsp5_release_modules(cd);
6234
6235 cyttsp5_proximity_release(dev);
6236 cyttsp5_btn_release(dev);
6237 cyttsp5_mt_release(dev);
6238
6239 //#ifdef CONFIG_HAS_EARLYSUSPEND
6240 // unregister_early_suspend(&cd->es);
6241 //#elif defined(CONFIG_FB)
6242 // fb_unregister_client(&cd->fb_notifier);
6243 //#endif
6244
6245 #if NEED_SUSPEND_NOTIFIER
6246 unregister_pm_notifier(&cd->pm_notifier);
6247 #endif
6248
6249 /*
6250 * Suspend the device before freeing the startup_work and stopping
6251 * the watchdog since sleep function restarts watchdog on failure
6252 */
6253 pm_runtime_suspend(dev);
6254 pm_runtime_disable(dev);
6255
6256 cancel_work_sync(&cd->startup_work);
6257
6258 #ifdef CYTTSP_WATCHDOG_DELAY_ENBALE
6259 cyttsp5_stop_wd_timer(cd);
6260 #endif
6261
6262 #if (KERNEL_VERSION(3, 16, 0) > LINUX_VERSION_CODE)
6263 device_wakeup_disable(dev);
6264 #endif
6265 device_init_wakeup(dev, 0);
6266
6267 #ifdef TTHE_TUNER_SUPPORT
6268 mutex_lock(&cd->tthe_lock);
6269 cd->tthe_exit = 1;
6270 wake_up(&cd->wait_q);
6271 mutex_unlock(&cd->tthe_lock);
6272 debugfs_remove(cd->tthe_debugfs);
6273 #endif
6274 remove_sysfs_interfaces(dev);
6275 free_irq(cd->irq, cd);
6276 if (cd->cpdata->init)
6277 cd->cpdata->init(cd->cpdata, 0, dev);
6278 dev_set_drvdata(dev, NULL);
6279 cyttsp5_del_core(dev);
6280 cyttsp5_free_si_ptrs(cd);
6281 cyttsp5_free_hid_reports(cd);
6282 kfree(cd);
6283
6284 priv_data = NULL;
6285
6286 return 0;
6287 }
6288 EXPORT_SYMBOL_GPL(cyttsp5_release);
6289
6290 MODULE_LICENSE("GPL");
6291 MODULE_DESCRIPTION("Parade TrueTouch(R) Standard Product Core Driver");
6292 MODULE_AUTHOR("Parade Technologies <ttdrivers@paradetech.com>");
6293