Thu Apr 18 17:35:53 2024 UTC (21d)
Renamed border/boundary variables to better describe their use.
Fix edge default values, factor out percentage calculation for more consistent
values. Use device_printf/DPRINTF to show errors instead of aprint variants.
Print raw input for debugging.

Correct capability parsing. Old devices were probed with nonexistent
commands and then used undefined boundary values that made them unusuable.

Fixes PR 57874.


(mlelstv)
diff -r1.82 -r1.83 src/sys/dev/pckbport/synaptics.c

cvs diff -r1.82 -r1.83 src/sys/dev/pckbport/synaptics.c (expand / switch to unified diff)

--- src/sys/dev/pckbport/synaptics.c 2023/09/05 05:55:12 1.82
+++ src/sys/dev/pckbport/synaptics.c 2024/04/18 17:35:53 1.83
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: synaptics.c,v 1.82 2023/09/05 05:55:12 mrg Exp $ */ 1/* $NetBSD: synaptics.c,v 1.83 2024/04/18 17:35:53 mlelstv Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005, Steve C. Woodford 4 * Copyright (c) 2005, Steve C. Woodford
5 * Copyright (c) 2004, Ales Krenek 5 * Copyright (c) 2004, Ales Krenek
6 * Copyright (c) 2004, Kentaro A. Kurahone 6 * Copyright (c) 2004, Kentaro A. Kurahone
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 12 *
13 * * Redistributions of source code must retain the above copyright 13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -38,27 +38,27 @@ @@ -38,27 +38,27 @@
38/* 38/*
39 * TODO: 39 * TODO:
40 * - Make the sysctl values per-instance instead of global. 40 * - Make the sysctl values per-instance instead of global.
41 * - Consider setting initial scaling factors at runtime according 41 * - Consider setting initial scaling factors at runtime according
42 * to the values returned by the 'Read Resolutions' command. 42 * to the values returned by the 'Read Resolutions' command.
43 * - Support the serial protocol (we only support PS/2 for now) 43 * - Support the serial protocol (we only support PS/2 for now)
44 * - Support auto-repeat for up/down button Z-axis emulation. 44 * - Support auto-repeat for up/down button Z-axis emulation.
45 * - Maybe add some more gestures (can we use Palm support somehow?) 45 * - Maybe add some more gestures (can we use Palm support somehow?)
46 */ 46 */
47 47
48#include "opt_pms.h" 48#include "opt_pms.h"
49 49
50#include <sys/cdefs.h> 50#include <sys/cdefs.h>
51__KERNEL_RCSID(0, "$NetBSD: synaptics.c,v 1.82 2023/09/05 05:55:12 mrg Exp $"); 51__KERNEL_RCSID(0, "$NetBSD: synaptics.c,v 1.83 2024/04/18 17:35:53 mlelstv Exp $");
52 52
53#include <sys/param.h> 53#include <sys/param.h>
54#include <sys/systm.h> 54#include <sys/systm.h>
55#include <sys/device.h> 55#include <sys/device.h>
56#include <sys/ioctl.h> 56#include <sys/ioctl.h>
57#include <sys/sysctl.h> 57#include <sys/sysctl.h>
58#include <sys/kernel.h> 58#include <sys/kernel.h>
59#include <sys/proc.h> 59#include <sys/proc.h>
60 60
61#include <sys/bus.h> 61#include <sys/bus.h>
62 62
63#include <dev/pckbport/pckbportvar.h> 63#include <dev/pckbport/pckbportvar.h>
64 64
@@ -102,30 +102,30 @@ static int pms_sysctl_synaptics_verify(S @@ -102,30 +102,30 @@ static int pms_sysctl_synaptics_verify(S
102 102
103/* Controlled by sysctl. */ 103/* Controlled by sysctl. */
104static int synaptics_up_down_emul = 3; 104static int synaptics_up_down_emul = 3;
105static int synaptics_up_down_motion_delta = 1; 105static int synaptics_up_down_motion_delta = 1;
106static int synaptics_gesture_move = 200; 106static int synaptics_gesture_move = 200;
107static int synaptics_gesture_length = 20; 107static int synaptics_gesture_length = 20;
108static int synaptics_edge_left = SYNAPTICS_EDGE_LEFT; 108static int synaptics_edge_left = SYNAPTICS_EDGE_LEFT;
109static int synaptics_edge_right = SYNAPTICS_EDGE_RIGHT; 109static int synaptics_edge_right = SYNAPTICS_EDGE_RIGHT;
110static int synaptics_edge_top = SYNAPTICS_EDGE_TOP; 110static int synaptics_edge_top = SYNAPTICS_EDGE_TOP;
111static int synaptics_edge_bottom = SYNAPTICS_EDGE_BOTTOM; 111static int synaptics_edge_bottom = SYNAPTICS_EDGE_BOTTOM;
112static int synaptics_edge_motion_delta = 32; 112static int synaptics_edge_motion_delta = 32;
113static u_int synaptics_finger_high = SYNAPTICS_FINGER_LIGHT + 5; 113static u_int synaptics_finger_high = SYNAPTICS_FINGER_LIGHT + 5;
114static u_int synaptics_finger_low = SYNAPTICS_FINGER_LIGHT - 10; 114static u_int synaptics_finger_low = SYNAPTICS_FINGER_LIGHT - 10;
115static int synaptics_horiz_pct = 0; 115static int synaptics_hscroll_pct = 0;
116static int synaptics_vert_pct = 0; 116static int synaptics_vscroll_pct = 0;
117static int synaptics_button_pct = 30; 117static int synaptics_button_pct = 0;
118static int synaptics_button_boundary; 118static int synaptics_button_boundary = SYNAPTICS_EDGE_BOTTOM;
119static int synaptics_button2; 119static int synaptics_button2;
120static int synaptics_button3; 120static int synaptics_button3;
121static int synaptics_two_fingers_emul = 0; 121static int synaptics_two_fingers_emul = 0;
122static int synaptics_scale_x = 8; 122static int synaptics_scale_x = 8;
123static int synaptics_scale_y = 8; 123static int synaptics_scale_y = 8;
124static int synaptics_scale_z = 32; 124static int synaptics_scale_z = 32;
125static int synaptics_max_speed_x = 32; 125static int synaptics_max_speed_x = 32;
126static int synaptics_max_speed_y = 32; 126static int synaptics_max_speed_y = 32;
127static int synaptics_max_speed_z = 2; 127static int synaptics_max_speed_z = 2;
128static int synaptics_movement_threshold = 4; 128static int synaptics_movement_threshold = 4;
129static int synaptics_movement_enable = 1; 129static int synaptics_movement_enable = 1;
130static int synaptics_button_region_movement = 1; 130static int synaptics_button_region_movement = 1;
131static bool synaptics_aux_mid_button_scroll = TRUE; 131static bool synaptics_aux_mid_button_scroll = TRUE;
@@ -156,82 +156,85 @@ static int synaptics_edge_motion_delta_n @@ -156,82 +156,85 @@ static int synaptics_edge_motion_delta_n
156static int synaptics_finger_high_nodenum; 156static int synaptics_finger_high_nodenum;
157static int synaptics_finger_low_nodenum; 157static int synaptics_finger_low_nodenum;
158static int synaptics_two_fingers_emul_nodenum; 158static int synaptics_two_fingers_emul_nodenum;
159static int synaptics_scale_x_nodenum; 159static int synaptics_scale_x_nodenum;
160static int synaptics_scale_y_nodenum; 160static int synaptics_scale_y_nodenum;
161static int synaptics_scale_z_nodenum; 161static int synaptics_scale_z_nodenum;
162static int synaptics_max_speed_x_nodenum; 162static int synaptics_max_speed_x_nodenum;
163static int synaptics_max_speed_y_nodenum; 163static int synaptics_max_speed_y_nodenum;
164static int synaptics_max_speed_z_nodenum; 164static int synaptics_max_speed_z_nodenum;
165static int synaptics_movement_threshold_nodenum; 165static int synaptics_movement_threshold_nodenum;
166static int synaptics_movement_enable_nodenum; 166static int synaptics_movement_enable_nodenum;
167static int synaptics_button_region_movement_nodenum; 167static int synaptics_button_region_movement_nodenum;
168static int synaptics_aux_mid_button_scroll_nodenum; 168static int synaptics_aux_mid_button_scroll_nodenum;
169static int synaptics_horiz_pct_nodenum; 169static int synaptics_hscroll_pct_nodenum;
170static int synaptics_vert_pct_nodenum; 170static int synaptics_vscroll_pct_nodenum;
171static int synaptics_button_pct_nodenum; 171static int synaptics_button_pct_nodenum;
172 172
173/* 173/*
174 * copy of edges so we can recalculate edge limit if there is  174 * copy of edges so we can recalculate edge limit if there is
175 * vertical scroll region 175 * vertical scroll region
176 */ 176 */
177static int synaptics_actual_edge_right; 177static int synaptics_true_edge_right;
178static int synaptics_actual_edge_bottom; 178static int synaptics_true_edge_bottom;
179 179
180static int synaptics_old_vert_pct = 0; 180/*
181static int synaptics_old_horiz_pct = 0; 181 * invalid old values, recalculate everything
182static int synaptics_old_button_pct = 0; 182 */
183static int synaptics_old_button_boundary = SYNAPTICS_EDGE_BOTTOM; 183static int synaptics_old_vscroll_pct = -1;
184static int synaptics_old_horiz_edge = SYNAPTICS_EDGE_BOTTOM; 184static int synaptics_old_hscroll_pct = -1;
185static int synaptics_old_vert_edge = SYNAPTICS_EDGE_RIGHT; 185static int synaptics_old_button_pct = -1;
 186static int synaptics_old_button_boundary = -1;
 187static int synaptics_old_edge_right = -1;
 188static int synaptics_old_edge_bottom = -1;
186 189
187/* 190/*
188 * This holds the processed packet data, it is global because multiple 191 * This holds the processed packet data, it is global because multiple
189 * packets from the trackpad may be processed when handling multiple 192 * packets from the trackpad may be processed when handling multiple
190 * fingers on the trackpad to gather all the data. 193 * fingers on the trackpad to gather all the data.
191 */ 194 */
192static struct synaptics_packet packet; 195static struct synaptics_packet packet;
193 196
194static int 197static int
195synaptics_poll_cmd(struct pms_softc *psc, ...) 198synaptics_poll_cmd(struct pms_softc *psc, ...)
196{ 199{
197 u_char cmd[4]; 200 u_char cmd[4];
198 size_t i; 201 size_t i;
199 va_list ap; 202 va_list ap;
200 203
201 va_start(ap, psc); 204 va_start(ap, psc);
202 205
203 for (i = 0; i < __arraycount(cmd); i++) 206 for (i = 0; i < __arraycount(cmd); i++)
204 if ((cmd[i] = (u_char)va_arg(ap, int)) == 0) 207 if ((cmd[i] = (u_char)va_arg(ap, int)) == 0)
205 break; 208 break;
206 va_end(ap); 209 va_end(ap);
207 210
208 int res = pckbport_poll_cmd(psc->sc_kbctag, psc->sc_kbcslot, cmd, i, 0, 211 int res = pckbport_poll_cmd(psc->sc_kbctag, psc->sc_kbcslot, cmd, i, 0,
209 NULL, 0); 212 NULL, 0);
210 if (res) 213 if (res)
211 aprint_error_dev(psc->sc_dev, "command error %#x\n", cmd[0]); 214 device_printf(psc->sc_dev, "command error %#x\n", cmd[0]);
212 return res; 215 return res;
213} 216}
214 217
215static int 218static int
216synaptics_poll_reset(struct pms_softc *psc) 219synaptics_poll_reset(struct pms_softc *psc)
217{ 220{
218 u_char resp[2]; 221 u_char resp[2];
219 int res; 222 int res;
220 223
221 u_char cmd[1] = { PMS_RESET }; 224 u_char cmd[1] = { PMS_RESET };
222 res = pckbport_poll_cmd(psc->sc_kbctag, psc->sc_kbcslot, cmd, 1, 2, 225 res = pckbport_poll_cmd(psc->sc_kbctag, psc->sc_kbcslot, cmd, 1, 2,
223 resp, 1); 226 resp, 1);
224 aprint_debug_dev(psc->sc_dev, "reset %d 0x%02x 0x%02x\n", 227 DPRINTF(10, &psc->u.synaptics, "reset %d 0x%02x 0x%02x\n",
225 res, resp[0], resp[1]); 228 res, resp[0], resp[1]);
226 return res; 229 return res;
227} 230}
228 231
229static int 232static int
230synaptics_special_read(struct pms_softc *psc, u_char slice, u_char resp[3]) 233synaptics_special_read(struct pms_softc *psc, u_char slice, u_char resp[3])
231{ 234{
232 u_char cmd[1] = { PMS_SEND_DEV_STATUS }; 235 u_char cmd[1] = { PMS_SEND_DEV_STATUS };
233 int res = pms_sliced_command(psc->sc_kbctag, psc->sc_kbcslot, slice); 236 int res = pms_sliced_command(psc->sc_kbctag, psc->sc_kbcslot, slice);
234 237
235 return res | pckbport_poll_cmd(psc->sc_kbctag, psc->sc_kbcslot, 238 return res | pckbport_poll_cmd(psc->sc_kbctag, psc->sc_kbcslot,
236 cmd, 1, 3, resp, 0); 239 cmd, 1, 3, resp, 0);
237} 240}
@@ -241,167 +244,177 @@ synaptics_special_write(struct pms_softc @@ -241,167 +244,177 @@ synaptics_special_write(struct pms_softc
241{ 244{
242 int res = pms_sliced_command(psc->sc_kbctag, psc->sc_kbcslot, arg); 245 int res = pms_sliced_command(psc->sc_kbctag, psc->sc_kbcslot, arg);
243 if (res) 246 if (res)
244 return res; 247 return res;
245 248
246 u_char cmd[2]; 249 u_char cmd[2];
247 cmd[0] = PMS_SET_SAMPLE; 250 cmd[0] = PMS_SET_SAMPLE;
248 cmd[1] = command; 251 cmd[1] = command;
249 res = pckbport_poll_cmd(psc->sc_kbctag, psc->sc_kbcslot, 252 res = pckbport_poll_cmd(psc->sc_kbctag, psc->sc_kbcslot,
250 cmd, 2, 0, NULL, 0); 253 cmd, 2, 0, NULL, 0);
251 return res; 254 return res;
252} 255}
253 256
 257static int
 258synaptics_value(int pct, int low, int high)
 259{
 260 return low + pct * (high - low) / 100UL;
 261}
 262
 263static int
 264synaptics_percentage(int val, int low, int high)
 265{
 266 return ((val - low) * 100UL + high - low - 1) / (high - low);
 267}
 268
254static void 269static void
255pms_synaptics_set_boundaries(void) 270pms_synaptics_set_boundaries(void)
256{ 271{
257 if (synaptics_vert_pct != synaptics_old_vert_pct ) { 272 if (synaptics_vscroll_pct != synaptics_old_vscroll_pct ) {
258 synaptics_edge_right = synaptics_actual_edge_right - 273 synaptics_edge_right = synaptics_value(
259 ((unsigned long) synaptics_vert_pct * 274 100 - synaptics_vscroll_pct,
260 (synaptics_actual_edge_right - synaptics_edge_left)) / 100; 275 synaptics_edge_left,
261 synaptics_old_vert_pct = synaptics_vert_pct; 276 synaptics_true_edge_right);
262 synaptics_old_vert_edge = synaptics_edge_right; 277 synaptics_old_vscroll_pct = synaptics_vscroll_pct;
263 } 278 }
264 279
265 if (synaptics_edge_right != synaptics_old_vert_edge) { 280 if (synaptics_edge_right != synaptics_old_edge_right) {
266 if (synaptics_edge_right >= synaptics_actual_edge_right) { 281 if (synaptics_edge_right >= synaptics_true_edge_right) {
267 synaptics_vert_pct = 0; 282 synaptics_vscroll_pct = 0;
268 synaptics_edge_right = synaptics_actual_edge_right; 283 synaptics_edge_right = synaptics_true_edge_right;
269 } else { 284 } else {
270 synaptics_vert_pct = 100 - 285 synaptics_vscroll_pct = 100 - synaptics_percentage(
271 ((unsigned long) 100 * synaptics_edge_right) / 286 synaptics_edge_right,
272 (synaptics_actual_edge_right - synaptics_edge_left); 287 synaptics_edge_left,
273 } 288 synaptics_true_edge_right);
274 synaptics_old_vert_pct = synaptics_vert_pct; 289 }
275 synaptics_old_vert_edge = synaptics_edge_right; 290 synaptics_old_vscroll_pct = synaptics_vscroll_pct;
276 } 291 synaptics_old_edge_right = synaptics_edge_right;
277 292 }
278 if (synaptics_horiz_pct != synaptics_old_horiz_pct ) { 293
279 synaptics_edge_bottom = synaptics_actual_edge_bottom + 294 if (synaptics_hscroll_pct != synaptics_old_hscroll_pct ) {
280 ((unsigned long) synaptics_horiz_pct * 295 synaptics_edge_bottom = synaptics_value(
281 (synaptics_edge_top - synaptics_actual_edge_bottom)) / 100; 296 synaptics_hscroll_pct,
282 synaptics_old_horiz_pct = synaptics_horiz_pct; 297 synaptics_true_edge_bottom,
283 synaptics_old_horiz_edge = synaptics_edge_bottom; 298 synaptics_edge_top);
284 } 299 synaptics_old_hscroll_pct = synaptics_hscroll_pct;
285 300 }
286 if (synaptics_edge_bottom != synaptics_old_horiz_edge) { 301
287 if (synaptics_edge_bottom <= synaptics_actual_edge_bottom) { 302 if (synaptics_edge_bottom != synaptics_old_edge_bottom) {
288 synaptics_vert_pct = 0; 303 if (synaptics_edge_bottom <= synaptics_true_edge_bottom) {
289 synaptics_edge_bottom = synaptics_actual_edge_bottom; 304 synaptics_hscroll_pct = 0;
 305 synaptics_edge_bottom = synaptics_true_edge_bottom;
290 } else { 306 } else {
291 synaptics_horiz_pct = 100 - 307 synaptics_hscroll_pct = synaptics_percentage(
292 ((unsigned long) 100 * synaptics_edge_bottom) / 308 synaptics_edge_bottom,
293 (synaptics_edge_top - synaptics_actual_edge_bottom); 309 synaptics_true_edge_bottom,
 310 synaptics_edge_top);
294 } 311 }
295 synaptics_old_horiz_edge = synaptics_edge_bottom; 312 synaptics_old_hscroll_pct = synaptics_hscroll_pct;
 313 synaptics_old_edge_bottom = synaptics_edge_bottom;
296 } 314 }
297 315
298 if (synaptics_button_pct != synaptics_old_button_pct) { 316 if (synaptics_button_pct != synaptics_old_button_pct) {
 317 synaptics_button_boundary = synaptics_value(
 318 synaptics_button_pct,
 319 synaptics_edge_bottom,
 320 synaptics_edge_top);
299 synaptics_old_button_pct = synaptics_button_pct; 321 synaptics_old_button_pct = synaptics_button_pct;
300 } 322 }
301 323
302 if (synaptics_button_boundary != synaptics_old_button_boundary) { 324 if (synaptics_button_boundary != synaptics_old_button_boundary) {
303 if (synaptics_button_boundary <= synaptics_edge_bottom) { 325 if (synaptics_button_boundary <= synaptics_edge_bottom) {
304 synaptics_button_pct = 0; 326 synaptics_button_pct = 0;
 327 synaptics_button_boundary = synaptics_edge_bottom;
305 } else if (synaptics_button_boundary >= synaptics_edge_top) { 328 } else if (synaptics_button_boundary >= synaptics_edge_top) {
306 synaptics_button_pct = 100; 329 synaptics_button_pct = 100;
 330 synaptics_button_boundary = synaptics_edge_top;
307 } else { 331 } else {
308 synaptics_button_pct = 332 synaptics_button_pct = synaptics_percentage(
309 (synaptics_button_boundary - synaptics_edge_bottom) 333 synaptics_button_boundary,
310 * 100 334 synaptics_edge_bottom,
311 / (synaptics_edge_top - synaptics_edge_bottom); 335 synaptics_edge_top);
312 } 336 }
313 synaptics_old_button_pct = synaptics_button_pct; 337 synaptics_old_button_pct = synaptics_button_pct;
 338 synaptics_old_button_boundary = synaptics_button_boundary;
314 } 339 }
315 340
316 /* 
317 * calculate the button boundary 
318 */ 
319 if (synaptics_edge_top > synaptics_edge_bottom) { 
320 synaptics_button_boundary = synaptics_edge_bottom +  
321 ((unsigned long) synaptics_button_pct *  
322 (synaptics_edge_top - synaptics_edge_bottom)) / 100; 
323 } else { 
324 synaptics_button_boundary = synaptics_edge_bottom; 
325 } 
326 synaptics_old_button_boundary = synaptics_button_boundary; 
327 
328 synaptics_button2 = synaptics_edge_left + 341 synaptics_button2 = synaptics_edge_left +
329 (synaptics_edge_right - synaptics_edge_left) / 3; 342 (synaptics_edge_right - synaptics_edge_left) / 3;
330 synaptics_button3 = synaptics_edge_left + 343 synaptics_button3 = synaptics_edge_left +
331 2 * (synaptics_edge_right - synaptics_edge_left) / 3; 344 2 * (synaptics_edge_right - synaptics_edge_left) / 3;
332 345
333} 346}
334 347
335static void 348static void
336pms_synaptics_probe_extended(struct pms_softc *psc) 349pms_synaptics_probe_extended(struct pms_softc *psc)
337{ 350{
338 struct synaptics_softc *sc = &psc->u.synaptics; 351 struct synaptics_softc *sc = &psc->u.synaptics;
339 u_char resp[3]; 352 u_char resp[3];
340 int res; 353 int res;
341 354
342 aprint_debug_dev(psc->sc_dev, 355 DPRINTF(10, sc,
343 "synaptics_probe: Capabilities 0x%04x.\n", sc->caps); 356 "synaptics_probe: Capabilities 0x%04x.\n", sc->caps);
344 if (sc->caps & SYNAPTICS_CAP_PASSTHROUGH) 357 if (sc->caps & SYNAPTICS_CAP_PASSTHROUGH)
345 sc->flags |= SYN_FLAG_HAS_PASSTHROUGH; 358 sc->flags |= SYN_FLAG_HAS_PASSTHROUGH;
346 359
347 if (sc->caps & SYNAPTICS_CAP_PALMDETECT) 360 if (sc->caps & SYNAPTICS_CAP_PALMDETECT)
348 sc->flags |= SYN_FLAG_HAS_PALM_DETECT; 361 sc->flags |= SYN_FLAG_HAS_PALM_DETECT;
349 362
350 if (sc->caps & SYNAPTICS_CAP_MULTIDETECT) 363 if (sc->caps & SYNAPTICS_CAP_MULTIDETECT)
351 sc->flags |= SYN_FLAG_HAS_MULTI_FINGER; 364 sc->flags |= SYN_FLAG_HAS_MULTI_FINGER;
352 365
353 if (sc->caps & SYNAPTICS_CAP_MULTIFINGERREPORT) 366 if (sc->caps & SYNAPTICS_CAP_MULTIFINGERREPORT)
354 sc->flags |= SYN_FLAG_HAS_MULTI_FINGER_REPORT; 367 sc->flags |= SYN_FLAG_HAS_MULTI_FINGER_REPORT;
355 368
356 /* Ask about extra buttons to detect up/down. */ 369 /* Ask about extra buttons to detect up/down. */
357 if (((sc->caps & SYNAPTICS_CAP_EXTNUM) + 0x08) 370 if ((__SHIFTOUT(sc->caps, SYNAPTICS_CAP_EXTNUM) + 0x08)
358 >= SYNAPTICS_EXTENDED_QUERY) 371 >= SYNAPTICS_EXTENDED_QUERY)
359 { 372 {
360 res = synaptics_special_read(psc, SYNAPTICS_EXTENDED_QUERY, resp); 373 res = synaptics_special_read(psc, SYNAPTICS_EXTENDED_QUERY, resp);
361 if (res == 0) { 374 if (res == 0) {
362 sc->num_buttons = (resp[1] >> 4); 375 sc->num_buttons = (resp[1] >> 4);
363 if (sc->num_buttons > 0) 376 if (sc->num_buttons > 0)
364 sc->button_mask = sc->button_mask << 377 sc->button_mask = sc->button_mask <<
365 ((sc->num_buttons + 1) >> 1); 378 ((sc->num_buttons + 1) >> 1);
366 379
367 aprint_debug_dev(psc->sc_dev, 380 DPRINTF(10, sc,
368 "%s: Extended Buttons: %d.\n", __func__, 381 "Extended Buttons: %d.\n",
369 sc->num_buttons); 382 sc->num_buttons);
370 383
371 aprint_debug_dev(psc->sc_dev, "%s: Extended " 384 DPRINTF(10, sc, "Extended "
372 "Capabilities: 0x%02x 0x%02x 0x%02x.\n", __func__, 385 "Capabilities: 0x%02x 0x%02x 0x%02x.\n",
373 resp[0], resp[1], resp[2]); 386 resp[0], resp[1], resp[2]);
374 if (sc->num_buttons >= 2) { 387 if (sc->num_buttons >= 2) {
375 /* Yes. */ 388 /* Yes. */
376 sc->flags |= SYN_FLAG_HAS_UP_DOWN_BUTTONS; 389 sc->flags |= SYN_FLAG_HAS_UP_DOWN_BUTTONS;
377 } 390 }
378 if (resp[0] & 0x1) { 391 if (resp[0] & 0x1) {
379 /* Vertical scroll area */ 392 /* Vertical scroll area */
380 sc->flags |= SYN_FLAG_HAS_VERTICAL_SCROLL; 393 sc->flags |= SYN_FLAG_HAS_VERTICAL_SCROLL;
381 } 394 }
382 if (resp[0] & 0x2) { 395 if (resp[0] & 0x2) {
383 /* Horizontal scroll area */ 396 /* Horizontal scroll area */
384 sc->flags |= SYN_FLAG_HAS_HORIZONTAL_SCROLL; 397 sc->flags |= SYN_FLAG_HAS_HORIZONTAL_SCROLL;
385 } 398 }
386 if (resp[0] & 0x4) { 399 if (resp[0] & 0x4) {
387 /* Extended W-Mode */ 400 /* Extended W-Mode */
388 sc->flags |= SYN_FLAG_HAS_EXTENDED_WMODE; 401 sc->flags |= SYN_FLAG_HAS_EXTENDED_WMODE;
389 } 402 }
390 } 403 }
391 } 404 }
392 405
393 /* Ask about click pad */ 406 /* Ask about click pad */
394 if (((sc->caps & SYNAPTICS_CAP_EXTNUM) + 0x08) >= 407 if ((__SHIFTOUT(sc->caps, SYNAPTICS_CAP_EXTNUM) + 0x08) >=
395 SYNAPTICS_CONTINUED_CAPABILITIES) 408 SYNAPTICS_CONTINUED_CAPABILITIES)
396 { 409 {
397 res = synaptics_special_read(psc, 410 res = synaptics_special_read(psc,
398 SYNAPTICS_CONTINUED_CAPABILITIES, resp); 411 SYNAPTICS_CONTINUED_CAPABILITIES, resp);
399 412
400/* 413/*
401 * The following describes response for the 414 * The following describes response for the
402 * SYNAPTICS_CONTINUED_CAPABILITIES query. 415 * SYNAPTICS_CONTINUED_CAPABILITIES query.
403 * 416 *
404 * byte mask name meaning 417 * byte mask name meaning
405 * ---- ---- ------- ------------ 418 * ---- ---- ------- ------------
406 * 0 0x01 adjustable threshold capacitive button sensitivity 419 * 0 0x01 adjustable threshold capacitive button sensitivity
407 * can be adjusted 420 * can be adjusted
@@ -418,28 +431,28 @@ pms_synaptics_probe_extended(struct pms_ @@ -418,28 +431,28 @@ pms_synaptics_probe_extended(struct pms_
418 * ala multimedia control bar 431 * ala multimedia control bar
419 * 1 0x04 reduced filtering firmware does less filtering on 432 * 1 0x04 reduced filtering firmware does less filtering on
420 * position data, driver should watch 433 * position data, driver should watch
421 * for noise. 434 * for noise.
422 * 1 0x08 image sensor image sensor tracks 5 fingers, but only 435 * 1 0x08 image sensor image sensor tracks 5 fingers, but only
423 * reports 2. 436 * reports 2.
424 * 1 0x10 uniform clickpad whole clickpad moves instead of being 437 * 1 0x10 uniform clickpad whole clickpad moves instead of being
425 * hinged at the top. 438 * hinged at the top.
426 * 1 0x20 report min query 0x0f gives min coord reported 439 * 1 0x20 report min query 0x0f gives min coord reported
427 */ 440 */
428 if (res == 0) { 441 if (res == 0) {
429 uint val = SYN_CCAP_VALUE(resp); 442 uint val = SYN_CCAP_VALUE(resp);
430 443
431 aprint_debug_dev(psc->sc_dev, "%s: Continued " 444 DPRINTF(10, sc, "Continued "
432 "Capabilities 0x%02x 0x%02x 0x%02x.\n", __func__, 445 "Capabilities 0x%02x 0x%02x 0x%02x.\n",
433 resp[0], resp[1], resp[2]); 446 resp[0], resp[1], resp[2]);
434 switch (SYN_CCAP_CLICKPAD_TYPE(val)) { 447 switch (SYN_CCAP_CLICKPAD_TYPE(val)) {
435 case 0: /* not a clickpad */ 448 case 0: /* not a clickpad */
436 break; 449 break;
437 case 1: 450 case 1:
438 sc->flags |= SYN_FLAG_HAS_ONE_BUTTON_CLICKPAD; 451 sc->flags |= SYN_FLAG_HAS_ONE_BUTTON_CLICKPAD;
439 break; 452 break;
440 case 2: 453 case 2:
441 sc->flags |= SYN_FLAG_HAS_TWO_BUTTON_CLICKPAD; 454 sc->flags |= SYN_FLAG_HAS_TWO_BUTTON_CLICKPAD;
442 break; 455 break;
443 case 3: /* reserved */ 456 case 3: /* reserved */
444 default: 457 default:
445 /* unreached */ 458 /* unreached */
@@ -504,40 +517,40 @@ pms_synaptics_probe_init(void *vsc) @@ -504,40 +517,40 @@ pms_synaptics_probe_init(void *vsc)
504 } 517 }
505 518
506 if (resp[1] != SYNAPTICS_MAGIC_BYTE) { 519 if (resp[1] != SYNAPTICS_MAGIC_BYTE) {
507 aprint_debug_dev(psc->sc_dev, 520 aprint_debug_dev(psc->sc_dev,
508 "synaptics_probe: Not synaptics.\n"); 521 "synaptics_probe: Not synaptics.\n");
509 res = 1; 522 res = 1;
510 goto doreset; 523 goto doreset;
511 } 524 }
512 525
513 sc->flags = 0; 526 sc->flags = 0;
514 sc->num_buttons = 0; 527 sc->num_buttons = 0;
515 sc->button_mask = 0xff; 528 sc->button_mask = 0xff;
516 529
517 pms_synaptics_set_boundaries(); 530 synaptics_true_edge_right = synaptics_edge_right;
 531 synaptics_true_edge_bottom = synaptics_edge_bottom;
518 532
519 /* Check for minimum version and print a nice message. */ 533 /* Check for minimum version and print a nice message. */
520 ver_major = resp[2] & 0x0f; 534 ver_major = resp[2] & 0x0f;
521 ver_minor = resp[0]; 535 ver_minor = resp[0];
522 aprint_normal_dev(psc->sc_dev, "Synaptics touchpad version %d.%d\n", 536 aprint_normal_dev(psc->sc_dev, "Synaptics touchpad version %d.%d\n",
523 ver_major, ver_minor); 537 ver_major, ver_minor);
524 if (ver_major * 10 + ver_minor < SYNAPTICS_MIN_VERSION) { 538 if (ver_major * 10 + ver_minor < SYNAPTICS_MIN_VERSION) {
525 /* No capability query support. */ 539 /* No capability query support. */
526 sc->caps = 0; 540 sc->caps = 0;
527 goto done; 541 goto done;
528 } 542 }
529 543
530 
531 /* Query the hardware capabilities. */ 544 /* Query the hardware capabilities. */
532 res = synaptics_special_read(psc, SYNAPTICS_READ_CAPABILITIES, resp); 545 res = synaptics_special_read(psc, SYNAPTICS_READ_CAPABILITIES, resp);
533 if (res) { 546 if (res) {
534 /* Hmm, failed to get capabilities. */ 547 /* Hmm, failed to get capabilities. */
535 aprint_error_dev(psc->sc_dev, 548 aprint_error_dev(psc->sc_dev,
536 "synaptics_probe: Failed to query capabilities.\n"); 549 "synaptics_probe: Failed to query capabilities.\n");
537 goto doreset; 550 goto doreset;
538 } 551 }
539 552
540 sc->caps = SYNAPTICS_CAP_VALUE(resp); 553 sc->caps = SYNAPTICS_CAP_VALUE(resp);
541 554
542 if (sc->caps & SYNAPTICS_CAP_MBUTTON) 555 if (sc->caps & SYNAPTICS_CAP_MBUTTON)
543 sc->flags |= SYN_FLAG_HAS_MIDDLE_BUTTON; 556 sc->flags |= SYN_FLAG_HAS_MIDDLE_BUTTON;
@@ -564,27 +577,27 @@ pms_synaptics_probe_init(void *vsc) @@ -564,27 +577,27 @@ pms_synaptics_probe_init(void *vsc)
564 577
565 if (sc->flags & SYN_FLAG_HAS_MAX_REPORT) { 578 if (sc->flags & SYN_FLAG_HAS_MAX_REPORT) {
566 res = synaptics_special_read(psc, SYNAPTICS_READ_MAX_COORDS, 579 res = synaptics_special_read(psc, SYNAPTICS_READ_MAX_COORDS,
567 resp); 580 resp);
568 if (res) { 581 if (res) {
569 aprint_error_dev(psc->sc_dev, 582 aprint_error_dev(psc->sc_dev,
570 "synaptics_probe: Failed to query max coords.\n"); 583 "synaptics_probe: Failed to query max coords.\n");
571 } else { 584 } else {
572 synaptics_edge_right = (resp[0] << 5) + 585 synaptics_edge_right = (resp[0] << 5) +
573 ((resp[1] & 0x0f) << 1); 586 ((resp[1] & 0x0f) << 1);
574 synaptics_edge_top = (resp[2] << 5) +  587 synaptics_edge_top = (resp[2] << 5) +
575 ((resp[1] & 0xf0) >> 3); 588 ((resp[1] & 0xf0) >> 3);
576 589
577 synaptics_actual_edge_right = synaptics_edge_right; 590 synaptics_true_edge_right = synaptics_edge_right;
578 591
579 /* 592 /*
580 * If we have vertical scroll then steal 10% 593 * If we have vertical scroll then steal 10%
581 * for that region. 594 * for that region.
582 */ 595 */
583 if (sc->flags & SYN_FLAG_HAS_VERTICAL_SCROLL) 596 if (sc->flags & SYN_FLAG_HAS_VERTICAL_SCROLL)
584 synaptics_edge_right -= 597 synaptics_edge_right -=
585 synaptics_edge_right / 10; 598 synaptics_edge_right / 10;
586 599
587 aprint_normal_dev(psc->sc_dev, 600 aprint_normal_dev(psc->sc_dev,
588 "Probed max coordinates right: %d, top: %d\n", 601 "Probed max coordinates right: %d, top: %d\n",
589 synaptics_edge_right, synaptics_edge_top); 602 synaptics_edge_right, synaptics_edge_top);
590 } 603 }
@@ -592,44 +605,44 @@ pms_synaptics_probe_init(void *vsc) @@ -592,44 +605,44 @@ pms_synaptics_probe_init(void *vsc)
592 605
593 if (sc->flags & SYN_FLAG_HAS_MIN_REPORT) { 606 if (sc->flags & SYN_FLAG_HAS_MIN_REPORT) {
594 res = synaptics_special_read(psc, SYNAPTICS_READ_MIN_COORDS, 607 res = synaptics_special_read(psc, SYNAPTICS_READ_MIN_COORDS,
595 resp); 608 resp);
596 if (res) { 609 if (res) {
597 aprint_error_dev(psc->sc_dev, 610 aprint_error_dev(psc->sc_dev,
598 "synaptics_probe: Failed to query min coords.\n"); 611 "synaptics_probe: Failed to query min coords.\n");
599 } else { 612 } else {
600 synaptics_edge_left = (resp[0] << 5) + 613 synaptics_edge_left = (resp[0] << 5) +
601 ((resp[1] & 0x0f) << 1); 614 ((resp[1] & 0x0f) << 1);
602 synaptics_edge_bottom = (resp[2] << 5) +  615 synaptics_edge_bottom = (resp[2] << 5) +
603 ((resp[1] & 0xf0) >> 3); 616 ((resp[1] & 0xf0) >> 3);
604 617
605 synaptics_actual_edge_bottom = synaptics_edge_bottom; 618 synaptics_true_edge_bottom = synaptics_edge_bottom;
606 619
607 /* 620 /*
608 * If we have horizontal scroll then steal 10% 621 * If we have horizontal scroll then steal 10%
609 * for that region. 622 * for that region.
610 */ 623 */
611 if (sc->flags & SYN_FLAG_HAS_HORIZONTAL_SCROLL) 624 if (sc->flags & SYN_FLAG_HAS_HORIZONTAL_SCROLL)
612 synaptics_horiz_pct = 10; 625 synaptics_hscroll_pct = 10;
613 626
614 aprint_normal_dev(psc->sc_dev, 627 aprint_normal_dev(psc->sc_dev,
615 "Probed min coordinates left: %d, bottom: %d\n", 628 "Probed min coordinates left: %d, bottom: %d\n",
616 synaptics_edge_left, synaptics_edge_bottom); 629 synaptics_edge_left, synaptics_edge_bottom);
617 } 630 }
618 } 631 }
619 632
 633done:
620 pms_synaptics_set_boundaries(); 634 pms_synaptics_set_boundaries();
621 635
622done: 
623 pms_sysctl_synaptics(&clog); 636 pms_sysctl_synaptics(&clog);
624 pckbport_set_inputhandler(psc->sc_kbctag, psc->sc_kbcslot, 637 pckbport_set_inputhandler(psc->sc_kbctag, psc->sc_kbcslot,
625 pms_synaptics_input, psc, device_xname(psc->sc_dev)); 638 pms_synaptics_input, psc, device_xname(psc->sc_dev));
626 639
627 return (0); 640 return (0);
628} 641}
629 642
630void 643void
631pms_synaptics_enable(void *vsc) 644pms_synaptics_enable(void *vsc)
632{ 645{
633 struct pms_softc *psc = vsc; 646 struct pms_softc *psc = vsc;
634 struct synaptics_softc *sc = &psc->u.synaptics; 647 struct synaptics_softc *sc = &psc->u.synaptics;
635 u_char enable_modes; 648 u_char enable_modes;
@@ -656,27 +669,27 @@ pms_synaptics_enable(void *vsc) @@ -656,27 +669,27 @@ pms_synaptics_enable(void *vsc)
656 enable_modes |= SYNAPTICS_MODE_EXTENDED_W; 669 enable_modes |= SYNAPTICS_MODE_EXTENDED_W;
657 670
658 /* 671 /*
659 * Synaptics documentation says to disable device before 672 * Synaptics documentation says to disable device before
660 * setting mode. 673 * setting mode.
661 */ 674 */
662 synaptics_poll_cmd(psc, PMS_DEV_DISABLE, 0); 675 synaptics_poll_cmd(psc, PMS_DEV_DISABLE, 0);
663 /* a couple of set scales to clear out pending commands */ 676 /* a couple of set scales to clear out pending commands */
664 for (i = 0; i < 2; i++) 677 for (i = 0; i < 2; i++)
665 synaptics_poll_cmd(psc, PMS_SET_SCALE11, 0); 678 synaptics_poll_cmd(psc, PMS_SET_SCALE11, 0);
666 679
667 res = synaptics_special_write(psc, SYNAPTICS_CMD_SET_MODE2, enable_modes); 680 res = synaptics_special_write(psc, SYNAPTICS_CMD_SET_MODE2, enable_modes);
668 if (res) 681 if (res)
669 aprint_error("synaptics: set mode error\n"); 682 device_printf(psc->sc_dev, "set mode error\n");
670 683
671 /* a couple of set scales to clear out pending commands */ 684 /* a couple of set scales to clear out pending commands */
672 for (i = 0; i < 2; i++) 685 for (i = 0; i < 2; i++)
673 synaptics_poll_cmd(psc, PMS_SET_SCALE11, 0); 686 synaptics_poll_cmd(psc, PMS_SET_SCALE11, 0);
674 687
675 /* Set advanced gesture mode */ 688 /* Set advanced gesture mode */
676 if ((sc->flags & SYN_FLAG_HAS_EXTENDED_WMODE) || 689 if ((sc->flags & SYN_FLAG_HAS_EXTENDED_WMODE) ||
677 (sc->flags & SYN_FLAG_HAS_ADV_GESTURE_MODE)) 690 (sc->flags & SYN_FLAG_HAS_ADV_GESTURE_MODE))
678 synaptics_special_write(psc, SYNAPTICS_WRITE_DELUXE_3, 0x3);  691 synaptics_special_write(psc, SYNAPTICS_WRITE_DELUXE_3, 0x3);
679 692
680 /* Disable motion in the button region for clickpads */ 693 /* Disable motion in the button region for clickpads */
681 if(sc->flags & SYN_FLAG_HAS_ONE_BUTTON_CLICKPAD) 694 if(sc->flags & SYN_FLAG_HAS_ONE_BUTTON_CLICKPAD)
682 synaptics_button_region_movement = 0; 695 synaptics_button_region_movement = 0;
@@ -1013,44 +1026,44 @@ pms_sysctl_synaptics(struct sysctllog ** @@ -1013,44 +1026,44 @@ pms_sysctl_synaptics(struct sysctllog **
1013 pms_sysctl_synaptics_verify, 0, 1026 pms_sysctl_synaptics_verify, 0,
1014 &synaptics_aux_mid_button_scroll, 1027 &synaptics_aux_mid_button_scroll,
1015 0, CTL_HW, root_num, CTL_CREATE, 1028 0, CTL_HW, root_num, CTL_CREATE,
1016 CTL_EOL)) != 0) 1029 CTL_EOL)) != 0)
1017 goto err; 1030 goto err;
1018 1031
1019 synaptics_aux_mid_button_scroll_nodenum = node->sysctl_num; 1032 synaptics_aux_mid_button_scroll_nodenum = node->sysctl_num;
1020 1033
1021 if ((rc = sysctl_createv(clog, 0, NULL, &node, 1034 if ((rc = sysctl_createv(clog, 0, NULL, &node,
1022 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, 1035 CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
1023 CTLTYPE_INT, "vert_scroll_percent", 1036 CTLTYPE_INT, "vert_scroll_percent",
1024 SYSCTL_DESCR("Percent of trackpad width to reserve for vertical scroll region"), 1037 SYSCTL_DESCR("Percent of trackpad width to reserve for vertical scroll region"),
1025 pms_sysctl_synaptics_verify, 0, 1038 pms_sysctl_synaptics_verify, 0,
1026 &synaptics_vert_pct, 1039 &synaptics_vscroll_pct,
1027 0, CTL_HW, root_num, CTL_CREATE, 1040 0, CTL_HW, root_num, CTL_CREATE,
1028 CTL_EOL)) != 0) 1041 CTL_EOL)) != 0)
1029 goto err; 1042 goto err;
1030 1043
1031 synaptics_vert_pct_nodenum = node->sysctl_num; 1044 synaptics_vscroll_pct_nodenum = node->sysctl_num;
1032 1045
1033 if ((rc = sysctl_createv(clog, 0, NULL, &node, 1046 if ((rc = sysctl_createv(clog, 0, NULL, &node,
1034 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, 1047 CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
1035 CTLTYPE_INT, "horizontal_scroll_percent", 1048 CTLTYPE_INT, "horizontal_scroll_percent",
1036 SYSCTL_DESCR("Percent of trackpad height to reserve for scroll region"), 1049 SYSCTL_DESCR("Percent of trackpad height to reserve for scroll region"),
1037 pms_sysctl_synaptics_verify, 0, 1050 pms_sysctl_synaptics_verify, 0,
1038 &synaptics_horiz_pct, 1051 &synaptics_hscroll_pct,
1039 0, CTL_HW, root_num, CTL_CREATE, 1052 0, CTL_HW, root_num, CTL_CREATE,
1040 CTL_EOL)) != 0) 1053 CTL_EOL)) != 0)
1041 goto err; 1054 goto err;
1042 1055
1043 synaptics_horiz_pct_nodenum = node->sysctl_num; 1056 synaptics_hscroll_pct_nodenum = node->sysctl_num;
1044 1057
1045 if ((rc = sysctl_createv(clog, 0, NULL, &node, 1058 if ((rc = sysctl_createv(clog, 0, NULL, &node,
1046 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, 1059 CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
1047 CTLTYPE_INT, "button_region_percent", 1060 CTLTYPE_INT, "button_region_percent",
1048 SYSCTL_DESCR("Percent of trackpad height to reserve for button region"), 1061 SYSCTL_DESCR("Percent of trackpad height to reserve for button region"),
1049 pms_sysctl_synaptics_verify, 0, 1062 pms_sysctl_synaptics_verify, 0,
1050 &synaptics_button_pct, 1063 &synaptics_button_pct,
1051 0, CTL_HW, root_num, CTL_CREATE, 1064 0, CTL_HW, root_num, CTL_CREATE,
1052 CTL_EOL)) != 0) 1065 CTL_EOL)) != 0)
1053 goto err; 1066 goto err;
1054 1067
1055 synaptics_button_pct_nodenum = node->sysctl_num; 1068 synaptics_button_pct_nodenum = node->sysctl_num;
1056 1069
@@ -1144,31 +1157,31 @@ pms_sysctl_synaptics_verify(SYSCTLFN_ARG @@ -1144,31 +1157,31 @@ pms_sysctl_synaptics_verify(SYSCTLFN_ARG
1144 } else 1157 } else
1145 if (node.sysctl_num == synaptics_movement_enable_nodenum) { 1158 if (node.sysctl_num == synaptics_movement_enable_nodenum) {
1146 if (t < 0 || t > 1) 1159 if (t < 0 || t > 1)
1147 return (EINVAL); 1160 return (EINVAL);
1148 } else 1161 } else
1149 if (node.sysctl_num == synaptics_button_region_movement_nodenum) { 1162 if (node.sysctl_num == synaptics_button_region_movement_nodenum) {
1150 if (t < 0 || t > 1) 1163 if (t < 0 || t > 1)
1151 return (EINVAL); 1164 return (EINVAL);
1152 } else 1165 } else
1153 if (node.sysctl_num == synaptics_aux_mid_button_scroll_nodenum) { 1166 if (node.sysctl_num == synaptics_aux_mid_button_scroll_nodenum) {
1154 if (t < 0 || t > 1) 1167 if (t < 0 || t > 1)
1155 return (EINVAL); 1168 return (EINVAL);
1156 } else 1169 } else
1157 if (node.sysctl_num == synaptics_vert_pct_nodenum) { 1170 if (node.sysctl_num == synaptics_vscroll_pct_nodenum) {
1158 if (t < 0 || t > 100) 1171 if (t < 0 || t > 100)
1159 return (EINVAL); 1172 return (EINVAL);
1160 } else 1173 } else
1161 if (node.sysctl_num == synaptics_horiz_pct_nodenum) { 1174 if (node.sysctl_num == synaptics_hscroll_pct_nodenum) {
1162 if (t < 0 || t > 100) 1175 if (t < 0 || t > 100)
1163 return (EINVAL); 1176 return (EINVAL);
1164 } else 1177 } else
1165 if (node.sysctl_num == synaptics_button_pct_nodenum) { 1178 if (node.sysctl_num == synaptics_button_pct_nodenum) {
1166 if (t < 0 || t > 100) 1179 if (t < 0 || t > 100)
1167 return (EINVAL); 1180 return (EINVAL);
1168 } else 1181 } else
1169 return (EINVAL); 1182 return (EINVAL);
1170 1183
1171 *(int *)rnode->sysctl_data = t; 1184 *(int *)rnode->sysctl_data = t;
1172 1185
1173 pms_synaptics_set_boundaries(); 1186 pms_synaptics_set_boundaries();
1174 1187
@@ -1204,27 +1217,27 @@ pms_synaptics_get_fingers(struct pms_sof @@ -1204,27 +1217,27 @@ pms_synaptics_get_fingers(struct pms_sof
1204 case SYNAPTICS_EW_WHEEL: 1217 case SYNAPTICS_EW_WHEEL:
1205 break; 1218 break;
1206 1219
1207 case SYNAPTICS_EW_SECONDARY_FINGER: 1220 case SYNAPTICS_EW_SECONDARY_FINGER:
1208 /* to get here we must have 2 fingers at least */ 1221 /* to get here we must have 2 fingers at least */
1209 fingers = 2; 1222 fingers = 2;
1210 break; 1223 break;
1211 1224
1212 case SYNAPTICS_EW_FINGER_STATUS: 1225 case SYNAPTICS_EW_FINGER_STATUS:
1213 fingers = psc->packet[1] & 0x0f; 1226 fingers = psc->packet[1] & 0x0f;
1214 break; 1227 break;
1215 1228
1216 default: 1229 default:
1217 aprint_error_dev(psc->sc_dev, 1230 device_printf(psc->sc_dev,
1218 "invalid extended w mode %d\n", 1231 "invalid extended w mode %d\n",
1219 ew_mode); 1232 ew_mode);
1220 return 0; /* pretend there are no fingers */ 1233 return 0; /* pretend there are no fingers */
1221 } 1234 }
1222 } else { 1235 } else {
1223 1236
1224 fingers = 1; 1237 fingers = 1;
1225 1238
1226 /* 1239 /*
1227 * If SYN_FLAG_HAS_MULTI_FINGER is set then check 1240 * If SYN_FLAG_HAS_MULTI_FINGER is set then check
1228 * sp_w is below SYNAPTICS_WIDTH_FINGER_MIN, if it is 1241 * sp_w is below SYNAPTICS_WIDTH_FINGER_MIN, if it is
1229 * then this will be the finger count. 1242 * then this will be the finger count.
1230 * 1243 *
@@ -1269,27 +1282,27 @@ pms_synaptics_parse(struct pms_softc *ps @@ -1269,27 +1282,27 @@ pms_synaptics_parse(struct pms_softc *ps
1269 + ((psc->packet[0] & 0x04) >> 1) 1282 + ((psc->packet[0] & 0x04) >> 1)
1270 + ((psc->packet[3] & 0x04) >> 2); 1283 + ((psc->packet[3] & 0x04) >> 2);
1271 1284
1272 v = 0; 1285 v = 0;
1273 primary_finger = 0; 1286 primary_finger = 0;
1274 secondary_finger = 0; 1287 secondary_finger = 0;
1275 if ((sc->flags & SYN_FLAG_HAS_EXTENDED_WMODE) && 1288 if ((sc->flags & SYN_FLAG_HAS_EXTENDED_WMODE) &&
1276 (nsp.sp_w == SYNAPTICS_WIDTH_EXTENDED_W)) { 1289 (nsp.sp_w == SYNAPTICS_WIDTH_EXTENDED_W)) {
1277 ew_mode = psc->packet[5] >> 4; 1290 ew_mode = psc->packet[5] >> 4;
1278 switch (ew_mode) 1291 switch (ew_mode)
1279 { 1292 {
1280 case SYNAPTICS_EW_WHEEL: 1293 case SYNAPTICS_EW_WHEEL:
1281 /* scroll wheel report, ignore for now */ 1294 /* scroll wheel report, ignore for now */
1282 aprint_debug_dev(psc->sc_dev, "mouse wheel packet\n"); 1295 DPRINTF(10, sc, "mouse wheel packet\n");
1283 return; 1296 return;
1284 1297
1285 case SYNAPTICS_EW_SECONDARY_FINGER: 1298 case SYNAPTICS_EW_SECONDARY_FINGER:
1286 /* parse the second finger report */ 1299 /* parse the second finger report */
1287 1300
1288 nsp.sp_secondary = 1; 1301 nsp.sp_secondary = 1;
1289 1302
1290 nsp.sp_sx = ((psc->packet[1] & 0xfe) << 1) 1303 nsp.sp_sx = ((psc->packet[1] & 0xfe) << 1)
1291 + ((psc->packet[4] & 0x0f) << 9); 1304 + ((psc->packet[4] & 0x0f) << 9);
1292 nsp.sp_sy = ((psc->packet[2] & 0xfe) << 1) 1305 nsp.sp_sy = ((psc->packet[2] & 0xfe) << 1)
1293 + ((psc->packet[4] & 0xf0) << 5); 1306 + ((psc->packet[4] & 0xf0) << 5);
1294 nsp.sp_sz = (psc->packet[3] & 0x30) 1307 nsp.sp_sz = (psc->packet[3] & 0x30)
1295 + ((psc->packet[5] & 0x0e) << 1); 1308 + ((psc->packet[5] & 0x0e) << 1);
@@ -1333,27 +1346,27 @@ pms_synaptics_parse(struct pms_softc *ps @@ -1333,27 +1346,27 @@ pms_synaptics_parse(struct pms_softc *ps
1333 * index. 1346 * index.
1334 * 1347 *
1335 * XXX Park this, possibly handle a finger 1348 * XXX Park this, possibly handle a finger
1336 * XXX change if indexes change. 1349 * XXX change if indexes change.
1337 */ 1350 */
1338 primary_finger = psc->packet[2]; 1351 primary_finger = psc->packet[2];
1339 secondary_finger = psc->packet[4]; 1352 secondary_finger = psc->packet[4];
1340 nsp.sp_finger_status = 1; 1353 nsp.sp_finger_status = 1;
1341 nsp.sp_finger_count = pms_synaptics_get_fingers(psc, 1354 nsp.sp_finger_count = pms_synaptics_get_fingers(psc,
1342 nsp.sp_w, nsp.sp_z); 1355 nsp.sp_w, nsp.sp_z);
1343 goto skip_position; 1356 goto skip_position;
1344 1357
1345 default: 1358 default:
1346 aprint_error_dev(psc->sc_dev, 1359 device_printf(psc->sc_dev,
1347 "invalid extended w mode %d\n", 1360 "invalid extended w mode %d\n",
1348 ew_mode); 1361 ew_mode);
1349 return; 1362 return;
1350 } 1363 }
1351 } else { 1364 } else {
1352 nsp.sp_primary = 1; 1365 nsp.sp_primary = 1;
1353 1366
1354 /* 1367 /*
1355 * If the trackpad has external buttons and one of 1368 * If the trackpad has external buttons and one of
1356 * those buttons is pressed then the lower bits of 1369 * those buttons is pressed then the lower bits of
1357 * x and y are "stolen" for button status. We can tell 1370 * x and y are "stolen" for button status. We can tell
1358 * this has happened by doing an xor of the two right 1371 * this has happened by doing an xor of the two right
1359 * button status bits residing in byte 0 and 3, if the 1372 * button status bits residing in byte 0 and 3, if the
@@ -1452,27 +1465,27 @@ pms_synaptics_parse(struct pms_softc *ps @@ -1452,27 +1465,27 @@ pms_synaptics_parse(struct pms_softc *ps
1452 */ 1465 */
1453 if (((sc->flags & SYN_FLAG_HAS_EXTENDED_WMODE) 1466 if (((sc->flags & SYN_FLAG_HAS_EXTENDED_WMODE)
1454 != SYN_FLAG_HAS_EXTENDED_WMODE) && 1467 != SYN_FLAG_HAS_EXTENDED_WMODE) &&
1455 (nsp.sp_finger_count > 1)) { 1468 (nsp.sp_finger_count > 1)) {
1456 nsp.sp_secondary = 1; 1469 nsp.sp_secondary = 1;
1457 nsp.sp_sx = 0; 1470 nsp.sp_sx = 0;
1458 nsp.sp_sy = 0; 1471 nsp.sp_sy = 0;
1459 nsp.sp_sz = 0; 1472 nsp.sp_sz = 0;
1460 } 1473 }
1461 1474
1462 if ((psc->packet[0] ^ psc->packet[3]) & 0x02) { 1475 if ((psc->packet[0] ^ psc->packet[3]) & 0x02) {
1463 /* extended buttons */ 1476 /* extended buttons */
1464 1477
1465 aprint_debug_dev(psc->sc_dev, 1478 DPRINTF(10, sc,
1466 "synaptics_parse: %02x %02x %02x %02x %02x %02x\n", 1479 "synaptics_parse: %02x %02x %02x %02x %02x %02x\n",
1467 psc->packet[0], psc->packet[1], psc->packet[2], 1480 psc->packet[0], psc->packet[1], psc->packet[2],
1468 psc->packet[3], psc->packet[4], psc->packet[5]); 1481 psc->packet[3], psc->packet[4], psc->packet[5]);
1469 1482
1470 if ((psc->packet[4] & SYN_1BUTMASK) != 0) 1483 if ((psc->packet[4] & SYN_1BUTMASK) != 0)
1471 ext_left = PMS_LBUTMASK; 1484 ext_left = PMS_LBUTMASK;
1472 else 1485 else
1473 ext_left = 0; 1486 ext_left = 0;
1474 1487
1475 if ((psc->packet[4] & SYN_3BUTMASK) != 0) 1488 if ((psc->packet[4] & SYN_3BUTMASK) != 0)
1476 ext_middle = PMS_MBUTMASK; 1489 ext_middle = PMS_MBUTMASK;
1477 else 1490 else
1478 ext_middle = 0; 1491 ext_middle = 0;
@@ -1706,74 +1719,75 @@ pms_synaptics_input(void *vsc, int data) @@ -1706,74 +1719,75 @@ pms_synaptics_input(void *vsc, int data)
1706 struct pms_softc *psc = vsc; 1719 struct pms_softc *psc = vsc;
1707 struct timeval diff; 1720 struct timeval diff;
1708 1721
1709 if (!psc->sc_enabled) { 1722 if (!psc->sc_enabled) {
1710 /* Interrupts are not expected. Discard the byte. */ 1723 /* Interrupts are not expected. Discard the byte. */
1711 return; 1724 return;
1712 } 1725 }
1713 1726
1714 getmicrouptime(&psc->current); 1727 getmicrouptime(&psc->current);
1715 1728
1716 if (psc->inputstate > 0) { 1729 if (psc->inputstate > 0) {
1717 timersub(&psc->current, &psc->last, &diff); 1730 timersub(&psc->current, &psc->last, &diff);
1718 if (diff.tv_sec > 0 || diff.tv_usec >= 40000) { 1731 if (diff.tv_sec > 0 || diff.tv_usec >= 40000) {
1719 aprint_debug_dev(psc->sc_dev, 1732 device_printf(psc->sc_dev,
1720 "pms_synaptics_input: unusual delay (%ld.%06ld s), " 1733 "pms_synaptics_input: unusual delay (%ld.%06ld s), "
1721 "scheduling reset\n", 1734 "scheduling reset\n",
1722 (long)diff.tv_sec, (long)diff.tv_usec); 1735 (long)diff.tv_sec, (long)diff.tv_usec);
1723 printf("pms_synaptics_input: unusual delay (%ld.%06ld s), " 
1724 "scheduling reset\n", 
1725 (long)diff.tv_sec, (long)diff.tv_usec); 
1726 psc->inputstate = 0; 1736 psc->inputstate = 0;
1727 psc->sc_enabled = 0; 1737 psc->sc_enabled = 0;
1728 wakeup(&psc->sc_enabled); 1738 wakeup(&psc->sc_enabled);
1729 return; 1739 return;
1730 } 1740 }
1731 } 1741 }
1732 psc->last = psc->current; 1742 psc->last = psc->current;
1733 1743
1734 switch (psc->inputstate) { 1744 switch (psc->inputstate) {
1735 case -5: 1745 case -5:
1736 case -4: 1746 case -4:
1737 case -3: 1747 case -3:
1738 case -2: 1748 case -2:
1739 case -1: 1749 case -1:
1740 case 0: 1750 case 0:
1741 if ((data & 0xc8) != 0x80) { 1751 if ((data & 0xc8) != 0x80) {
1742 aprint_debug_dev(psc->sc_dev, 1752 device_printf(psc->sc_dev,
1743 "pms_synaptics_input: 0x%02x out of sync\n", data); 1753 "pms_synaptics_input: 0x%02x out of sync\n", data);
1744 /* use negative counts to limit resync phase */ 1754 /* use negative counts to limit resync phase */
1745 psc->inputstate--; 1755 psc->inputstate--;
1746 return; /* not in sync yet, discard input */ 1756 return; /* not in sync yet, discard input */
1747 } 1757 }
1748 psc->inputstate = 0; 1758 psc->inputstate = 0;
1749 /*FALLTHROUGH*/ 1759 /*FALLTHROUGH*/
1750 1760
1751 case -6: 1761 case -6:
1752 case 3: 1762 case 3:
1753 if ((data & 8) == 8) { 1763 if ((data & 8) == 8) {
1754 aprint_debug_dev(psc->sc_dev, 1764 device_printf(psc->sc_dev,
1755 "pms_synaptics_input: dropped in relative mode, reset\n"); 1765 "pms_synaptics_input: dropped in relative mode, reset\n");
1756 psc->inputstate = 0; 1766 psc->inputstate = 0;
1757 psc->sc_enabled = 0; 1767 psc->sc_enabled = 0;
1758 wakeup(&psc->sc_enabled); 1768 wakeup(&psc->sc_enabled);
1759 return; 1769 return;
1760 } 1770 }
1761 } 1771 }
1762 if (psc->inputstate >= sizeof(psc->packet)) 1772 if (psc->inputstate >= sizeof(psc->packet))
1763 panic("inputstate should never be %d", psc->inputstate); 1773 panic("inputstate should never be %d", psc->inputstate);
1764 1774
1765 psc->packet[psc->inputstate++] = data & 0xff; 1775 psc->packet[psc->inputstate++] = data & 0xff;
1766 if (psc->inputstate == 6) { 1776 if (psc->inputstate == 6) {
 1777 struct synaptics_softc *sc = &psc->u.synaptics;
 1778 DPRINTF(10, sc, "synaptics: packet: 0x%02x%02x%02x%02x%02x%02x\n",
 1779 psc->packet[0], psc->packet[1], psc->packet[2],
 1780 psc->packet[3], psc->packet[4], psc->packet[5]);
1767 /* 1781 /*
1768 * We have a complete packet. 1782 * We have a complete packet.
1769 * Extract the pertinent details. 1783 * Extract the pertinent details.
1770 */ 1784 */
1771 psc->inputstate = 0; 1785 psc->inputstate = 0;
1772 if ((psc->packet[0] & 0xfc) == 0x84 && 1786 if ((psc->packet[0] & 0xfc) == 0x84 &&
1773 (psc->packet[3] & 0xcc) == 0xc4) { 1787 (psc->packet[3] & 0xcc) == 0xc4) {
1774 /* W = SYNAPTICS_WIDTH_PASSTHROUGH, PS/2 passthrough */ 1788 /* W = SYNAPTICS_WIDTH_PASSTHROUGH, PS/2 passthrough */
1775 pms_synaptics_passthrough(psc); 1789 pms_synaptics_passthrough(psc);
1776 } else { 1790 } else {
1777 pms_synaptics_parse(psc); 1791 pms_synaptics_parse(psc);
1778 } 1792 }
1779 } 1793 }