xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/cyttsp5/cyttsp5_mt_common.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * cyttsp5_mt_common.c
3  * Parade TrueTouch(TM) Standard Product V5 Multi-Touch Reports 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 
31 #define CYTTSP5_MT_NAME "cyttsp5_mt"
32 
33 #define MT_PARAM_SIGNAL(md, sig_ost) PARAM_SIGNAL(md->pdata->frmwrk, sig_ost)
34 #define MT_PARAM_MIN(md, sig_ost) PARAM_MIN(md->pdata->frmwrk, sig_ost)
35 #define MT_PARAM_MAX(md, sig_ost) PARAM_MAX(md->pdata->frmwrk, sig_ost)
36 #define MT_PARAM_FUZZ(md, sig_ost) PARAM_FUZZ(md->pdata->frmwrk, sig_ost)
37 #define MT_PARAM_FLAT(md, sig_ost) PARAM_FLAT(md->pdata->frmwrk, sig_ost)
38 
39 static int screen_max_x 		= 1872;
40 static int screen_max_y 		= 1404;
41 static int revert_x_flag 		= 0;
42 static int revert_y_flag 		= 0;
43 static int exchange_x_y_flag 	= 0;
44 
cyttsp5_mt_lift_all(struct cyttsp5_mt_data * md)45 static void cyttsp5_mt_lift_all(struct cyttsp5_mt_data *md)
46 {
47 	int max = md->si->tch_abs[CY_TCH_T].max;
48 
49 	if (md->num_prv_rec != 0) {
50 		if (md->mt_function.report_slot_liftoff)
51 			md->mt_function.report_slot_liftoff(md, max);
52 		input_sync(md->input);
53 		md->num_prv_rec = 0;
54 	}
55 }
56 
cyttsp5_get_touch_axis(struct cyttsp5_mt_data * md,int * axis,int size,int max,u8 * xy_data,int bofs)57 static void cyttsp5_get_touch_axis(struct cyttsp5_mt_data *md,
58 	int *axis, int size, int max, u8 *xy_data, int bofs)
59 {
60 	int nbyte;
61 	int next;
62 
63 	for (nbyte = 0, *axis = 0, next = 0; nbyte < size; nbyte++) {
64 		parade_debug(md->dev, DEBUG_LEVEL_2,
65 			"%s: *axis=%02X(%d) size=%d max=%08X xy_data=%p xy_data[%d]=%02X(%d) bofs=%d\n",
66 			__func__, *axis, *axis, size, max, xy_data, next,
67 			xy_data[next], xy_data[next], bofs);
68 		*axis = *axis + ((xy_data[next] >> bofs) << (nbyte * 8));
69 		next++;
70 	}
71 
72 	*axis &= max - 1;
73 
74 	parade_debug(md->dev, DEBUG_LEVEL_2,
75 		"%s: *axis=%02X(%d) size=%d max=%08X xy_data=%p xy_data[%d]=%02X(%d)\n",
76 		__func__, *axis, *axis, size, max, xy_data, next,
77 		xy_data[next], xy_data[next]);
78 }
79 
cyttsp5_get_touch_hdr(struct cyttsp5_mt_data * md,struct cyttsp5_touch * touch,u8 * xy_mode)80 static void cyttsp5_get_touch_hdr(struct cyttsp5_mt_data *md,
81 	struct cyttsp5_touch *touch, u8 *xy_mode)
82 {
83 	struct device *dev = md->dev;
84 	struct cyttsp5_sysinfo *si = md->si;
85 	enum cyttsp5_tch_hdr hdr;
86 
87 	for (hdr = CY_TCH_TIME; hdr < CY_TCH_NUM_HDR; hdr++) {
88 		if (!si->tch_hdr[hdr].report)
89 			continue;
90 		cyttsp5_get_touch_axis(md, &touch->hdr[hdr],
91 			si->tch_hdr[hdr].size,
92 			si->tch_hdr[hdr].max,
93 			xy_mode + si->tch_hdr[hdr].ofs,
94 			si->tch_hdr[hdr].bofs);
95 		parade_debug(dev, DEBUG_LEVEL_2, "%s: get %s=%04X(%d)\n",
96 			__func__, cyttsp5_tch_hdr_string[hdr],
97 			touch->hdr[hdr], touch->hdr[hdr]);
98 	}
99 
100 	parade_debug(dev, DEBUG_LEVEL_1,
101 		"%s: time=%X tch_num=%d lo=%d noise=%d counter=%d\n",
102 		__func__,
103 		touch->hdr[CY_TCH_TIME],
104 		touch->hdr[CY_TCH_NUM],
105 		touch->hdr[CY_TCH_LO],
106 		touch->hdr[CY_TCH_NOISE],
107 		touch->hdr[CY_TCH_COUNTER]);
108 }
109 
cyttsp5_get_touch_record(struct cyttsp5_mt_data * md,struct cyttsp5_touch * touch,u8 * xy_data)110 static void cyttsp5_get_touch_record(struct cyttsp5_mt_data *md,
111 	struct cyttsp5_touch *touch, u8 *xy_data)
112 {
113 	struct device *dev = md->dev;
114 	struct cyttsp5_sysinfo *si = md->si;
115 	enum cyttsp5_tch_abs abs;
116 
117 	for (abs = CY_TCH_X; abs < CY_TCH_NUM_ABS; abs++) {
118 		if (!si->tch_abs[abs].report)
119 			continue;
120 		cyttsp5_get_touch_axis(md, &touch->abs[abs],
121 			si->tch_abs[abs].size,
122 			si->tch_abs[abs].max,
123 			xy_data + si->tch_abs[abs].ofs,
124 			si->tch_abs[abs].bofs);
125 		parade_debug(dev, DEBUG_LEVEL_2, "%s: get %s=%04X(%d)\n",
126 			__func__, cyttsp5_tch_abs_string[abs],
127 			touch->abs[abs], touch->abs[abs]);
128 	}
129 }
130 
cyttsp5_mt_process_touch(struct cyttsp5_mt_data * md,struct cyttsp5_touch * touch)131 static void cyttsp5_mt_process_touch(struct cyttsp5_mt_data *md,
132 	struct cyttsp5_touch *touch)
133 {
134 	struct device *dev = md->dev;
135 	struct cyttsp5_sysinfo *si = md->si;
136 	int tmp;
137 	bool flipped;
138 
139 
140 	/* Orientation is signed */
141 	touch->abs[CY_TCH_OR] = (int8_t)touch->abs[CY_TCH_OR];
142 
143 	if (md->pdata->flags & CY_MT_FLAG_FLIP) {
144 		tmp = touch->abs[CY_TCH_X];
145 		touch->abs[CY_TCH_X] = touch->abs[CY_TCH_Y];
146 		touch->abs[CY_TCH_Y] = tmp;
147 		if (touch->abs[CY_TCH_OR] > 0)
148 			touch->abs[CY_TCH_OR] =
149 				md->or_max - touch->abs[CY_TCH_OR];
150 		else
151 			touch->abs[CY_TCH_OR] =
152 				md->or_min - touch->abs[CY_TCH_OR];
153 		flipped = true;
154 	} else
155 		flipped = false;
156 
157 	if (md->pdata->flags & CY_MT_FLAG_INV_X) {
158 		if (flipped)
159 			touch->abs[CY_TCH_X] = si->sensing_conf_data.res_y -
160 				touch->abs[CY_TCH_X];
161 		else
162 			touch->abs[CY_TCH_X] = si->sensing_conf_data.res_x -
163 				touch->abs[CY_TCH_X];
164 		touch->abs[CY_TCH_OR] *= -1;
165 	}
166 	if (md->pdata->flags & CY_MT_FLAG_INV_Y) {
167 		if (flipped)
168 			touch->abs[CY_TCH_Y] = si->sensing_conf_data.res_x -
169 				touch->abs[CY_TCH_Y];
170 		else
171 			touch->abs[CY_TCH_Y] = si->sensing_conf_data.res_y -
172 				touch->abs[CY_TCH_Y];
173 		touch->abs[CY_TCH_OR] *= -1;
174 	}
175 
176 	/* Convert MAJOR/MINOR from mm to resolution */
177 	tmp = touch->abs[CY_TCH_MAJ] * 100 * si->sensing_conf_data.res_x;
178 	touch->abs[CY_TCH_MAJ] = tmp / si->sensing_conf_data.len_x;
179 	tmp = touch->abs[CY_TCH_MIN] * 100 * si->sensing_conf_data.res_x;
180 	touch->abs[CY_TCH_MIN] = tmp / si->sensing_conf_data.len_x;
181 
182 	parade_debug(dev, DEBUG_LEVEL_2, "%s: flip=%s inv-x=%s inv-y=%s x=%04X(%d) y=%04X(%d)\n",
183 		__func__, flipped ? "true" : "false",
184 		md->pdata->flags & CY_MT_FLAG_INV_X ? "true" : "false",
185 		md->pdata->flags & CY_MT_FLAG_INV_Y ? "true" : "false",
186 		touch->abs[CY_TCH_X], touch->abs[CY_TCH_X],
187 		touch->abs[CY_TCH_Y], touch->abs[CY_TCH_Y]);
188 }
189 
cyttsp5_report_event(struct cyttsp5_mt_data * md,int event,int value)190 static void cyttsp5_report_event(struct cyttsp5_mt_data *md, int event,
191 		int value)
192 {
193 	int sig = MT_PARAM_SIGNAL(md, event);
194 
195 	if(sig == ABS_MT_POSITION_X || sig == ABS_MT_POSITION_Y){
196 	//printk("******cyttsp5_report_event sig=0x%x,%x,%x, value=%d\n", sig, ABS_MT_POSITION_X, ABS_MT_POSITION_Y, value);
197 	//printk("******cyttsp5_report_event x=%d, y=%d,z=%d\n", revert_x_flag,
198 		//revert_y_flag, exchange_x_y_flag);
199 
200 		if(exchange_x_y_flag ){
201 			if(sig == ABS_MT_POSITION_X)
202 			{
203 				sig = ABS_MT_POSITION_Y;
204 				if(value > screen_max_y)
205 					value = screen_max_y;
206 			}
207 			else
208 			{
209 				sig = ABS_MT_POSITION_X;
210 				if(value > screen_max_x)
211 					value = screen_max_x;
212 			}
213 		}
214 
215 		if(revert_x_flag && sig == ABS_MT_POSITION_X){
216 			value = screen_max_x - value;
217 		}
218 
219 		if(revert_y_flag && sig == ABS_MT_POSITION_Y){
220 			value = screen_max_y - value;
221 		}
222 		//printk("******cyttsp5_report_event 111 [%s], value=%d\n",
223 		//		sig == ABS_MT_POSITION_X ? "x" : "y", value);
224 	}
225 
226 	if (sig != CY_IGNORE_VALUE)
227 		input_report_abs(md->input, sig, value);
228 
229 }
230 
cyttsp5_get_mt_touches(struct cyttsp5_mt_data * md,struct cyttsp5_touch * tch,int num_cur_tch)231 static void cyttsp5_get_mt_touches(struct cyttsp5_mt_data *md,
232 		struct cyttsp5_touch *tch, int num_cur_tch)
233 {
234 	struct device *dev = md->dev;
235 	struct cyttsp5_sysinfo *si = md->si;
236 	int sig;
237 	int i, j, t = 0;
238 	DECLARE_BITMAP(ids, si->tch_abs[CY_TCH_T].max);
239 	int mt_sync_count = 0;
240 	u8 *tch_addr;
241 
242 	bitmap_zero(ids, si->tch_abs[CY_TCH_T].max);
243 	memset(tch->abs, 0, sizeof(tch->abs));
244 	//printk("***cyttsp5_get_mt_touches num_cur_tch=%x, count=%d\n", num_cur_tch,
245 	//		mt_sync_count);
246 
247 	for (i = 0; i < num_cur_tch; i++) {
248 		tch_addr = si->xy_data + (i * si->desc.tch_record_size);
249 		cyttsp5_get_touch_record(md, tch, tch_addr);
250 
251 		/*  Discard proximity event */
252 		if (tch->abs[CY_TCH_O] == CY_OBJ_PROXIMITY) {
253 			parade_debug(dev, DEBUG_LEVEL_2, "%s: Discarding proximity event\n",
254 					__func__);
255 			continue;
256 		}
257 
258 		/* Validate track_id */
259 		t = tch->abs[CY_TCH_T];
260 		if (t < md->t_min || t > md->t_max) {
261 			dev_err(dev, "%s: tch=%d -> bad trk_id=%d max_id=%d\n",
262 				__func__, i, t, md->t_max);
263 			if (md->mt_function.input_sync)
264 				md->mt_function.input_sync(md->input);
265 			mt_sync_count++;
266 			continue;
267 		}
268 
269 		/* Lift-off */
270 		if (tch->abs[CY_TCH_E] == CY_EV_LIFTOFF) {
271 			parade_debug(dev, DEBUG_LEVEL_1, "%s: t=%d e=%d lift-off\n",
272 				__func__, t, tch->abs[CY_TCH_E]);
273 			goto cyttsp5_get_mt_touches_pr_tch;
274 		}
275 
276 		/* Process touch */
277 		cyttsp5_mt_process_touch(md, tch);
278 
279 		/* use 0 based track id's */
280 		t -= md->t_min;
281 
282 		sig = MT_PARAM_SIGNAL(md, CY_ABS_ID_OST);
283 		if (sig != CY_IGNORE_VALUE) {
284 			if (md->mt_function.input_report)
285 				md->mt_function.input_report(md->input, sig,
286 						t, tch->abs[CY_TCH_O]);
287 			__set_bit(t, ids);
288 		}
289 
290 		/* If touch type is hover, send P as distance, reset P */
291 		if (tch->abs[CY_TCH_O] == CY_OBJ_HOVER) {
292 			/* CY_ABS_D_OST signal must be in touch framework */
293 			cyttsp5_report_event(md, CY_ABS_D_OST,
294 					tch->abs[CY_TCH_P]);
295 			tch->abs[CY_TCH_P] = 0;
296 		} else
297 			cyttsp5_report_event(md, CY_ABS_D_OST, 0);
298 
299 
300 		/* all devices: position and pressure fields */
301 		for (j = 0; j <= CY_ABS_W_OST; j++) {
302 			if (!si->tch_abs[j].report)
303 				continue;
304 			cyttsp5_report_event(md, CY_ABS_X_OST + j,
305 					tch->abs[CY_TCH_X + j]);
306 		}
307 
308 		/* Get the extended touch fields */
309 		for (j = 0; j < CY_NUM_EXT_TCH_FIELDS; j++) {
310 			if (!si->tch_abs[CY_ABS_MAJ_OST + j].report)
311 				continue;
312 			cyttsp5_report_event(md, CY_ABS_MAJ_OST + j,
313 					tch->abs[CY_TCH_MAJ + j]);
314 		}
315 		if (md->mt_function.input_sync)
316 			md->mt_function.input_sync(md->input);
317 		mt_sync_count++;
318 		//printk("***cyttsp5_get_mt_touches sync=0x%x, count=%d\n", md->mt_function.input_sync,
319 		//	mt_sync_count);
320 
321 cyttsp5_get_mt_touches_pr_tch:
322 		parade_debug(dev, DEBUG_LEVEL_1,
323 			"%s: t=%d x=%d y=%d z=%d M=%d m=%d o=%d e=%d obj=%d tip=%d\n",
324 			__func__, t,
325 			tch->abs[CY_TCH_X],
326 			tch->abs[CY_TCH_Y],
327 			tch->abs[CY_TCH_P],
328 			tch->abs[CY_TCH_MAJ],
329 			tch->abs[CY_TCH_MIN],
330 			tch->abs[CY_TCH_OR],
331 			tch->abs[CY_TCH_E],
332 			tch->abs[CY_TCH_O],
333 			tch->abs[CY_TCH_TIP]);
334 	}
335 
336 	if (md->mt_function.final_sync)
337 		md->mt_function.final_sync(md->input,
338 				si->tch_abs[CY_TCH_T].max, mt_sync_count, ids);
339 
340 	md->num_prv_rec = num_cur_tch;
341 }
342 
343 /* read xy_data for all current touches */
cyttsp5_xy_worker(struct cyttsp5_mt_data * md)344 static int cyttsp5_xy_worker(struct cyttsp5_mt_data *md)
345 {
346 	struct device *dev = md->dev;
347 	struct cyttsp5_sysinfo *si = md->si;
348 	int max_tch = si->sensing_conf_data.max_tch;
349 	struct cyttsp5_touch tch;
350 	u8 num_cur_tch;
351 	int rc = 0;
352 
353 	cyttsp5_get_touch_hdr(md, &tch, si->xy_mode + 3);
354 
355 	num_cur_tch = tch.hdr[CY_TCH_NUM];
356 	if (num_cur_tch > max_tch) {
357 		dev_err(dev, "%s: Num touch err detected (n=%d)\n",
358 			__func__, num_cur_tch);
359 		num_cur_tch = max_tch;
360 	}
361 
362 	if (tch.hdr[CY_TCH_LO]) {
363 		parade_debug(dev, DEBUG_LEVEL_1, "%s: Large area detected\n",
364 			__func__);
365 		if (md->pdata->flags & CY_MT_FLAG_NO_TOUCH_ON_LO)
366 			num_cur_tch = 0;
367 	}
368 
369 	if (num_cur_tch == 0 && md->num_prv_rec == 0)
370 		goto cyttsp5_xy_worker_exit;
371 
372 	/* extract xy_data for all currently reported touches */
373 	parade_debug(dev, DEBUG_LEVEL_2, "%s: extract data num_cur_tch=%d\n",
374 		__func__, num_cur_tch);
375 	if (num_cur_tch)
376 		cyttsp5_get_mt_touches(md, &tch, num_cur_tch);
377 	else
378 		cyttsp5_mt_lift_all(md);
379 
380 	rc = 0;
381 
382 cyttsp5_xy_worker_exit:
383 	return rc;
384 }
385 
cyttsp5_mt_send_dummy_event(struct cyttsp5_core_data * cd,struct cyttsp5_mt_data * md)386 static void cyttsp5_mt_send_dummy_event(struct cyttsp5_core_data *cd,
387 		struct cyttsp5_mt_data *md)
388 {
389 #ifndef EASYWAKE_TSG6
390 	/* TSG5 EasyWake */
391 	unsigned long ids = 0;
392 
393 	/* for easy wakeup */
394 	if (md->mt_function.input_report)
395 		md->mt_function.input_report(md->input, ABS_MT_TRACKING_ID,
396 			0, CY_OBJ_STANDARD_FINGER);
397 	if (md->mt_function.input_sync)
398 		md->mt_function.input_sync(md->input);
399 	if (md->mt_function.final_sync)
400 		md->mt_function.final_sync(md->input, 0, 1, &ids);
401 	if (md->mt_function.report_slot_liftoff)
402 		md->mt_function.report_slot_liftoff(md, 1);
403 	if (md->mt_function.final_sync)
404 		md->mt_function.final_sync(md->input, 1, 1, &ids);
405 #else
406 	/* TSG6 FW1.3 and above only. TSG6 FW1.0 - 1.2 does not */
407 	/*  support EasyWake, and this function will not be called */
408 	u8 key_value;
409 
410 	switch (cd->gesture_id) {
411 	case GESTURE_DOUBLE_TAP:
412 		key_value = KEY_F1;
413 	break;
414 	case GESTURE_TWO_FINGERS_SLIDE:
415 		key_value = KEY_F2;
416 	break;
417 	case GESTURE_TOUCH_DETECTED:
418 		key_value = KEY_F3;
419 	break;
420 	case GESTURE_PUSH_BUTTON:
421 		key_value = KEY_F4;
422 	break;
423 	case GESTURE_SINGLE_SLIDE_DE_TX:
424 		key_value = KEY_F5;
425 	break;
426 	case GESTURE_SINGLE_SLIDE_IN_TX:
427 		key_value = KEY_F6;
428 	break;
429 	case GESTURE_SINGLE_SLIDE_DE_RX:
430 		key_value = KEY_F7;
431 	break;
432 	case GESTURE_SINGLE_SLIDE_IN_RX:
433 		key_value = KEY_F8;
434 	break;
435 	default:
436 	break;
437 	}
438 
439 	input_report_key(md->input, key_value, 1);
440 	mdelay(10);
441 	input_report_key(md->input, key_value, 0);
442 	input_sync(md->input);
443 #endif
444 }
445 
cyttsp5_mt_attention(struct device * dev)446 static int cyttsp5_mt_attention(struct device *dev)
447 {
448 	struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
449 	struct cyttsp5_mt_data *md = &cd->md;
450 	int rc;
451 
452 	if (md->si->xy_mode[2] !=  md->si->desc.tch_report_id)
453 		return 0;
454 
455 	/* core handles handshake */
456 	mutex_lock(&md->mt_lock);
457 	rc = cyttsp5_xy_worker(md);
458 	mutex_unlock(&md->mt_lock);
459 	if (rc < 0)
460 		dev_err(dev, "%s: xy_worker error r=%d\n", __func__, rc);
461 
462 	return rc;
463 }
464 
cyttsp5_mt_wake_attention(struct device * dev)465 static int cyttsp5_mt_wake_attention(struct device *dev)
466 {
467 	struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
468 	struct cyttsp5_mt_data *md = &cd->md;
469 
470 	mutex_lock(&md->mt_lock);
471 	cyttsp5_mt_send_dummy_event(cd, md);
472 	mutex_unlock(&md->mt_lock);
473 	return 0;
474 }
475 
cyttsp5_startup_attention(struct device * dev)476 static int cyttsp5_startup_attention(struct device *dev)
477 {
478 	struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
479 	struct cyttsp5_mt_data *md = &cd->md;
480 
481 	mutex_lock(&md->mt_lock);
482 	cyttsp5_mt_lift_all(md);
483 	mutex_unlock(&md->mt_lock);
484 
485 	return 0;
486 }
487 
cyttsp5_mt_suspend_attention(struct device * dev)488 static int cyttsp5_mt_suspend_attention(struct device *dev)
489 {
490 	struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
491 	struct cyttsp5_mt_data *md = &cd->md;
492 
493 	mutex_lock(&md->mt_lock);
494 	cyttsp5_mt_lift_all(md);
495 	md->is_suspended = true;
496 	mutex_unlock(&md->mt_lock);
497 
498 	pm_runtime_put(dev);
499 
500 	return 0;
501 }
502 
cyttsp5_mt_resume_attention(struct device * dev)503 static int cyttsp5_mt_resume_attention(struct device *dev)
504 {
505 	struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
506 	struct cyttsp5_mt_data *md = &cd->md;
507 
508 	pm_runtime_get(dev);
509 
510 	mutex_lock(&md->mt_lock);
511 	md->is_suspended = false;
512 	mutex_unlock(&md->mt_lock);
513 
514 	return 0;
515 }
516 
cyttsp5_mt_open(struct input_dev * input)517 static int cyttsp5_mt_open(struct input_dev *input)
518 {
519 	struct device *dev = input->dev.parent;
520 	struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
521 	struct cyttsp5_mt_data *md = &cd->md;
522 
523 	pm_runtime_get_sync(dev);
524 
525 	mutex_lock(&md->mt_lock);
526 	md->is_suspended = false;
527 	mutex_unlock(&md->mt_lock);
528 
529 	parade_debug(dev, DEBUG_LEVEL_2, "%s: setup subscriptions\n", __func__);
530 
531 	/* set up touch call back */
532 	_cyttsp5_subscribe_attention(dev, CY_ATTEN_IRQ, CYTTSP5_MT_NAME,
533 		cyttsp5_mt_attention, CY_MODE_OPERATIONAL);
534 
535 	/* set up startup call back */
536 	_cyttsp5_subscribe_attention(dev, CY_ATTEN_STARTUP, CYTTSP5_MT_NAME,
537 		cyttsp5_startup_attention, 0);
538 
539 	/* set up wakeup call back */
540 	_cyttsp5_subscribe_attention(dev, CY_ATTEN_WAKE, CYTTSP5_MT_NAME,
541 		cyttsp5_mt_wake_attention, 0);
542 
543 	/* set up suspend call back */
544 	_cyttsp5_subscribe_attention(dev, CY_ATTEN_SUSPEND, CYTTSP5_MT_NAME,
545 		cyttsp5_mt_suspend_attention, 0);
546 
547 	/* set up resume call back */
548 	_cyttsp5_subscribe_attention(dev, CY_ATTEN_RESUME, CYTTSP5_MT_NAME,
549 		cyttsp5_mt_resume_attention, 0);
550 
551 	return 0;
552 }
553 
cyttsp5_mt_close(struct input_dev * input)554 static void cyttsp5_mt_close(struct input_dev *input)
555 {
556 	struct device *dev = input->dev.parent;
557 	struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
558 	struct cyttsp5_mt_data *md = &cd->md;
559 
560 	_cyttsp5_unsubscribe_attention(dev, CY_ATTEN_IRQ, CYTTSP5_MT_NAME,
561 		cyttsp5_mt_attention, CY_MODE_OPERATIONAL);
562 
563 	_cyttsp5_unsubscribe_attention(dev, CY_ATTEN_STARTUP, CYTTSP5_MT_NAME,
564 		cyttsp5_startup_attention, 0);
565 
566 	_cyttsp5_unsubscribe_attention(dev, CY_ATTEN_WAKE, CYTTSP5_MT_NAME,
567 		cyttsp5_mt_wake_attention, 0);
568 
569 	_cyttsp5_unsubscribe_attention(dev, CY_ATTEN_SUSPEND, CYTTSP5_MT_NAME,
570 		cyttsp5_mt_suspend_attention, 0);
571 
572 	_cyttsp5_unsubscribe_attention(dev, CY_ATTEN_RESUME, CYTTSP5_MT_NAME,
573 		cyttsp5_mt_resume_attention, 0);
574 
575 	mutex_lock(&md->mt_lock);
576 	if (!md->is_suspended) {
577 		pm_runtime_put(dev);
578 		md->is_suspended = true;
579 	}
580 	mutex_unlock(&md->mt_lock);
581 }
582 
cyttsp5_setup_input_device(struct device * dev)583 static int cyttsp5_setup_input_device(struct device *dev)
584 {
585 	struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
586 	struct cyttsp5_mt_data *md = &cd->md;
587 	int signal = CY_IGNORE_VALUE;
588 	int max_x, max_y, max_p, min, max;
589 	int max_x_tmp, max_y_tmp;
590 	int i;
591 	int rc;
592 
593 	parade_debug(dev, DEBUG_LEVEL_2, "%s: Initialize event signals\n",
594 		__func__);
595 	__set_bit(EV_ABS, md->input->evbit);
596 	__set_bit(EV_REL, md->input->evbit);
597 	__set_bit(EV_KEY, md->input->evbit);
598 #ifdef INPUT_PROP_DIRECT
599 	__set_bit(INPUT_PROP_DIRECT, md->input->propbit);
600 #endif
601 
602 	/* If virtualkeys enabled, don't use all screen */
603 	if (md->pdata->flags & CY_MT_FLAG_VKEYS) {
604 		max_x_tmp = md->pdata->vkeys_x;
605 		max_y_tmp = md->pdata->vkeys_y;
606 	} else {
607 		max_x_tmp = md->si->sensing_conf_data.res_x;
608 		max_y_tmp = md->si->sensing_conf_data.res_y;
609 	}
610 
611 	/* get maximum values from the sysinfo data */
612 	if (md->pdata->flags & CY_MT_FLAG_FLIP) {
613 		max_x = max_y_tmp - 1;
614 		max_y = max_x_tmp - 1;
615 	} else {
616 		max_x = max_x_tmp - 1;
617 		max_y = max_y_tmp - 1;
618 	}
619 	max_p = md->si->sensing_conf_data.max_z;
620 
621 	/* set event signal capabilities */
622 	for (i = 0; i < NUM_SIGNALS(md->pdata->frmwrk); i++) {
623 		signal = MT_PARAM_SIGNAL(md, i);
624 		if (signal != CY_IGNORE_VALUE) {
625 			__set_bit(signal, md->input->absbit);
626 
627 			min = MT_PARAM_MIN(md, i);
628 			max = MT_PARAM_MAX(md, i);
629 			if (i == CY_ABS_ID_OST) {
630 				/* shift track ids down to start at 0 */
631 				max = max - min;
632 				min = min - min;
633 			} else if (i == CY_ABS_X_OST)
634 				max = max_x;
635 			else if (i == CY_ABS_Y_OST)
636 				max = max_y;
637 			else if (i == CY_ABS_P_OST)
638 				max = max_p;
639 			/*change x-y max value*/
640 			if(signal == ABS_MT_POSITION_X)
641 				max = screen_max_x;
642 			if(signal == ABS_MT_POSITION_Y)
643 				max = screen_max_y;
644 
645 			input_set_abs_params(md->input, signal, min, max,
646 				MT_PARAM_FUZZ(md, i), MT_PARAM_FLAT(md, i));
647 			parade_debug(dev, DEBUG_LEVEL_1,
648 				"%s: register signal=%02X min=%d max=%d\n",
649 				__func__, signal, min, max);
650 		}
651 	}
652 
653 	md->or_min = MT_PARAM_MIN(md, CY_ABS_OR_OST);
654 	md->or_max = MT_PARAM_MAX(md, CY_ABS_OR_OST);
655 
656 	md->t_min = MT_PARAM_MIN(md, CY_ABS_ID_OST);
657 	md->t_max = MT_PARAM_MAX(md, CY_ABS_ID_OST);
658 
659 	rc = md->mt_function.input_register_device(md->input,
660 			md->si->tch_abs[CY_TCH_T].max);
661 	if (rc < 0)
662 		dev_err(dev, "%s: Error, failed register input device r=%d\n",
663 			__func__, rc);
664 	else
665 		md->input_device_registered = true;
666 
667 #ifdef EASYWAKE_TSG6
668 	input_set_capability(md->input, EV_KEY, KEY_F1);
669 	input_set_capability(md->input, EV_KEY, KEY_F2);
670 	input_set_capability(md->input, EV_KEY, KEY_F3);
671 	input_set_capability(md->input, EV_KEY, KEY_F4);
672 	input_set_capability(md->input, EV_KEY, KEY_F5);
673 	input_set_capability(md->input, EV_KEY, KEY_F6);
674 	input_set_capability(md->input, EV_KEY, KEY_F7);
675 	input_set_capability(md->input, EV_KEY, KEY_F8);
676 #endif
677 	return rc;
678 }
679 
cyttsp5_setup_input_attention(struct device * dev)680 static int cyttsp5_setup_input_attention(struct device *dev)
681 {
682 	struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
683 	struct cyttsp5_mt_data *md = &cd->md;
684 	int rc;
685 
686 	md->si = _cyttsp5_request_sysinfo(dev);
687 	if (!md->si)
688 		return -EINVAL;
689 
690 	rc = cyttsp5_setup_input_device(dev);
691 
692 	_cyttsp5_unsubscribe_attention(dev, CY_ATTEN_STARTUP, CYTTSP5_MT_NAME,
693 		cyttsp5_setup_input_attention, 0);
694 
695 	return rc;
696 }
697 
cyttsp5_mt_probe(struct device * dev)698 int cyttsp5_mt_probe(struct device *dev)
699 {
700 	struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
701 	struct cyttsp5_mt_data *md = &cd->md;
702 	struct cyttsp5_cydata *cydata = &cd->sysinfo.cydata;
703 	struct cyttsp5_platform_data *pdata = dev_get_platdata(dev);
704 	struct cyttsp5_mt_platform_data *mt_pdata;
705 	int rc = 0;
706 
707 	//printk("*****cyttsp5_mt_probe\n");
708 	if (!pdata || !pdata->mt_pdata) {
709 		dev_err(dev, "%s: Missing platform data\n", __func__);
710 		rc = -ENODEV;
711 		goto error_no_pdata;
712 	}
713 	mt_pdata = pdata->mt_pdata;
714 	revert_x_flag = mt_pdata->swap_x;
715 	revert_y_flag = mt_pdata->swap_y;
716 	exchange_x_y_flag = mt_pdata->xy_exchange;
717 	if (exchange_x_y_flag) {
718 		int tmp = screen_max_x;
719 		screen_max_x = screen_max_y;
720 		screen_max_y = tmp;
721 	}
722 
723 	//printk("*****cyttsp5_mt_probe 1111\n");
724 	cyttsp5_init_function_ptrs(md);
725 	//printk("*****cyttsp5_mt_probe 2222\n");
726 
727 	mutex_init(&md->mt_lock);
728 	md->dev = dev;
729 	md->pdata = mt_pdata;
730 
731 	/* Create the input device and register it. */
732 	parade_debug(dev, DEBUG_LEVEL_2,
733 		"%s: Create the input device and register it\n", __func__);
734 	md->input = input_allocate_device();
735 	if (!md->input) {
736 		dev_err(dev, "%s: Error, failed to allocate input device\n",
737 			__func__);
738 		rc = -ENODEV;
739 		goto error_alloc_failed;
740 	}
741 
742 	md->input->id.version = cydata->fw_ver_conf;
743 	if (md->pdata->inp_dev_name)
744 		md->input->name = md->pdata->inp_dev_name;
745 	else
746 		md->input->name = CYTTSP5_MT_NAME;
747 	scnprintf(md->phys, sizeof(md->phys), "%s/input%d", dev_name(dev),
748 			cd->phys_num++);
749 	md->input->phys = md->phys;
750 	md->input->dev.parent = md->dev;
751 	md->input->open = cyttsp5_mt_open;
752 	md->input->close = cyttsp5_mt_close;
753 	input_set_drvdata(md->input, md);
754 
755 	/* get sysinfo */
756 	md->si = _cyttsp5_request_sysinfo(dev);
757 
758 	if (md->si) {
759 		rc = cyttsp5_setup_input_device(dev);
760 		if (rc)
761 			goto error_init_input;
762 	} else {
763 		dev_err(dev, "%s: Fail get sysinfo pointer from core p=%p\n",
764 			__func__, md->si);
765 		_cyttsp5_subscribe_attention(dev, CY_ATTEN_STARTUP,
766 			CYTTSP5_MT_NAME, cyttsp5_setup_input_attention, 0);
767 	}
768 
769 	return 0;
770 
771 error_init_input:
772 	input_free_device(md->input);
773 error_alloc_failed:
774 error_no_pdata:
775 	dev_err(dev, "%s failed.\n", __func__);
776 	return rc;
777 }
778 
cyttsp5_mt_release(struct device * dev)779 int cyttsp5_mt_release(struct device *dev)
780 {
781 	struct cyttsp5_core_data *cd = dev_get_drvdata(dev);
782 	struct cyttsp5_mt_data *md = &cd->md;
783 
784 	if (md->input_device_registered) {
785 		input_unregister_device(md->input);
786 	} else {
787 		input_free_device(md->input);
788 		_cyttsp5_unsubscribe_attention(dev, CY_ATTEN_STARTUP,
789 			CYTTSP5_MT_NAME, cyttsp5_setup_input_attention, 0);
790 	}
791 
792 	return 0;
793 }
794