Merge tag 'v5.9-rc2' into regulator-5.9
[linux-2.6-microblaze.git] / drivers / input / mouse / sentelic.c
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  */
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  */
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
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
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 */
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
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
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
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
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
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
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 */
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
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
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  */
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
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  */
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
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
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
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
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
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
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
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
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
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
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
677 static void fsp_packet_debug(struct psmouse *psmouse, unsigned char packet[])
678 {
679 }
680 #endif
681
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
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
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
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
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
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
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
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
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 }