Lines 81-86
Link Here
|
81 |
#include <sys/sysctl.h> |
81 |
#include <sys/sysctl.h> |
82 |
#include <sys/time.h> |
82 |
#include <sys/time.h> |
83 |
#include <sys/uio.h> |
83 |
#include <sys/uio.h> |
|
|
84 |
#include <sys/libkern.h> |
84 |
|
85 |
|
85 |
#include <sys/limits.h> |
86 |
#include <sys/limits.h> |
86 |
#include <sys/mouse.h> |
87 |
#include <sys/mouse.h> |
Lines 161-200
Link Here
|
161 |
#define PSM_PACKETQUEUE 128 |
162 |
#define PSM_PACKETQUEUE 128 |
162 |
#endif |
163 |
#endif |
163 |
|
164 |
|
164 |
enum { |
|
|
165 |
SYNAPTICS_SYSCTL_MIN_PRESSURE, |
166 |
SYNAPTICS_SYSCTL_MAX_PRESSURE, |
167 |
SYNAPTICS_SYSCTL_MAX_WIDTH, |
168 |
SYNAPTICS_SYSCTL_MARGIN_TOP, |
169 |
SYNAPTICS_SYSCTL_MARGIN_RIGHT, |
170 |
SYNAPTICS_SYSCTL_MARGIN_BOTTOM, |
171 |
SYNAPTICS_SYSCTL_MARGIN_LEFT, |
172 |
SYNAPTICS_SYSCTL_NA_TOP, |
173 |
SYNAPTICS_SYSCTL_NA_RIGHT, |
174 |
SYNAPTICS_SYSCTL_NA_BOTTOM, |
175 |
SYNAPTICS_SYSCTL_NA_LEFT, |
176 |
SYNAPTICS_SYSCTL_WINDOW_MIN, |
177 |
SYNAPTICS_SYSCTL_WINDOW_MAX, |
178 |
SYNAPTICS_SYSCTL_MULTIPLICATOR, |
179 |
SYNAPTICS_SYSCTL_WEIGHT_CURRENT, |
180 |
SYNAPTICS_SYSCTL_WEIGHT_PREVIOUS, |
181 |
SYNAPTICS_SYSCTL_WEIGHT_PREVIOUS_NA, |
182 |
SYNAPTICS_SYSCTL_WEIGHT_LEN_SQUARED, |
183 |
SYNAPTICS_SYSCTL_DIV_MIN, |
184 |
SYNAPTICS_SYSCTL_DIV_MAX, |
185 |
SYNAPTICS_SYSCTL_DIV_MAX_NA, |
186 |
SYNAPTICS_SYSCTL_DIV_LEN, |
187 |
SYNAPTICS_SYSCTL_TAP_MAX_DELTA, |
188 |
SYNAPTICS_SYSCTL_TAP_MIN_QUEUE, |
189 |
SYNAPTICS_SYSCTL_TAPHOLD_TIMEOUT, |
190 |
SYNAPTICS_SYSCTL_VSCROLL_HOR_AREA, |
191 |
SYNAPTICS_SYSCTL_VSCROLL_VER_AREA, |
192 |
SYNAPTICS_SYSCTL_VSCROLL_MIN_DELTA, |
193 |
SYNAPTICS_SYSCTL_VSCROLL_DIV_MIN, |
194 |
SYNAPTICS_SYSCTL_VSCROLL_DIV_MAX, |
195 |
SYNAPTICS_SYSCTL_TOUCHPAD_OFF |
196 |
}; |
197 |
|
198 |
typedef struct synapticsinfo { |
165 |
typedef struct synapticsinfo { |
199 |
struct sysctl_ctx_list sysctl_ctx; |
166 |
struct sysctl_ctx_list sysctl_ctx; |
200 |
struct sysctl_oid *sysctl_tree; |
167 |
struct sysctl_oid *sysctl_tree; |
Lines 231-236
Link Here
|
231 |
int vscroll_div_min; |
198 |
int vscroll_div_min; |
232 |
int vscroll_div_max; |
199 |
int vscroll_div_max; |
233 |
int touchpad_off; |
200 |
int touchpad_off; |
|
|
201 |
int softbuttons; |
202 |
int softbuttons_y; |
203 |
int softbutton2_x; |
204 |
int softbutton3_x; |
205 |
int softbutton_nomove; |
234 |
} synapticsinfo_t; |
206 |
} synapticsinfo_t; |
235 |
|
207 |
|
236 |
typedef struct synapticspacket { |
208 |
typedef struct synapticspacket { |
Lines 295-300
Link Here
|
295 |
int skipback; |
267 |
int skipback; |
296 |
} trackpointinfo_t; |
268 |
} trackpointinfo_t; |
297 |
|
269 |
|
|
|
270 |
typedef struct finger { |
271 |
int x; |
272 |
int y; |
273 |
int p; |
274 |
int w; |
275 |
int flags; |
276 |
} finger_t; |
277 |
#define PSM_GESTURE_FINGERS 2 |
278 |
#define PSM_FINGER_IS_PEN (1<<0) |
279 |
#define PSM_FINGER_FUZZY (1<<1) |
280 |
#define PSM_FINGER_IS_SET(f) ((f).x != -1 && (f).y != -1 && (f).p != 0) |
281 |
#define PSM_FINGER_RESET(f) do \ |
282 |
(f) = (finger_t) { .x = -1, .y = -1, .p = 0, .w = 0, .flags = 0 }; \ |
283 |
while (0) |
284 |
|
285 |
typedef struct elantechhw { |
286 |
int hwversion; |
287 |
int fwversion; |
288 |
int sizex; |
289 |
int sizey; |
290 |
int dpix; |
291 |
int dpiy; |
292 |
int ntracesx; |
293 |
int ntracesy; |
294 |
int isclickpad; |
295 |
int hascrc; |
296 |
int hastrackpad; |
297 |
int haspressure; |
298 |
} elantechhw_t; |
299 |
|
300 |
/* minimum versions supported by this driver */ |
301 |
#define ELANTECH_HW_IS_V1(fwver) ((fwver) < 0x020030 || (fwver) == 0x020600) |
302 |
|
303 |
#define ELANTECH_MAGIC(magic) \ |
304 |
((magic)[0] == 0x3c && (magic)[1] == 0x03 && \ |
305 |
((magic)[2] == 0xc8 || (magic)[2] == 0x00)) |
306 |
|
307 |
#define ELANTECH_FW_ID 0x00 |
308 |
#define ELANTECH_FW_VERSION 0x01 |
309 |
#define ELANTECH_CAPABILITIES 0x02 |
310 |
#define ELANTECH_SAMPLE 0x03 |
311 |
#define ELANTECH_RESOLUTION 0x04 |
312 |
#define ELANTECH_REG_READ 0x10 |
313 |
#define ELANTECH_REG_WRITE 0x11 |
314 |
#define ELANTECH_REG_RDWR 0x00 |
315 |
#define ELANTECH_CUSTOM_CMD 0xf8 |
316 |
|
317 |
#define ELANTECH_FINGER_DEFAULT_P tap_threshold |
318 |
#define ELANTECH_FINGER_DEFAULT_W 1 |
319 |
#define ELANTECH_FINGER_SET_XYP(pb) (finger_t) { \ |
320 |
.x = (((pb)->ipacket[1] & 0x0f) << 8) | (pb)->ipacket[2], \ |
321 |
.y = (((pb)->ipacket[4] & 0x0f) << 8) | (pb)->ipacket[5], \ |
322 |
.p = ((pb)->ipacket[1] & 0xf0) | (((pb)->ipacket[4] >> 4) & 0x0f), \ |
323 |
.w = ELANTECH_FINGER_DEFAULT_W, \ |
324 |
.flags = 0 \ |
325 |
} |
326 |
|
327 |
enum { |
328 |
ELANTECH_PKT_NOP, |
329 |
ELANTECH_PKT_TRACKPOINT, |
330 |
ELANTECH_PKT_V2_COMMON, |
331 |
ELANTECH_PKT_V2_2FINGER, |
332 |
ELANTECH_PKT_V3, |
333 |
ELANTECH_PKT_V4_STATUS, |
334 |
ELANTECH_PKT_V4_HEAD, |
335 |
ELANTECH_PKT_V4_MOTION |
336 |
}; |
337 |
|
338 |
#define ELANTECH_PKT_IS_TRACKPOINT(pb) (((pb)->ipacket[3] & 0x0f) == 0x06) |
339 |
#define ELANTECH_PKT_IS_DEBOUNCE(pb, hwversion) ((hwversion) == 4 ? 0 : \ |
340 |
(pb)->ipacket[0] == ((hwversion) == 2 ? 0x84 : 0xc4) && \ |
341 |
(pb)->ipacket[1] == 0xff && (pb)->ipacket[2] == 0xff && \ |
342 |
(pb)->ipacket[3] == 0x02 && (pb)->ipacket[4] == 0xff && \ |
343 |
(pb)->ipacket[5] == 0xff) |
344 |
#define ELANTECH_PKT_IS_V2(pb) \ |
345 |
(((pb)->ipacket[0] & 0x0c) == 0x04 && ((pb)->ipacket[3] & 0x0f) == 0x02) |
346 |
#define ELANTECH_PKT_IS_V3_HEAD(pb, hascrc) ((hascrc) ? \ |
347 |
((pb)->ipacket[3] & 0x09) == 0x08 : \ |
348 |
((pb)->ipacket[0] & 0x0c) == 0x04 && ((pb)->ipacket[3] & 0xcf) == 0x02) |
349 |
#define ELANTECH_PKT_IS_V3_TAIL(pb, hascrc) ((hascrc) ? \ |
350 |
((pb)->ipacket[3] & 0x09) == 0x09 : \ |
351 |
((pb)->ipacket[0] & 0x0c) == 0x0c && ((pb)->ipacket[3] & 0xce) == 0x0c) |
352 |
#define ELANTECH_PKT_IS_V4(pb, hascrc) ((hascrc) ? \ |
353 |
((pb)->ipacket[3] & 0x08) == 0x00 : \ |
354 |
((pb)->ipacket[0] & 0x0c) == 0x04 && ((pb)->ipacket[3] & 0x1c) == 0x10) |
355 |
|
356 |
typedef struct elantechaction { |
357 |
finger_t fingers[PSM_GESTURE_FINGERS]; |
358 |
int nfingers; |
359 |
} elantechaction_t; |
360 |
|
298 |
/* driver control block */ |
361 |
/* driver control block */ |
299 |
struct psm_softc { /* Driver status information */ |
362 |
struct psm_softc { /* Driver status information */ |
300 |
int unit; |
363 |
int unit; |
Lines 308-314
Link Here
|
308 |
mousehw_t hw; /* hardware information */ |
371 |
mousehw_t hw; /* hardware information */ |
309 |
synapticshw_t synhw; /* Synaptics hardware information */ |
372 |
synapticshw_t synhw; /* Synaptics hardware information */ |
310 |
synapticsinfo_t syninfo; /* Synaptics configuration */ |
373 |
synapticsinfo_t syninfo; /* Synaptics configuration */ |
311 |
synapticsaction_t synaction; /* Synaptics action context */ |
374 |
synapticsaction_t |
|
|
375 |
synaction[PSM_GESTURE_FINGERS]; /* Synaptics action context */ |
376 |
elantechhw_t elanhw; /* Elantech hardware information */ |
377 |
elantechaction_t elanaction; /* Elantech action context */ |
312 |
int tphw; /* TrackPoint hardware information */ |
378 |
int tphw; /* TrackPoint hardware information */ |
313 |
trackpointinfo_t tpinfo; /* TrackPoint configuration */ |
379 |
trackpointinfo_t tpinfo; /* TrackPoint configuration */ |
314 |
mousemode_t mode; /* operation mode */ |
380 |
mousemode_t mode; /* operation mode */ |
Lines 331-336
Link Here
|
331 |
struct timeval lastsoftintr; /* time of last soft interrupt */ |
397 |
struct timeval lastsoftintr; /* time of last soft interrupt */ |
332 |
struct timeval lastinputerr; /* time last sync error happened */ |
398 |
struct timeval lastinputerr; /* time last sync error happened */ |
333 |
struct timeval taptimeout; /* tap timeout for touchpads */ |
399 |
struct timeval taptimeout; /* tap timeout for touchpads */ |
|
|
400 |
struct timeval idletimeout; |
401 |
packetbuf_t idlepacket; /* packet to send after idle timeout */ |
334 |
int watchdog; /* watchdog timer flag */ |
402 |
int watchdog; /* watchdog timer flag */ |
335 |
struct callout callout; /* watchdog timer call out */ |
403 |
struct callout callout; /* watchdog timer call out */ |
336 |
struct callout softcallout; /* buffer timer call out */ |
404 |
struct callout softcallout; /* buffer timer call out */ |
Lines 375-380
Link Here
|
375 |
/* other flags (flags) */ |
443 |
/* other flags (flags) */ |
376 |
#define PSM_FLAGS_FINGERDOWN 0x0001 /* VersaPad finger down */ |
444 |
#define PSM_FLAGS_FINGERDOWN 0x0001 /* VersaPad finger down */ |
377 |
|
445 |
|
|
|
446 |
#define kbdcp(p) ((atkbdc_softc_t *)(p)) |
447 |
#define ALWAYS_RESTORE_CONTROLLER(kbdc) !(kbdcp(kbdc)->quirks \ |
448 |
& KBDC_QUIRK_KEEP_ACTIVATED) |
449 |
|
378 |
/* Tunables */ |
450 |
/* Tunables */ |
379 |
static int tap_enabled = -1; |
451 |
static int tap_enabled = -1; |
380 |
TUNABLE_INT("hw.psm.tap_enabled", &tap_enabled); |
452 |
TUNABLE_INT("hw.psm.tap_enabled", &tap_enabled); |
Lines 385-390
Link Here
|
385 |
static int trackpoint_support = 0; |
457 |
static int trackpoint_support = 0; |
386 |
TUNABLE_INT("hw.psm.trackpoint_support", &trackpoint_support); |
458 |
TUNABLE_INT("hw.psm.trackpoint_support", &trackpoint_support); |
387 |
|
459 |
|
|
|
460 |
static int elantech_support = 0; |
461 |
TUNABLE_INT("hw.psm.elantech_support", &elantech_support); |
462 |
|
388 |
static int verbose = PSM_DEBUG; |
463 |
static int verbose = PSM_DEBUG; |
389 |
TUNABLE_INT("debug.psm.loglevel", &verbose); |
464 |
TUNABLE_INT("debug.psm.loglevel", &verbose); |
390 |
|
465 |
|
Lines 407-412
Link Here
|
407 |
int accelfactor; |
482 |
int accelfactor; |
408 |
} old_mousemode_t; |
483 |
} old_mousemode_t; |
409 |
|
484 |
|
|
|
485 |
#define SYN_OFFSET(field) offsetof(struct psm_softc, syninfo.field) |
486 |
enum { |
487 |
SYNAPTICS_SYSCTL_MIN_PRESSURE = SYN_OFFSET(min_pressure), |
488 |
SYNAPTICS_SYSCTL_MAX_PRESSURE = SYN_OFFSET(max_pressure), |
489 |
SYNAPTICS_SYSCTL_MAX_WIDTH = SYN_OFFSET(max_width), |
490 |
SYNAPTICS_SYSCTL_MARGIN_TOP = SYN_OFFSET(margin_top), |
491 |
SYNAPTICS_SYSCTL_MARGIN_RIGHT = SYN_OFFSET(margin_right), |
492 |
SYNAPTICS_SYSCTL_MARGIN_BOTTOM = SYN_OFFSET(margin_bottom), |
493 |
SYNAPTICS_SYSCTL_MARGIN_LEFT = SYN_OFFSET(margin_left), |
494 |
SYNAPTICS_SYSCTL_NA_TOP = SYN_OFFSET(na_top), |
495 |
SYNAPTICS_SYSCTL_NA_RIGHT = SYN_OFFSET(na_right), |
496 |
SYNAPTICS_SYSCTL_NA_BOTTOM = SYN_OFFSET(na_bottom), |
497 |
SYNAPTICS_SYSCTL_NA_LEFT = SYN_OFFSET(na_left), |
498 |
SYNAPTICS_SYSCTL_WINDOW_MIN = SYN_OFFSET(window_min), |
499 |
SYNAPTICS_SYSCTL_WINDOW_MAX = SYN_OFFSET(window_max), |
500 |
SYNAPTICS_SYSCTL_MULTIPLICATOR = SYN_OFFSET(multiplicator), |
501 |
SYNAPTICS_SYSCTL_WEIGHT_CURRENT = SYN_OFFSET(weight_current), |
502 |
SYNAPTICS_SYSCTL_WEIGHT_PREVIOUS = SYN_OFFSET(weight_previous), |
503 |
SYNAPTICS_SYSCTL_WEIGHT_PREVIOUS_NA = SYN_OFFSET(weight_previous_na), |
504 |
SYNAPTICS_SYSCTL_WEIGHT_LEN_SQUARED = SYN_OFFSET(weight_len_squared), |
505 |
SYNAPTICS_SYSCTL_DIV_MIN = SYN_OFFSET(div_min), |
506 |
SYNAPTICS_SYSCTL_DIV_MAX = SYN_OFFSET(div_max), |
507 |
SYNAPTICS_SYSCTL_DIV_MAX_NA = SYN_OFFSET(div_max_na), |
508 |
SYNAPTICS_SYSCTL_DIV_LEN = SYN_OFFSET(div_len), |
509 |
SYNAPTICS_SYSCTL_TAP_MAX_DELTA = SYN_OFFSET(tap_max_delta), |
510 |
SYNAPTICS_SYSCTL_TAP_MIN_QUEUE = SYN_OFFSET(tap_min_queue), |
511 |
SYNAPTICS_SYSCTL_TAPHOLD_TIMEOUT = SYN_OFFSET(taphold_timeout), |
512 |
SYNAPTICS_SYSCTL_VSCROLL_HOR_AREA = SYN_OFFSET(vscroll_hor_area), |
513 |
SYNAPTICS_SYSCTL_VSCROLL_VER_AREA = SYN_OFFSET(vscroll_ver_area), |
514 |
SYNAPTICS_SYSCTL_VSCROLL_MIN_DELTA = SYN_OFFSET(vscroll_min_delta), |
515 |
SYNAPTICS_SYSCTL_VSCROLL_DIV_MIN = SYN_OFFSET(vscroll_div_min), |
516 |
SYNAPTICS_SYSCTL_VSCROLL_DIV_MAX = SYN_OFFSET(vscroll_div_max), |
517 |
SYNAPTICS_SYSCTL_TOUCHPAD_OFF = SYN_OFFSET(touchpad_off), |
518 |
SYNAPTICS_SYSCTL_SOFTBUTTONS = SYN_OFFSET(softbuttons), |
519 |
SYNAPTICS_SYSCTL_SOFTBUTTONS_Y = SYN_OFFSET(softbuttons_y), |
520 |
SYNAPTICS_SYSCTL_SOFTBUTTON2_X = SYN_OFFSET(softbutton2_x), |
521 |
SYNAPTICS_SYSCTL_SOFTBUTTON3_X = SYN_OFFSET(softbutton3_x), |
522 |
SYNAPTICS_SYSCTL_SOFTBUTTON_NOMOVE = SYN_OFFSET(softbutton_nomove) |
523 |
}; |
524 |
|
410 |
/* packet formatting function */ |
525 |
/* packet formatting function */ |
411 |
typedef int packetfunc_t(struct psm_softc *, u_char *, int *, int, |
526 |
typedef int packetfunc_t(struct psm_softc *, u_char *, int *, int, |
412 |
mousestatus_t *); |
527 |
mousestatus_t *); |
Lines 442-447
Link Here
|
442 |
static int reinitialize(struct psm_softc *, int); |
557 |
static int reinitialize(struct psm_softc *, int); |
443 |
static char *model_name(int); |
558 |
static char *model_name(int); |
444 |
static void psmsoftintr(void *); |
559 |
static void psmsoftintr(void *); |
|
|
560 |
static void psmsoftintridle(void *); |
445 |
static void psmintr(void *); |
561 |
static void psmintr(void *); |
446 |
static void psmtimeout(void *); |
562 |
static void psmtimeout(void *); |
447 |
static int timeelapsed(const struct timeval *, int, int, |
563 |
static int timeelapsed(const struct timeval *, int, int, |
Lines 454-464
Link Here
|
454 |
mousestatus_t *, int *, int *, int *); |
570 |
mousestatus_t *, int *, int *, int *); |
455 |
static void proc_versapad(struct psm_softc *, packetbuf_t *, |
571 |
static void proc_versapad(struct psm_softc *, packetbuf_t *, |
456 |
mousestatus_t *, int *, int *, int *); |
572 |
mousestatus_t *, int *, int *, int *); |
|
|
573 |
static int proc_elantech(struct psm_softc *, packetbuf_t *, |
574 |
mousestatus_t *, int *, int *, int *); |
575 |
static void psmgestures(struct psm_softc *, synapticsaction_t *, finger_t, |
576 |
int, mousestatus_t *, int *, int *); |
577 |
static int psmsoftbuttons(struct psm_softc *, finger_t, int); |
457 |
static int tame_mouse(struct psm_softc *, packetbuf_t *, mousestatus_t *, |
578 |
static int tame_mouse(struct psm_softc *, packetbuf_t *, mousestatus_t *, |
458 |
u_char *); |
579 |
u_char *); |
459 |
|
580 |
|
460 |
/* vendor specific features */ |
581 |
/* vendor specific features */ |
461 |
typedef int probefunc_t(KBDC, struct psm_softc *); |
582 |
enum probearg { PROBE, REINIT }; |
|
|
583 |
typedef int probefunc_t(struct psm_softc *, enum probearg); |
462 |
|
584 |
|
463 |
static int mouse_id_proc1(KBDC, int, int, int *); |
585 |
static int mouse_id_proc1(KBDC, int, int, int *); |
464 |
static int mouse_ext_command(KBDC, int); |
586 |
static int mouse_ext_command(KBDC, int); |
Lines 475-484
Link Here
|
475 |
static probefunc_t enable_synaptics; |
597 |
static probefunc_t enable_synaptics; |
476 |
static probefunc_t enable_trackpoint; |
598 |
static probefunc_t enable_trackpoint; |
477 |
static probefunc_t enable_versapad; |
599 |
static probefunc_t enable_versapad; |
|
|
600 |
static probefunc_t enable_elantech; |
478 |
|
601 |
|
479 |
static void set_trackpoint_parameters(struct psm_softc *sc); |
602 |
static void set_trackpoint_parameters(struct psm_softc *sc); |
480 |
static void synaptics_passthrough_on(struct psm_softc *sc); |
603 |
static void synaptics_passthrough_on(struct psm_softc *sc); |
481 |
static void synaptics_passthrough_off(struct psm_softc *sc); |
604 |
static void synaptics_passthrough_off(struct psm_softc *sc); |
|
|
605 |
static int synaptics_preferred_mode(struct psm_softc *sc); |
606 |
static void synaptics_set_mode(struct psm_softc *sc, int mode_byte); |
482 |
|
607 |
|
483 |
static struct { |
608 |
static struct { |
484 |
int model; |
609 |
int model; |
Lines 504-509
Link Here
|
504 |
0xc8, MOUSE_4DPLUS_PACKETSIZE, enable_4dplus }, |
629 |
0xc8, MOUSE_4DPLUS_PACKETSIZE, enable_4dplus }, |
505 |
{ MOUSE_MODEL_SYNAPTICS, /* Synaptics Touchpad */ |
630 |
{ MOUSE_MODEL_SYNAPTICS, /* Synaptics Touchpad */ |
506 |
0xc0, MOUSE_SYNAPTICS_PACKETSIZE, enable_synaptics }, |
631 |
0xc0, MOUSE_SYNAPTICS_PACKETSIZE, enable_synaptics }, |
|
|
632 |
{ MOUSE_MODEL_ELANTECH, /* Elantech Touchpad */ |
633 |
0x04, MOUSE_ELANTECH_PACKETSIZE, enable_elantech }, |
507 |
{ MOUSE_MODEL_INTELLI, /* Microsoft IntelliMouse */ |
634 |
{ MOUSE_MODEL_INTELLI, /* Microsoft IntelliMouse */ |
508 |
0x08, MOUSE_PS2INTELLI_PACKETSIZE, enable_msintelli }, |
635 |
0x08, MOUSE_PS2INTELLI_PACKETSIZE, enable_msintelli }, |
509 |
{ MOUSE_MODEL_GLIDEPOINT, /* ALPS GlidePoint */ |
636 |
{ MOUSE_MODEL_GLIDEPOINT, /* ALPS GlidePoint */ |
Lines 756-761
Link Here
|
756 |
{ MOUSE_MODEL_4DPLUS, "4D+ Mouse" }, |
883 |
{ MOUSE_MODEL_4DPLUS, "4D+ Mouse" }, |
757 |
{ MOUSE_MODEL_SYNAPTICS, "Synaptics Touchpad" }, |
884 |
{ MOUSE_MODEL_SYNAPTICS, "Synaptics Touchpad" }, |
758 |
{ MOUSE_MODEL_TRACKPOINT, "IBM/Lenovo TrackPoint" }, |
885 |
{ MOUSE_MODEL_TRACKPOINT, "IBM/Lenovo TrackPoint" }, |
|
|
886 |
{ MOUSE_MODEL_ELANTECH, "Elantech Touchpad" }, |
759 |
{ MOUSE_MODEL_GENERIC, "Generic PS/2 mouse" }, |
887 |
{ MOUSE_MODEL_GENERIC, "Generic PS/2 mouse" }, |
760 |
{ MOUSE_MODEL_UNKNOWN, "Unknown" }, |
888 |
{ MOUSE_MODEL_UNKNOWN, "Unknown" }, |
761 |
}; |
889 |
}; |
Lines 876-882
Link Here
|
876 |
/* Re-enable the mouse. */ |
1004 |
/* Re-enable the mouse. */ |
877 |
for (i = 0; vendortype[i].probefunc != NULL; ++i) |
1005 |
for (i = 0; vendortype[i].probefunc != NULL; ++i) |
878 |
if (vendortype[i].model == sc->hw.model) |
1006 |
if (vendortype[i].model == sc->hw.model) |
879 |
(*vendortype[i].probefunc)(sc->kbdc, NULL); |
1007 |
(*vendortype[i].probefunc)(sc, REINIT); |
880 |
|
1008 |
|
881 |
/* set mouse parameters */ |
1009 |
/* set mouse parameters */ |
882 |
if (mode != (mousemode_t *)NULL) { |
1010 |
if (mode != (mousemode_t *)NULL) { |
Lines 887-899
Link Here
|
887 |
set_mouse_resolution(kbdc, mode->resolution); |
1015 |
set_mouse_resolution(kbdc, mode->resolution); |
888 |
set_mouse_scaling(kbdc, 1); |
1016 |
set_mouse_scaling(kbdc, 1); |
889 |
set_mouse_mode(kbdc); |
1017 |
set_mouse_mode(kbdc); |
890 |
|
|
|
891 |
/* |
892 |
* Trackpoint settings are lost on resume. |
893 |
* Restore them here. |
894 |
*/ |
895 |
if (sc->tphw > 0) |
896 |
set_trackpoint_parameters(sc); |
897 |
} |
1018 |
} |
898 |
|
1019 |
|
899 |
/* Record sync on the next data packet we see. */ |
1020 |
/* Record sync on the next data packet we see. */ |
Lines 929-942
Link Here
|
929 |
get_mouse_status(sc->kbdc, stat, 0, 3); |
1050 |
get_mouse_status(sc->kbdc, stat, 0, 3); |
930 |
if ((SYNAPTICS_VERSION_GE(sc->synhw, 7, 5) || |
1051 |
if ((SYNAPTICS_VERSION_GE(sc->synhw, 7, 5) || |
931 |
stat[1] == 0x47) && |
1052 |
stat[1] == 0x47) && |
932 |
stat[2] == 0x40) { |
1053 |
stat[2] == 0x40) { |
933 |
/* Set the mode byte -- request wmode where |
1054 |
synaptics_set_mode(sc, synaptics_preferred_mode(sc)); |
934 |
* available */ |
|
|
935 |
if (sc->synhw.capExtended) |
936 |
mouse_ext_command(sc->kbdc, 0xc1); |
937 |
else |
938 |
mouse_ext_command(sc->kbdc, 0xc0); |
939 |
set_mouse_sampling_rate(sc->kbdc, 20); |
940 |
VLOG(5, (LOG_DEBUG, "psm%d: Synaptis Absolute Mode " |
1055 |
VLOG(5, (LOG_DEBUG, "psm%d: Synaptis Absolute Mode " |
941 |
"hopefully restored\n", |
1056 |
"hopefully restored\n", |
942 |
sc->unit)); |
1057 |
sc->unit)); |
Lines 1246-1252
Link Here
|
1246 |
* this is CONTROLLER ERROR; I don't know how to recover |
1361 |
* this is CONTROLLER ERROR; I don't know how to recover |
1247 |
* from this error... |
1362 |
* from this error... |
1248 |
*/ |
1363 |
*/ |
1249 |
restore_controller(sc->kbdc, command_byte); |
1364 |
if (ALWAYS_RESTORE_CONTROLLER(sc->kbdc)) |
|
|
1365 |
restore_controller(sc->kbdc, command_byte); |
1250 |
printf("psm%d: unable to set the command byte.\n", unit); |
1366 |
printf("psm%d: unable to set the command byte.\n", unit); |
1251 |
endprobe(ENXIO); |
1367 |
endprobe(ENXIO); |
1252 |
} |
1368 |
} |
Lines 1285-1291
Link Here
|
1285 |
recover_from_error(sc->kbdc); |
1401 |
recover_from_error(sc->kbdc); |
1286 |
if (sc->config & PSM_CONFIG_IGNPORTERROR) |
1402 |
if (sc->config & PSM_CONFIG_IGNPORTERROR) |
1287 |
break; |
1403 |
break; |
1288 |
restore_controller(sc->kbdc, command_byte); |
1404 |
if (ALWAYS_RESTORE_CONTROLLER(sc->kbdc)) |
|
|
1405 |
restore_controller(sc->kbdc, command_byte); |
1289 |
if (verbose) |
1406 |
if (verbose) |
1290 |
printf("psm%d: the aux port is not functioning (%d).\n", |
1407 |
printf("psm%d: the aux port is not functioning (%d).\n", |
1291 |
unit, i); |
1408 |
unit, i); |
Lines 1308-1314
Link Here
|
1308 |
*/ |
1425 |
*/ |
1309 |
if (!reset_aux_dev(sc->kbdc)) { |
1426 |
if (!reset_aux_dev(sc->kbdc)) { |
1310 |
recover_from_error(sc->kbdc); |
1427 |
recover_from_error(sc->kbdc); |
1311 |
restore_controller(sc->kbdc, command_byte); |
1428 |
if (ALWAYS_RESTORE_CONTROLLER(sc->kbdc)) |
|
|
1429 |
restore_controller(sc->kbdc, command_byte); |
1312 |
if (verbose) |
1430 |
if (verbose) |
1313 |
printf("psm%d: failed to reset the aux " |
1431 |
printf("psm%d: failed to reset the aux " |
1314 |
"device.\n", unit); |
1432 |
"device.\n", unit); |
Lines 1330-1336
Link Here
|
1330 |
if (!enable_aux_dev(sc->kbdc) || !disable_aux_dev(sc->kbdc)) { |
1448 |
if (!enable_aux_dev(sc->kbdc) || !disable_aux_dev(sc->kbdc)) { |
1331 |
/* MOUSE ERROR */ |
1449 |
/* MOUSE ERROR */ |
1332 |
recover_from_error(sc->kbdc); |
1450 |
recover_from_error(sc->kbdc); |
1333 |
restore_controller(sc->kbdc, command_byte); |
1451 |
if (ALWAYS_RESTORE_CONTROLLER(sc->kbdc)) |
|
|
1452 |
restore_controller(sc->kbdc, command_byte); |
1334 |
if (verbose) |
1453 |
if (verbose) |
1335 |
printf("psm%d: failed to enable the aux device.\n", |
1454 |
printf("psm%d: failed to enable the aux device.\n", |
1336 |
unit); |
1455 |
unit); |
Lines 1352-1358
Link Here
|
1352 |
/* verify the device is a mouse */ |
1471 |
/* verify the device is a mouse */ |
1353 |
sc->hw.hwid = get_aux_id(sc->kbdc); |
1472 |
sc->hw.hwid = get_aux_id(sc->kbdc); |
1354 |
if (!is_a_mouse(sc->hw.hwid)) { |
1473 |
if (!is_a_mouse(sc->hw.hwid)) { |
1355 |
restore_controller(sc->kbdc, command_byte); |
1474 |
if (ALWAYS_RESTORE_CONTROLLER(sc->kbdc)) |
|
|
1475 |
restore_controller(sc->kbdc, command_byte); |
1356 |
if (verbose) |
1476 |
if (verbose) |
1357 |
printf("psm%d: unknown device type (%d).\n", unit, |
1477 |
printf("psm%d: unknown device type (%d).\n", unit, |
1358 |
sc->hw.hwid); |
1478 |
sc->hw.hwid); |
Lines 1383-1389
Link Here
|
1383 |
|
1503 |
|
1384 |
/* other parameters */ |
1504 |
/* other parameters */ |
1385 |
for (i = 0; vendortype[i].probefunc != NULL; ++i) |
1505 |
for (i = 0; vendortype[i].probefunc != NULL; ++i) |
1386 |
if ((*vendortype[i].probefunc)(sc->kbdc, sc)) { |
1506 |
if ((*vendortype[i].probefunc)(sc, PROBE)) { |
1387 |
if (verbose >= 2) |
1507 |
if (verbose >= 2) |
1388 |
printf("psm%d: found %s\n", unit, |
1508 |
printf("psm%d: found %s\n", unit, |
1389 |
model_name(vendortype[i].model)); |
1509 |
model_name(vendortype[i].model)); |
Lines 1458-1464
Link Here
|
1458 |
* this is CONTROLLER ERROR; I don't know the proper way to |
1578 |
* this is CONTROLLER ERROR; I don't know the proper way to |
1459 |
* recover from this error... |
1579 |
* recover from this error... |
1460 |
*/ |
1580 |
*/ |
1461 |
restore_controller(sc->kbdc, command_byte); |
1581 |
if (ALWAYS_RESTORE_CONTROLLER(sc->kbdc)) |
|
|
1582 |
restore_controller(sc->kbdc, command_byte); |
1462 |
printf("psm%d: unable to set the command byte.\n", unit); |
1583 |
printf("psm%d: unable to set the command byte.\n", unit); |
1463 |
endprobe(ENXIO); |
1584 |
endprobe(ENXIO); |
1464 |
} |
1585 |
} |
Lines 1505-1510
Link Here
|
1505 |
case MOUSE_MODEL_SYNAPTICS: |
1626 |
case MOUSE_MODEL_SYNAPTICS: |
1506 |
case MOUSE_MODEL_GLIDEPOINT: |
1627 |
case MOUSE_MODEL_GLIDEPOINT: |
1507 |
case MOUSE_MODEL_VERSAPAD: |
1628 |
case MOUSE_MODEL_VERSAPAD: |
|
|
1629 |
case MOUSE_MODEL_ELANTECH: |
1508 |
sc->config |= PSM_CONFIG_INITAFTERSUSPEND; |
1630 |
sc->config |= PSM_CONFIG_INITAFTERSUSPEND; |
1509 |
break; |
1631 |
break; |
1510 |
default: |
1632 |
default: |
Lines 2166-2171
Link Here
|
2166 |
(*(int *)addr > PSM_LEVEL_MAX)) |
2288 |
(*(int *)addr > PSM_LEVEL_MAX)) |
2167 |
return (EINVAL); |
2289 |
return (EINVAL); |
2168 |
sc->mode.level = *(int *)addr; |
2290 |
sc->mode.level = *(int *)addr; |
|
|
2291 |
|
2292 |
if (sc->hw.model == MOUSE_MODEL_SYNAPTICS) { |
2293 |
/* |
2294 |
* If we are entering PSM_LEVEL_NATIVE, we want to |
2295 |
* enable sending of "extended W mode" packets to |
2296 |
* userland. Reset the mode of the touchpad so that the |
2297 |
* change in the level is picked up. |
2298 |
*/ |
2299 |
error = block_mouse_data(sc, &command_byte); |
2300 |
if (error) |
2301 |
return (error); |
2302 |
synaptics_set_mode(sc, synaptics_preferred_mode(sc)); |
2303 |
unblock_mouse_data(sc, command_byte); |
2304 |
} |
2169 |
break; |
2305 |
break; |
2170 |
|
2306 |
|
2171 |
case MOUSE_GETSTATUS: |
2307 |
case MOUSE_GETSTATUS: |
Lines 2614-2620
Link Here
|
2614 |
{ |
2750 |
{ |
2615 |
static int touchpad_buttons; |
2751 |
static int touchpad_buttons; |
2616 |
static int guest_buttons; |
2752 |
static int guest_buttons; |
2617 |
int w, x0, y0; |
2753 |
finger_t f; |
|
|
2754 |
int w, nfingers; |
2618 |
|
2755 |
|
2619 |
/* TouchPad PS/2 absolute mode message format with capFourButtons: |
2756 |
/* TouchPad PS/2 absolute mode message format with capFourButtons: |
2620 |
* |
2757 |
* |
Lines 2793-2799
Link Here
|
2793 |
pb->ipacket[4] &= ~(mask); |
2930 |
pb->ipacket[4] &= ~(mask); |
2794 |
pb->ipacket[5] &= ~(mask); |
2931 |
pb->ipacket[5] &= ~(mask); |
2795 |
} else if (!sc->syninfo.directional_scrolls && |
2932 |
} else if (!sc->syninfo.directional_scrolls && |
2796 |
!sc->synaction.in_vscroll) { |
2933 |
!sc->synaction[0].in_vscroll) { |
2797 |
/* |
2934 |
/* |
2798 |
* Keep reporting MOUSE DOWN until we get a new packet |
2935 |
* Keep reporting MOUSE DOWN until we get a new packet |
2799 |
* indicating otherwise. |
2936 |
* indicating otherwise. |
Lines 2801-2819
Link Here
|
2801 |
touchpad_buttons |= sc->extended_buttons; |
2938 |
touchpad_buttons |= sc->extended_buttons; |
2802 |
} |
2939 |
} |
2803 |
} |
2940 |
} |
|
|
2941 |
|
2942 |
f.x = ((pb->ipacket[3] & 0x10) << 8) | |
2943 |
((pb->ipacket[1] & 0x0f) << 8) | |
2944 |
pb->ipacket[4]; |
2945 |
f.y = ((pb->ipacket[3] & 0x20) << 7) | |
2946 |
((pb->ipacket[1] & 0xf0) << 4) | |
2947 |
pb->ipacket[5]; |
2948 |
f.p = *z; |
2949 |
f.w = w; |
2950 |
f.flags |= w == 2 ? PSM_FINGER_IS_PEN : 0; |
2951 |
f.flags |= w < 2 ? PSM_FINGER_FUZZY : 0; |
2952 |
nfingers = w < 2 ? w + 2 : 1; |
2953 |
|
2804 |
/* Handle ClickPad. */ |
2954 |
/* Handle ClickPad. */ |
2805 |
if (sc->synhw.capClickPad && |
2955 |
if (sc->synhw.capClickPad) |
2806 |
((pb->ipacket[0] ^ pb->ipacket[3]) & 0x01)) |
2956 |
touchpad_buttons |= psmsoftbuttons(sc, f, |
2807 |
touchpad_buttons |= MOUSE_BUTTON1DOWN; |
2957 |
(pb->ipacket[0] ^ pb->ipacket[3]) & 0x01); |
2808 |
|
2958 |
|
2809 |
ms->button = touchpad_buttons | guest_buttons; |
2959 |
ms->button = touchpad_buttons | guest_buttons; |
2810 |
|
2960 |
|
|
|
2961 |
psmgestures(sc, &sc->synaction[0], f, nfingers, ms, x, y); |
2962 |
|
2963 |
SYNAPTICS_END: |
2811 |
/* |
2964 |
/* |
|
|
2965 |
* Use the extra buttons as a scrollwheel |
2966 |
* |
2967 |
* XXX X.Org uses the Z axis for vertical wheel only, |
2968 |
* whereas moused(8) understands special values to differ |
2969 |
* vertical and horizontal wheels. |
2970 |
* |
2971 |
* xf86-input-mouse needs therefore a small patch to |
2972 |
* understand these special values. Without it, the |
2973 |
* horizontal wheel acts as a vertical wheel in X.Org. |
2974 |
* |
2975 |
* That's why the horizontal wheel is disabled by |
2976 |
* default for now. |
2977 |
*/ |
2978 |
if (ms->button & MOUSE_BUTTON4DOWN) { |
2979 |
*z = -1; |
2980 |
ms->button &= ~MOUSE_BUTTON4DOWN; |
2981 |
} else if (ms->button & MOUSE_BUTTON5DOWN) { |
2982 |
*z = 1; |
2983 |
ms->button &= ~MOUSE_BUTTON5DOWN; |
2984 |
} else if (ms->button & MOUSE_BUTTON6DOWN) { |
2985 |
*z = -2; |
2986 |
ms->button &= ~MOUSE_BUTTON6DOWN; |
2987 |
} else if (ms->button & MOUSE_BUTTON7DOWN) { |
2988 |
*z = 2; |
2989 |
ms->button &= ~MOUSE_BUTTON7DOWN; |
2990 |
} else |
2991 |
*z = 0; |
2992 |
|
2993 |
return (0); |
2994 |
} |
2995 |
|
2996 |
static void |
2997 |
psmgestures(struct psm_softc *sc, synapticsaction_t *synaction, finger_t f, |
2998 |
int nfingers, mousestatus_t *ms, int *x, int *y) |
2999 |
{ |
3000 |
*x = *y = 0; |
3001 |
|
3002 |
/* |
2812 |
* Check pressure to detect a real wanted action on the |
3003 |
* Check pressure to detect a real wanted action on the |
2813 |
* touchpad. |
3004 |
* touchpad. |
2814 |
*/ |
3005 |
*/ |
2815 |
if (*z >= sc->syninfo.min_pressure) { |
3006 |
if (f.p >= sc->syninfo.min_pressure) { |
2816 |
synapticsaction_t *synaction; |
3007 |
int x0, y0; |
2817 |
int cursor, peer, window; |
3008 |
int cursor, peer, window; |
2818 |
int dx, dy, dxp, dyp; |
3009 |
int dx, dy, dxp, dyp; |
2819 |
int max_width, max_pressure; |
3010 |
int max_width, max_pressure; |
Lines 2825-2832
Link Here
|
2825 |
int div_min, div_max, div_len; |
3016 |
int div_min, div_max, div_len; |
2826 |
int vscroll_hor_area, vscroll_ver_area; |
3017 |
int vscroll_hor_area, vscroll_ver_area; |
2827 |
int two_finger_scroll; |
3018 |
int two_finger_scroll; |
|
|
3019 |
int max_x, max_y; |
2828 |
int len, weight_prev_x, weight_prev_y; |
3020 |
int len, weight_prev_x, weight_prev_y; |
2829 |
int div_max_x, div_max_y, div_x, div_y; |
3021 |
int div_max_x, div_max_y, div_x, div_y; |
|
|
3022 |
int exiting_scroll; |
2830 |
|
3023 |
|
2831 |
/* Read sysctl. */ |
3024 |
/* Read sysctl. */ |
2832 |
/* XXX Verify values? */ |
3025 |
/* XXX Verify values? */ |
Lines 2852-2890
Link Here
|
2852 |
vscroll_hor_area = sc->syninfo.vscroll_hor_area; |
3045 |
vscroll_hor_area = sc->syninfo.vscroll_hor_area; |
2853 |
vscroll_ver_area = sc->syninfo.vscroll_ver_area; |
3046 |
vscroll_ver_area = sc->syninfo.vscroll_ver_area; |
2854 |
two_finger_scroll = sc->syninfo.two_finger_scroll; |
3047 |
two_finger_scroll = sc->syninfo.two_finger_scroll; |
|
|
3048 |
max_x = sc->synhw.maximumXCoord; |
3049 |
max_y = sc->synhw.maximumYCoord; |
2855 |
|
3050 |
|
|
|
3051 |
exiting_scroll = 0; |
3052 |
|
2856 |
/* Palm detection. */ |
3053 |
/* Palm detection. */ |
2857 |
if (!( |
3054 |
if (!( |
2858 |
(sc->synhw.capMultiFinger && (w == 0 || w == 1)) || |
3055 |
((sc->synhw.capMultiFinger || |
2859 |
(sc->synhw.capPalmDetect && w >= 4 && w <= max_width) || |
3056 |
sc->synhw.capAdvancedGestures) && nfingers > 1) || |
2860 |
(!sc->synhw.capPalmDetect && *z <= max_pressure) || |
3057 |
(sc->synhw.capPalmDetect && f.w <= max_width) || |
2861 |
(sc->synhw.capPen && w == 2))) { |
3058 |
(!sc->synhw.capPalmDetect && f.p <= max_pressure) || |
|
|
3059 |
(sc->synhw.capPen && f.flags & PSM_FINGER_IS_PEN))) { |
2862 |
/* |
3060 |
/* |
2863 |
* We consider the packet irrelevant for the current |
3061 |
* We consider the packet irrelevant for the current |
2864 |
* action when: |
3062 |
* action when: |
2865 |
* - the width isn't comprised in: |
3063 |
* - the width isn't comprised in: |
2866 |
* [4; max_width] |
3064 |
* [1; max_width] |
2867 |
* - the pressure isn't comprised in: |
3065 |
* - the pressure isn't comprised in: |
2868 |
* [min_pressure; max_pressure] |
3066 |
* [min_pressure; max_pressure] |
2869 |
* - pen aren't supported but w is 2 |
3067 |
* - pen aren't supported but PSM_FiNGER_IS_PEN is set |
2870 |
* |
3068 |
* |
2871 |
* Note that this doesn't terminate the current action. |
3069 |
* Note that this doesn't terminate the current action. |
2872 |
*/ |
3070 |
*/ |
2873 |
VLOG(2, (LOG_DEBUG, |
3071 |
VLOG(2, (LOG_DEBUG, |
2874 |
"synaptics: palm detected! (%d)\n", w)); |
3072 |
"synaptics: palm detected! (%d)\n", f.w)); |
2875 |
goto SYNAPTICS_END; |
3073 |
return; |
2876 |
} |
3074 |
} |
2877 |
|
3075 |
|
2878 |
/* Read current absolute position. */ |
3076 |
/* Read current absolute position. */ |
2879 |
x0 = ((pb->ipacket[3] & 0x10) << 8) | |
3077 |
x0 = f.x; |
2880 |
((pb->ipacket[1] & 0x0f) << 8) | |
3078 |
y0 = f.y; |
2881 |
pb->ipacket[4]; |
|
|
2882 |
y0 = ((pb->ipacket[3] & 0x20) << 7) | |
2883 |
((pb->ipacket[1] & 0xf0) << 4) | |
2884 |
pb->ipacket[5]; |
2885 |
|
3079 |
|
2886 |
synaction = &(sc->synaction); |
|
|
2887 |
|
2888 |
/* |
3080 |
/* |
2889 |
* If the action is just beginning, init the structure and |
3081 |
* If the action is just beginning, init the structure and |
2890 |
* compute tap timeout. |
3082 |
* compute tap timeout. |
Lines 2947-2961
Link Here
|
2947 |
*/ |
3139 |
*/ |
2948 |
if (x0 <= margin_left) |
3140 |
if (x0 <= margin_left) |
2949 |
x0 = margin_left; |
3141 |
x0 = margin_left; |
2950 |
else if (x0 >= 6143 - margin_right) |
3142 |
else if (x0 >= max_x - margin_right) |
2951 |
x0 = 6143 - margin_right; |
3143 |
x0 = max_x - margin_right; |
2952 |
if (y0 <= margin_bottom) |
3144 |
if (y0 <= margin_bottom) |
2953 |
y0 = margin_bottom; |
3145 |
y0 = margin_bottom; |
2954 |
else if (y0 >= 6143 - margin_top) |
3146 |
else if (y0 >= max_y - margin_top) |
2955 |
y0 = 6143 - margin_top; |
3147 |
y0 = max_y - margin_top; |
2956 |
|
3148 |
|
2957 |
VLOG(3, (LOG_DEBUG, "synaptics: ipacket: [%d, %d], %d, %d\n", |
3149 |
VLOG(3, (LOG_DEBUG, "synaptics: ipacket: [%d, %d], %d, %d\n", |
2958 |
x0, y0, *z, w)); |
3150 |
x0, y0, f.p, f.w)); |
2959 |
|
3151 |
|
2960 |
/* Queue this new packet. */ |
3152 |
/* Queue this new packet. */ |
2961 |
cursor = SYNAPTICS_QUEUE_CURSOR(synaction->queue_cursor - 1); |
3153 |
cursor = SYNAPTICS_QUEUE_CURSOR(synaction->queue_cursor - 1); |
Lines 2973-2998
Link Here
|
2973 |
* pressure peak. Also with multiple fingers, we increase |
3165 |
* pressure peak. Also with multiple fingers, we increase |
2974 |
* the minimum window. |
3166 |
* the minimum window. |
2975 |
*/ |
3167 |
*/ |
2976 |
switch (w) { |
3168 |
if (nfingers > 1) |
2977 |
case 1: /* Three or more fingers. */ |
|
|
2978 |
synaction->fingers_nb = imax(3, synaction->fingers_nb); |
2979 |
synaction->window_min = window_max; |
3169 |
synaction->window_min = window_max; |
2980 |
break; |
3170 |
synaction->fingers_nb = imax(nfingers, synaction->fingers_nb); |
2981 |
case 0: /* Two fingers. */ |
3171 |
sc->zmax = imax(f.p, sc->zmax); |
2982 |
synaction->fingers_nb = imax(2, synaction->fingers_nb); |
|
|
2983 |
synaction->window_min = window_max; |
2984 |
break; |
2985 |
default: /* One finger or undetectable. */ |
2986 |
synaction->fingers_nb = imax(1, synaction->fingers_nb); |
2987 |
} |
2988 |
sc->zmax = imax(*z, sc->zmax); |
2989 |
|
3172 |
|
2990 |
/* Do we have enough packets to consider this a movement? */ |
3173 |
/* Do we have enough packets to consider this a movement? */ |
2991 |
if (synaction->queue_len < synaction->window_min) |
3174 |
if (synaction->queue_len < synaction->window_min) |
2992 |
goto SYNAPTICS_END; |
3175 |
return; |
2993 |
|
3176 |
|
2994 |
/* Is a scrolling action occuring? */ |
3177 |
/* Is a scrolling action occuring? */ |
2995 |
if (!synaction->in_taphold && !synaction->in_vscroll) { |
3178 |
if (!synaction->in_taphold && |
|
|
3179 |
(!synaction->in_vscroll || two_finger_scroll)) { |
2996 |
/* |
3180 |
/* |
2997 |
* A scrolling action must not conflict with a tap |
3181 |
* A scrolling action must not conflict with a tap |
2998 |
* action. Here are the conditions to consider a |
3182 |
* action. Here are the conditions to consider a |
Lines 3017-3023
Link Here
|
3017 |
* as that keeps the maximum number of fingers. |
3201 |
* as that keeps the maximum number of fingers. |
3018 |
*/ |
3202 |
*/ |
3019 |
if (two_finger_scroll) { |
3203 |
if (two_finger_scroll) { |
3020 |
if (w == 0) { |
3204 |
if (nfingers == 2) { |
3021 |
synaction->in_vscroll += |
3205 |
synaction->in_vscroll += |
3022 |
dyp ? 2 : 0; |
3206 |
dyp ? 2 : 0; |
3023 |
synaction->in_vscroll += |
3207 |
synaction->in_vscroll += |
Lines 3030-3036
Link Here
|
3030 |
vscroll_hor_area) || |
3214 |
vscroll_hor_area) || |
3031 |
(vscroll_hor_area < 0 && |
3215 |
(vscroll_hor_area < 0 && |
3032 |
synaction->start_y >= |
3216 |
synaction->start_y >= |
3033 |
6143 + vscroll_hor_area)) |
3217 |
max_y + vscroll_hor_area)) |
3034 |
synaction->in_vscroll += 2; |
3218 |
synaction->in_vscroll += 2; |
3035 |
|
3219 |
|
3036 |
/* Check for vertical scrolling. */ |
3220 |
/* Check for vertical scrolling. */ |
Lines 3039-3045
Link Here
|
3039 |
vscroll_ver_area) || |
3223 |
vscroll_ver_area) || |
3040 |
(vscroll_ver_area < 0 && |
3224 |
(vscroll_ver_area < 0 && |
3041 |
synaction->start_x >= |
3225 |
synaction->start_x >= |
3042 |
6143 + vscroll_ver_area)) |
3226 |
max_x + vscroll_ver_area)) |
3043 |
synaction->in_vscroll += 1; |
3227 |
synaction->in_vscroll += 1; |
3044 |
} |
3228 |
} |
3045 |
|
3229 |
|
Lines 3053-3060
Link Here
|
3053 |
* Reset two finger scrolling when the number of fingers |
3237 |
* Reset two finger scrolling when the number of fingers |
3054 |
* is different from two. |
3238 |
* is different from two. |
3055 |
*/ |
3239 |
*/ |
3056 |
if (two_finger_scroll && w != 0) |
3240 |
if (two_finger_scroll && nfingers != 2 && synaction->in_vscroll != 0) { |
3057 |
synaction->in_vscroll = 0; |
3241 |
synaction->in_vscroll = 0; |
|
|
3242 |
exiting_scroll = 1; |
3243 |
} |
3058 |
|
3244 |
|
3059 |
VLOG(5, (LOG_DEBUG, |
3245 |
VLOG(5, (LOG_DEBUG, |
3060 |
"synaptics: virtual scrolling: %s " |
3246 |
"synaptics: virtual scrolling: %s " |
Lines 3077-3088
Link Here
|
3077 |
* using this area, we apply a special weight and |
3263 |
* using this area, we apply a special weight and |
3078 |
* div. |
3264 |
* div. |
3079 |
*/ |
3265 |
*/ |
3080 |
if (x0 <= na_left || x0 >= 6143 - na_right) { |
3266 |
if (x0 <= na_left || x0 >= max_x - na_right) { |
3081 |
weight_prev_x = sc->syninfo.weight_previous_na; |
3267 |
weight_prev_x = sc->syninfo.weight_previous_na; |
3082 |
div_max_x = sc->syninfo.div_max_na; |
3268 |
div_max_x = sc->syninfo.div_max_na; |
3083 |
} |
3269 |
} |
3084 |
|
3270 |
|
3085 |
if (y0 <= na_bottom || y0 >= 6143 - na_top) { |
3271 |
if (y0 <= na_bottom || y0 >= max_y - na_top) { |
3086 |
weight_prev_y = sc->syninfo.weight_previous_na; |
3272 |
weight_prev_y = sc->syninfo.weight_previous_na; |
3087 |
div_max_y = sc->syninfo.div_max_na; |
3273 |
div_max_y = sc->syninfo.div_max_na; |
3088 |
} |
3274 |
} |
Lines 3162-3167
Link Here
|
3162 |
/* The pointer is not moved. */ |
3348 |
/* The pointer is not moved. */ |
3163 |
*x = *y = 0; |
3349 |
*x = *y = 0; |
3164 |
} else { |
3350 |
} else { |
|
|
3351 |
/* On exit the x/y pos may jump, ignore this */ |
3352 |
if (exiting_scroll) |
3353 |
*x = *y = 0; |
3354 |
|
3165 |
VLOG(3, (LOG_DEBUG, "synaptics: [%d, %d] -> [%d, %d]\n", |
3355 |
VLOG(3, (LOG_DEBUG, "synaptics: [%d, %d] -> [%d, %d]\n", |
3166 |
dx, dy, *x, *y)); |
3356 |
dx, dy, *x, *y)); |
3167 |
} |
3357 |
} |
Lines 3170-3179
Link Here
|
3170 |
* An action is currently taking place but the pressure |
3360 |
* An action is currently taking place but the pressure |
3171 |
* dropped under the minimum, putting an end to it. |
3361 |
* dropped under the minimum, putting an end to it. |
3172 |
*/ |
3362 |
*/ |
3173 |
synapticsaction_t *synaction; |
|
|
3174 |
int taphold_timeout, dx, dy, tap_max_delta; |
3363 |
int taphold_timeout, dx, dy, tap_max_delta; |
3175 |
|
3364 |
|
3176 |
synaction = &(sc->synaction); |
|
|
3177 |
dx = abs(synaction->queue[synaction->queue_cursor].x - |
3365 |
dx = abs(synaction->queue[synaction->queue_cursor].x - |
3178 |
synaction->start_x); |
3366 |
synaction->start_x); |
3179 |
dy = abs(synaction->queue[synaction->queue_cursor].y - |
3367 |
dy = abs(synaction->queue[synaction->queue_cursor].y - |
Lines 3224-3229
Link Here
|
3224 |
"synaptics: button RELEASE: %d\n", |
3412 |
"synaptics: button RELEASE: %d\n", |
3225 |
synaction->tap_button)); |
3413 |
synaction->tap_button)); |
3226 |
sc->flags |= PSM_FLAGS_FINGERDOWN; |
3414 |
sc->flags |= PSM_FLAGS_FINGERDOWN; |
|
|
3415 |
|
3416 |
/* Schedule button press on next interrupt */ |
3417 |
sc->idletimeout.tv_sec = psmhz > 1 ? |
3418 |
0 : 1; |
3419 |
sc->idletimeout.tv_usec = psmhz > 1 ? |
3420 |
1000000 / psmhz : 0; |
3227 |
} else { |
3421 |
} else { |
3228 |
/* |
3422 |
/* |
3229 |
* This is the first tap: we set the |
3423 |
* This is the first tap: we set the |
Lines 3236-3241
Link Here
|
3236 |
1000000; |
3430 |
1000000; |
3237 |
sc->taptimeout.tv_usec = taphold_timeout % |
3431 |
sc->taptimeout.tv_usec = taphold_timeout % |
3238 |
1000000; |
3432 |
1000000; |
|
|
3433 |
sc->idletimeout = sc->taptimeout; |
3239 |
timevaladd(&sc->taptimeout, &sc->lastsoftintr); |
3434 |
timevaladd(&sc->taptimeout, &sc->lastsoftintr); |
3240 |
|
3435 |
|
3241 |
switch (synaction->fingers_nb) { |
3436 |
switch (synaction->fingers_nb) { |
Lines 3272-3278
Link Here
|
3272 |
} |
3467 |
} |
3273 |
} |
3468 |
} |
3274 |
} else if (!(sc->flags & PSM_FLAGS_FINGERDOWN) && |
3469 |
} else if (!(sc->flags & PSM_FLAGS_FINGERDOWN) && |
3275 |
sc->synaction.in_taphold) { |
3470 |
synaction->in_taphold) { |
3276 |
/* |
3471 |
/* |
3277 |
* For a tap-hold to work, the button must remain down at |
3472 |
* For a tap-hold to work, the button must remain down at |
3278 |
* least until timeout (where the in_taphold flags will be |
3473 |
* least until timeout (where the in_taphold flags will be |
Lines 3279-3323
Link Here
|
3279 |
* cleared) or during the next action. |
3474 |
* cleared) or during the next action. |
3280 |
*/ |
3475 |
*/ |
3281 |
if (timevalcmp(&sc->lastsoftintr, &sc->taptimeout, <=)) { |
3476 |
if (timevalcmp(&sc->lastsoftintr, &sc->taptimeout, <=)) { |
3282 |
ms->button |= sc->synaction.tap_button; |
3477 |
ms->button |= synaction->tap_button; |
3283 |
} else { |
3478 |
} else { |
3284 |
VLOG(2, (LOG_DEBUG, |
3479 |
VLOG(2, (LOG_DEBUG, |
3285 |
"synaptics: button RELEASE: %d\n", |
3480 |
"synaptics: button RELEASE: %d\n", |
3286 |
sc->synaction.tap_button)); |
3481 |
synaction->tap_button)); |
3287 |
sc->synaction.in_taphold = 0; |
3482 |
synaction->in_taphold = 0; |
3288 |
} |
3483 |
} |
3289 |
} |
3484 |
} |
3290 |
|
3485 |
|
3291 |
SYNAPTICS_END: |
3486 |
return; |
|
|
3487 |
} |
3488 |
|
3489 |
static int |
3490 |
psmsoftbuttons(struct psm_softc *sc, finger_t f, int pressed) |
3491 |
{ |
3492 |
static int button = 0; |
3493 |
int y_ok, center_button, center_x, right_button, right_x; |
3494 |
|
3495 |
/* Dont change clickpad softbutton after pressing */ |
3496 |
if (pressed && !button) { |
3497 |
y_ok = sc->syninfo.softbuttons_y >= 0 ? |
3498 |
f.y < sc->syninfo.softbuttons_y : |
3499 |
f.y > sc->synhw.maximumYCoord - sc->syninfo.softbuttons_y; |
3500 |
|
3501 |
center_button = MOUSE_BUTTON2DOWN; |
3502 |
center_x = sc->syninfo.softbutton2_x; |
3503 |
right_button = MOUSE_BUTTON3DOWN; |
3504 |
right_x = sc->syninfo.softbutton3_x; |
3505 |
|
3506 |
if (center_x > 0 && right_x > 0 && center_x > right_x) { |
3507 |
center_button = MOUSE_BUTTON3DOWN; |
3508 |
center_x = sc->syninfo.softbutton3_x; |
3509 |
right_button = MOUSE_BUTTON2DOWN; |
3510 |
right_x = sc->syninfo.softbutton2_x; |
3511 |
} |
3512 |
|
3513 |
if (right_x > 0 && f.x > right_x && y_ok) |
3514 |
button = right_button; |
3515 |
else if (center_x > 0 && f.x > center_x && y_ok) |
3516 |
button = center_button; |
3517 |
else |
3518 |
button = MOUSE_BUTTON1DOWN; |
3519 |
VLOG(2, (LOG_DEBUG, "softbutton: PRESS: %d\n", button)); |
3520 |
} |
3521 |
|
3522 |
/* Clickpad releases */ |
3523 |
if (!pressed && button) { |
3524 |
VLOG(2, (LOG_DEBUG, "softbutton: RELEASE: %d\n", button)); |
3525 |
button = 0; |
3526 |
} |
3527 |
|
3528 |
return (button); |
3529 |
} |
3530 |
|
3531 |
static int |
3532 |
proc_elantech(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms, |
3533 |
int *x, int *y, int *z) |
3534 |
{ |
3535 |
static int touchpad_button, trackpoint_button; |
3536 |
static int v4nfingers = 0; |
3537 |
finger_t fn, f[PSM_GESTURE_FINGERS]; |
3538 |
int pkt, id, scale, i, nfingers, reset_queue; |
3539 |
|
3540 |
if (!elantech_support) |
3541 |
return (0); |
3542 |
|
3543 |
/* Determine packet format and do a sanity check for out of sync packets. */ |
3544 |
if (ELANTECH_PKT_IS_DEBOUNCE(pb, sc->elanhw.hwversion)) |
3545 |
pkt = ELANTECH_PKT_NOP; |
3546 |
else if (ELANTECH_PKT_IS_TRACKPOINT(pb)) |
3547 |
pkt = ELANTECH_PKT_TRACKPOINT; |
3548 |
else |
3549 |
switch (sc->elanhw.hwversion) { |
3550 |
case 2: |
3551 |
if (!ELANTECH_PKT_IS_V2(pb)) |
3552 |
return (-1); |
3553 |
|
3554 |
pkt = (pb->ipacket[0] & 0xc0) == 0x80 ? |
3555 |
ELANTECH_PKT_V2_2FINGER : ELANTECH_PKT_V2_COMMON; |
3556 |
break; |
3557 |
case 3: |
3558 |
if (!ELANTECH_PKT_IS_V3_HEAD(pb, sc->elanhw.hascrc) && |
3559 |
!ELANTECH_PKT_IS_V3_TAIL(pb, sc->elanhw.hascrc)) |
3560 |
return (-1); |
3561 |
|
3562 |
pkt = ELANTECH_PKT_V3; |
3563 |
break; |
3564 |
case 4: |
3565 |
if (!ELANTECH_PKT_IS_V4(pb, sc->elanhw.hascrc)) |
3566 |
return (-1); |
3567 |
|
3568 |
switch (pb->ipacket[3] & 0x03) { |
3569 |
case 0x00: |
3570 |
pkt = ELANTECH_PKT_V4_STATUS; |
3571 |
break; |
3572 |
case 0x01: |
3573 |
pkt = ELANTECH_PKT_V4_HEAD; |
3574 |
break; |
3575 |
case 0x02: |
3576 |
pkt = ELANTECH_PKT_V4_MOTION; |
3577 |
break; |
3578 |
default: |
3579 |
return (-1); |
3580 |
} |
3581 |
break; |
3582 |
default: |
3583 |
return (-1); |
3584 |
} |
3585 |
|
3586 |
VLOG(5, (LOG_DEBUG, "elantech: ipacket format: %d\n", pkt)); |
3587 |
|
3588 |
for (id = 0; id < PSM_GESTURE_FINGERS; id++) |
3589 |
PSM_FINGER_RESET(f[id]); |
3590 |
|
3591 |
*x = *y = *z = 0; |
3592 |
ms->button = ms->obutton; |
3593 |
|
3594 |
if (sc->syninfo.touchpad_off) |
3595 |
return (0); |
3596 |
|
3597 |
/* Common legend |
3598 |
* L: Left mouse button pressed |
3599 |
* R: Right mouse button pressed |
3600 |
* N: number of fingers on touchpad |
3601 |
* X: absolute x value (horizontal) |
3602 |
* Y: absolute y value (vertical) |
3603 |
* W; width of the finger touch |
3604 |
* P: pressure |
3605 |
*/ |
3606 |
switch (pkt) { |
3607 |
case ELANTECH_PKT_V2_COMMON: /* HW V2. One/Three finger touch */ |
3608 |
/* 7 6 5 4 3 2 1 0 (LSB) |
3609 |
* ------------------------------------------- |
3610 |
* ipacket[0]: N1 N0 W3 W2 . . R L |
3611 |
* ipacket[1]: P7 P6 P5 P4 X11 X10 X9 X8 |
3612 |
* ipacket[2]: X7 X6 X5 X4 X3 X2 X1 X0 |
3613 |
* ipacket[3]: N4 VF W1 W0 . . . B2 |
3614 |
* ipacket[4]: P3 P1 P2 P0 Y11 Y10 Y9 Y8 |
3615 |
* ipacket[5]: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 |
3616 |
* ------------------------------------------- |
3617 |
* N4: set if more than 3 fingers (only in 3 fingers mode) |
3618 |
* VF: a kind of flag? (only on EF123, 0 when finger |
3619 |
* is over one of the buttons, 1 otherwise) |
3620 |
* B2: (on EF113 only, 0 otherwise), one button pressed |
3621 |
* P & W is not reported on EF113 touchpads |
3622 |
*/ |
3623 |
nfingers = (pb->ipacket[0] & 0xc0) >> 6; |
3624 |
|
3625 |
fn = ELANTECH_FINGER_SET_XYP(pb); |
3626 |
if (sc->elanhw.haspressure) { |
3627 |
fn.w = ((pb->ipacket[0] & 0x30) >> 2) | |
3628 |
((pb->ipacket[3] & 0x30) >> 4); |
3629 |
} else { |
3630 |
fn.p = ELANTECH_FINGER_DEFAULT_P; |
3631 |
fn.w = ELANTECH_FINGER_DEFAULT_W; |
3632 |
} |
3633 |
|
3634 |
/* |
3635 |
* HW v2 dont report exact finger positions when 3 or more |
3636 |
* fingers are on touchpad. Use reported value as fingers |
3637 |
* position as it is required for tap detection |
3638 |
*/ |
3639 |
if (nfingers > 2) { |
3640 |
fn.flags = PSM_FINGER_FUZZY; |
3641 |
f[0] = f[1] = fn; |
3642 |
} |
3643 |
|
3644 |
id = nfingers - 1; |
3645 |
if (id >= 0 && id < PSM_GESTURE_FINGERS) |
3646 |
f[id] = fn; |
3647 |
break; |
3648 |
|
3649 |
case ELANTECH_PKT_V2_2FINGER: /*HW V2. Two finger touch */ |
3650 |
/* 7 6 5 4 3 2 1 0 (LSB) |
3651 |
* ------------------------------------------- |
3652 |
* ipacket[0]: N1 N0 AY8 AX8 . . R L |
3653 |
* ipacket[1]: AX7 AX6 AX5 AX4 AX3 AX2 AX1 AX0 |
3654 |
* ipacket[2]: AY7 AY6 AY5 AY4 AY3 AY2 AY1 AY0 |
3655 |
* ipacket[3]: . . BY8 BX8 . . . . |
3656 |
* ipacket[4]: BX7 BX6 BX5 BX4 BX3 BX2 BX1 BX0 |
3657 |
* ipacket[5]: BY7 BY6 BY5 BY4 BY3 BY2 BY1 BY0 |
3658 |
* ------------------------------------------- |
3659 |
* AX: lower-left finger absolute x value |
3660 |
* AY: lower-left finger absolute y value |
3661 |
* BX: upper-right finger absolute x value |
3662 |
* BY: upper-right finger absolute y value |
3663 |
*/ |
3664 |
nfingers = 2; |
3665 |
|
3666 |
VLOG(5, (LOG_DEBUG, "elantech: v2 BBX: [%d, %d] [%d, %d]\n", |
3667 |
((pb->ipacket[0] & 0x10) << 4) | pb->ipacket[1], |
3668 |
((pb->ipacket[0] & 0x20) << 3) | pb->ipacket[2], |
3669 |
((pb->ipacket[3] & 0x10) << 4) | pb->ipacket[4], |
3670 |
((pb->ipacket[3] & 0x20) << 3) | pb->ipacket[5] |
3671 |
)); |
3672 |
for (id = 0; id < imin(2, PSM_GESTURE_FINGERS); id ++) |
3673 |
f[id] = (finger_t) { |
3674 |
.x = (((pb->ipacket[id * 3] & 0x10) << 4) | |
3675 |
pb->ipacket[id * 3 + 1]) << 2, |
3676 |
.y = (((pb->ipacket[id * 3] & 0x20) << 3) | |
3677 |
pb->ipacket[id * 3 + 2]) << 2, |
3678 |
.p = ELANTECH_FINGER_DEFAULT_P, |
3679 |
.w = ELANTECH_FINGER_DEFAULT_W, |
3680 |
/* HW ver.2 sends bounding box */ |
3681 |
.flags = PSM_FINGER_FUZZY |
3682 |
}; |
3683 |
break; |
3684 |
|
3685 |
case ELANTECH_PKT_V3: /* HW Version 3 */ |
3686 |
/* 7 6 5 4 3 2 1 0 (LSB) |
3687 |
* ------------------------------------------- |
3688 |
* ipacket[0]: N1 N0 W3 W2 0 1 R L |
3689 |
* ipacket[1]: P7 P6 P5 P4 X11 X10 X9 X8 |
3690 |
* ipacket[2]: X7 X6 X5 X4 X3 X2 X1 X0 |
3691 |
* ipacket[3]: 0 0 W1 W0 0 0 1 0 |
3692 |
* ipacket[4]: P3 P1 P2 P0 Y11 Y10 Y9 Y8 |
3693 |
* ipacket[5]: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 |
3694 |
* ------------------------------------------- |
3695 |
*/ |
3696 |
nfingers = (pb->ipacket[0] & 0xc0) >> 6; |
3697 |
id = nfingers - 1; |
3698 |
|
3699 |
fn = ELANTECH_FINGER_SET_XYP(pb); |
3700 |
fn.w = ((pb->ipacket[0] & 0x30) >> 2) | |
3701 |
((pb->ipacket[3] & 0x30) >> 4); |
3702 |
|
3703 |
/* |
3704 |
* HW v3 dont report exact finger positions when 3 or more |
3705 |
* fingers are on touchpad. Use reported value as fingers |
3706 |
* position as it is required for tap detection |
3707 |
*/ |
3708 |
if (nfingers > 2) { |
3709 |
fn.flags = PSM_FINGER_FUZZY; |
3710 |
f[0] = f[1] = fn; |
3711 |
} |
3712 |
|
3713 |
if (nfingers == 2 && |
3714 |
ELANTECH_PKT_IS_V3_HEAD(pb, sc->elanhw.hascrc)) |
3715 |
id = 0; |
3716 |
|
3717 |
if (id >= 0 && id < PSM_GESTURE_FINGERS) { |
3718 |
f[id] = fn; |
3719 |
} |
3720 |
break; |
3721 |
|
3722 |
case ELANTECH_PKT_V4_STATUS: /* HW Version 4. Status packet */ |
3723 |
/* 7 6 5 4 3 2 1 0 (LSB) |
3724 |
* ------------------------------------------- |
3725 |
* ipacket[0]: . . . . 0 1 R L |
3726 |
* ipacket[1]: . . . F4 F3 F2 F1 F0 |
3727 |
* ipacket[2]: . . . . . . . . |
3728 |
* ipacket[3]: . . . 1 0 0 0 0 |
3729 |
* ipacket[4]: PL . . . . . . . |
3730 |
* ipacket[5]: . . . . . . . . |
3731 |
* ------------------------------------------- |
3732 |
* Fn: finger n is on touchpad |
3733 |
* PL: palm |
3734 |
* HV ver4 sends a status packet to indicate that the numbers |
3735 |
* or identities of the fingers has been changed |
3736 |
*/ |
3737 |
|
3738 |
v4nfingers = fls(pb->ipacket[1] & 0x1f); |
3739 |
|
3740 |
if (v4nfingers > sc->elanaction.nfingers) |
3741 |
return (0); |
3742 |
|
3743 |
nfingers = v4nfingers; |
3744 |
|
3745 |
break; |
3746 |
|
3747 |
case ELANTECH_PKT_V4_HEAD: /* HW Version 4. Head packet */ |
3748 |
/* 7 6 5 4 3 2 1 0 (LSB) |
3749 |
* ------------------------------------------- |
3750 |
* ipacket[0]: W3 W2 W1 W0 0 1 R L |
3751 |
* ipacket[1]: P7 P6 P5 P4 X11 X10 X9 X8 |
3752 |
* ipacket[2]: X7 X6 X5 X4 X3 X2 X1 X0 |
3753 |
* ipacket[3]: ID2 ID1 ID0 1 0 0 0 1 |
3754 |
* ipacket[4]: P3 P1 P2 P0 Y11 Y10 Y9 Y8 |
3755 |
* ipacket[5]: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 |
3756 |
* ------------------------------------------- |
3757 |
* ID: finger id |
3758 |
* HW ver 4 sends head packets in two cases: |
3759 |
* 1. One finger touch and movement. |
3760 |
* 2. Next after status packet to tell new finger positions. |
3761 |
*/ |
3762 |
nfingers = v4nfingers; |
3763 |
id = ((pb->ipacket[3] & 0xe0) >> 5) - 1; |
3764 |
|
3765 |
if (id >= 0 && id < PSM_GESTURE_FINGERS) { |
3766 |
f[id] = ELANTECH_FINGER_SET_XYP(pb); |
3767 |
f[id].w = (pb->ipacket[0] & 0xf0) >> 4; |
3768 |
} |
3769 |
break; |
3770 |
|
3771 |
case ELANTECH_PKT_V4_MOTION: /* HW Version 4. Motion packet */ |
3772 |
/* 7 6 5 4 3 2 1 0 (LSB) |
3773 |
* ------------------------------------------- |
3774 |
* ipacket[0]: ID2 ID1 ID0 OF 0 1 R L |
3775 |
* ipacket[1]: DX7 DX6 DX5 DX4 DX3 DX2 DX1 DX0 |
3776 |
* ipacket[2]: DY7 DY6 DY5 DY4 DY3 DY2 DY1 DY0 |
3777 |
* ipacket[3]: ID2 ID1 ID0 1 0 0 1 0 |
3778 |
* ipacket[4]: DX7 DX6 DX5 DX4 DX3 DX2 DX1 DX0 |
3779 |
* ipacket[5]: DY7 DY6 DY5 DY4 DY3 DY2 DY1 DY0 |
3780 |
* ------------------------------------------- |
3781 |
* OF: delta overflows (> 127 or < -128), in this case |
3782 |
* firmware sends us (delta x / 5) and (delta y / 5) |
3783 |
* ID: finger id |
3784 |
* DX: delta x (two's complement) |
3785 |
* XY: delta y (two's complement) |
3786 |
* byte 0 ~ 2 for one finger |
3787 |
* byte 3 ~ 5 for another finger |
3788 |
*/ |
3789 |
nfingers = v4nfingers; |
3790 |
|
3791 |
scale = (pb->ipacket[0] & 0x10) ? 5 : 1; |
3792 |
for (i = 0; i <= 3; i += 3) { |
3793 |
id = ((pb->ipacket[i] & 0xe0) >> 5) - 1; |
3794 |
if (id < 0 || id >= PSM_GESTURE_FINGERS) |
3795 |
continue; |
3796 |
|
3797 |
if (PSM_FINGER_IS_SET(sc->elanaction.fingers[id])) { |
3798 |
f[id] = sc->elanaction.fingers[id]; |
3799 |
f[id].x += imax(-f[id].x, |
3800 |
(signed char)pb->ipacket[i+1] * scale); |
3801 |
f[id].y += imax(-f[id].y, |
3802 |
(signed char)pb->ipacket[i+2] * scale); |
3803 |
} else { |
3804 |
VLOG(3, (LOG_DEBUG, "elantech: " |
3805 |
"HW v4 motion packet skipped\n")); |
3806 |
} |
3807 |
} |
3808 |
|
3809 |
break; |
3810 |
|
3811 |
case ELANTECH_PKT_TRACKPOINT: |
3812 |
/* 7 6 5 4 3 2 1 0 (LSB) |
3813 |
* ------------------------------------------- |
3814 |
* ipacket[0]: 0 0 SX SY 0 M R L |
3815 |
* ipacket[1]: ~SX 0 0 0 0 0 0 0 |
3816 |
* ipacket[2]: ~SY 0 0 0 0 0 0 0 |
3817 |
* ipacket[3]: 0 0 ~SY ~SX 0 1 1 0 |
3818 |
* ipacket[4]: X7 X6 X5 X4 X3 X2 X1 X0 |
3819 |
* ipacket[5]: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 |
3820 |
* ------------------------------------------- |
3821 |
* X and Y are written in two's complement spread |
3822 |
* over 9 bits with SX/SY the relative top bit and |
3823 |
* X7..X0 and Y7..Y0 the lower bits. |
3824 |
*/ |
3825 |
*x = (pb->ipacket[0] & 0x20) ? |
3826 |
pb->ipacket[4] - 256 : pb->ipacket[4]; |
3827 |
*y = (pb->ipacket[0] & 0x10) ? |
3828 |
pb->ipacket[5] - 256 : pb->ipacket[5]; |
3829 |
|
3830 |
trackpoint_button = |
3831 |
((pb->ipacket[0] & 0x01) ? MOUSE_BUTTON1DOWN : 0) | |
3832 |
((pb->ipacket[0] & 0x02) ? MOUSE_BUTTON3DOWN : 0) | |
3833 |
((pb->ipacket[0] & 0x04) ? MOUSE_BUTTON2DOWN : 0); |
3834 |
|
3835 |
ms->button = touchpad_button | trackpoint_button; |
3836 |
return (0); |
3837 |
|
3838 |
case ELANTECH_PKT_NOP: |
3839 |
return (0); |
3840 |
|
3841 |
default: |
3842 |
return (-1); |
3843 |
} |
3844 |
|
3845 |
for (id = 0; id < PSM_GESTURE_FINGERS; id++) |
3846 |
if (PSM_FINGER_IS_SET(f[id])) |
3847 |
VLOG(2, (LOG_DEBUG, "elantech: " |
3848 |
"finger %d: down [%d, %d], %d, %d, %d\n", id + 1, |
3849 |
f[id].x, f[id].y, f[id].p, f[id].w, f[id].flags)); |
3850 |
|
3851 |
/* Touchpad button presses */ |
3852 |
if (sc->elanhw.isclickpad) { |
3853 |
touchpad_button = |
3854 |
psmsoftbuttons(sc, f[0], pb->ipacket[0] & 0x03); |
3855 |
} else { |
3856 |
touchpad_button = |
3857 |
((pb->ipacket[0] & 0x01) ? MOUSE_BUTTON1DOWN : 0) | |
3858 |
((pb->ipacket[0] & 0x02) ? MOUSE_BUTTON3DOWN : 0); |
3859 |
} |
3860 |
|
3861 |
ms->button = touchpad_button | trackpoint_button; |
3862 |
|
3292 |
/* |
3863 |
/* |
3293 |
* Use the extra buttons as a scrollwheel |
3864 |
* Send finger positions to movement smoother. |
3294 |
* |
3865 |
* Try to avoid nonreenterable code paths of movement smoother |
3295 |
* XXX X.Org uses the Z axis for vertical wheel only, |
3866 |
* like initialization and tap processing for 2nd finger. |
3296 |
* whereas moused(8) understands special values to differ |
|
|
3297 |
* vertical and horizontal wheels. |
3298 |
* |
3299 |
* xf86-input-mouse needs therefore a small patch to |
3300 |
* understand these special values. Without it, the |
3301 |
* horizontal wheel acts as a vertical wheel in X.Org. |
3302 |
* |
3303 |
* That's why the horizontal wheel is disabled by |
3304 |
* default for now. |
3305 |
*/ |
3867 |
*/ |
|
|
3868 |
for (id = 0; id < PSM_GESTURE_FINGERS; id++) { |
3306 |
|
3869 |
|
3307 |
if (ms->button & MOUSE_BUTTON4DOWN) { |
3870 |
if (!(PSM_FINGER_IS_SET(f[id]) || (id == 0 && nfingers == 0))) |
|
|
3871 |
continue; |
3872 |
if (id == 1 && sc->syninfo.two_finger_scroll == 0) |
3873 |
continue; |
3874 |
|
3875 |
reset_queue = 0; |
3876 |
|
3877 |
/* Avoid cursor jumping on switching real<->fuzzy position */ |
3878 |
if (PSM_FINGER_IS_SET(f[id]) && |
3879 |
((f[id].flags & PSM_FINGER_FUZZY) != |
3880 |
(sc->elanaction.fingers[id].flags & PSM_FINGER_FUZZY))) |
3881 |
reset_queue = 1; |
3882 |
|
3883 |
/* Reset 2-nd finger synaction queue on action start */ |
3884 |
if (id > 0 && !PSM_FINGER_IS_SET(sc->elanaction.fingers[id])) { |
3885 |
reset_queue = 1; |
3886 |
} |
3887 |
|
3888 |
if (reset_queue) { |
3889 |
VLOG(3, (LOG_DEBUG, "elantech: " |
3890 |
"finger %d: reset synaptics queue\n", id + 1)); |
3891 |
sc->synaction[id].queue_cursor = 0; |
3892 |
sc->synaction[id].queue_len = 0; |
3893 |
sc->synaction[id].queue[0].x = f[id].x; |
3894 |
sc->synaction[id].queue[0].y = f[id].y; |
3895 |
sc->synaction[id].start_x = f[id].x; |
3896 |
sc->synaction[id].start_y = f[id].y; |
3897 |
sc->synaction[id].window_min = sc->syninfo.window_min; |
3898 |
sc->synaction[id].squelch_x = 0; |
3899 |
sc->synaction[id].squelch_y = 0; |
3900 |
sc->synaction[id].avg_dx = 0; |
3901 |
sc->synaction[id].avg_dy = 0; |
3902 |
sc->synaction[id].fingers_nb = 0; |
3903 |
sc->synaction[id].in_vscroll = 0; |
3904 |
} |
3905 |
|
3906 |
/* prevent palm detection for fuzzy finger touches */ |
3907 |
if (f[id].flags & PSM_FINGER_FUZZY) { |
3908 |
f[id].p = ELANTECH_FINGER_DEFAULT_P; |
3909 |
f[id].w = ELANTECH_FINGER_DEFAULT_W; |
3910 |
} |
3911 |
|
3912 |
psmgestures(sc, &sc->synaction[id], f[id], imin(nfingers, 3), |
3913 |
ms, x, y); |
3914 |
} |
3915 |
|
3916 |
/* Store current finger positions in action context */ |
3917 |
sc->elanaction.nfingers = nfingers; |
3918 |
for (id = 0; id < PSM_GESTURE_FINGERS; id++) { |
3919 |
if (PSM_FINGER_IS_SET(f[id])) |
3920 |
sc->elanaction.fingers[id] = f[id]; |
3921 |
if (id >= nfingers) |
3922 |
PSM_FINGER_RESET(sc->elanaction.fingers[id]); |
3923 |
} |
3924 |
|
3925 |
/* Use the extra buttons as a scrollwheel */ |
3926 |
if (ms->button & MOUSE_BUTTON4DOWN) |
3308 |
*z = -1; |
3927 |
*z = -1; |
3309 |
ms->button &= ~MOUSE_BUTTON4DOWN; |
3928 |
else if (ms->button & MOUSE_BUTTON5DOWN) |
3310 |
} else if (ms->button & MOUSE_BUTTON5DOWN) { |
|
|
3311 |
*z = 1; |
3929 |
*z = 1; |
3312 |
ms->button &= ~MOUSE_BUTTON5DOWN; |
3930 |
else if (ms->button & MOUSE_BUTTON6DOWN) |
3313 |
} else if (ms->button & MOUSE_BUTTON6DOWN) { |
|
|
3314 |
*z = -2; |
3931 |
*z = -2; |
3315 |
ms->button &= ~MOUSE_BUTTON6DOWN; |
3932 |
else if (ms->button & MOUSE_BUTTON7DOWN) |
3316 |
} else if (ms->button & MOUSE_BUTTON7DOWN) { |
|
|
3317 |
*z = 2; |
3933 |
*z = 2; |
3318 |
ms->button &= ~MOUSE_BUTTON7DOWN; |
3934 |
else |
3319 |
} else |
|
|
3320 |
*z = 0; |
3935 |
*z = 0; |
|
|
3936 |
ms->button &= ~(MOUSE_BUTTON4DOWN | MOUSE_BUTTON5DOWN | |
3937 |
MOUSE_BUTTON6DOWN | MOUSE_BUTTON7DOWN); |
3321 |
|
3938 |
|
3322 |
return (0); |
3939 |
return (0); |
3323 |
} |
3940 |
} |
Lines 3390-3395
Link Here
|
3390 |
} |
4007 |
} |
3391 |
|
4008 |
|
3392 |
static void |
4009 |
static void |
|
|
4010 |
psmsoftintridle(void *arg) |
4011 |
{ |
4012 |
struct psm_softc *sc = arg; |
4013 |
packetbuf_t *pb; |
4014 |
|
4015 |
/* Invoke soft handler only when pqueue is empty. Otherwise it will be |
4016 |
* invoked from psmintr soon with pqueue filled with real data */ |
4017 |
if (sc->pqueue_start == sc->pqueue_end && |
4018 |
sc->idlepacket.inputbytes > 0) { |
4019 |
/* Grow circular queue backwards to avoid race with psmintr */ |
4020 |
if (--sc->pqueue_start < 0) |
4021 |
sc->pqueue_start = PSM_PACKETQUEUE - 1; |
4022 |
|
4023 |
pb = &sc->pqueue[sc->pqueue_start]; |
4024 |
memcpy(pb, &sc->idlepacket, sizeof(packetbuf_t)); |
4025 |
VLOG(4, (LOG_DEBUG, |
4026 |
"psmsoftintridle: %02x %02x %02x %02x %02x %02x\n", |
4027 |
pb->ipacket[0], pb->ipacket[1], pb->ipacket[2], |
4028 |
pb->ipacket[3], pb->ipacket[4], pb->ipacket[5])); |
4029 |
|
4030 |
psmsoftintr(arg); |
4031 |
} |
4032 |
} |
4033 |
|
4034 |
static void |
3393 |
psmsoftintr(void *arg) |
4035 |
psmsoftintr(void *arg) |
3394 |
{ |
4036 |
{ |
3395 |
/* |
4037 |
/* |
Lines 3442-3447
Link Here
|
3442 |
if (sc->config & PSM_CONFIG_FORCETAP) |
4084 |
if (sc->config & PSM_CONFIG_FORCETAP) |
3443 |
ms.button |= ((c & MOUSE_PS2_TAP)) ? |
4085 |
ms.button |= ((c & MOUSE_PS2_TAP)) ? |
3444 |
0 : MOUSE_BUTTON4DOWN; |
4086 |
0 : MOUSE_BUTTON4DOWN; |
|
|
4087 |
timevalclear(&sc->idletimeout); |
4088 |
sc->idlepacket.inputbytes = 0; |
3445 |
|
4089 |
|
3446 |
switch (sc->hw.model) { |
4090 |
switch (sc->hw.model) { |
3447 |
|
4091 |
|
Lines 3580-3585
Link Here
|
3580 |
goto next; |
4224 |
goto next; |
3581 |
break; |
4225 |
break; |
3582 |
|
4226 |
|
|
|
4227 |
case MOUSE_MODEL_ELANTECH: |
4228 |
if (proc_elantech(sc, pb, &ms, &x, &y, &z) != 0) |
4229 |
goto next; |
4230 |
break; |
4231 |
|
3583 |
case MOUSE_MODEL_TRACKPOINT: |
4232 |
case MOUSE_MODEL_TRACKPOINT: |
3584 |
case MOUSE_MODEL_GENERIC: |
4233 |
case MOUSE_MODEL_GENERIC: |
3585 |
default: |
4234 |
default: |
Lines 3604-3609
Link Here
|
3604 |
} |
4253 |
} |
3605 |
} |
4254 |
} |
3606 |
|
4255 |
|
|
|
4256 |
/* Store last packet for reinjection if it has not been set already */ |
4257 |
if (timevalisset(&sc->idletimeout) && sc->idlepacket.inputbytes == 0) |
4258 |
sc->idlepacket = *pb; |
4259 |
|
3607 |
ms.dx = x; |
4260 |
ms.dx = x; |
3608 |
ms.dy = y; |
4261 |
ms.dy = y; |
3609 |
ms.dz = z; |
4262 |
ms.dz = z; |
Lines 3650-3655
Link Here
|
3650 |
pgsigio(&sc->async, SIGIO, 0); |
4303 |
pgsigio(&sc->async, SIGIO, 0); |
3651 |
} |
4304 |
} |
3652 |
sc->state &= ~PSM_SOFTARMED; |
4305 |
sc->state &= ~PSM_SOFTARMED; |
|
|
4306 |
|
4307 |
/* schedule injection of predefined packet after idletimeout |
4308 |
* if no data packets have been received from psmintr */ |
4309 |
if (timevalisset(&sc->idletimeout)) { |
4310 |
sc->state |= PSM_SOFTARMED; |
4311 |
callout_reset(&sc->softcallout, tvtohz(&sc->idletimeout), |
4312 |
psmsoftintridle, sc); |
4313 |
VLOG(2, (LOG_DEBUG, "softintr: callout set: %d ticks\n", |
4314 |
tvtohz(&sc->idletimeout))); |
4315 |
} |
3653 |
splx(s); |
4316 |
splx(s); |
3654 |
} |
4317 |
} |
3655 |
|
4318 |
|
Lines 3710-3717
Link Here
|
3710 |
#ifdef notyet |
4373 |
#ifdef notyet |
3711 |
/* Logitech MouseMan Cordless II */ |
4374 |
/* Logitech MouseMan Cordless II */ |
3712 |
static int |
4375 |
static int |
3713 |
enable_lcordless(KDBC kbdc, struct psm_softc *sc) |
4376 |
enable_lcordless(struct psm_softc *sc, enum probearg arg) |
3714 |
{ |
4377 |
{ |
|
|
4378 |
KBDC kbdc = sc->kbdc; |
3715 |
int status[3]; |
4379 |
int status[3]; |
3716 |
int ch; |
4380 |
int ch; |
3717 |
|
4381 |
|
Lines 3732-3739
Link Here
|
3732 |
|
4396 |
|
3733 |
/* Genius NetScroll Mouse, MouseSystems SmartScroll Mouse */ |
4397 |
/* Genius NetScroll Mouse, MouseSystems SmartScroll Mouse */ |
3734 |
static int |
4398 |
static int |
3735 |
enable_groller(KBDC kbdc, struct psm_softc *sc) |
4399 |
enable_groller(struct psm_softc *sc, enum probearg arg) |
3736 |
{ |
4400 |
{ |
|
|
4401 |
KBDC kbdc = sc->kbdc; |
3737 |
int status[3]; |
4402 |
int status[3]; |
3738 |
|
4403 |
|
3739 |
/* |
4404 |
/* |
Lines 3762-3768
Link Here
|
3762 |
if ((status[1] != '3') || (status[2] != 'D')) |
4427 |
if ((status[1] != '3') || (status[2] != 'D')) |
3763 |
return (FALSE); |
4428 |
return (FALSE); |
3764 |
/* FIXME: SmartScroll Mouse has 5 buttons! XXX */ |
4429 |
/* FIXME: SmartScroll Mouse has 5 buttons! XXX */ |
3765 |
if (sc != NULL) |
4430 |
if (arg == PROBE) |
3766 |
sc->hw.buttons = 4; |
4431 |
sc->hw.buttons = 4; |
3767 |
return (TRUE); |
4432 |
return (TRUE); |
3768 |
} |
4433 |
} |
Lines 3769-3776
Link Here
|
3769 |
|
4434 |
|
3770 |
/* Genius NetMouse/NetMouse Pro, ASCII Mie Mouse, NetScroll Optical */ |
4435 |
/* Genius NetMouse/NetMouse Pro, ASCII Mie Mouse, NetScroll Optical */ |
3771 |
static int |
4436 |
static int |
3772 |
enable_gmouse(KBDC kbdc, struct psm_softc *sc) |
4437 |
enable_gmouse(struct psm_softc *sc, enum probearg arg) |
3773 |
{ |
4438 |
{ |
|
|
4439 |
KBDC kbdc = sc->kbdc; |
3774 |
int status[3]; |
4440 |
int status[3]; |
3775 |
|
4441 |
|
3776 |
/* |
4442 |
/* |
Lines 3792-3799
Link Here
|
3792 |
|
4458 |
|
3793 |
/* ALPS GlidePoint */ |
4459 |
/* ALPS GlidePoint */ |
3794 |
static int |
4460 |
static int |
3795 |
enable_aglide(KBDC kbdc, struct psm_softc *sc) |
4461 |
enable_aglide(struct psm_softc *sc, enum probearg arg) |
3796 |
{ |
4462 |
{ |
|
|
4463 |
KBDC kbdc = sc->kbdc; |
3797 |
int status[3]; |
4464 |
int status[3]; |
3798 |
|
4465 |
|
3799 |
/* |
4466 |
/* |
Lines 3814-3822
Link Here
|
3814 |
|
4481 |
|
3815 |
/* Kensington ThinkingMouse/Trackball */ |
4482 |
/* Kensington ThinkingMouse/Trackball */ |
3816 |
static int |
4483 |
static int |
3817 |
enable_kmouse(KBDC kbdc, struct psm_softc *sc) |
4484 |
enable_kmouse(struct psm_softc *sc, enum probearg arg) |
3818 |
{ |
4485 |
{ |
3819 |
static u_char rate[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 }; |
4486 |
static u_char rate[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 }; |
|
|
4487 |
KBDC kbdc = sc->kbdc; |
3820 |
int status[3]; |
4488 |
int status[3]; |
3821 |
int id1; |
4489 |
int id1; |
3822 |
int id2; |
4490 |
int id2; |
Lines 3867-3874
Link Here
|
3867 |
|
4535 |
|
3868 |
/* Logitech MouseMan+/FirstMouse+, IBM ScrollPoint Mouse */ |
4536 |
/* Logitech MouseMan+/FirstMouse+, IBM ScrollPoint Mouse */ |
3869 |
static int |
4537 |
static int |
3870 |
enable_mmanplus(KBDC kbdc, struct psm_softc *sc) |
4538 |
enable_mmanplus(struct psm_softc *sc, enum probearg arg) |
3871 |
{ |
4539 |
{ |
|
|
4540 |
KBDC kbdc = sc->kbdc; |
3872 |
int data[3]; |
4541 |
int data[3]; |
3873 |
|
4542 |
|
3874 |
/* the special sequence to enable the fourth button and the roller. */ |
4543 |
/* the special sequence to enable the fourth button and the roller. */ |
Lines 3909-3915
Link Here
|
3909 |
if (MOUSE_PS2PLUS_PACKET_TYPE(data) != 0) |
4578 |
if (MOUSE_PS2PLUS_PACKET_TYPE(data) != 0) |
3910 |
return (FALSE); |
4579 |
return (FALSE); |
3911 |
|
4580 |
|
3912 |
if (sc != NULL) { |
4581 |
if (arg == PROBE) { |
3913 |
sc->hw.hwid &= 0x00ff; |
4582 |
sc->hw.hwid &= 0x00ff; |
3914 |
sc->hw.hwid |= data[2] << 8; /* save model ID */ |
4583 |
sc->hw.hwid |= data[2] << 8; /* save model ID */ |
3915 |
} |
4584 |
} |
Lines 3925-3932
Link Here
|
3925 |
|
4594 |
|
3926 |
/* MS IntelliMouse Explorer */ |
4595 |
/* MS IntelliMouse Explorer */ |
3927 |
static int |
4596 |
static int |
3928 |
enable_msexplorer(KBDC kbdc, struct psm_softc *sc) |
4597 |
enable_msexplorer(struct psm_softc *sc, enum probearg arg) |
3929 |
{ |
4598 |
{ |
|
|
4599 |
KBDC kbdc = sc->kbdc; |
3930 |
static u_char rate0[] = { 200, 100, 80, }; |
4600 |
static u_char rate0[] = { 200, 100, 80, }; |
3931 |
static u_char rate1[] = { 200, 200, 80, }; |
4601 |
static u_char rate1[] = { 200, 200, 80, }; |
3932 |
int id; |
4602 |
int id; |
Lines 3937-3943
Link Here
|
3937 |
* straight to Explorer mode, but need to be set to Intelli mode |
4607 |
* straight to Explorer mode, but need to be set to Intelli mode |
3938 |
* first. |
4608 |
* first. |
3939 |
*/ |
4609 |
*/ |
3940 |
enable_msintelli(kbdc, sc); |
4610 |
enable_msintelli(sc, arg); |
3941 |
|
4611 |
|
3942 |
/* the special sequence to enable the extra buttons and the roller. */ |
4612 |
/* the special sequence to enable the extra buttons and the roller. */ |
3943 |
for (i = 0; i < sizeof(rate1)/sizeof(rate1[0]); ++i) |
4613 |
for (i = 0; i < sizeof(rate1)/sizeof(rate1[0]); ++i) |
Lines 3948-3954
Link Here
|
3948 |
if (id != PSM_EXPLORER_ID) |
4618 |
if (id != PSM_EXPLORER_ID) |
3949 |
return (FALSE); |
4619 |
return (FALSE); |
3950 |
|
4620 |
|
3951 |
if (sc != NULL) { |
4621 |
if (arg == PROBE) { |
3952 |
sc->hw.buttons = 5; /* IntelliMouse Explorer XXX */ |
4622 |
sc->hw.buttons = 5; /* IntelliMouse Explorer XXX */ |
3953 |
sc->hw.hwid = id; |
4623 |
sc->hw.hwid = id; |
3954 |
} |
4624 |
} |
Lines 3971-3985
Link Here
|
3971 |
return (TRUE); |
4641 |
return (TRUE); |
3972 |
} |
4642 |
} |
3973 |
|
4643 |
|
3974 |
/* MS IntelliMouse */ |
4644 |
/* |
|
|
4645 |
* MS IntelliMouse |
4646 |
* Logitech MouseMan+ and FirstMouse+ will also respond to this |
4647 |
* probe routine and act like IntelliMouse. |
4648 |
*/ |
3975 |
static int |
4649 |
static int |
3976 |
enable_msintelli(KBDC kbdc, struct psm_softc *sc) |
4650 |
enable_msintelli(struct psm_softc *sc, enum probearg arg) |
3977 |
{ |
4651 |
{ |
3978 |
/* |
4652 |
KBDC kbdc = sc->kbdc; |
3979 |
* Logitech MouseMan+ and FirstMouse+ will also respond to this |
|
|
3980 |
* probe routine and act like IntelliMouse. |
3981 |
*/ |
3982 |
|
3983 |
static u_char rate[] = { 200, 100, 80, }; |
4653 |
static u_char rate[] = { 200, 100, 80, }; |
3984 |
int id; |
4654 |
int id; |
3985 |
int i; |
4655 |
int i; |
Lines 3993-3999
Link Here
|
3993 |
if (id != PSM_INTELLI_ID) |
4663 |
if (id != PSM_INTELLI_ID) |
3994 |
return (FALSE); |
4664 |
return (FALSE); |
3995 |
|
4665 |
|
3996 |
if (sc != NULL) { |
4666 |
if (arg == PROBE) { |
3997 |
sc->hw.buttons = 3; |
4667 |
sc->hw.buttons = 3; |
3998 |
sc->hw.hwid = id; |
4668 |
sc->hw.hwid = id; |
3999 |
} |
4669 |
} |
Lines 4001-4015
Link Here
|
4001 |
return (TRUE); |
4671 |
return (TRUE); |
4002 |
} |
4672 |
} |
4003 |
|
4673 |
|
4004 |
/* A4 Tech 4D Mouse */ |
4674 |
/* |
|
|
4675 |
* A4 Tech 4D Mouse |
4676 |
* Newer wheel mice from A4 Tech may use the 4D+ protocol. |
4677 |
*/ |
4005 |
static int |
4678 |
static int |
4006 |
enable_4dmouse(KBDC kbdc, struct psm_softc *sc) |
4679 |
enable_4dmouse(struct psm_softc *sc, enum probearg arg) |
4007 |
{ |
4680 |
{ |
4008 |
/* |
|
|
4009 |
* Newer wheel mice from A4 Tech may use the 4D+ protocol. |
4010 |
*/ |
4011 |
|
4012 |
static u_char rate[] = { 200, 100, 80, 60, 40, 20 }; |
4681 |
static u_char rate[] = { 200, 100, 80, 60, 40, 20 }; |
|
|
4682 |
KBDC kbdc = sc->kbdc; |
4013 |
int id; |
4683 |
int id; |
4014 |
int i; |
4684 |
int i; |
4015 |
|
4685 |
|
Lines 4025-4031
Link Here
|
4025 |
if (id != PSM_4DMOUSE_ID) |
4695 |
if (id != PSM_4DMOUSE_ID) |
4026 |
return (FALSE); |
4696 |
return (FALSE); |
4027 |
|
4697 |
|
4028 |
if (sc != NULL) { |
4698 |
if (arg == PROBE) { |
4029 |
sc->hw.buttons = 3; /* XXX some 4D mice have 4? */ |
4699 |
sc->hw.buttons = 3; /* XXX some 4D mice have 4? */ |
4030 |
sc->hw.hwid = id; |
4700 |
sc->hw.hwid = id; |
4031 |
} |
4701 |
} |
Lines 4033-4046
Link Here
|
4033 |
return (TRUE); |
4703 |
return (TRUE); |
4034 |
} |
4704 |
} |
4035 |
|
4705 |
|
4036 |
/* A4 Tech 4D+ Mouse */ |
4706 |
/* |
|
|
4707 |
* A4 Tech 4D+ Mouse |
4708 |
* Newer wheel mice from A4 Tech seem to use this protocol. |
4709 |
* Older models are recognized as either 4D Mouse or IntelliMouse. |
4710 |
*/ |
4037 |
static int |
4711 |
static int |
4038 |
enable_4dplus(KBDC kbdc, struct psm_softc *sc) |
4712 |
enable_4dplus(struct psm_softc *sc, enum probearg arg) |
4039 |
{ |
4713 |
{ |
4040 |
/* |
4714 |
KBDC kbdc = sc->kbdc; |
4041 |
* Newer wheel mice from A4 Tech seem to use this protocol. |
|
|
4042 |
* Older models are recognized as either 4D Mouse or IntelliMouse. |
4043 |
*/ |
4044 |
int id; |
4715 |
int id; |
4045 |
|
4716 |
|
4046 |
/* |
4717 |
/* |
Lines 4063-4069
Link Here
|
4063 |
return (FALSE); |
4734 |
return (FALSE); |
4064 |
} |
4735 |
} |
4065 |
|
4736 |
|
4066 |
if (sc != NULL) { |
4737 |
if (arg == PROBE) { |
4067 |
sc->hw.buttons = (id == PSM_4DPLUS_ID) ? 4 : 3; |
4738 |
sc->hw.buttons = (id == PSM_4DPLUS_ID) ? 4 : 3; |
4068 |
sc->hw.hwid = id; |
4739 |
sc->hw.hwid = id; |
4069 |
} |
4740 |
} |
Lines 4075-4084
Link Here
|
4075 |
static int |
4746 |
static int |
4076 |
synaptics_sysctl(SYSCTL_HANDLER_ARGS) |
4747 |
synaptics_sysctl(SYSCTL_HANDLER_ARGS) |
4077 |
{ |
4748 |
{ |
|
|
4749 |
struct psm_softc *sc; |
4078 |
int error, arg; |
4750 |
int error, arg; |
4079 |
|
4751 |
|
|
|
4752 |
if (oidp->oid_arg1 == NULL || oidp->oid_arg2 < 0 || |
4753 |
oidp->oid_arg2 > SYNAPTICS_SYSCTL_SOFTBUTTON_NOMOVE) |
4754 |
return (EINVAL); |
4755 |
|
4756 |
sc = oidp->oid_arg1; |
4757 |
|
4080 |
/* Read the current value. */ |
4758 |
/* Read the current value. */ |
4081 |
arg = *(int *)oidp->oid_arg1; |
4759 |
arg = *(int *)((char *)sc + oidp->oid_arg2); |
4082 |
error = sysctl_handle_int(oidp, &arg, 0, req); |
4760 |
error = sysctl_handle_int(oidp, &arg, 0, req); |
4083 |
|
4761 |
|
4084 |
/* Sanity check. */ |
4762 |
/* Sanity check. */ |
Lines 4100-4113
Link Here
|
4100 |
return (EINVAL); |
4778 |
return (EINVAL); |
4101 |
break; |
4779 |
break; |
4102 |
case SYNAPTICS_SYSCTL_MARGIN_TOP: |
4780 |
case SYNAPTICS_SYSCTL_MARGIN_TOP: |
|
|
4781 |
case SYNAPTICS_SYSCTL_MARGIN_BOTTOM: |
4782 |
case SYNAPTICS_SYSCTL_NA_TOP: |
4783 |
case SYNAPTICS_SYSCTL_NA_BOTTOM: |
4784 |
if (arg < 0 || arg > sc->synhw.maximumYCoord) |
4785 |
return (EINVAL); |
4786 |
break; |
4103 |
case SYNAPTICS_SYSCTL_MARGIN_RIGHT: |
4787 |
case SYNAPTICS_SYSCTL_MARGIN_RIGHT: |
4104 |
case SYNAPTICS_SYSCTL_MARGIN_BOTTOM: |
|
|
4105 |
case SYNAPTICS_SYSCTL_MARGIN_LEFT: |
4788 |
case SYNAPTICS_SYSCTL_MARGIN_LEFT: |
4106 |
case SYNAPTICS_SYSCTL_NA_TOP: |
|
|
4107 |
case SYNAPTICS_SYSCTL_NA_RIGHT: |
4789 |
case SYNAPTICS_SYSCTL_NA_RIGHT: |
4108 |
case SYNAPTICS_SYSCTL_NA_BOTTOM: |
|
|
4109 |
case SYNAPTICS_SYSCTL_NA_LEFT: |
4790 |
case SYNAPTICS_SYSCTL_NA_LEFT: |
4110 |
if (arg < 0 || arg > 6143) |
4791 |
case SYNAPTICS_SYSCTL_SOFTBUTTON2_X: |
|
|
4792 |
case SYNAPTICS_SYSCTL_SOFTBUTTON3_X: |
4793 |
if (arg < 0 || arg > sc->synhw.maximumXCoord) |
4111 |
return (EINVAL); |
4794 |
return (EINVAL); |
4112 |
break; |
4795 |
break; |
4113 |
case SYNAPTICS_SYSCTL_WINDOW_MIN: |
4796 |
case SYNAPTICS_SYSCTL_WINDOW_MIN: |
Lines 4137-4162
Link Here
|
4137 |
return (EINVAL); |
4820 |
return (EINVAL); |
4138 |
break; |
4821 |
break; |
4139 |
case SYNAPTICS_SYSCTL_VSCROLL_HOR_AREA: |
4822 |
case SYNAPTICS_SYSCTL_VSCROLL_HOR_AREA: |
|
|
4823 |
if (arg < -sc->synhw.maximumXCoord || |
4824 |
arg > sc->synhw.maximumXCoord) |
4825 |
return (EINVAL); |
4826 |
break; |
4140 |
case SYNAPTICS_SYSCTL_VSCROLL_VER_AREA: |
4827 |
case SYNAPTICS_SYSCTL_VSCROLL_VER_AREA: |
4141 |
if (arg < -6143 || arg > 6143) |
4828 |
case SYNAPTICS_SYSCTL_SOFTBUTTONS_Y: |
|
|
4829 |
if (arg < -sc->synhw.maximumYCoord || |
4830 |
arg > sc->synhw.maximumYCoord) |
4142 |
return (EINVAL); |
4831 |
return (EINVAL); |
4143 |
break; |
4832 |
break; |
4144 |
case SYNAPTICS_SYSCTL_TOUCHPAD_OFF: |
4833 |
case SYNAPTICS_SYSCTL_TOUCHPAD_OFF: |
|
|
4834 |
case SYNAPTICS_SYSCTL_SOFTBUTTON_NOMOVE: |
4145 |
if (arg < 0 || arg > 1) |
4835 |
if (arg < 0 || arg > 1) |
4146 |
return (EINVAL); |
4836 |
return (EINVAL); |
4147 |
break; |
4837 |
break; |
|
|
4838 |
case SYNAPTICS_SYSCTL_SOFTBUTTONS: |
4839 |
/* Softbuttons is clickpad only feature */ |
4840 |
if (!sc->synhw.capClickPad && arg != 0) |
4841 |
return (EINVAL); |
4842 |
/* Set predefined sizes for softbuttons */ |
4843 |
switch (arg) { |
4844 |
case 3: |
4845 |
sc->syninfo.softbutton3_x = |
4846 |
sc->synhw.maximumXCoord * 2 / 3; |
4847 |
sc->syninfo.softbutton2_x = |
4848 |
sc->synhw.maximumXCoord / 3; |
4849 |
sc->syninfo.softbuttons_y = |
4850 |
sc->synhw.maximumYCoord / 4; |
4851 |
break; |
4852 |
case 2: |
4853 |
sc->syninfo.softbutton3_x = |
4854 |
sc->synhw.maximumXCoord / 2; |
4855 |
sc->syninfo.softbutton2_x = 0; |
4856 |
sc->syninfo.softbuttons_y = |
4857 |
sc->synhw.maximumYCoord / 4; |
4858 |
break; |
4859 |
case 1: |
4860 |
case 0: |
4861 |
sc->syninfo.softbutton3_x = 0; |
4862 |
sc->syninfo.softbutton2_x = 0; |
4863 |
sc->syninfo.softbuttons_y = 0; |
4864 |
break; |
4865 |
default: |
4866 |
return (EINVAL); |
4867 |
} |
4868 |
break; |
4148 |
default: |
4869 |
default: |
4149 |
return (EINVAL); |
4870 |
return (EINVAL); |
4150 |
} |
4871 |
} |
4151 |
|
4872 |
|
4152 |
/* Update. */ |
4873 |
/* Update. */ |
4153 |
*(int *)oidp->oid_arg1 = arg; |
4874 |
*(int *)((char *)sc + oidp->oid_arg2) = arg; |
4154 |
|
4875 |
|
4155 |
return (error); |
4876 |
return (error); |
4156 |
} |
4877 |
} |
4157 |
|
4878 |
|
4158 |
static void |
4879 |
static void |
4159 |
synaptics_sysctl_create_tree(struct psm_softc *sc) |
4880 |
synaptics_sysctl_create_tree(struct psm_softc *sc, const char *name, |
|
|
4881 |
const char *descr) |
4160 |
{ |
4882 |
{ |
4161 |
|
4883 |
|
4162 |
if (sc->syninfo.sysctl_tree != NULL) |
4884 |
if (sc->syninfo.sysctl_tree != NULL) |
Lines 4165-4172
Link Here
|
4165 |
/* Attach extra synaptics sysctl nodes under hw.psm.synaptics */ |
4887 |
/* Attach extra synaptics sysctl nodes under hw.psm.synaptics */ |
4166 |
sysctl_ctx_init(&sc->syninfo.sysctl_ctx); |
4888 |
sysctl_ctx_init(&sc->syninfo.sysctl_ctx); |
4167 |
sc->syninfo.sysctl_tree = SYSCTL_ADD_NODE(&sc->syninfo.sysctl_ctx, |
4889 |
sc->syninfo.sysctl_tree = SYSCTL_ADD_NODE(&sc->syninfo.sysctl_ctx, |
4168 |
SYSCTL_STATIC_CHILDREN(_hw_psm), OID_AUTO, "synaptics", CTLFLAG_RD, |
4890 |
SYSCTL_STATIC_CHILDREN(_hw_psm), OID_AUTO, name, CTLFLAG_RD, |
4169 |
0, "Synaptics TouchPad"); |
4891 |
0, descr); |
4170 |
|
4892 |
|
4171 |
/* hw.psm.synaptics.directional_scrolls. */ |
4893 |
/* hw.psm.synaptics.directional_scrolls. */ |
4172 |
sc->syninfo.directional_scrolls = 0; |
4894 |
sc->syninfo.directional_scrolls = 0; |
Lines 4182-4188
Link Here
|
4182 |
* physical area reserved for scrolling or when |
4904 |
* physical area reserved for scrolling or when |
4183 |
* there's no multi finger support. |
4905 |
* there's no multi finger support. |
4184 |
*/ |
4906 |
*/ |
4185 |
if (sc->synhw.verticalScroll || sc->synhw.capMultiFinger == 0) |
4907 |
if (sc->synhw.verticalScroll || (sc->synhw.capMultiFinger == 0 && |
|
|
4908 |
sc->synhw.capAdvancedGestures == 0)) |
4186 |
sc->syninfo.two_finger_scroll = 0; |
4909 |
sc->syninfo.two_finger_scroll = 0; |
4187 |
else |
4910 |
else |
4188 |
sc->syninfo.two_finger_scroll = 1; |
4911 |
sc->syninfo.two_finger_scroll = 1; |
Lines 4198-4204
Link Here
|
4198 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4921 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4199 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4922 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4200 |
"min_pressure", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4923 |
"min_pressure", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4201 |
&sc->syninfo.min_pressure, SYNAPTICS_SYSCTL_MIN_PRESSURE, |
4924 |
sc, SYNAPTICS_SYSCTL_MIN_PRESSURE, |
4202 |
synaptics_sysctl, "I", |
4925 |
synaptics_sysctl, "I", |
4203 |
"Minimum pressure required to start an action"); |
4926 |
"Minimum pressure required to start an action"); |
4204 |
|
4927 |
|
Lines 4207-4213
Link Here
|
4207 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4930 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4208 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4931 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4209 |
"max_pressure", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4932 |
"max_pressure", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4210 |
&sc->syninfo.max_pressure, SYNAPTICS_SYSCTL_MAX_PRESSURE, |
4933 |
sc, SYNAPTICS_SYSCTL_MAX_PRESSURE, |
4211 |
synaptics_sysctl, "I", |
4934 |
synaptics_sysctl, "I", |
4212 |
"Maximum pressure to detect palm"); |
4935 |
"Maximum pressure to detect palm"); |
4213 |
|
4936 |
|
Lines 4216-4222
Link Here
|
4216 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4939 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4217 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4940 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4218 |
"max_width", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4941 |
"max_width", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4219 |
&sc->syninfo.max_width, SYNAPTICS_SYSCTL_MAX_WIDTH, |
4942 |
sc, SYNAPTICS_SYSCTL_MAX_WIDTH, |
4220 |
synaptics_sysctl, "I", |
4943 |
synaptics_sysctl, "I", |
4221 |
"Maximum finger width to detect palm"); |
4944 |
"Maximum finger width to detect palm"); |
4222 |
|
4945 |
|
Lines 4225-4231
Link Here
|
4225 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4948 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4226 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4949 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4227 |
"margin_top", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4950 |
"margin_top", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4228 |
&sc->syninfo.margin_top, SYNAPTICS_SYSCTL_MARGIN_TOP, |
4951 |
sc, SYNAPTICS_SYSCTL_MARGIN_TOP, |
4229 |
synaptics_sysctl, "I", |
4952 |
synaptics_sysctl, "I", |
4230 |
"Top margin"); |
4953 |
"Top margin"); |
4231 |
|
4954 |
|
Lines 4234-4240
Link Here
|
4234 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4957 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4235 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4958 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4236 |
"margin_right", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4959 |
"margin_right", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4237 |
&sc->syninfo.margin_right, SYNAPTICS_SYSCTL_MARGIN_RIGHT, |
4960 |
sc, SYNAPTICS_SYSCTL_MARGIN_RIGHT, |
4238 |
synaptics_sysctl, "I", |
4961 |
synaptics_sysctl, "I", |
4239 |
"Right margin"); |
4962 |
"Right margin"); |
4240 |
|
4963 |
|
Lines 4243-4249
Link Here
|
4243 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4966 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4244 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4967 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4245 |
"margin_bottom", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4968 |
"margin_bottom", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4246 |
&sc->syninfo.margin_bottom, SYNAPTICS_SYSCTL_MARGIN_BOTTOM, |
4969 |
sc, SYNAPTICS_SYSCTL_MARGIN_BOTTOM, |
4247 |
synaptics_sysctl, "I", |
4970 |
synaptics_sysctl, "I", |
4248 |
"Bottom margin"); |
4971 |
"Bottom margin"); |
4249 |
|
4972 |
|
Lines 4252-4258
Link Here
|
4252 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4975 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4253 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4976 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4254 |
"margin_left", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4977 |
"margin_left", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4255 |
&sc->syninfo.margin_left, SYNAPTICS_SYSCTL_MARGIN_LEFT, |
4978 |
sc, SYNAPTICS_SYSCTL_MARGIN_LEFT, |
4256 |
synaptics_sysctl, "I", |
4979 |
synaptics_sysctl, "I", |
4257 |
"Left margin"); |
4980 |
"Left margin"); |
4258 |
|
4981 |
|
Lines 4261-4267
Link Here
|
4261 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4984 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4262 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4985 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4263 |
"na_top", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4986 |
"na_top", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4264 |
&sc->syninfo.na_top, SYNAPTICS_SYSCTL_NA_TOP, |
4987 |
sc, SYNAPTICS_SYSCTL_NA_TOP, |
4265 |
synaptics_sysctl, "I", |
4988 |
synaptics_sysctl, "I", |
4266 |
"Top noisy area, where weight_previous_na is used instead " |
4989 |
"Top noisy area, where weight_previous_na is used instead " |
4267 |
"of weight_previous"); |
4990 |
"of weight_previous"); |
Lines 4271-4277
Link Here
|
4271 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4994 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4272 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4995 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4273 |
"na_right", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4996 |
"na_right", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4274 |
&sc->syninfo.na_right, SYNAPTICS_SYSCTL_NA_RIGHT, |
4997 |
sc, SYNAPTICS_SYSCTL_NA_RIGHT, |
4275 |
synaptics_sysctl, "I", |
4998 |
synaptics_sysctl, "I", |
4276 |
"Right noisy area, where weight_previous_na is used instead " |
4999 |
"Right noisy area, where weight_previous_na is used instead " |
4277 |
"of weight_previous"); |
5000 |
"of weight_previous"); |
Lines 4281-4287
Link Here
|
4281 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5004 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4282 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5005 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4283 |
"na_bottom", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5006 |
"na_bottom", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4284 |
&sc->syninfo.na_bottom, SYNAPTICS_SYSCTL_NA_BOTTOM, |
5007 |
sc, SYNAPTICS_SYSCTL_NA_BOTTOM, |
4285 |
synaptics_sysctl, "I", |
5008 |
synaptics_sysctl, "I", |
4286 |
"Bottom noisy area, where weight_previous_na is used instead " |
5009 |
"Bottom noisy area, where weight_previous_na is used instead " |
4287 |
"of weight_previous"); |
5010 |
"of weight_previous"); |
Lines 4291-4297
Link Here
|
4291 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5014 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4292 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5015 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4293 |
"na_left", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5016 |
"na_left", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4294 |
&sc->syninfo.na_left, SYNAPTICS_SYSCTL_NA_LEFT, |
5017 |
sc, SYNAPTICS_SYSCTL_NA_LEFT, |
4295 |
synaptics_sysctl, "I", |
5018 |
synaptics_sysctl, "I", |
4296 |
"Left noisy area, where weight_previous_na is used instead " |
5019 |
"Left noisy area, where weight_previous_na is used instead " |
4297 |
"of weight_previous"); |
5020 |
"of weight_previous"); |
Lines 4301-4307
Link Here
|
4301 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5024 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4302 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5025 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4303 |
"window_min", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5026 |
"window_min", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4304 |
&sc->syninfo.window_min, SYNAPTICS_SYSCTL_WINDOW_MIN, |
5027 |
sc, SYNAPTICS_SYSCTL_WINDOW_MIN, |
4305 |
synaptics_sysctl, "I", |
5028 |
synaptics_sysctl, "I", |
4306 |
"Minimum window size to start an action"); |
5029 |
"Minimum window size to start an action"); |
4307 |
|
5030 |
|
Lines 4310-4316
Link Here
|
4310 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5033 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4311 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5034 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4312 |
"window_max", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5035 |
"window_max", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4313 |
&sc->syninfo.window_max, SYNAPTICS_SYSCTL_WINDOW_MAX, |
5036 |
sc, SYNAPTICS_SYSCTL_WINDOW_MAX, |
4314 |
synaptics_sysctl, "I", |
5037 |
synaptics_sysctl, "I", |
4315 |
"Maximum window size"); |
5038 |
"Maximum window size"); |
4316 |
|
5039 |
|
Lines 4319-4325
Link Here
|
4319 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5042 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4320 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5043 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4321 |
"multiplicator", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5044 |
"multiplicator", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4322 |
&sc->syninfo.multiplicator, SYNAPTICS_SYSCTL_MULTIPLICATOR, |
5045 |
sc, SYNAPTICS_SYSCTL_MULTIPLICATOR, |
4323 |
synaptics_sysctl, "I", |
5046 |
synaptics_sysctl, "I", |
4324 |
"Multiplicator to increase precision in averages and divisions"); |
5047 |
"Multiplicator to increase precision in averages and divisions"); |
4325 |
|
5048 |
|
Lines 4328-4334
Link Here
|
4328 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5051 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4329 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5052 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4330 |
"weight_current", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5053 |
"weight_current", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4331 |
&sc->syninfo.weight_current, SYNAPTICS_SYSCTL_WEIGHT_CURRENT, |
5054 |
sc, SYNAPTICS_SYSCTL_WEIGHT_CURRENT, |
4332 |
synaptics_sysctl, "I", |
5055 |
synaptics_sysctl, "I", |
4333 |
"Weight of the current movement in the new average"); |
5056 |
"Weight of the current movement in the new average"); |
4334 |
|
5057 |
|
Lines 4337-4343
Link Here
|
4337 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5060 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4338 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5061 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4339 |
"weight_previous", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5062 |
"weight_previous", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4340 |
&sc->syninfo.weight_previous, SYNAPTICS_SYSCTL_WEIGHT_PREVIOUS, |
5063 |
sc, SYNAPTICS_SYSCTL_WEIGHT_PREVIOUS, |
4341 |
synaptics_sysctl, "I", |
5064 |
synaptics_sysctl, "I", |
4342 |
"Weight of the previous average"); |
5065 |
"Weight of the previous average"); |
4343 |
|
5066 |
|
Lines 4346-4353
Link Here
|
4346 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5069 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4347 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5070 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4348 |
"weight_previous_na", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5071 |
"weight_previous_na", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4349 |
&sc->syninfo.weight_previous_na, |
5072 |
sc, SYNAPTICS_SYSCTL_WEIGHT_PREVIOUS_NA, |
4350 |
SYNAPTICS_SYSCTL_WEIGHT_PREVIOUS_NA, |
|
|
4351 |
synaptics_sysctl, "I", |
5073 |
synaptics_sysctl, "I", |
4352 |
"Weight of the previous average (inside the noisy area)"); |
5074 |
"Weight of the previous average (inside the noisy area)"); |
4353 |
|
5075 |
|
Lines 4356-4363
Link Here
|
4356 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5078 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4357 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5079 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4358 |
"weight_len_squared", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5080 |
"weight_len_squared", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4359 |
&sc->syninfo.weight_len_squared, |
5081 |
sc, SYNAPTICS_SYSCTL_WEIGHT_LEN_SQUARED, |
4360 |
SYNAPTICS_SYSCTL_WEIGHT_LEN_SQUARED, |
|
|
4361 |
synaptics_sysctl, "I", |
5082 |
synaptics_sysctl, "I", |
4362 |
"Length (squared) of segments where weight_previous " |
5083 |
"Length (squared) of segments where weight_previous " |
4363 |
"starts to decrease"); |
5084 |
"starts to decrease"); |
Lines 4367-4373
Link Here
|
4367 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5088 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4368 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5089 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4369 |
"div_min", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5090 |
"div_min", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4370 |
&sc->syninfo.div_min, SYNAPTICS_SYSCTL_DIV_MIN, |
5091 |
sc, SYNAPTICS_SYSCTL_DIV_MIN, |
4371 |
synaptics_sysctl, "I", |
5092 |
synaptics_sysctl, "I", |
4372 |
"Divisor for fast movements"); |
5093 |
"Divisor for fast movements"); |
4373 |
|
5094 |
|
Lines 4376-4382
Link Here
|
4376 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5097 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4377 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5098 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4378 |
"div_max", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5099 |
"div_max", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4379 |
&sc->syninfo.div_max, SYNAPTICS_SYSCTL_DIV_MAX, |
5100 |
sc, SYNAPTICS_SYSCTL_DIV_MAX, |
4380 |
synaptics_sysctl, "I", |
5101 |
synaptics_sysctl, "I", |
4381 |
"Divisor for slow movements"); |
5102 |
"Divisor for slow movements"); |
4382 |
|
5103 |
|
Lines 4385-4391
Link Here
|
4385 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5106 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4386 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5107 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4387 |
"div_max_na", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5108 |
"div_max_na", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4388 |
&sc->syninfo.div_max_na, SYNAPTICS_SYSCTL_DIV_MAX_NA, |
5109 |
sc, SYNAPTICS_SYSCTL_DIV_MAX_NA, |
4389 |
synaptics_sysctl, "I", |
5110 |
synaptics_sysctl, "I", |
4390 |
"Divisor with slow movements (inside the noisy area)"); |
5111 |
"Divisor with slow movements (inside the noisy area)"); |
4391 |
|
5112 |
|
Lines 4394-4400
Link Here
|
4394 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5115 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4395 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5116 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4396 |
"div_len", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5117 |
"div_len", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4397 |
&sc->syninfo.div_len, SYNAPTICS_SYSCTL_DIV_LEN, |
5118 |
sc, SYNAPTICS_SYSCTL_DIV_LEN, |
4398 |
synaptics_sysctl, "I", |
5119 |
synaptics_sysctl, "I", |
4399 |
"Length of segments where div_max starts to decrease"); |
5120 |
"Length of segments where div_max starts to decrease"); |
4400 |
|
5121 |
|
Lines 4403-4409
Link Here
|
4403 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5124 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4404 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5125 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4405 |
"tap_max_delta", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5126 |
"tap_max_delta", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4406 |
&sc->syninfo.tap_max_delta, SYNAPTICS_SYSCTL_TAP_MAX_DELTA, |
5127 |
sc, SYNAPTICS_SYSCTL_TAP_MAX_DELTA, |
4407 |
synaptics_sysctl, "I", |
5128 |
synaptics_sysctl, "I", |
4408 |
"Length of segments above which a tap is ignored"); |
5129 |
"Length of segments above which a tap is ignored"); |
4409 |
|
5130 |
|
Lines 4412-4428
Link Here
|
4412 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5133 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4413 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5134 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4414 |
"tap_min_queue", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5135 |
"tap_min_queue", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4415 |
&sc->syninfo.tap_min_queue, SYNAPTICS_SYSCTL_TAP_MIN_QUEUE, |
5136 |
sc, SYNAPTICS_SYSCTL_TAP_MIN_QUEUE, |
4416 |
synaptics_sysctl, "I", |
5137 |
synaptics_sysctl, "I", |
4417 |
"Number of packets required to consider a tap"); |
5138 |
"Number of packets required to consider a tap"); |
4418 |
|
5139 |
|
4419 |
/* hw.psm.synaptics.taphold_timeout. */ |
5140 |
/* hw.psm.synaptics.taphold_timeout. */ |
4420 |
sc->synaction.in_taphold = 0; |
5141 |
sc->synaction[0].in_taphold = 0; |
4421 |
sc->syninfo.taphold_timeout = tap_timeout; |
5142 |
sc->syninfo.taphold_timeout = tap_timeout; |
4422 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5143 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4423 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5144 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4424 |
"taphold_timeout", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5145 |
"taphold_timeout", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4425 |
&sc->syninfo.taphold_timeout, SYNAPTICS_SYSCTL_TAPHOLD_TIMEOUT, |
5146 |
sc, SYNAPTICS_SYSCTL_TAPHOLD_TIMEOUT, |
4426 |
synaptics_sysctl, "I", |
5147 |
synaptics_sysctl, "I", |
4427 |
"Maximum elapsed time between two taps to consider a tap-hold " |
5148 |
"Maximum elapsed time between two taps to consider a tap-hold " |
4428 |
"action"); |
5149 |
"action"); |
Lines 4432-4438
Link Here
|
4432 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5153 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4433 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5154 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4434 |
"vscroll_hor_area", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5155 |
"vscroll_hor_area", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4435 |
&sc->syninfo.vscroll_hor_area, SYNAPTICS_SYSCTL_VSCROLL_HOR_AREA, |
5156 |
sc, SYNAPTICS_SYSCTL_VSCROLL_HOR_AREA, |
4436 |
synaptics_sysctl, "I", |
5157 |
synaptics_sysctl, "I", |
4437 |
"Area reserved for horizontal virtual scrolling"); |
5158 |
"Area reserved for horizontal virtual scrolling"); |
4438 |
|
5159 |
|
Lines 4441-4447
Link Here
|
4441 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5162 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4442 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5163 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4443 |
"vscroll_ver_area", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5164 |
"vscroll_ver_area", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4444 |
&sc->syninfo.vscroll_ver_area, SYNAPTICS_SYSCTL_VSCROLL_VER_AREA, |
5165 |
sc, SYNAPTICS_SYSCTL_VSCROLL_VER_AREA, |
4445 |
synaptics_sysctl, "I", |
5166 |
synaptics_sysctl, "I", |
4446 |
"Area reserved for vertical virtual scrolling"); |
5167 |
"Area reserved for vertical virtual scrolling"); |
4447 |
|
5168 |
|
Lines 4450-4457
Link Here
|
4450 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5171 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4451 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5172 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4452 |
"vscroll_min_delta", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5173 |
"vscroll_min_delta", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4453 |
&sc->syninfo.vscroll_min_delta, |
5174 |
sc, SYNAPTICS_SYSCTL_VSCROLL_MIN_DELTA, |
4454 |
SYNAPTICS_SYSCTL_VSCROLL_MIN_DELTA, |
|
|
4455 |
synaptics_sysctl, "I", |
5175 |
synaptics_sysctl, "I", |
4456 |
"Minimum movement to consider virtual scrolling"); |
5176 |
"Minimum movement to consider virtual scrolling"); |
4457 |
|
5177 |
|
Lines 4460-4466
Link Here
|
4460 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5180 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4461 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5181 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4462 |
"vscroll_div_min", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5182 |
"vscroll_div_min", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4463 |
&sc->syninfo.vscroll_div_min, SYNAPTICS_SYSCTL_VSCROLL_DIV_MIN, |
5183 |
sc, SYNAPTICS_SYSCTL_VSCROLL_DIV_MIN, |
4464 |
synaptics_sysctl, "I", |
5184 |
synaptics_sysctl, "I", |
4465 |
"Divisor for fast scrolling"); |
5185 |
"Divisor for fast scrolling"); |
4466 |
|
5186 |
|
Lines 4469-4475
Link Here
|
4469 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5189 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4470 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5190 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4471 |
"vscroll_div_max", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5191 |
"vscroll_div_max", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4472 |
&sc->syninfo.vscroll_div_max, SYNAPTICS_SYSCTL_VSCROLL_DIV_MAX, |
5192 |
sc, SYNAPTICS_SYSCTL_VSCROLL_DIV_MAX, |
4473 |
synaptics_sysctl, "I", |
5193 |
synaptics_sysctl, "I", |
4474 |
"Divisor for slow scrolling"); |
5194 |
"Divisor for slow scrolling"); |
4475 |
|
5195 |
|
Lines 4478-4491
Link Here
|
4478 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5198 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
4479 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5199 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
4480 |
"touchpad_off", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5200 |
"touchpad_off", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
4481 |
&sc->syninfo.touchpad_off, SYNAPTICS_SYSCTL_TOUCHPAD_OFF, |
5201 |
sc, SYNAPTICS_SYSCTL_TOUCHPAD_OFF, |
4482 |
synaptics_sysctl, "I", |
5202 |
synaptics_sysctl, "I", |
4483 |
"Turn off touchpad"); |
5203 |
"Turn off touchpad"); |
|
|
5204 |
|
5205 |
sc->syninfo.softbuttons = 0; |
5206 |
sc->syninfo.softbuttons_y = 0; |
5207 |
sc->syninfo.softbutton2_x = 0; |
5208 |
sc->syninfo.softbutton3_x = 0; |
5209 |
sc->syninfo.softbutton_nomove = 0; |
5210 |
|
5211 |
/* skip softbuttons sysctl on not clickpads */ |
5212 |
if (!sc->synhw.capClickPad) |
5213 |
return; |
5214 |
|
5215 |
/* hw.psm.synaptics.softbuttons */ |
5216 |
sc->syninfo.softbuttons = 3; |
5217 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5218 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5219 |
"softbuttons", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5220 |
sc, SYNAPTICS_SYSCTL_SOFTBUTTONS, |
5221 |
synaptics_sysctl, "I", |
5222 |
"Enables top or bottom edges to be a softbuttons on clickpads"); |
5223 |
|
5224 |
/* hw.psm.synaptics.softbuttons_y */ |
5225 |
sc->syninfo.softbuttons_y = sc->synhw.maximumYCoord / 4; |
5226 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5227 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5228 |
"softbuttons_y", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5229 |
sc, SYNAPTICS_SYSCTL_SOFTBUTTONS_Y, |
5230 |
synaptics_sysctl, "I", |
5231 |
"Vertical size of softbuttons area"); |
5232 |
|
5233 |
/* hw.psm.synaptics.softbutton2_x */ |
5234 |
sc->syninfo.softbutton2_x = sc->synhw.maximumXCoord / 3; |
5235 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5236 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5237 |
"softbutton2_x", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5238 |
sc, SYNAPTICS_SYSCTL_SOFTBUTTON2_X, |
5239 |
synaptics_sysctl, "I", |
5240 |
"Horisontal position of 2-nd softbutton left edge (0-disable)"); |
5241 |
|
5242 |
/* hw.psm.synaptics.softbutton3_x */ |
5243 |
sc->syninfo.softbutton3_x = sc->synhw.maximumXCoord * 2 / 3; |
5244 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5245 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5246 |
"softbutton3_x", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5247 |
sc, SYNAPTICS_SYSCTL_SOFTBUTTON3_X, |
5248 |
synaptics_sysctl, "I", |
5249 |
"Horisontal position of 3-rd softbutton left edge (0-disable)"); |
5250 |
|
5251 |
/* hw.psm.synaptics.softbutton_nomove */ |
5252 |
sc->syninfo.softbutton_nomove = 0; |
5253 |
SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx, |
5254 |
SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO, |
5255 |
"softbutton_nomove", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY, |
5256 |
sc, SYNAPTICS_SYSCTL_SOFTBUTTON_NOMOVE, |
5257 |
synaptics_sysctl, "I", |
5258 |
"Disable movement on the bottom edge area so it works as buttons"); |
4484 |
} |
5259 |
} |
4485 |
|
5260 |
|
4486 |
static int |
5261 |
static int |
4487 |
enable_synaptics(KBDC kbdc, struct psm_softc *sc) |
5262 |
synaptics_preferred_mode(struct psm_softc *sc) { |
|
|
5263 |
int mode_byte; |
5264 |
|
5265 |
mode_byte = 0xc0; |
5266 |
|
5267 |
/* request wmode where available */ |
5268 |
if (sc->synhw.capExtended) |
5269 |
mode_byte |= 1; |
5270 |
|
5271 |
/* |
5272 |
* Disable gesture processing when native packets are requested. This |
5273 |
* enables sending of encapsulated "extended W mode" packets. |
5274 |
*/ |
5275 |
if (sc->mode.level == PSM_LEVEL_NATIVE) |
5276 |
mode_byte |= (1 << 2); |
5277 |
|
5278 |
return mode_byte; |
5279 |
} |
5280 |
|
5281 |
static void |
5282 |
synaptics_set_mode(struct psm_softc *sc, int mode_byte) { |
5283 |
mouse_ext_command(sc->kbdc, mode_byte); |
5284 |
|
5285 |
/* "Commit" the Set Mode Byte command sent above. */ |
5286 |
set_mouse_sampling_rate(sc->kbdc, 20); |
5287 |
|
5288 |
/* |
5289 |
* Enable advanced gestures mode if supported and we are not entering |
5290 |
* passthrough mode. |
5291 |
*/ |
5292 |
if (sc->synhw.capAdvancedGestures && !(mode_byte & (1 << 5))) { |
5293 |
mouse_ext_command(sc->kbdc, 3); |
5294 |
set_mouse_sampling_rate(sc->kbdc, 0xc8); |
5295 |
} |
5296 |
} |
5297 |
|
5298 |
static int |
5299 |
enable_synaptics(struct psm_softc *sc, enum probearg arg) |
4488 |
{ |
5300 |
{ |
|
|
5301 |
KBDC kbdc = sc->kbdc; |
4489 |
synapticshw_t synhw; |
5302 |
synapticshw_t synhw; |
4490 |
int status[3]; |
5303 |
int status[3]; |
4491 |
int buttons; |
5304 |
int buttons; |
Lines 4566-4579
Link Here
|
4566 |
buttons = 0; |
5379 |
buttons = 0; |
4567 |
synhw.capExtended = (status[0] & 0x80) != 0; |
5380 |
synhw.capExtended = (status[0] & 0x80) != 0; |
4568 |
if (synhw.capExtended) { |
5381 |
if (synhw.capExtended) { |
4569 |
synhw.nExtendedQueries = (status[0] & 0x70) != 0; |
5382 |
synhw.nExtendedQueries = (status[0] & 0x70) >> 4; |
4570 |
synhw.capMiddle = (status[0] & 0x04) != 0; |
5383 |
synhw.capMiddle = (status[0] & 0x04) != 0; |
4571 |
synhw.capPassthrough = (status[2] & 0x80) != 0; |
5384 |
synhw.capPassthrough = (status[2] & 0x80) != 0; |
|
|
5385 |
synhw.capLowPower = (status[2] & 0x40) != 0; |
5386 |
synhw.capMultiFingerReport = |
5387 |
(status[2] & 0x20) != 0; |
4572 |
synhw.capSleep = (status[2] & 0x10) != 0; |
5388 |
synhw.capSleep = (status[2] & 0x10) != 0; |
4573 |
synhw.capFourButtons = (status[2] & 0x08) != 0; |
5389 |
synhw.capFourButtons = (status[2] & 0x08) != 0; |
|
|
5390 |
synhw.capBallistics = (status[2] & 0x04) != 0; |
4574 |
synhw.capMultiFinger = (status[2] & 0x02) != 0; |
5391 |
synhw.capMultiFinger = (status[2] & 0x02) != 0; |
4575 |
synhw.capPalmDetect = (status[2] & 0x01) != 0; |
5392 |
synhw.capPalmDetect = (status[2] & 0x01) != 0; |
4576 |
|
5393 |
|
|
|
5394 |
if (!set_mouse_scaling(kbdc, 1)) |
5395 |
return (FALSE); |
5396 |
if (mouse_ext_command(kbdc, 0x08) == 0) |
5397 |
return (FALSE); |
5398 |
if (get_mouse_status(kbdc, status, 0, 3) != 3) |
5399 |
return (FALSE); |
5400 |
|
5401 |
synhw.infoXupmm = status[0]; |
5402 |
synhw.infoYupmm = status[2]; |
5403 |
|
4577 |
if (verbose >= 2) { |
5404 |
if (verbose >= 2) { |
4578 |
printf(" Extended capabilities:\n"); |
5405 |
printf(" Extended capabilities:\n"); |
4579 |
printf(" capExtended: %d\n", synhw.capExtended); |
5406 |
printf(" capExtended: %d\n", synhw.capExtended); |
Lines 4581-4590
Link Here
|
4581 |
printf(" nExtendedQueries: %d\n", |
5408 |
printf(" nExtendedQueries: %d\n", |
4582 |
synhw.nExtendedQueries); |
5409 |
synhw.nExtendedQueries); |
4583 |
printf(" capPassthrough: %d\n", synhw.capPassthrough); |
5410 |
printf(" capPassthrough: %d\n", synhw.capPassthrough); |
|
|
5411 |
printf(" capLowPower: %d\n", synhw.capLowPower); |
5412 |
printf(" capMultiFingerReport: %d\n", |
5413 |
synhw.capMultiFingerReport); |
4584 |
printf(" capSleep: %d\n", synhw.capSleep); |
5414 |
printf(" capSleep: %d\n", synhw.capSleep); |
4585 |
printf(" capFourButtons: %d\n", synhw.capFourButtons); |
5415 |
printf(" capFourButtons: %d\n", synhw.capFourButtons); |
|
|
5416 |
printf(" capBallistics: %d\n", synhw.capBallistics); |
4586 |
printf(" capMultiFinger: %d\n", synhw.capMultiFinger); |
5417 |
printf(" capMultiFinger: %d\n", synhw.capMultiFinger); |
4587 |
printf(" capPalmDetect: %d\n", synhw.capPalmDetect); |
5418 |
printf(" capPalmDetect: %d\n", synhw.capPalmDetect); |
|
|
5419 |
printf(" infoXupmm: %d\n", synhw.infoXupmm); |
5420 |
printf(" infoYupmm: %d\n", synhw.infoYupmm); |
4588 |
} |
5421 |
} |
4589 |
|
5422 |
|
4590 |
/* |
5423 |
/* |
Lines 4592-4598
Link Here
|
4592 |
* supports this number of extended queries. We can load |
5425 |
* supports this number of extended queries. We can load |
4593 |
* more information about buttons using query 0x09. |
5426 |
* more information about buttons using query 0x09. |
4594 |
*/ |
5427 |
*/ |
4595 |
if (synhw.capExtended && synhw.nExtendedQueries) { |
5428 |
if (synhw.nExtendedQueries >= 1) { |
|
|
5429 |
if (!set_mouse_scaling(kbdc, 1)) |
5430 |
return (FALSE); |
4596 |
if (mouse_ext_command(kbdc, 0x09) == 0) |
5431 |
if (mouse_ext_command(kbdc, 0x09) == 0) |
4597 |
return (FALSE); |
5432 |
return (FALSE); |
4598 |
if (get_mouse_status(kbdc, status, 0, 3) != 3) |
5433 |
if (get_mouse_status(kbdc, status, 0, 3) != 3) |
Lines 4601-4606
Link Here
|
4601 |
synhw.horizontalScroll = (status[0] & 0x02) != 0; |
5436 |
synhw.horizontalScroll = (status[0] & 0x02) != 0; |
4602 |
synhw.verticalWheel = (status[0] & 0x08) != 0; |
5437 |
synhw.verticalWheel = (status[0] & 0x08) != 0; |
4603 |
synhw.nExtendedButtons = (status[1] & 0xf0) >> 4; |
5438 |
synhw.nExtendedButtons = (status[1] & 0xf0) >> 4; |
|
|
5439 |
synhw.capEWmode = (status[0] & 0x04) != 0; |
4604 |
if (verbose >= 2) { |
5440 |
if (verbose >= 2) { |
4605 |
printf(" Extended model ID:\n"); |
5441 |
printf(" Extended model ID:\n"); |
4606 |
printf(" verticalScroll: %d\n", |
5442 |
printf(" verticalScroll: %d\n", |
Lines 4611-4616
Link Here
|
4611 |
synhw.verticalWheel); |
5447 |
synhw.verticalWheel); |
4612 |
printf(" nExtendedButtons: %d\n", |
5448 |
printf(" nExtendedButtons: %d\n", |
4613 |
synhw.nExtendedButtons); |
5449 |
synhw.nExtendedButtons); |
|
|
5450 |
printf(" capEWmode: %d\n", |
5451 |
synhw.capEWmode); |
4614 |
} |
5452 |
} |
4615 |
/* |
5453 |
/* |
4616 |
* Add the number of extended buttons to the total |
5454 |
* Add the number of extended buttons to the total |
Lines 4624-4630
Link Here
|
4624 |
* add a fourth button to the total button count. |
5462 |
* add a fourth button to the total button count. |
4625 |
*/ |
5463 |
*/ |
4626 |
buttons = synhw.capFourButtons ? 1 : 0; |
5464 |
buttons = synhw.capFourButtons ? 1 : 0; |
|
|
5465 |
|
5466 |
/* Read the continued capabilities bits. */ |
5467 |
if (synhw.nExtendedQueries >= 4) { |
5468 |
if (!set_mouse_scaling(kbdc, 1)) |
5469 |
return (FALSE); |
5470 |
if (mouse_ext_command(kbdc, 0x0c) == 0) |
5471 |
return (FALSE); |
5472 |
if (get_mouse_status(kbdc, status, 0, 3) != 3) |
5473 |
return (FALSE); |
5474 |
|
5475 |
synhw.capClickPad = (status[1] & 0x01) << 1; |
5476 |
synhw.capClickPad |= (status[0] & 0x10) != 0; |
5477 |
synhw.capDeluxeLEDs = (status[1] & 0x02) != 0; |
5478 |
synhw.noAbsoluteFilter = (status[1] & 0x04) != 0; |
5479 |
synhw.capReportsV = (status[1] & 0x08) != 0; |
5480 |
synhw.capUniformClickPad = (status[1] & 0x10) != 0; |
5481 |
synhw.capReportsMin = (status[1] & 0x20) != 0; |
5482 |
synhw.capInterTouch = (status[1] & 0x40) != 0; |
5483 |
synhw.capReportsMax = (status[0] & 0x02) != 0; |
5484 |
synhw.capClearPad = (status[0] & 0x04) != 0; |
5485 |
synhw.capAdvancedGestures = (status[0] & 0x08) != 0; |
5486 |
synhw.capCoveredPad = (status[0] & 0x80) != 0; |
5487 |
|
5488 |
if (synhw.capReportsMax) { |
5489 |
if (!set_mouse_scaling(kbdc, 1)) |
5490 |
return (FALSE); |
5491 |
if (mouse_ext_command(kbdc, 0x0d) == 0) |
5492 |
return (FALSE); |
5493 |
if (get_mouse_status(kbdc, status, 0, 3) != 3) |
5494 |
return (FALSE); |
5495 |
|
5496 |
synhw.maximumXCoord = (status[0] << 5) | |
5497 |
((status[1] & 0x0f) << 1); |
5498 |
synhw.maximumYCoord = (status[2] << 5) | |
5499 |
((status[1] & 0xf0) >> 3); |
5500 |
} else |
5501 |
synhw.maximumXCoord = synhw.maximumYCoord = |
5502 |
6143; |
5503 |
|
5504 |
if (synhw.capReportsMin) { |
5505 |
if (!set_mouse_scaling(kbdc, 1)) |
5506 |
return (FALSE); |
5507 |
if (mouse_ext_command(kbdc, 0x0f) == 0) |
5508 |
return (FALSE); |
5509 |
if (get_mouse_status(kbdc, status, 0, 3) != 3) |
5510 |
return (FALSE); |
5511 |
|
5512 |
synhw.minimumXCoord = (status[0] << 5) | |
5513 |
((status[1] & 0x0f) << 1); |
5514 |
synhw.minimumYCoord = (status[2] << 5) | |
5515 |
((status[1] & 0xf0) >> 3); |
5516 |
} else |
5517 |
synhw.minimumXCoord = synhw.minimumYCoord = 0; |
5518 |
|
5519 |
if (verbose >= 2) { |
5520 |
printf(" Continued capabilities:\n"); |
5521 |
printf(" capClickPad: %d\n", |
5522 |
synhw.capClickPad); |
5523 |
printf(" capDeluxeLEDs: %d\n", |
5524 |
synhw.capDeluxeLEDs); |
5525 |
printf(" noAbsoluteFilter: %d\n", |
5526 |
synhw.noAbsoluteFilter); |
5527 |
printf(" capReportsV: %d\n", |
5528 |
synhw.capReportsV); |
5529 |
printf(" capUniformClickPad: %d\n", |
5530 |
synhw.capUniformClickPad); |
5531 |
printf(" capReportsMin: %d\n", |
5532 |
synhw.capReportsMin); |
5533 |
printf(" capInterTouch: %d\n", |
5534 |
synhw.capInterTouch); |
5535 |
printf(" capReportsMax: %d\n", |
5536 |
synhw.capReportsMax); |
5537 |
printf(" capClearPad: %d\n", |
5538 |
synhw.capClearPad); |
5539 |
printf(" capAdvancedGestures: %d\n", |
5540 |
synhw.capAdvancedGestures); |
5541 |
printf(" capCoveredPad: %d\n", |
5542 |
synhw.capCoveredPad); |
5543 |
if (synhw.capReportsMax) { |
5544 |
printf(" maximumXCoord: %d\n", |
5545 |
synhw.maximumXCoord); |
5546 |
printf(" maximumYCoord: %d\n", |
5547 |
synhw.maximumYCoord); |
5548 |
} |
5549 |
if (synhw.capReportsMin) { |
5550 |
printf(" minimumXCoord: %d\n", |
5551 |
synhw.minimumXCoord); |
5552 |
printf(" minimumYCoord: %d\n", |
5553 |
synhw.minimumYCoord); |
5554 |
} |
5555 |
} |
5556 |
buttons += synhw.capClickPad; |
5557 |
} |
4627 |
} |
5558 |
} |
|
|
5559 |
|
4628 |
if (verbose >= 2) { |
5560 |
if (verbose >= 2) { |
4629 |
if (synhw.capExtended) |
5561 |
if (synhw.capExtended) |
4630 |
printf(" Additional Buttons: %d\n", buttons); |
5562 |
printf(" Additional Buttons: %d\n", buttons); |
Lines 4632-4673
Link Here
|
4632 |
printf(" No extended capabilities\n"); |
5564 |
printf(" No extended capabilities\n"); |
4633 |
} |
5565 |
} |
4634 |
|
5566 |
|
4635 |
/* Read the continued capabilities bits. */ |
|
|
4636 |
if (mouse_ext_command(kbdc, 0xc) != 0 && |
4637 |
get_mouse_status(kbdc, status, 0, 3) == 3) { |
4638 |
synhw.capClickPad = (status[1] & 0x01) << 1; |
4639 |
synhw.capClickPad |= (status[0] & 0x10) != 0; |
4640 |
synhw.capDeluxeLEDs = (status[1] & 0x02) != 0; |
4641 |
synhw.noAbsoluteFilter = (status[1] & 0x04) != 0; |
4642 |
synhw.capReportsV = (status[1] & 0x08) != 0; |
4643 |
synhw.capUniformClickPad = (status[1] & 0x10) != 0; |
4644 |
synhw.capReportsMin = (status[1] & 0x20) != 0; |
4645 |
synhw.capInterTouch = (status[1] & 0x40) != 0; |
4646 |
synhw.capReportsMax = (status[2] & 0x02) != 0; |
4647 |
synhw.capClearPad = (status[2] & 0x04) != 0; |
4648 |
synhw.capAdvancedGestures = (status[2] & 0x08) != 0; |
4649 |
synhw.capCoveredPad = (status[2] & 0x80) != 0; |
4650 |
|
4651 |
if (verbose >= 2) { |
4652 |
printf(" Continued capabilities:\n"); |
4653 |
printf(" capClickPad: %d\n", synhw.capClickPad); |
4654 |
printf(" capDeluxeLEDs: %d\n", synhw.capDeluxeLEDs); |
4655 |
printf(" noAbsoluteFilter: %d\n", |
4656 |
synhw.noAbsoluteFilter); |
4657 |
printf(" capReportsV: %d\n", synhw.capReportsV); |
4658 |
printf(" capUniformClickPad: %d\n", |
4659 |
synhw.capUniformClickPad); |
4660 |
printf(" capReportsMin: %d\n", synhw.capReportsMin); |
4661 |
printf(" capInterTouch: %d\n", synhw.capInterTouch); |
4662 |
printf(" capReportsMax: %d\n", synhw.capReportsMax); |
4663 |
printf(" capClearPad: %d\n", synhw.capClearPad); |
4664 |
printf(" capAdvancedGestures: %d\n", |
4665 |
synhw.capAdvancedGestures); |
4666 |
printf(" capCoveredPad: %d\n", synhw.capCoveredPad); |
4667 |
} |
4668 |
buttons += synhw.capClickPad; |
4669 |
} |
4670 |
|
4671 |
/* |
5567 |
/* |
4672 |
* Add the default number of 3 buttons to the total |
5568 |
* Add the default number of 3 buttons to the total |
4673 |
* count of supported buttons reported above. |
5569 |
* count of supported buttons reported above. |
Lines 4690-4716
Link Here
|
4690 |
return (FALSE); |
5586 |
return (FALSE); |
4691 |
} |
5587 |
} |
4692 |
|
5588 |
|
4693 |
if (sc != NULL) |
5589 |
if (arg == PROBE) |
4694 |
sc->synhw = synhw; |
5590 |
sc->synhw = synhw; |
4695 |
if (!synaptics_support) |
5591 |
if (!synaptics_support) |
4696 |
return (FALSE); |
5592 |
return (FALSE); |
4697 |
|
5593 |
|
4698 |
/* Set the mode byte; request wmode where available. */ |
5594 |
synaptics_set_mode(sc, synaptics_preferred_mode(sc)); |
4699 |
mouse_ext_command(kbdc, synhw.capExtended ? 0xc1 : 0xc0); |
|
|
4700 |
|
5595 |
|
4701 |
/* "Commit" the Set Mode Byte command sent above. */ |
5596 |
if (trackpoint_support && synhw.capPassthrough) { |
4702 |
set_mouse_sampling_rate(kbdc, 20); |
5597 |
enable_trackpoint(sc, arg); |
|
|
5598 |
} |
4703 |
|
5599 |
|
4704 |
VLOG(3, (LOG_DEBUG, "synaptics: END init (%d buttons)\n", buttons)); |
5600 |
VLOG(3, (LOG_DEBUG, "synaptics: END init (%d buttons)\n", buttons)); |
4705 |
|
5601 |
|
4706 |
if (sc != NULL) { |
5602 |
if (arg == PROBE) { |
4707 |
if (trackpoint_support && synhw.capPassthrough) { |
|
|
4708 |
synaptics_passthrough_on(sc); |
4709 |
enable_trackpoint(kbdc, sc); |
4710 |
synaptics_passthrough_off(sc); |
4711 |
} |
4712 |
/* Create sysctl tree. */ |
5603 |
/* Create sysctl tree. */ |
4713 |
synaptics_sysctl_create_tree(sc); |
5604 |
synaptics_sysctl_create_tree(sc, "synaptics", |
|
|
5605 |
"Synaptics TouchPad"); |
4714 |
sc->hw.buttons = buttons; |
5606 |
sc->hw.buttons = buttons; |
4715 |
} |
5607 |
} |
4716 |
|
5608 |
|
Lines 4720-4749
Link Here
|
4720 |
static void |
5612 |
static void |
4721 |
synaptics_passthrough_on(struct psm_softc *sc) |
5613 |
synaptics_passthrough_on(struct psm_softc *sc) |
4722 |
{ |
5614 |
{ |
4723 |
int mode_byte; |
5615 |
VLOG(2, (LOG_NOTICE, "psm: setting pass-through mode.\n")); |
4724 |
|
5616 |
synaptics_set_mode(sc, synaptics_preferred_mode(sc) | (1 << 5)); |
4725 |
mode_byte = 0xc1 | (1 << 5); |
|
|
4726 |
VLOG(2, (LOG_NOTICE, "psm: setting pass-through mode. %d\n", |
4727 |
mode_byte)); |
4728 |
mouse_ext_command(sc->kbdc, mode_byte); |
4729 |
|
4730 |
/* "Commit" the Set Mode Byte command sent above. */ |
4731 |
set_mouse_sampling_rate(sc->kbdc, 20); |
4732 |
} |
5617 |
} |
4733 |
|
5618 |
|
4734 |
static void |
5619 |
static void |
4735 |
synaptics_passthrough_off(struct psm_softc *sc) |
5620 |
synaptics_passthrough_off(struct psm_softc *sc) |
4736 |
{ |
5621 |
{ |
4737 |
int mode_byte; |
|
|
4738 |
|
4739 |
mode_byte = 0xc1; |
4740 |
VLOG(2, (LOG_NOTICE, "psm: turning pass-through mode off.\n")); |
5622 |
VLOG(2, (LOG_NOTICE, "psm: turning pass-through mode off.\n")); |
4741 |
set_mouse_scaling(sc->kbdc, 2); |
5623 |
set_mouse_scaling(sc->kbdc, 2); |
4742 |
set_mouse_scaling(sc->kbdc, 1); |
5624 |
set_mouse_scaling(sc->kbdc, 1); |
4743 |
mouse_ext_command(sc->kbdc, mode_byte); |
5625 |
synaptics_set_mode(sc, synaptics_preferred_mode(sc)); |
4744 |
|
|
|
4745 |
/* "Commit" the Set Mode Byte command sent above. */ |
4746 |
set_mouse_sampling_rate(sc->kbdc, 20); |
4747 |
} |
5626 |
} |
4748 |
|
5627 |
|
4749 |
/* IBM/Lenovo TrackPoint */ |
5628 |
/* IBM/Lenovo TrackPoint */ |
Lines 4966-4990
Link Here
|
4966 |
} |
5845 |
} |
4967 |
|
5846 |
|
4968 |
static int |
5847 |
static int |
4969 |
enable_trackpoint(KBDC kbdc, struct psm_softc *sc) |
5848 |
enable_trackpoint(struct psm_softc *sc, enum probearg arg) |
4970 |
{ |
5849 |
{ |
|
|
5850 |
KBDC kbdc = sc->kbdc; |
4971 |
int id; |
5851 |
int id; |
4972 |
|
5852 |
|
|
|
5853 |
/* |
5854 |
* If called from enable_synaptics(), make sure that passthrough |
5855 |
* mode is enabled so we can reach the trackpoint. |
5856 |
* However, passthrough mode must be disabled before setting the |
5857 |
* trackpoint parameters, as rackpoint_command() enables and disables |
5858 |
* passthrough mode on its own. |
5859 |
*/ |
5860 |
if (sc->synhw.capPassthrough) |
5861 |
synaptics_passthrough_on(sc); |
5862 |
|
4973 |
if (send_aux_command(kbdc, 0xe1) != PSM_ACK || |
5863 |
if (send_aux_command(kbdc, 0xe1) != PSM_ACK || |
4974 |
read_aux_data(kbdc) != 0x01) |
5864 |
read_aux_data(kbdc) != 0x01) |
4975 |
return (FALSE); |
5865 |
goto no_trackpoint; |
4976 |
id = read_aux_data(kbdc); |
5866 |
id = read_aux_data(kbdc); |
4977 |
if (id < 0x01) |
5867 |
if (id < 0x01) |
4978 |
return (FALSE); |
5868 |
goto no_trackpoint; |
4979 |
if (sc != NULL) |
5869 |
if (arg == PROBE) |
4980 |
sc->tphw = id; |
5870 |
sc->tphw = id; |
4981 |
if (!trackpoint_support) |
5871 |
if (!trackpoint_support) |
4982 |
return (FALSE); |
5872 |
goto no_trackpoint; |
4983 |
|
5873 |
|
4984 |
if (sc != NULL) { |
5874 |
if (sc->synhw.capPassthrough) |
4985 |
/* Create sysctl tree. */ |
5875 |
synaptics_passthrough_off(sc); |
|
|
5876 |
|
5877 |
if (arg == PROBE) { |
4986 |
trackpoint_sysctl_create_tree(sc); |
5878 |
trackpoint_sysctl_create_tree(sc); |
4987 |
|
|
|
4988 |
/* |
5879 |
/* |
4989 |
* Don't overwrite hwid and buttons when we are |
5880 |
* Don't overwrite hwid and buttons when we are |
4990 |
* a guest device. |
5881 |
* a guest device. |
Lines 4995-5007
Link Here
|
4995 |
} |
5886 |
} |
4996 |
} |
5887 |
} |
4997 |
|
5888 |
|
|
|
5889 |
set_trackpoint_parameters(sc); |
5890 |
|
4998 |
return (TRUE); |
5891 |
return (TRUE); |
|
|
5892 |
|
5893 |
no_trackpoint: |
5894 |
if (sc->synhw.capPassthrough) |
5895 |
synaptics_passthrough_off(sc); |
5896 |
|
5897 |
return (FALSE); |
4999 |
} |
5898 |
} |
5000 |
|
5899 |
|
5001 |
/* Interlink electronics VersaPad */ |
5900 |
/* Interlink electronics VersaPad */ |
5002 |
static int |
5901 |
static int |
5003 |
enable_versapad(KBDC kbdc, struct psm_softc *sc) |
5902 |
enable_versapad(struct psm_softc *sc, enum probearg arg) |
5004 |
{ |
5903 |
{ |
|
|
5904 |
KBDC kbdc = sc->kbdc; |
5005 |
int data[3]; |
5905 |
int data[3]; |
5006 |
|
5906 |
|
5007 |
set_mouse_resolution(kbdc, PSMD_RES_MEDIUM_HIGH); /* set res. 2 */ |
5907 |
set_mouse_resolution(kbdc, PSMD_RES_MEDIUM_HIGH); /* set res. 2 */ |
Lines 5019-5024
Link Here
|
5019 |
return (TRUE); /* PS/2 absolute mode */ |
5919 |
return (TRUE); /* PS/2 absolute mode */ |
5020 |
} |
5920 |
} |
5021 |
|
5921 |
|
|
|
5922 |
/* Elantech Touchpad */ |
5923 |
static int |
5924 |
elantech_read_1(KBDC kbdc, int hwversion, int reg, int *val) |
5925 |
{ |
5926 |
int res, readcmd, retidx; |
5927 |
int resp[3]; |
5928 |
|
5929 |
readcmd = hwversion == 2 ? ELANTECH_REG_READ : ELANTECH_REG_RDWR; |
5930 |
retidx = hwversion == 4 ? 1 : 0; |
5931 |
|
5932 |
res = send_aux_command(kbdc, ELANTECH_CUSTOM_CMD) != PSM_ACK; |
5933 |
res |= send_aux_command(kbdc, readcmd) != PSM_ACK; |
5934 |
res |= send_aux_command(kbdc, ELANTECH_CUSTOM_CMD) != PSM_ACK; |
5935 |
res |= send_aux_command(kbdc, reg) != PSM_ACK; |
5936 |
res |= get_mouse_status(kbdc, resp, 0, 3) != 3; |
5937 |
|
5938 |
if (res == 0) |
5939 |
*val = resp[retidx]; |
5940 |
|
5941 |
return (res); |
5942 |
} |
5943 |
|
5944 |
static int |
5945 |
elantech_write_1(KBDC kbdc, int hwversion, int reg, int val) |
5946 |
{ |
5947 |
int res, writecmd; |
5948 |
|
5949 |
writecmd = hwversion == 2 ? ELANTECH_REG_WRITE : ELANTECH_REG_RDWR; |
5950 |
|
5951 |
res = send_aux_command(kbdc, ELANTECH_CUSTOM_CMD) != PSM_ACK; |
5952 |
res |= send_aux_command(kbdc, writecmd) != PSM_ACK; |
5953 |
res |= send_aux_command(kbdc, ELANTECH_CUSTOM_CMD) != PSM_ACK; |
5954 |
res |= send_aux_command(kbdc, reg) != PSM_ACK; |
5955 |
if (hwversion == 4) { |
5956 |
res |= send_aux_command(kbdc, ELANTECH_CUSTOM_CMD) != PSM_ACK; |
5957 |
res |= send_aux_command(kbdc, writecmd) != PSM_ACK; |
5958 |
} |
5959 |
res |= send_aux_command(kbdc, ELANTECH_CUSTOM_CMD) != PSM_ACK; |
5960 |
res |= send_aux_command(kbdc, val) != PSM_ACK; |
5961 |
res |= set_mouse_scaling(kbdc, 1) == 0; |
5962 |
|
5963 |
return (res); |
5964 |
} |
5965 |
|
5966 |
static int |
5967 |
elantech_cmd(KBDC kbdc, int hwversion, int cmd, int *resp) |
5968 |
{ |
5969 |
int res; |
5970 |
|
5971 |
if (hwversion == 2) { |
5972 |
res = set_mouse_scaling(kbdc, 1) == 0; |
5973 |
res |= mouse_ext_command(kbdc, cmd) == 0; |
5974 |
} else { |
5975 |
res = send_aux_command(kbdc, ELANTECH_CUSTOM_CMD) != PSM_ACK; |
5976 |
res |= send_aux_command(kbdc, cmd) != PSM_ACK; |
5977 |
} |
5978 |
res |= get_mouse_status(kbdc, resp, 0, 3) != 3; |
5979 |
|
5980 |
return (res); |
5981 |
} |
5982 |
|
5983 |
static int |
5984 |
elantech_init(KBDC kbdc, elantechhw_t *elanhw) |
5985 |
{ |
5986 |
int i, val, res, hwversion, reg10; |
5987 |
|
5988 |
/* set absolute mode */ |
5989 |
hwversion = elanhw->hwversion; |
5990 |
reg10 = -1; |
5991 |
switch (hwversion) { |
5992 |
case 2: |
5993 |
reg10 = elanhw->fwversion == 0x020030 ? 0x54 : 0xc4; |
5994 |
res = elantech_write_1(kbdc, hwversion, 0x10, reg10); |
5995 |
if (res) |
5996 |
break; |
5997 |
res = elantech_write_1(kbdc, hwversion, 0x11, 0x8A); |
5998 |
break; |
5999 |
case 3: |
6000 |
reg10 = 0x0b; |
6001 |
res = elantech_write_1(kbdc, hwversion, 0x10, reg10); |
6002 |
break; |
6003 |
case 4: |
6004 |
res = elantech_write_1(kbdc, hwversion, 0x07, 0x01); |
6005 |
break; |
6006 |
default: |
6007 |
res = 1; |
6008 |
} |
6009 |
|
6010 |
/* Read back reg 0x10 to ensure hardware is ready. */ |
6011 |
if (res == 0 && reg10 >= 0) { |
6012 |
for (i = 0; i < 5; i++) { |
6013 |
if (elantech_read_1(kbdc, hwversion, 0x10, &val) == 0) |
6014 |
break; |
6015 |
pause("elan", 1); |
6016 |
} |
6017 |
if (i == 5) |
6018 |
res = 1; |
6019 |
} |
6020 |
|
6021 |
if (res) |
6022 |
printf("couldn't set absolute mode\n"); |
6023 |
|
6024 |
return (res); |
6025 |
} |
6026 |
|
6027 |
static void |
6028 |
elantech_init_synaptics(struct psm_softc *sc) |
6029 |
{ |
6030 |
|
6031 |
/* Set capabilites required by movement smother */ |
6032 |
sc->synhw.infoMajor = sc->elanhw.hwversion; |
6033 |
sc->synhw.infoMinor = sc->elanhw.fwversion; |
6034 |
sc->synhw.infoXupmm = (sc->elanhw.dpix * 10 + 5) / 254; |
6035 |
sc->synhw.infoYupmm = (sc->elanhw.dpiy * 10 + 5) / 254; |
6036 |
sc->synhw.verticalScroll = 0; |
6037 |
sc->synhw.nExtendedQueries = 4; |
6038 |
sc->synhw.capExtended = 1; |
6039 |
sc->synhw.capPassthrough = sc->elanhw.hastrackpad; |
6040 |
sc->synhw.capClickPad = sc->elanhw.isclickpad; |
6041 |
sc->synhw.capMultiFinger = 1; |
6042 |
sc->synhw.capPalmDetect = 1; |
6043 |
sc->synhw.capPen = 0; |
6044 |
sc->synhw.capReportsMax = 1; |
6045 |
sc->synhw.maximumXCoord = sc->elanhw.sizex; |
6046 |
sc->synhw.maximumYCoord = sc->elanhw.sizey; |
6047 |
sc->synhw.capReportsMin = 1; |
6048 |
sc->synhw.minimumXCoord = 0; |
6049 |
sc->synhw.minimumYCoord = 0; |
6050 |
|
6051 |
if (sc->syninfo.sysctl_tree == NULL) { |
6052 |
synaptics_sysctl_create_tree(sc, "elantech", |
6053 |
"Elantech Touchpad"); |
6054 |
|
6055 |
/* |
6056 |
* Adjust synaptic smoother tunables |
6057 |
* 1. Disable finger detection pressure threshold. Unlike |
6058 |
* synaptics we assume the finger is acting when packet with |
6059 |
* its X&Y arrives not when pressure exceedes some threshold |
6060 |
* 2. Disable unrelated features like margins and noisy areas |
6061 |
* 3. Disable virtual scroll areas as 2nd finger is preferable |
6062 |
* 4. Scale down divisors and movement lengths by a factor of 3 |
6063 |
* where 3 is Synaptics to Elantech (~2200/800) dpi ratio |
6064 |
*/ |
6065 |
|
6066 |
/* Disable finger detection pressure threshold */ |
6067 |
sc->syninfo.min_pressure = 1; |
6068 |
|
6069 |
/* Use full area of touchpad */ |
6070 |
sc->syninfo.margin_top = 0; |
6071 |
sc->syninfo.margin_right = 0; |
6072 |
sc->syninfo.margin_bottom = 0; |
6073 |
sc->syninfo.margin_left = 0; |
6074 |
/* Disable noisy area */ |
6075 |
sc->syninfo.na_top = 0; |
6076 |
sc->syninfo.na_right = 0; |
6077 |
sc->syninfo.na_bottom = 0; |
6078 |
sc->syninfo.na_left = 0; |
6079 |
|
6080 |
/* tune divisors and movement lengths */ |
6081 |
sc->syninfo.weight_len_squared = 200; |
6082 |
sc->syninfo.div_min = 3; |
6083 |
sc->syninfo.div_max = 6; |
6084 |
sc->syninfo.div_max_na = 10; |
6085 |
sc->syninfo.div_len = 30; |
6086 |
sc->syninfo.tap_max_delta = 25; |
6087 |
|
6088 |
/* disable virtual scrolling areas and tune its divisors */ |
6089 |
sc->syninfo.vscroll_hor_area = 0; |
6090 |
sc->syninfo.vscroll_ver_area = 0; |
6091 |
sc->syninfo.vscroll_min_delta = 15; |
6092 |
sc->syninfo.vscroll_div_min = 30; |
6093 |
sc->syninfo.vscroll_div_max = 50; |
6094 |
} |
6095 |
|
6096 |
return; |
6097 |
} |
6098 |
|
6099 |
static int |
6100 |
enable_elantech(struct psm_softc *sc, enum probearg arg) |
6101 |
{ |
6102 |
static const int ic2hw[] = |
6103 |
/*IC: 0 1 2 3 4 5 6 7 8 9 a b c d e f */ |
6104 |
{ 0, 0, 2, 0, 2, 3, 4, 4, 4, 4, 4, 0, 0, 4, 4, 0 }; |
6105 |
elantechhw_t elanhw; |
6106 |
int icversion, hwversion, dptracex, dptracey, id, resp[3]; |
6107 |
KBDC kbdc = sc->kbdc; |
6108 |
|
6109 |
VLOG(3, (LOG_DEBUG, "elantech: BEGIN init\n")); |
6110 |
|
6111 |
set_mouse_scaling(kbdc, 1); |
6112 |
set_mouse_scaling(kbdc, 1); |
6113 |
set_mouse_scaling(kbdc, 1); |
6114 |
if (get_mouse_status(kbdc, resp, 0, 3) != 3) |
6115 |
return (FALSE); |
6116 |
|
6117 |
if (!ELANTECH_MAGIC(resp)) |
6118 |
return (FALSE); |
6119 |
|
6120 |
/* Identify the Touchpad version. */ |
6121 |
if (elantech_cmd(kbdc, 2, ELANTECH_FW_VERSION, resp)) |
6122 |
return (FALSE); |
6123 |
|
6124 |
bzero(&elanhw, sizeof(elanhw)); |
6125 |
|
6126 |
elanhw.fwversion = (resp[0] << 16) | (resp[1] << 8) | resp[2]; |
6127 |
icversion = resp[0] & 0x0f; |
6128 |
hwversion = ic2hw[icversion]; |
6129 |
|
6130 |
if (verbose >= 2) |
6131 |
printf("Elantech touchpad hardware v.%d firmware v.0x%06x\n", |
6132 |
hwversion, elanhw.fwversion); |
6133 |
|
6134 |
if (ELANTECH_HW_IS_V1(elanhw.fwversion)) { |
6135 |
printf (" Unsupported touchpad hardware (v1)\n"); |
6136 |
return (FALSE); |
6137 |
} |
6138 |
if (hwversion == 0) { |
6139 |
printf (" Unknown touchpad hardware (firmware v.0x%06x)\n", |
6140 |
elanhw.fwversion); |
6141 |
return (FALSE); |
6142 |
} |
6143 |
|
6144 |
/* Get the Touchpad model information. */ |
6145 |
elanhw.hwversion = hwversion; |
6146 |
elanhw.isclickpad = (resp[1] & 0x10) != 0; |
6147 |
elanhw.hascrc = (resp[1] & 0x40) != 0; |
6148 |
elanhw.haspressure = elanhw.fwversion >= 0x020800; |
6149 |
|
6150 |
/* Read the capability bits. */ |
6151 |
if (elantech_cmd(kbdc, hwversion, ELANTECH_CAPABILITIES, resp) != 0) { |
6152 |
printf(" Failed to read capability bits\n"); |
6153 |
return (FALSE); |
6154 |
} |
6155 |
|
6156 |
elanhw.ntracesx = resp[1] - 1; |
6157 |
elanhw.ntracesy = resp[2] - 1; |
6158 |
elanhw.hastrackpad = (resp[0] & 0x80) != 0; |
6159 |
|
6160 |
/* Get the touchpad resolution */ |
6161 |
switch (hwversion) { |
6162 |
case 2: |
6163 |
elanhw.dpix = elanhw.dpiy = 400; |
6164 |
break; |
6165 |
case 4: |
6166 |
if (elantech_cmd(kbdc, hwversion, ELANTECH_RESOLUTION, resp) |
6167 |
== 0) { |
6168 |
elanhw.dpix = (resp[1] & 0x0f) * 10 + 790; |
6169 |
elanhw.dpiy = ((resp[1] & 0xf0) >> 4) * 10 + 790; |
6170 |
break; |
6171 |
} |
6172 |
/* FALLTHROUGH */ |
6173 |
case 3: |
6174 |
elanhw.dpix = elanhw.dpiy = 800; |
6175 |
break; |
6176 |
} |
6177 |
|
6178 |
if (!elantech_support) |
6179 |
return (FALSE); |
6180 |
|
6181 |
if (elantech_init(kbdc, &elanhw)) { |
6182 |
printf("couldn't initialize elantech touchpad\n"); |
6183 |
return (FALSE); |
6184 |
} |
6185 |
|
6186 |
/* |
6187 |
* Get the touchpad reporting range. |
6188 |
* On HW v.3 touchpads it should be done after switching hardware |
6189 |
* to real resolution mode (by setting bit 3 of reg10) |
6190 |
*/ |
6191 |
if (elantech_cmd(kbdc, hwversion, ELANTECH_FW_ID, resp) != 0) { |
6192 |
printf(" Failed to read touchpad size\n"); |
6193 |
elanhw.sizex = 10000; /* Arbitrary high values to */ |
6194 |
elanhw.sizey = 10000; /* prevent clipping in smoother */ |
6195 |
} else if (hwversion == 2) { |
6196 |
dptracex = dptracey = 64; |
6197 |
if ((elanhw.fwversion >> 16) == 0x14 && (resp[1] & 0x10) && |
6198 |
!elantech_cmd(kbdc, hwversion, ELANTECH_SAMPLE, resp)) { |
6199 |
dptracex = resp[1] / 2; |
6200 |
dptracey = resp[2] / 2; |
6201 |
} |
6202 |
elanhw.sizex = (elanhw.ntracesx - 1) * dptracex; |
6203 |
elanhw.sizey = (elanhw.ntracesy - 1) * dptracey; |
6204 |
} else { |
6205 |
elanhw.sizex = (resp[0] & 0x0f) << 8 | resp[1]; |
6206 |
elanhw.sizey = (resp[0] & 0xf0) << 4 | resp[2]; |
6207 |
} |
6208 |
|
6209 |
if (verbose >= 2) { |
6210 |
printf(" Model information:\n"); |
6211 |
printf(" MaxX: %d\n", elanhw.sizex); |
6212 |
printf(" MaxY: %d\n", elanhw.sizey); |
6213 |
printf(" DpiX: %d\n", elanhw.dpix); |
6214 |
printf(" DpiY: %d\n", elanhw.dpiy); |
6215 |
printf(" TracesX: %d\n", elanhw.ntracesx); |
6216 |
printf(" TracesY: %d\n", elanhw.ntracesy); |
6217 |
printf(" Clickpad: %d\n", elanhw.isclickpad); |
6218 |
printf(" Trackpad: %d\n", elanhw.hastrackpad); |
6219 |
printf(" CRC: %d\n", elanhw.hascrc); |
6220 |
printf(" Pressure: %d\n", elanhw.haspressure); |
6221 |
} |
6222 |
|
6223 |
VLOG(3, (LOG_DEBUG, "elantech: END init\n")); |
6224 |
|
6225 |
if (arg == PROBE) { |
6226 |
sc->elanhw = elanhw; |
6227 |
sc->hw.buttons = 3; |
6228 |
|
6229 |
/* Initialize synaptics movement smoother */ |
6230 |
elantech_init_synaptics(sc); |
6231 |
|
6232 |
for (id = 0; id < PSM_GESTURE_FINGERS; id++) |
6233 |
PSM_FINGER_RESET(sc->elanaction.fingers[id]); |
6234 |
|
6235 |
if (elanhw.hascrc) |
6236 |
sc->config |= PSM_CONFIG_NOCHECKSYNC; |
6237 |
} |
6238 |
|
6239 |
return (TRUE); |
6240 |
} |
6241 |
|
5022 |
/* |
6242 |
/* |
5023 |
* Return true if 'now' is earlier than (start + (secs.usecs)). |
6243 |
* Return true if 'now' is earlier than (start + (secs.usecs)). |
5024 |
* Now may be NULL and the function will fetch the current time from |
6244 |
* Now may be NULL and the function will fetch the current time from |