xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/cyttsp5/cyttsp5_core.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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(&param_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 = &param_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