xref: /openbmc/linux/drivers/input/mouse/sentelic.c (revision 62b31a045757eac81fed94b19df47418a0818528)
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