Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/input/mouse/synaptics.c
15109 views
1
/*
2
* Synaptics TouchPad PS/2 mouse driver
3
*
4
* 2003 Dmitry Torokhov <[email protected]>
5
* Added support for pass-through port. Special thanks to Peter Berg Larsen
6
* for explaining various Synaptics quirks.
7
*
8
* 2003 Peter Osterlund <[email protected]>
9
* Ported to 2.5 input device infrastructure.
10
*
11
* Copyright (C) 2001 Stefan Gmeiner <[email protected]>
12
* start merging tpconfig and gpm code to a xfree-input module
13
* adding some changes and extensions (ex. 3rd and 4th button)
14
*
15
* Copyright (c) 1997 C. Scott Ananian <[email protected]>
16
* Copyright (c) 1998-2000 Bruce Kalk <[email protected]>
17
* code for the special synaptics commands (from the tpconfig-source)
18
*
19
* This program is free software; you can redistribute it and/or modify it
20
* under the terms of the GNU General Public License version 2 as published by
21
* the Free Software Foundation.
22
*
23
* Trademarks are the property of their respective owners.
24
*/
25
26
#include <linux/module.h>
27
#include <linux/dmi.h>
28
#include <linux/input/mt.h>
29
#include <linux/serio.h>
30
#include <linux/libps2.h>
31
#include <linux/slab.h>
32
#include "psmouse.h"
33
#include "synaptics.h"
34
35
/*
36
* The x/y limits are taken from the Synaptics TouchPad interfacing Guide,
37
* section 2.3.2, which says that they should be valid regardless of the
38
* actual size of the sensor.
39
* Note that newer firmware allows querying device for maximum useable
40
* coordinates.
41
*/
42
#define XMIN_NOMINAL 1472
43
#define XMAX_NOMINAL 5472
44
#define YMIN_NOMINAL 1408
45
#define YMAX_NOMINAL 4448
46
47
48
/*****************************************************************************
49
* Stuff we need even when we do not want native Synaptics support
50
****************************************************************************/
51
52
/*
53
* Set the synaptics touchpad mode byte by special commands
54
*/
55
static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode)
56
{
57
unsigned char param[1];
58
59
if (psmouse_sliced_command(psmouse, mode))
60
return -1;
61
param[0] = SYN_PS_SET_MODE2;
62
if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE))
63
return -1;
64
return 0;
65
}
66
67
int synaptics_detect(struct psmouse *psmouse, bool set_properties)
68
{
69
struct ps2dev *ps2dev = &psmouse->ps2dev;
70
unsigned char param[4];
71
72
param[0] = 0;
73
74
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
75
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
76
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
77
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
78
ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
79
80
if (param[1] != 0x47)
81
return -ENODEV;
82
83
if (set_properties) {
84
psmouse->vendor = "Synaptics";
85
psmouse->name = "TouchPad";
86
}
87
88
return 0;
89
}
90
91
void synaptics_reset(struct psmouse *psmouse)
92
{
93
/* reset touchpad back to relative mode, gestures enabled */
94
synaptics_mode_cmd(psmouse, 0);
95
}
96
97
#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
98
99
/*****************************************************************************
100
* Synaptics communications functions
101
****************************************************************************/
102
103
/*
104
* Send a command to the synpatics touchpad by special commands
105
*/
106
static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param)
107
{
108
if (psmouse_sliced_command(psmouse, c))
109
return -1;
110
if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO))
111
return -1;
112
return 0;
113
}
114
115
/*
116
* Read the model-id bytes from the touchpad
117
* see also SYN_MODEL_* macros
118
*/
119
static int synaptics_model_id(struct psmouse *psmouse)
120
{
121
struct synaptics_data *priv = psmouse->private;
122
unsigned char mi[3];
123
124
if (synaptics_send_cmd(psmouse, SYN_QUE_MODEL, mi))
125
return -1;
126
priv->model_id = (mi[0]<<16) | (mi[1]<<8) | mi[2];
127
return 0;
128
}
129
130
/*
131
* Read the capability-bits from the touchpad
132
* see also the SYN_CAP_* macros
133
*/
134
static int synaptics_capability(struct psmouse *psmouse)
135
{
136
struct synaptics_data *priv = psmouse->private;
137
unsigned char cap[3];
138
139
if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap))
140
return -1;
141
priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2];
142
priv->ext_cap = priv->ext_cap_0c = 0;
143
144
/*
145
* Older firmwares had submodel ID fixed to 0x47
146
*/
147
if (SYN_ID_FULL(priv->identity) < 0x705 &&
148
SYN_CAP_SUBMODEL_ID(priv->capabilities) != 0x47) {
149
return -1;
150
}
151
152
/*
153
* Unless capExtended is set the rest of the flags should be ignored
154
*/
155
if (!SYN_CAP_EXTENDED(priv->capabilities))
156
priv->capabilities = 0;
157
158
if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) {
159
if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
160
printk(KERN_ERR "Synaptics claims to have extended capabilities,"
161
" but I'm not able to read them.\n");
162
} else {
163
priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2];
164
165
/*
166
* if nExtBtn is greater than 8 it should be considered
167
* invalid and treated as 0
168
*/
169
if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 8)
170
priv->ext_cap &= 0xff0fff;
171
}
172
}
173
174
if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) {
175
if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) {
176
printk(KERN_ERR "Synaptics claims to have extended capability 0x0c,"
177
" but I'm not able to read it.\n");
178
} else {
179
priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2];
180
}
181
}
182
183
return 0;
184
}
185
186
/*
187
* Identify Touchpad
188
* See also the SYN_ID_* macros
189
*/
190
static int synaptics_identify(struct psmouse *psmouse)
191
{
192
struct synaptics_data *priv = psmouse->private;
193
unsigned char id[3];
194
195
if (synaptics_send_cmd(psmouse, SYN_QUE_IDENTIFY, id))
196
return -1;
197
priv->identity = (id[0]<<16) | (id[1]<<8) | id[2];
198
if (SYN_ID_IS_SYNAPTICS(priv->identity))
199
return 0;
200
return -1;
201
}
202
203
/*
204
* Read touchpad resolution and maximum reported coordinates
205
* Resolution is left zero if touchpad does not support the query
206
*/
207
static int synaptics_resolution(struct psmouse *psmouse)
208
{
209
struct synaptics_data *priv = psmouse->private;
210
unsigned char res[3];
211
unsigned char max[3];
212
213
if (SYN_ID_MAJOR(priv->identity) < 4)
214
return 0;
215
216
if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res) == 0) {
217
if (res[0] != 0 && (res[1] & 0x80) && res[2] != 0) {
218
priv->x_res = res[0]; /* x resolution in units/mm */
219
priv->y_res = res[2]; /* y resolution in units/mm */
220
}
221
}
222
223
if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 &&
224
SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) {
225
if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_DIMENSIONS, max)) {
226
printk(KERN_ERR "Synaptics claims to have dimensions query,"
227
" but I'm not able to read it.\n");
228
} else {
229
priv->x_max = (max[0] << 5) | ((max[1] & 0x0f) << 1);
230
priv->y_max = (max[2] << 5) | ((max[1] & 0xf0) >> 3);
231
}
232
}
233
234
return 0;
235
}
236
237
static int synaptics_query_hardware(struct psmouse *psmouse)
238
{
239
if (synaptics_identify(psmouse))
240
return -1;
241
if (synaptics_model_id(psmouse))
242
return -1;
243
if (synaptics_capability(psmouse))
244
return -1;
245
if (synaptics_resolution(psmouse))
246
return -1;
247
248
return 0;
249
}
250
251
static int synaptics_set_absolute_mode(struct psmouse *psmouse)
252
{
253
struct synaptics_data *priv = psmouse->private;
254
255
priv->mode = SYN_BIT_ABSOLUTE_MODE;
256
if (SYN_ID_MAJOR(priv->identity) >= 4)
257
priv->mode |= SYN_BIT_DISABLE_GESTURE;
258
if (SYN_CAP_EXTENDED(priv->capabilities))
259
priv->mode |= SYN_BIT_W_MODE;
260
261
if (synaptics_mode_cmd(psmouse, priv->mode))
262
return -1;
263
264
return 0;
265
}
266
267
static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate)
268
{
269
struct synaptics_data *priv = psmouse->private;
270
271
if (rate >= 80) {
272
priv->mode |= SYN_BIT_HIGH_RATE;
273
psmouse->rate = 80;
274
} else {
275
priv->mode &= ~SYN_BIT_HIGH_RATE;
276
psmouse->rate = 40;
277
}
278
279
synaptics_mode_cmd(psmouse, priv->mode);
280
}
281
282
static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
283
{
284
static unsigned char param = 0xc8;
285
struct synaptics_data *priv = psmouse->private;
286
287
if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))
288
return 0;
289
290
if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL))
291
return -1;
292
if (ps2_command(&psmouse->ps2dev, &param, PSMOUSE_CMD_SETRATE))
293
return -1;
294
295
/* Advanced gesture mode also sends multi finger data */
296
priv->capabilities |= BIT(1);
297
298
return 0;
299
}
300
301
/*****************************************************************************
302
* Synaptics pass-through PS/2 port support
303
****************************************************************************/
304
static int synaptics_pt_write(struct serio *serio, unsigned char c)
305
{
306
struct psmouse *parent = serio_get_drvdata(serio->parent);
307
char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
308
309
if (psmouse_sliced_command(parent, c))
310
return -1;
311
if (ps2_command(&parent->ps2dev, &rate_param, PSMOUSE_CMD_SETRATE))
312
return -1;
313
return 0;
314
}
315
316
static int synaptics_pt_start(struct serio *serio)
317
{
318
struct psmouse *parent = serio_get_drvdata(serio->parent);
319
struct synaptics_data *priv = parent->private;
320
321
serio_pause_rx(parent->ps2dev.serio);
322
priv->pt_port = serio;
323
serio_continue_rx(parent->ps2dev.serio);
324
325
return 0;
326
}
327
328
static void synaptics_pt_stop(struct serio *serio)
329
{
330
struct psmouse *parent = serio_get_drvdata(serio->parent);
331
struct synaptics_data *priv = parent->private;
332
333
serio_pause_rx(parent->ps2dev.serio);
334
priv->pt_port = NULL;
335
serio_continue_rx(parent->ps2dev.serio);
336
}
337
338
static int synaptics_is_pt_packet(unsigned char *buf)
339
{
340
return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4;
341
}
342
343
static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet)
344
{
345
struct psmouse *child = serio_get_drvdata(ptport);
346
347
if (child && child->state == PSMOUSE_ACTIVATED) {
348
serio_interrupt(ptport, packet[1], 0);
349
serio_interrupt(ptport, packet[4], 0);
350
serio_interrupt(ptport, packet[5], 0);
351
if (child->pktsize == 4)
352
serio_interrupt(ptport, packet[2], 0);
353
} else
354
serio_interrupt(ptport, packet[1], 0);
355
}
356
357
static void synaptics_pt_activate(struct psmouse *psmouse)
358
{
359
struct synaptics_data *priv = psmouse->private;
360
struct psmouse *child = serio_get_drvdata(priv->pt_port);
361
362
/* adjust the touchpad to child's choice of protocol */
363
if (child) {
364
if (child->pktsize == 4)
365
priv->mode |= SYN_BIT_FOUR_BYTE_CLIENT;
366
else
367
priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT;
368
369
if (synaptics_mode_cmd(psmouse, priv->mode))
370
printk(KERN_INFO "synaptics: failed to switch guest protocol\n");
371
}
372
}
373
374
static void synaptics_pt_create(struct psmouse *psmouse)
375
{
376
struct serio *serio;
377
378
serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
379
if (!serio) {
380
printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n");
381
return;
382
}
383
384
serio->id.type = SERIO_PS_PSTHRU;
385
strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name));
386
strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name));
387
serio->write = synaptics_pt_write;
388
serio->start = synaptics_pt_start;
389
serio->stop = synaptics_pt_stop;
390
serio->parent = psmouse->ps2dev.serio;
391
392
psmouse->pt_activate = synaptics_pt_activate;
393
394
printk(KERN_INFO "serio: %s port at %s\n", serio->name, psmouse->phys);
395
serio_register_port(serio);
396
}
397
398
/*****************************************************************************
399
* Functions to interpret the absolute mode packets
400
****************************************************************************/
401
402
static int synaptics_parse_hw_state(const unsigned char buf[],
403
struct synaptics_data *priv,
404
struct synaptics_hw_state *hw)
405
{
406
memset(hw, 0, sizeof(struct synaptics_hw_state));
407
408
if (SYN_MODEL_NEWABS(priv->model_id)) {
409
hw->x = (((buf[3] & 0x10) << 8) |
410
((buf[1] & 0x0f) << 8) |
411
buf[4]);
412
hw->y = (((buf[3] & 0x20) << 7) |
413
((buf[1] & 0xf0) << 4) |
414
buf[5]);
415
416
hw->z = buf[2];
417
hw->w = (((buf[0] & 0x30) >> 2) |
418
((buf[0] & 0x04) >> 1) |
419
((buf[3] & 0x04) >> 2));
420
421
if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) {
422
/* Gesture packet: (x, y, z) at half resolution */
423
priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1;
424
priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1;
425
priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1;
426
return 1;
427
}
428
429
hw->left = (buf[0] & 0x01) ? 1 : 0;
430
hw->right = (buf[0] & 0x02) ? 1 : 0;
431
432
if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
433
/*
434
* Clickpad's button is transmitted as middle button,
435
* however, since it is primary button, we will report
436
* it as BTN_LEFT.
437
*/
438
hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
439
440
} else if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
441
hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
442
if (hw->w == 2)
443
hw->scroll = (signed char)(buf[1]);
444
}
445
446
if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
447
hw->up = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
448
hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
449
}
450
451
if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
452
((buf[0] ^ buf[3]) & 0x02)) {
453
switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
454
default:
455
/*
456
* if nExtBtn is greater than 8 it should be
457
* considered invalid and treated as 0
458
*/
459
break;
460
case 8:
461
hw->ext_buttons |= ((buf[5] & 0x08)) ? 0x80 : 0;
462
hw->ext_buttons |= ((buf[4] & 0x08)) ? 0x40 : 0;
463
case 6:
464
hw->ext_buttons |= ((buf[5] & 0x04)) ? 0x20 : 0;
465
hw->ext_buttons |= ((buf[4] & 0x04)) ? 0x10 : 0;
466
case 4:
467
hw->ext_buttons |= ((buf[5] & 0x02)) ? 0x08 : 0;
468
hw->ext_buttons |= ((buf[4] & 0x02)) ? 0x04 : 0;
469
case 2:
470
hw->ext_buttons |= ((buf[5] & 0x01)) ? 0x02 : 0;
471
hw->ext_buttons |= ((buf[4] & 0x01)) ? 0x01 : 0;
472
}
473
}
474
} else {
475
hw->x = (((buf[1] & 0x1f) << 8) | buf[2]);
476
hw->y = (((buf[4] & 0x1f) << 8) | buf[5]);
477
478
hw->z = (((buf[0] & 0x30) << 2) | (buf[3] & 0x3F));
479
hw->w = (((buf[1] & 0x80) >> 4) | ((buf[0] & 0x04) >> 1));
480
481
hw->left = (buf[0] & 0x01) ? 1 : 0;
482
hw->right = (buf[0] & 0x02) ? 1 : 0;
483
}
484
485
return 0;
486
}
487
488
static void set_slot(struct input_dev *dev, int slot, bool active, int x, int y)
489
{
490
input_mt_slot(dev, slot);
491
input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
492
if (active) {
493
input_report_abs(dev, ABS_MT_POSITION_X, x);
494
input_report_abs(dev, ABS_MT_POSITION_Y,
495
YMAX_NOMINAL + YMIN_NOMINAL - y);
496
}
497
}
498
499
static void synaptics_report_semi_mt_data(struct input_dev *dev,
500
const struct synaptics_hw_state *a,
501
const struct synaptics_hw_state *b,
502
int num_fingers)
503
{
504
if (num_fingers >= 2) {
505
set_slot(dev, 0, true, min(a->x, b->x), min(a->y, b->y));
506
set_slot(dev, 1, true, max(a->x, b->x), max(a->y, b->y));
507
} else if (num_fingers == 1) {
508
set_slot(dev, 0, true, a->x, a->y);
509
set_slot(dev, 1, false, 0, 0);
510
} else {
511
set_slot(dev, 0, false, 0, 0);
512
set_slot(dev, 1, false, 0, 0);
513
}
514
}
515
516
/*
517
* called for each full received packet from the touchpad
518
*/
519
static void synaptics_process_packet(struct psmouse *psmouse)
520
{
521
struct input_dev *dev = psmouse->dev;
522
struct synaptics_data *priv = psmouse->private;
523
struct synaptics_hw_state hw;
524
int num_fingers;
525
int finger_width;
526
int i;
527
528
if (synaptics_parse_hw_state(psmouse->packet, priv, &hw))
529
return;
530
531
if (hw.scroll) {
532
priv->scroll += hw.scroll;
533
534
while (priv->scroll >= 4) {
535
input_report_key(dev, BTN_BACK, !hw.down);
536
input_sync(dev);
537
input_report_key(dev, BTN_BACK, hw.down);
538
input_sync(dev);
539
priv->scroll -= 4;
540
}
541
while (priv->scroll <= -4) {
542
input_report_key(dev, BTN_FORWARD, !hw.up);
543
input_sync(dev);
544
input_report_key(dev, BTN_FORWARD, hw.up);
545
input_sync(dev);
546
priv->scroll += 4;
547
}
548
return;
549
}
550
551
if (hw.z > 0 && hw.x > 1) {
552
num_fingers = 1;
553
finger_width = 5;
554
if (SYN_CAP_EXTENDED(priv->capabilities)) {
555
switch (hw.w) {
556
case 0 ... 1:
557
if (SYN_CAP_MULTIFINGER(priv->capabilities))
558
num_fingers = hw.w + 2;
559
break;
560
case 2:
561
if (SYN_MODEL_PEN(priv->model_id))
562
; /* Nothing, treat a pen as a single finger */
563
break;
564
case 4 ... 15:
565
if (SYN_CAP_PALMDETECT(priv->capabilities))
566
finger_width = hw.w;
567
break;
568
}
569
}
570
} else {
571
num_fingers = 0;
572
finger_width = 0;
573
}
574
575
if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))
576
synaptics_report_semi_mt_data(dev, &hw, &priv->mt, num_fingers);
577
578
/* Post events
579
* BTN_TOUCH has to be first as mousedev relies on it when doing
580
* absolute -> relative conversion
581
*/
582
if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1);
583
if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0);
584
585
if (num_fingers > 0) {
586
input_report_abs(dev, ABS_X, hw.x);
587
input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y);
588
}
589
input_report_abs(dev, ABS_PRESSURE, hw.z);
590
591
if (SYN_CAP_PALMDETECT(priv->capabilities))
592
input_report_abs(dev, ABS_TOOL_WIDTH, finger_width);
593
594
input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1);
595
input_report_key(dev, BTN_LEFT, hw.left);
596
input_report_key(dev, BTN_RIGHT, hw.right);
597
598
if (SYN_CAP_MULTIFINGER(priv->capabilities)) {
599
input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
600
input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
601
}
602
603
if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
604
input_report_key(dev, BTN_MIDDLE, hw.middle);
605
606
if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
607
input_report_key(dev, BTN_FORWARD, hw.up);
608
input_report_key(dev, BTN_BACK, hw.down);
609
}
610
611
for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
612
input_report_key(dev, BTN_0 + i, hw.ext_buttons & (1 << i));
613
614
input_sync(dev);
615
}
616
617
static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned char pkt_type)
618
{
619
static const unsigned char newabs_mask[] = { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
620
static const unsigned char newabs_rel_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
621
static const unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
622
static const unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
623
static const unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
624
625
if (idx < 0 || idx > 4)
626
return 0;
627
628
switch (pkt_type) {
629
630
case SYN_NEWABS:
631
case SYN_NEWABS_RELAXED:
632
return (packet[idx] & newabs_rel_mask[idx]) == newabs_rslt[idx];
633
634
case SYN_NEWABS_STRICT:
635
return (packet[idx] & newabs_mask[idx]) == newabs_rslt[idx];
636
637
case SYN_OLDABS:
638
return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx];
639
640
default:
641
printk(KERN_ERR "synaptics: unknown packet type %d\n", pkt_type);
642
return 0;
643
}
644
}
645
646
static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse)
647
{
648
int i;
649
650
for (i = 0; i < 5; i++)
651
if (!synaptics_validate_byte(psmouse->packet, i, SYN_NEWABS_STRICT)) {
652
printk(KERN_INFO "synaptics: using relaxed packet validation\n");
653
return SYN_NEWABS_RELAXED;
654
}
655
656
return SYN_NEWABS_STRICT;
657
}
658
659
static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
660
{
661
struct synaptics_data *priv = psmouse->private;
662
663
if (psmouse->pktcnt >= 6) { /* Full packet received */
664
if (unlikely(priv->pkt_type == SYN_NEWABS))
665
priv->pkt_type = synaptics_detect_pkt_type(psmouse);
666
667
if (SYN_CAP_PASS_THROUGH(priv->capabilities) &&
668
synaptics_is_pt_packet(psmouse->packet)) {
669
if (priv->pt_port)
670
synaptics_pass_pt_packet(priv->pt_port, psmouse->packet);
671
} else
672
synaptics_process_packet(psmouse);
673
674
return PSMOUSE_FULL_PACKET;
675
}
676
677
return synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type) ?
678
PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
679
}
680
681
/*****************************************************************************
682
* Driver initialization/cleanup functions
683
****************************************************************************/
684
static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
685
{
686
int i;
687
688
__set_bit(INPUT_PROP_POINTER, dev->propbit);
689
690
__set_bit(EV_ABS, dev->evbit);
691
input_set_abs_params(dev, ABS_X,
692
XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0);
693
input_set_abs_params(dev, ABS_Y,
694
YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0);
695
input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
696
697
if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) {
698
__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
699
input_mt_init_slots(dev, 2);
700
input_set_abs_params(dev, ABS_MT_POSITION_X, XMIN_NOMINAL,
701
priv->x_max ?: XMAX_NOMINAL, 0, 0);
702
input_set_abs_params(dev, ABS_MT_POSITION_Y, YMIN_NOMINAL,
703
priv->y_max ?: YMAX_NOMINAL, 0, 0);
704
}
705
706
if (SYN_CAP_PALMDETECT(priv->capabilities))
707
input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
708
709
__set_bit(EV_KEY, dev->evbit);
710
__set_bit(BTN_TOUCH, dev->keybit);
711
__set_bit(BTN_TOOL_FINGER, dev->keybit);
712
__set_bit(BTN_LEFT, dev->keybit);
713
__set_bit(BTN_RIGHT, dev->keybit);
714
715
if (SYN_CAP_MULTIFINGER(priv->capabilities)) {
716
__set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
717
__set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
718
}
719
720
if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
721
__set_bit(BTN_MIDDLE, dev->keybit);
722
723
if (SYN_CAP_FOUR_BUTTON(priv->capabilities) ||
724
SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
725
__set_bit(BTN_FORWARD, dev->keybit);
726
__set_bit(BTN_BACK, dev->keybit);
727
}
728
729
for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
730
__set_bit(BTN_0 + i, dev->keybit);
731
732
__clear_bit(EV_REL, dev->evbit);
733
__clear_bit(REL_X, dev->relbit);
734
__clear_bit(REL_Y, dev->relbit);
735
736
input_abs_set_res(dev, ABS_X, priv->x_res);
737
input_abs_set_res(dev, ABS_Y, priv->y_res);
738
739
if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
740
__set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
741
/* Clickpads report only left button */
742
__clear_bit(BTN_RIGHT, dev->keybit);
743
__clear_bit(BTN_MIDDLE, dev->keybit);
744
}
745
}
746
747
static void synaptics_disconnect(struct psmouse *psmouse)
748
{
749
synaptics_reset(psmouse);
750
kfree(psmouse->private);
751
psmouse->private = NULL;
752
}
753
754
static int synaptics_reconnect(struct psmouse *psmouse)
755
{
756
struct synaptics_data *priv = psmouse->private;
757
struct synaptics_data old_priv = *priv;
758
int retry = 0;
759
int error;
760
761
do {
762
psmouse_reset(psmouse);
763
error = synaptics_detect(psmouse, 0);
764
} while (error && ++retry < 3);
765
766
if (error)
767
return -1;
768
769
if (retry > 1)
770
printk(KERN_DEBUG "Synaptics reconnected after %d tries\n",
771
retry);
772
773
if (synaptics_query_hardware(psmouse)) {
774
printk(KERN_ERR "Unable to query Synaptics hardware.\n");
775
return -1;
776
}
777
778
if (synaptics_set_absolute_mode(psmouse)) {
779
printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
780
return -1;
781
}
782
783
if (synaptics_set_advanced_gesture_mode(psmouse)) {
784
printk(KERN_ERR "Advanced gesture mode reconnect failed.\n");
785
return -1;
786
}
787
788
if (old_priv.identity != priv->identity ||
789
old_priv.model_id != priv->model_id ||
790
old_priv.capabilities != priv->capabilities ||
791
old_priv.ext_cap != priv->ext_cap) {
792
printk(KERN_ERR "Synaptics hardware appears to be different: "
793
"id(%ld-%ld), model(%ld-%ld), caps(%lx-%lx), ext(%lx-%lx).\n",
794
old_priv.identity, priv->identity,
795
old_priv.model_id, priv->model_id,
796
old_priv.capabilities, priv->capabilities,
797
old_priv.ext_cap, priv->ext_cap);
798
return -1;
799
}
800
801
return 0;
802
}
803
804
static bool impaired_toshiba_kbc;
805
806
static const struct dmi_system_id __initconst toshiba_dmi_table[] = {
807
#if defined(CONFIG_DMI) && defined(CONFIG_X86)
808
{
809
/* Toshiba Satellite */
810
.matches = {
811
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
812
DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"),
813
},
814
},
815
{
816
/* Toshiba Dynabook */
817
.matches = {
818
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
819
DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"),
820
},
821
},
822
{
823
/* Toshiba Portege M300 */
824
.matches = {
825
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
826
DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
827
},
828
829
},
830
{
831
/* Toshiba Portege M300 */
832
.matches = {
833
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
834
DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
835
DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"),
836
},
837
838
},
839
#endif
840
{ }
841
};
842
843
static bool broken_olpc_ec;
844
845
static const struct dmi_system_id __initconst olpc_dmi_table[] = {
846
#if defined(CONFIG_DMI) && defined(CONFIG_OLPC)
847
{
848
/* OLPC XO-1 or XO-1.5 */
849
.matches = {
850
DMI_MATCH(DMI_SYS_VENDOR, "OLPC"),
851
DMI_MATCH(DMI_PRODUCT_NAME, "XO"),
852
},
853
},
854
#endif
855
{ }
856
};
857
858
void __init synaptics_module_init(void)
859
{
860
impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
861
broken_olpc_ec = dmi_check_system(olpc_dmi_table);
862
}
863
864
int synaptics_init(struct psmouse *psmouse)
865
{
866
struct synaptics_data *priv;
867
868
/*
869
* The OLPC XO has issues with Synaptics' absolute mode; similarly to
870
* the HGPK, it quickly degrades and the hardware becomes jumpy and
871
* overly sensitive. Not only that, but the constant packet spew
872
* (even at a lowered 40pps rate) overloads the EC such that key
873
* presses on the keyboard are missed. Given all of that, don't
874
* even attempt to use Synaptics mode. Relative mode seems to work
875
* just fine.
876
*/
877
if (broken_olpc_ec) {
878
printk(KERN_INFO "synaptics: OLPC XO detected, not enabling Synaptics protocol.\n");
879
return -ENODEV;
880
}
881
882
psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL);
883
if (!priv)
884
return -ENOMEM;
885
886
psmouse_reset(psmouse);
887
888
if (synaptics_query_hardware(psmouse)) {
889
printk(KERN_ERR "Unable to query Synaptics hardware.\n");
890
goto init_fail;
891
}
892
893
if (synaptics_set_absolute_mode(psmouse)) {
894
printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
895
goto init_fail;
896
}
897
898
if (synaptics_set_advanced_gesture_mode(psmouse)) {
899
printk(KERN_ERR "Advanced gesture mode init failed.\n");
900
goto init_fail;
901
}
902
903
priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
904
905
printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n",
906
SYN_ID_MODEL(priv->identity),
907
SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
908
priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c);
909
910
set_input_params(psmouse->dev, priv);
911
912
/*
913
* Encode touchpad model so that it can be used to set
914
* input device->id.version and be visible to userspace.
915
* Because version is __u16 we have to drop something.
916
* Hardware info bits seem to be good candidates as they
917
* are documented to be for Synaptics corp. internal use.
918
*/
919
psmouse->model = ((priv->model_id & 0x00ff0000) >> 8) |
920
(priv->model_id & 0x000000ff);
921
922
psmouse->protocol_handler = synaptics_process_byte;
923
psmouse->set_rate = synaptics_set_rate;
924
psmouse->disconnect = synaptics_disconnect;
925
psmouse->reconnect = synaptics_reconnect;
926
psmouse->cleanup = synaptics_reset;
927
psmouse->pktsize = 6;
928
/* Synaptics can usually stay in sync without extra help */
929
psmouse->resync_time = 0;
930
931
if (SYN_CAP_PASS_THROUGH(priv->capabilities))
932
synaptics_pt_create(psmouse);
933
934
/*
935
* Toshiba's KBC seems to have trouble handling data from
936
* Synaptics at full rate. Switch to a lower rate (roughly
937
* the same rate as a standard PS/2 mouse).
938
*/
939
if (psmouse->rate >= 80 && impaired_toshiba_kbc) {
940
printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n",
941
dmi_get_system_info(DMI_PRODUCT_NAME));
942
psmouse->rate = 40;
943
}
944
945
return 0;
946
947
init_fail:
948
kfree(priv);
949
return -1;
950
}
951
952
bool synaptics_supported(void)
953
{
954
return true;
955
}
956
957
#else /* CONFIG_MOUSE_PS2_SYNAPTICS */
958
959
void __init synaptics_module_init(void)
960
{
961
}
962
963
int synaptics_init(struct psmouse *psmouse)
964
{
965
return -ENOSYS;
966
}
967
968
bool synaptics_supported(void)
969
{
970
return false;
971
}
972
973
#endif /* CONFIG_MOUSE_PS2_SYNAPTICS */
974
975
976