• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*-
3  * Finger Sensing Pad PS/2 mouse driver.
4  *
5  * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
6  * Copyright (C) 2005-2012 Tai-hwa Liang, Sentelic Corporation.
7  */
8 
9 #include <linux/module.h>
10 #include <linux/input.h>
11 #include <linux/input/mt.h>
12 #include <linux/ctype.h>
13 #include <linux/libps2.h>
14 #include <linux/serio.h>
15 #include <linux/jiffies.h>
16 #include <linux/slab.h>
17 
18 #include "psmouse.h"
19 #include "sentelic.h"
20 
21 /*
22  * Timeout for FSP PS/2 command only (in milliseconds).
23  */
24 #define	FSP_CMD_TIMEOUT		200
25 #define	FSP_CMD_TIMEOUT2	30
26 
27 #define	GET_ABS_X(packet)	((packet[1] << 2) | ((packet[3] >> 2) & 0x03))
28 #define	GET_ABS_Y(packet)	((packet[2] << 2) | (packet[3] & 0x03))
29 
30 /** Driver version. */
31 static const char fsp_drv_ver[] = "1.1.0-K";
32 
33 /*
34  * Make sure that the value being sent to FSP will not conflict with
35  * possible sample rate values.
36  */
fsp_test_swap_cmd(unsigned char reg_val)37 static unsigned char fsp_test_swap_cmd(unsigned char reg_val)
38 {
39 	switch (reg_val) {
40 	case 10: case 20: case 40: case 60: case 80: case 100: case 200:
41 		/*
42 		 * The requested value being sent to FSP matched to possible
43 		 * sample rates, swap the given value such that the hardware
44 		 * wouldn't get confused.
45 		 */
46 		return (reg_val >> 4) | (reg_val << 4);
47 	default:
48 		return reg_val;	/* swap isn't necessary */
49 	}
50 }
51 
52 /*
53  * Make sure that the value being sent to FSP will not conflict with certain
54  * commands.
55  */
fsp_test_invert_cmd(unsigned char reg_val)56 static unsigned char fsp_test_invert_cmd(unsigned char reg_val)
57 {
58 	switch (reg_val) {
59 	case 0xe9: case 0xee: case 0xf2: case 0xff:
60 		/*
61 		 * The requested value being sent to FSP matched to certain
62 		 * commands, inverse the given value such that the hardware
63 		 * wouldn't get confused.
64 		 */
65 		return ~reg_val;
66 	default:
67 		return reg_val;	/* inversion isn't necessary */
68 	}
69 }
70 
fsp_reg_read(struct psmouse * psmouse,int reg_addr,int * reg_val)71 static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val)
72 {
73 	struct ps2dev *ps2dev = &psmouse->ps2dev;
74 	unsigned char param[3];
75 	unsigned char addr;
76 	int rc = -1;
77 
78 	/*
79 	 * We need to shut off the device and switch it into command
80 	 * mode so we don't confuse our protocol handler. We don't need
81 	 * to do that for writes because sysfs set helper does this for
82 	 * us.
83 	 */
84 	psmouse_deactivate(psmouse);
85 
86 	ps2_begin_command(ps2dev);
87 
88 	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
89 		goto out;
90 
91 	/* should return 0xfe(request for resending) */
92 	ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
93 	/* should return 0xfc(failed) */
94 	ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
95 
96 	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
97 		goto out;
98 
99 	if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
100 		ps2_sendbyte(ps2dev, 0x68, FSP_CMD_TIMEOUT2);
101 	} else if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
102 		/* swapping is required */
103 		ps2_sendbyte(ps2dev, 0xcc, FSP_CMD_TIMEOUT2);
104 		/* expect 0xfe */
105 	} else {
106 		/* swapping isn't necessary */
107 		ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
108 		/* expect 0xfe */
109 	}
110 	/* should return 0xfc(failed) */
111 	ps2_sendbyte(ps2dev, addr, FSP_CMD_TIMEOUT);
112 
113 	if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) < 0)
114 		goto out;
115 
116 	*reg_val = param[2];
117 	rc = 0;
118 
119  out:
120 	ps2_end_command(ps2dev);
121 	psmouse_activate(psmouse);
122 	psmouse_dbg(psmouse,
123 		    "READ REG: 0x%02x is 0x%02x (rc = %d)\n",
124 		    reg_addr, *reg_val, rc);
125 	return rc;
126 }
127 
fsp_reg_write(struct psmouse * psmouse,int reg_addr,int reg_val)128 static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val)
129 {
130 	struct ps2dev *ps2dev = &psmouse->ps2dev;
131 	unsigned char v;
132 	int rc = -1;
133 
134 	ps2_begin_command(ps2dev);
135 
136 	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
137 		goto out;
138 
139 	if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
140 		/* inversion is required */
141 		ps2_sendbyte(ps2dev, 0x74, FSP_CMD_TIMEOUT2);
142 	} else {
143 		if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
144 			/* swapping is required */
145 			ps2_sendbyte(ps2dev, 0x77, FSP_CMD_TIMEOUT2);
146 		} else {
147 			/* swapping isn't necessary */
148 			ps2_sendbyte(ps2dev, 0x55, FSP_CMD_TIMEOUT2);
149 		}
150 	}
151 	/* write the register address in correct order */
152 	ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
153 
154 	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
155 		goto out;
156 
157 	if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
158 		/* inversion is required */
159 		ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
160 	} else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
161 		/* swapping is required */
162 		ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
163 	} else {
164 		/* swapping isn't necessary */
165 		ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
166 	}
167 
168 	/* write the register value in correct order */
169 	ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
170 	rc = 0;
171 
172  out:
173 	ps2_end_command(ps2dev);
174 	psmouse_dbg(psmouse,
175 		    "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n",
176 		    reg_addr, reg_val, rc);
177 	return rc;
178 }
179 
180 /* Enable register clock gating for writing certain registers */
fsp_reg_write_enable(struct psmouse * psmouse,bool enable)181 static int fsp_reg_write_enable(struct psmouse *psmouse, bool enable)
182 {
183 	int v, nv;
184 
185 	if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1)
186 		return -1;
187 
188 	if (enable)
189 		nv = v | FSP_BIT_EN_REG_CLK;
190 	else
191 		nv = v & ~FSP_BIT_EN_REG_CLK;
192 
193 	/* only write if necessary */
194 	if (nv != v)
195 		if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1)
196 			return -1;
197 
198 	return 0;
199 }
200 
fsp_page_reg_read(struct psmouse * psmouse,int * reg_val)201 static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val)
202 {
203 	struct ps2dev *ps2dev = &psmouse->ps2dev;
204 	unsigned char param[3];
205 	int rc = -1;
206 
207 	psmouse_deactivate(psmouse);
208 
209 	ps2_begin_command(ps2dev);
210 
211 	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
212 		goto out;
213 
214 	ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
215 	ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
216 
217 	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
218 		goto out;
219 
220 	ps2_sendbyte(ps2dev, 0x83, FSP_CMD_TIMEOUT2);
221 	ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
222 
223 	/* get the returned result */
224 	if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
225 		goto out;
226 
227 	*reg_val = param[2];
228 	rc = 0;
229 
230  out:
231 	ps2_end_command(ps2dev);
232 	psmouse_activate(psmouse);
233 	psmouse_dbg(psmouse,
234 		    "READ PAGE REG: 0x%02x (rc = %d)\n",
235 		    *reg_val, rc);
236 	return rc;
237 }
238 
fsp_page_reg_write(struct psmouse * psmouse,int reg_val)239 static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val)
240 {
241 	struct ps2dev *ps2dev = &psmouse->ps2dev;
242 	unsigned char v;
243 	int rc = -1;
244 
245 	ps2_begin_command(ps2dev);
246 
247 	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
248 		goto out;
249 
250 	ps2_sendbyte(ps2dev, 0x38, FSP_CMD_TIMEOUT2);
251 	ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
252 
253 	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
254 		goto out;
255 
256 	if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
257 		ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
258 	} else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
259 		/* swapping is required */
260 		ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
261 	} else {
262 		/* swapping isn't necessary */
263 		ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
264 	}
265 
266 	ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
267 	rc = 0;
268 
269  out:
270 	ps2_end_command(ps2dev);
271 	psmouse_dbg(psmouse,
272 		    "WRITE PAGE REG: to 0x%02x (rc = %d)\n",
273 		    reg_val, rc);
274 	return rc;
275 }
276 
fsp_get_version(struct psmouse * psmouse,int * version)277 static int fsp_get_version(struct psmouse *psmouse, int *version)
278 {
279 	if (fsp_reg_read(psmouse, FSP_REG_VERSION, version))
280 		return -EIO;
281 
282 	return 0;
283 }
284 
fsp_get_revision(struct psmouse * psmouse,int * rev)285 static int fsp_get_revision(struct psmouse *psmouse, int *rev)
286 {
287 	if (fsp_reg_read(psmouse, FSP_REG_REVISION, rev))
288 		return -EIO;
289 
290 	return 0;
291 }
292 
fsp_get_sn(struct psmouse * psmouse,int * sn)293 static int fsp_get_sn(struct psmouse *psmouse, int *sn)
294 {
295 	int v0, v1, v2;
296 	int rc = -EIO;
297 
298 	/* production number since Cx is available at: 0x0b40 ~ 0x0b42 */
299 	if (fsp_page_reg_write(psmouse, FSP_PAGE_0B))
300 		goto out;
301 	if (fsp_reg_read(psmouse, FSP_REG_SN0, &v0))
302 		goto out;
303 	if (fsp_reg_read(psmouse, FSP_REG_SN1, &v1))
304 		goto out;
305 	if (fsp_reg_read(psmouse, FSP_REG_SN2, &v2))
306 		goto out;
307 	*sn = (v0 << 16) | (v1 << 8) | v2;
308 	rc = 0;
309 out:
310 	fsp_page_reg_write(psmouse, FSP_PAGE_DEFAULT);
311 	return rc;
312 }
313 
fsp_get_buttons(struct psmouse * psmouse,int * btn)314 static int fsp_get_buttons(struct psmouse *psmouse, int *btn)
315 {
316 	static const int buttons[] = {
317 		0x16, /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */
318 		0x06, /* Left/Middle/Right & Scroll Up/Down/Right/Left */
319 		0x04, /* Left/Middle/Right & Scroll Up/Down */
320 		0x02, /* Left/Middle/Right */
321 	};
322 	int val;
323 
324 	if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS, &val) == -1)
325 		return -EIO;
326 
327 	*btn = buttons[(val & 0x30) >> 4];
328 	return 0;
329 }
330 
331 /* Enable on-pad command tag output */
fsp_opc_tag_enable(struct psmouse * psmouse,bool enable)332 static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
333 {
334 	int v, nv;
335 	int res = 0;
336 
337 	if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) {
338 		psmouse_err(psmouse, "Unable get OPC state.\n");
339 		return -EIO;
340 	}
341 
342 	if (enable)
343 		nv = v | FSP_BIT_EN_OPC_TAG;
344 	else
345 		nv = v & ~FSP_BIT_EN_OPC_TAG;
346 
347 	/* only write if necessary */
348 	if (nv != v) {
349 		fsp_reg_write_enable(psmouse, true);
350 		res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv);
351 		fsp_reg_write_enable(psmouse, false);
352 	}
353 
354 	if (res != 0) {
355 		psmouse_err(psmouse, "Unable to enable OPC tag.\n");
356 		res = -EIO;
357 	}
358 
359 	return res;
360 }
361 
fsp_onpad_vscr(struct psmouse * psmouse,bool enable)362 static int fsp_onpad_vscr(struct psmouse *psmouse, bool enable)
363 {
364 	struct fsp_data *pad = psmouse->private;
365 	int val;
366 
367 	if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
368 		return -EIO;
369 
370 	pad->vscroll = enable;
371 
372 	if (enable)
373 		val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE);
374 	else
375 		val &= ~FSP_BIT_FIX_VSCR;
376 
377 	if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
378 		return -EIO;
379 
380 	return 0;
381 }
382 
fsp_onpad_hscr(struct psmouse * psmouse,bool enable)383 static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable)
384 {
385 	struct fsp_data *pad = psmouse->private;
386 	int val, v2;
387 
388 	if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
389 		return -EIO;
390 
391 	if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2))
392 		return -EIO;
393 
394 	pad->hscroll = enable;
395 
396 	if (enable) {
397 		val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE);
398 		v2 |= FSP_BIT_EN_MSID6;
399 	} else {
400 		val &= ~FSP_BIT_FIX_HSCR;
401 		v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8);
402 	}
403 
404 	if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
405 		return -EIO;
406 
407 	/* reconfigure horizontal scrolling packet output */
408 	if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2))
409 		return -EIO;
410 
411 	return 0;
412 }
413 
414 /*
415  * Write device specific initial parameters.
416  *
417  * ex: 0xab 0xcd - write oxcd into register 0xab
418  */
fsp_attr_set_setreg(struct psmouse * psmouse,void * data,const char * buf,size_t count)419 static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data,
420 				   const char *buf, size_t count)
421 {
422 	unsigned int reg, val;
423 	char *rest;
424 	ssize_t retval;
425 
426 	reg = simple_strtoul(buf, &rest, 16);
427 	if (rest == buf || *rest != ' ' || reg > 0xff)
428 		return -EINVAL;
429 
430 	retval = kstrtouint(rest + 1, 16, &val);
431 	if (retval)
432 		return retval;
433 
434 	if (val > 0xff)
435 		return -EINVAL;
436 
437 	if (fsp_reg_write_enable(psmouse, true))
438 		return -EIO;
439 
440 	retval = fsp_reg_write(psmouse, reg, val) < 0 ? -EIO : count;
441 
442 	fsp_reg_write_enable(psmouse, false);
443 
444 	return retval;
445 }
446 
447 PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg);
448 
fsp_attr_show_getreg(struct psmouse * psmouse,void * data,char * buf)449 static ssize_t fsp_attr_show_getreg(struct psmouse *psmouse,
450 					void *data, char *buf)
451 {
452 	struct fsp_data *pad = psmouse->private;
453 
454 	return sprintf(buf, "%02x%02x\n", pad->last_reg, pad->last_val);
455 }
456 
457 /*
458  * Read a register from device.
459  *
460  * ex: 0xab -- read content from register 0xab
461  */
fsp_attr_set_getreg(struct psmouse * psmouse,void * data,const char * buf,size_t count)462 static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data,
463 					const char *buf, size_t count)
464 {
465 	struct fsp_data *pad = psmouse->private;
466 	unsigned int reg, val;
467 	int err;
468 
469 	err = kstrtouint(buf, 16, &reg);
470 	if (err)
471 		return err;
472 
473 	if (reg > 0xff)
474 		return -EINVAL;
475 
476 	if (fsp_reg_read(psmouse, reg, &val))
477 		return -EIO;
478 
479 	pad->last_reg = reg;
480 	pad->last_val = val;
481 
482 	return count;
483 }
484 
485 PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL,
486 			fsp_attr_show_getreg, fsp_attr_set_getreg);
487 
fsp_attr_show_pagereg(struct psmouse * psmouse,void * data,char * buf)488 static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse,
489 					void *data, char *buf)
490 {
491 	int val = 0;
492 
493 	if (fsp_page_reg_read(psmouse, &val))
494 		return -EIO;
495 
496 	return sprintf(buf, "%02x\n", val);
497 }
498 
fsp_attr_set_pagereg(struct psmouse * psmouse,void * data,const char * buf,size_t count)499 static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data,
500 					const char *buf, size_t count)
501 {
502 	unsigned int val;
503 	int err;
504 
505 	err = kstrtouint(buf, 16, &val);
506 	if (err)
507 		return err;
508 
509 	if (val > 0xff)
510 		return -EINVAL;
511 
512 	if (fsp_page_reg_write(psmouse, val))
513 		return -EIO;
514 
515 	return count;
516 }
517 
518 PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL,
519 			fsp_attr_show_pagereg, fsp_attr_set_pagereg);
520 
fsp_attr_show_vscroll(struct psmouse * psmouse,void * data,char * buf)521 static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse,
522 					void *data, char *buf)
523 {
524 	struct fsp_data *pad = psmouse->private;
525 
526 	return sprintf(buf, "%d\n", pad->vscroll);
527 }
528 
fsp_attr_set_vscroll(struct psmouse * psmouse,void * data,const char * buf,size_t count)529 static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data,
530 					const char *buf, size_t count)
531 {
532 	unsigned int val;
533 	int err;
534 
535 	err = kstrtouint(buf, 10, &val);
536 	if (err)
537 		return err;
538 
539 	if (val > 1)
540 		return -EINVAL;
541 
542 	fsp_onpad_vscr(psmouse, val);
543 
544 	return count;
545 }
546 
547 PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL,
548 			fsp_attr_show_vscroll, fsp_attr_set_vscroll);
549 
fsp_attr_show_hscroll(struct psmouse * psmouse,void * data,char * buf)550 static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse,
551 					void *data, char *buf)
552 {
553 	struct fsp_data *pad = psmouse->private;
554 
555 	return sprintf(buf, "%d\n", pad->hscroll);
556 }
557 
fsp_attr_set_hscroll(struct psmouse * psmouse,void * data,const char * buf,size_t count)558 static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data,
559 					const char *buf, size_t count)
560 {
561 	unsigned int val;
562 	int err;
563 
564 	err = kstrtouint(buf, 10, &val);
565 	if (err)
566 		return err;
567 
568 	if (val > 1)
569 		return -EINVAL;
570 
571 	fsp_onpad_hscr(psmouse, val);
572 
573 	return count;
574 }
575 
576 PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL,
577 			fsp_attr_show_hscroll, fsp_attr_set_hscroll);
578 
fsp_attr_show_flags(struct psmouse * psmouse,void * data,char * buf)579 static ssize_t fsp_attr_show_flags(struct psmouse *psmouse,
580 					void *data, char *buf)
581 {
582 	struct fsp_data *pad = psmouse->private;
583 
584 	return sprintf(buf, "%c\n",
585 			pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c');
586 }
587 
fsp_attr_set_flags(struct psmouse * psmouse,void * data,const char * buf,size_t count)588 static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data,
589 					const char *buf, size_t count)
590 {
591 	struct fsp_data *pad = psmouse->private;
592 	size_t i;
593 
594 	for (i = 0; i < count; i++) {
595 		switch (buf[i]) {
596 		case 'C':
597 			pad->flags |= FSPDRV_FLAG_EN_OPC;
598 			break;
599 		case 'c':
600 			pad->flags &= ~FSPDRV_FLAG_EN_OPC;
601 			break;
602 		default:
603 			return -EINVAL;
604 		}
605 	}
606 	return count;
607 }
608 
609 PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL,
610 			fsp_attr_show_flags, fsp_attr_set_flags);
611 
fsp_attr_show_ver(struct psmouse * psmouse,void * data,char * buf)612 static ssize_t fsp_attr_show_ver(struct psmouse *psmouse,
613 					void *data, char *buf)
614 {
615 	return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver);
616 }
617 
618 PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver);
619 
620 static struct attribute *fsp_attributes[] = {
621 	&psmouse_attr_setreg.dattr.attr,
622 	&psmouse_attr_getreg.dattr.attr,
623 	&psmouse_attr_page.dattr.attr,
624 	&psmouse_attr_vscroll.dattr.attr,
625 	&psmouse_attr_hscroll.dattr.attr,
626 	&psmouse_attr_flags.dattr.attr,
627 	&psmouse_attr_ver.dattr.attr,
628 	NULL
629 };
630 
631 static struct attribute_group fsp_attribute_group = {
632 	.attrs = fsp_attributes,
633 };
634 
635 #ifdef	FSP_DEBUG
fsp_packet_debug(struct psmouse * psmouse,unsigned char packet[])636 static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[])
637 {
638 	static unsigned int ps2_packet_cnt;
639 	static unsigned int ps2_last_second;
640 	unsigned int jiffies_msec;
641 	const char *packet_type = "UNKNOWN";
642 	unsigned short abs_x = 0, abs_y = 0;
643 
644 	/* Interpret & dump the packet data. */
645 	switch (packet[0] >> FSP_PKT_TYPE_SHIFT) {
646 	case FSP_PKT_TYPE_ABS:
647 		packet_type = "Absolute";
648 		abs_x = GET_ABS_X(packet);
649 		abs_y = GET_ABS_Y(packet);
650 		break;
651 	case FSP_PKT_TYPE_NORMAL:
652 		packet_type = "Normal";
653 		break;
654 	case FSP_PKT_TYPE_NOTIFY:
655 		packet_type = "Notify";
656 		break;
657 	case FSP_PKT_TYPE_NORMAL_OPC:
658 		packet_type = "Normal-OPC";
659 		break;
660 	}
661 
662 	ps2_packet_cnt++;
663 	jiffies_msec = jiffies_to_msecs(jiffies);
664 	psmouse_dbg(psmouse,
665 		    "%08dms %s packets: %02x, %02x, %02x, %02x; "
666 		    "abs_x: %d, abs_y: %d\n",
667 		    jiffies_msec, packet_type,
668 		    packet[0], packet[1], packet[2], packet[3], abs_x, abs_y);
669 
670 	if (jiffies_msec - ps2_last_second > 1000) {
671 		psmouse_dbg(psmouse, "PS/2 packets/sec = %d\n", ps2_packet_cnt);
672 		ps2_packet_cnt = 0;
673 		ps2_last_second = jiffies_msec;
674 	}
675 }
676 #else
fsp_packet_debug(struct psmouse * psmouse,unsigned char packet[])677 static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[])
678 {
679 }
680 #endif
681 
fsp_set_slot(struct input_dev * dev,int slot,bool active,unsigned int x,unsigned int y)682 static void fsp_set_slot(struct input_dev *dev, int slot, bool active,
683 			 unsigned int x, unsigned int y)
684 {
685 	input_mt_slot(dev, slot);
686 	input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
687 	if (active) {
688 		input_report_abs(dev, ABS_MT_POSITION_X, x);
689 		input_report_abs(dev, ABS_MT_POSITION_Y, y);
690 	}
691 }
692 
fsp_process_byte(struct psmouse * psmouse)693 static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
694 {
695 	struct input_dev *dev = psmouse->dev;
696 	struct fsp_data *ad = psmouse->private;
697 	unsigned char *packet = psmouse->packet;
698 	unsigned char button_status = 0, lscroll = 0, rscroll = 0;
699 	unsigned short abs_x, abs_y, fgrs = 0;
700 
701 	if (psmouse->pktcnt < 4)
702 		return PSMOUSE_GOOD_DATA;
703 
704 	/*
705 	 * Full packet accumulated, process it
706 	 */
707 
708 	fsp_packet_debug(psmouse, packet);
709 
710 	switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
711 	case FSP_PKT_TYPE_ABS:
712 
713 		if ((packet[0] == 0x48 || packet[0] == 0x49) &&
714 		    packet[1] == 0 && packet[2] == 0) {
715 			/*
716 			 * Ignore coordinate noise when finger leaving the
717 			 * surface, otherwise cursor may jump to upper-left
718 			 * corner.
719 			 */
720 			packet[3] &= 0xf0;
721 		}
722 
723 		abs_x = GET_ABS_X(packet);
724 		abs_y = GET_ABS_Y(packet);
725 
726 		if (packet[0] & FSP_PB0_MFMC) {
727 			/*
728 			 * MFMC packet: assume that there are two fingers on
729 			 * pad
730 			 */
731 			fgrs = 2;
732 
733 			/* MFMC packet */
734 			if (packet[0] & FSP_PB0_MFMC_FGR2) {
735 				/* 2nd finger */
736 				if (ad->last_mt_fgr == 2) {
737 					/*
738 					 * workaround for buggy firmware
739 					 * which doesn't clear MFMC bit if
740 					 * the 1st finger is up
741 					 */
742 					fgrs = 1;
743 					fsp_set_slot(dev, 0, false, 0, 0);
744 				}
745 				ad->last_mt_fgr = 2;
746 
747 				fsp_set_slot(dev, 1, fgrs == 2, abs_x, abs_y);
748 			} else {
749 				/* 1st finger */
750 				if (ad->last_mt_fgr == 1) {
751 					/*
752 					 * workaround for buggy firmware
753 					 * which doesn't clear MFMC bit if
754 					 * the 2nd finger is up
755 					 */
756 					fgrs = 1;
757 					fsp_set_slot(dev, 1, false, 0, 0);
758 				}
759 				ad->last_mt_fgr = 1;
760 				fsp_set_slot(dev, 0, fgrs != 0, abs_x, abs_y);
761 			}
762 		} else {
763 			/* SFAC packet */
764 			if ((packet[0] & (FSP_PB0_LBTN|FSP_PB0_PHY_BTN)) ==
765 				FSP_PB0_LBTN) {
766 				/* On-pad click in SFAC mode should be handled
767 				 * by userspace.  On-pad clicks in MFMC mode
768 				 * are real clickpad clicks, and not ignored.
769 				 */
770 				packet[0] &= ~FSP_PB0_LBTN;
771 			}
772 
773 			/* no multi-finger information */
774 			ad->last_mt_fgr = 0;
775 
776 			if (abs_x != 0 && abs_y != 0)
777 				fgrs = 1;
778 
779 			fsp_set_slot(dev, 0, fgrs > 0, abs_x, abs_y);
780 			fsp_set_slot(dev, 1, false, 0, 0);
781 		}
782 		if (fgrs == 1 || (fgrs == 2 && !(packet[0] & FSP_PB0_MFMC_FGR2))) {
783 			input_report_abs(dev, ABS_X, abs_x);
784 			input_report_abs(dev, ABS_Y, abs_y);
785 		}
786 		input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
787 		input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
788 		input_report_key(dev, BTN_TOUCH, fgrs);
789 		input_report_key(dev, BTN_TOOL_FINGER, fgrs == 1);
790 		input_report_key(dev, BTN_TOOL_DOUBLETAP, fgrs == 2);
791 		break;
792 
793 	case FSP_PKT_TYPE_NORMAL_OPC:
794 		/* on-pad click, filter it if necessary */
795 		if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC)
796 			packet[0] &= ~FSP_PB0_LBTN;
797 		fallthrough;
798 
799 	case FSP_PKT_TYPE_NORMAL:
800 		/* normal packet */
801 		/* special packet data translation from on-pad packets */
802 		if (packet[3] != 0) {
803 			if (packet[3] & BIT(0))
804 				button_status |= 0x01;	/* wheel down */
805 			if (packet[3] & BIT(1))
806 				button_status |= 0x0f;	/* wheel up */
807 			if (packet[3] & BIT(2))
808 				button_status |= BIT(4);/* horizontal left */
809 			if (packet[3] & BIT(3))
810 				button_status |= BIT(5);/* horizontal right */
811 			/* push back to packet queue */
812 			if (button_status != 0)
813 				packet[3] = button_status;
814 			rscroll = (packet[3] >> 4) & 1;
815 			lscroll = (packet[3] >> 5) & 1;
816 		}
817 		/*
818 		 * Processing wheel up/down and extra button events
819 		 */
820 		input_report_rel(dev, REL_WHEEL,
821 				 (int)(packet[3] & 8) - (int)(packet[3] & 7));
822 		input_report_rel(dev, REL_HWHEEL, lscroll - rscroll);
823 		input_report_key(dev, BTN_BACK, lscroll);
824 		input_report_key(dev, BTN_FORWARD, rscroll);
825 
826 		/*
827 		 * Standard PS/2 Mouse
828 		 */
829 		psmouse_report_standard_packet(dev, packet);
830 		break;
831 	}
832 
833 	input_sync(dev);
834 
835 	return PSMOUSE_FULL_PACKET;
836 }
837 
fsp_activate_protocol(struct psmouse * psmouse)838 static int fsp_activate_protocol(struct psmouse *psmouse)
839 {
840 	struct fsp_data *pad = psmouse->private;
841 	struct ps2dev *ps2dev = &psmouse->ps2dev;
842 	unsigned char param[2];
843 	int val;
844 
845 	/*
846 	 * Standard procedure to enter FSP Intellimouse mode
847 	 * (scrolling wheel, 4th and 5th buttons)
848 	 */
849 	param[0] = 200;
850 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
851 	param[0] = 200;
852 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
853 	param[0] =  80;
854 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
855 
856 	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
857 	if (param[0] != 0x04) {
858 		psmouse_err(psmouse,
859 			    "Unable to enable 4 bytes packet format.\n");
860 		return -EIO;
861 	}
862 
863 	if (pad->ver < FSP_VER_STL3888_C0) {
864 		/* Preparing relative coordinates output for older hardware */
865 		if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) {
866 			psmouse_err(psmouse,
867 				    "Unable to read SYSCTL5 register.\n");
868 			return -EIO;
869 		}
870 
871 		if (fsp_get_buttons(psmouse, &pad->buttons)) {
872 			psmouse_err(psmouse,
873 				    "Unable to retrieve number of buttons.\n");
874 			return -EIO;
875 		}
876 
877 		val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8);
878 		/* Ensure we are not in absolute mode */
879 		val &= ~FSP_BIT_EN_PKT_G0;
880 		if (pad->buttons == 0x06) {
881 			/* Left/Middle/Right & Scroll Up/Down/Right/Left */
882 			val |= FSP_BIT_EN_MSID6;
883 		}
884 
885 		if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) {
886 			psmouse_err(psmouse,
887 				    "Unable to set up required mode bits.\n");
888 			return -EIO;
889 		}
890 
891 		/*
892 		 * Enable OPC tags such that driver can tell the difference
893 		 * between on-pad and real button click
894 		 */
895 		if (fsp_opc_tag_enable(psmouse, true))
896 			psmouse_warn(psmouse,
897 				     "Failed to enable OPC tag mode.\n");
898 		/* enable on-pad click by default */
899 		pad->flags |= FSPDRV_FLAG_EN_OPC;
900 
901 		/* Enable on-pad vertical and horizontal scrolling */
902 		fsp_onpad_vscr(psmouse, true);
903 		fsp_onpad_hscr(psmouse, true);
904 	} else {
905 		/* Enable absolute coordinates output for Cx/Dx hardware */
906 		if (fsp_reg_write(psmouse, FSP_REG_SWC1,
907 				  FSP_BIT_SWC1_EN_ABS_1F |
908 				  FSP_BIT_SWC1_EN_ABS_2F |
909 				  FSP_BIT_SWC1_EN_FUP_OUT |
910 				  FSP_BIT_SWC1_EN_ABS_CON)) {
911 			psmouse_err(psmouse,
912 				    "Unable to enable absolute coordinates output.\n");
913 			return -EIO;
914 		}
915 	}
916 
917 	return 0;
918 }
919 
fsp_set_input_params(struct psmouse * psmouse)920 static int fsp_set_input_params(struct psmouse *psmouse)
921 {
922 	struct input_dev *dev = psmouse->dev;
923 	struct fsp_data *pad = psmouse->private;
924 
925 	if (pad->ver < FSP_VER_STL3888_C0) {
926 		__set_bit(BTN_MIDDLE, dev->keybit);
927 		__set_bit(BTN_BACK, dev->keybit);
928 		__set_bit(BTN_FORWARD, dev->keybit);
929 		__set_bit(REL_WHEEL, dev->relbit);
930 		__set_bit(REL_HWHEEL, dev->relbit);
931 	} else {
932 		/*
933 		 * Hardware prior to Cx performs much better in relative mode;
934 		 * hence, only enable absolute coordinates output as well as
935 		 * multi-touch output for the newer hardware.
936 		 *
937 		 * Maximum coordinates can be computed as:
938 		 *
939 		 *	number of scanlines * 64 - 57
940 		 *
941 		 * where number of X/Y scanline lines are 16/12.
942 		 */
943 		int abs_x = 967, abs_y = 711;
944 
945 		__set_bit(EV_ABS, dev->evbit);
946 		__clear_bit(EV_REL, dev->evbit);
947 		__set_bit(BTN_TOUCH, dev->keybit);
948 		__set_bit(BTN_TOOL_FINGER, dev->keybit);
949 		__set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
950 		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
951 
952 		input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0);
953 		input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0);
954 		input_mt_init_slots(dev, 2, 0);
955 		input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0);
956 		input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0);
957 	}
958 
959 	return 0;
960 }
961 
fsp_detect(struct psmouse * psmouse,bool set_properties)962 int fsp_detect(struct psmouse *psmouse, bool set_properties)
963 {
964 	int id;
965 
966 	if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id))
967 		return -EIO;
968 
969 	if (id != 0x01)
970 		return -ENODEV;
971 
972 	if (set_properties) {
973 		psmouse->vendor = "Sentelic";
974 		psmouse->name = "FingerSensingPad";
975 	}
976 
977 	return 0;
978 }
979 
fsp_reset(struct psmouse * psmouse)980 static void fsp_reset(struct psmouse *psmouse)
981 {
982 	fsp_opc_tag_enable(psmouse, false);
983 	fsp_onpad_vscr(psmouse, false);
984 	fsp_onpad_hscr(psmouse, false);
985 }
986 
fsp_disconnect(struct psmouse * psmouse)987 static void fsp_disconnect(struct psmouse *psmouse)
988 {
989 	sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj,
990 			   &fsp_attribute_group);
991 
992 	fsp_reset(psmouse);
993 	kfree(psmouse->private);
994 }
995 
fsp_reconnect(struct psmouse * psmouse)996 static int fsp_reconnect(struct psmouse *psmouse)
997 {
998 	int version;
999 
1000 	if (fsp_detect(psmouse, 0))
1001 		return -ENODEV;
1002 
1003 	if (fsp_get_version(psmouse, &version))
1004 		return -ENODEV;
1005 
1006 	if (fsp_activate_protocol(psmouse))
1007 		return -EIO;
1008 
1009 	return 0;
1010 }
1011 
fsp_init(struct psmouse * psmouse)1012 int fsp_init(struct psmouse *psmouse)
1013 {
1014 	struct fsp_data *priv;
1015 	int ver, rev, sn = 0;
1016 	int error;
1017 
1018 	if (fsp_get_version(psmouse, &ver) ||
1019 	    fsp_get_revision(psmouse, &rev)) {
1020 		return -ENODEV;
1021 	}
1022 	if (ver >= FSP_VER_STL3888_C0) {
1023 		/* firmware information is only available since C0 */
1024 		fsp_get_sn(psmouse, &sn);
1025 	}
1026 
1027 	psmouse_info(psmouse,
1028 		     "Finger Sensing Pad, hw: %d.%d.%d, sn: %x, sw: %s\n",
1029 		     ver >> 4, ver & 0x0F, rev, sn, fsp_drv_ver);
1030 
1031 	psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL);
1032 	if (!priv)
1033 		return -ENOMEM;
1034 
1035 	priv->ver = ver;
1036 	priv->rev = rev;
1037 
1038 	psmouse->protocol_handler = fsp_process_byte;
1039 	psmouse->disconnect = fsp_disconnect;
1040 	psmouse->reconnect = fsp_reconnect;
1041 	psmouse->cleanup = fsp_reset;
1042 	psmouse->pktsize = 4;
1043 
1044 	error = fsp_activate_protocol(psmouse);
1045 	if (error)
1046 		goto err_out;
1047 
1048 	/* Set up various supported input event bits */
1049 	error = fsp_set_input_params(psmouse);
1050 	if (error)
1051 		goto err_out;
1052 
1053 	error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
1054 				   &fsp_attribute_group);
1055 	if (error) {
1056 		psmouse_err(psmouse,
1057 			    "Failed to create sysfs attributes (%d)", error);
1058 		goto err_out;
1059 	}
1060 
1061 	return 0;
1062 
1063  err_out:
1064 	kfree(psmouse->private);
1065 	psmouse->private = NULL;
1066 	return error;
1067 }
1068