| @@ -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. */ |
104 | static int synaptics_up_down_emul = 3; | | 104 | static int synaptics_up_down_emul = 3; |
105 | static int synaptics_up_down_motion_delta = 1; | | 105 | static int synaptics_up_down_motion_delta = 1; |
106 | static int synaptics_gesture_move = 200; | | 106 | static int synaptics_gesture_move = 200; |
107 | static int synaptics_gesture_length = 20; | | 107 | static int synaptics_gesture_length = 20; |
108 | static int synaptics_edge_left = SYNAPTICS_EDGE_LEFT; | | 108 | static int synaptics_edge_left = SYNAPTICS_EDGE_LEFT; |
109 | static int synaptics_edge_right = SYNAPTICS_EDGE_RIGHT; | | 109 | static int synaptics_edge_right = SYNAPTICS_EDGE_RIGHT; |
110 | static int synaptics_edge_top = SYNAPTICS_EDGE_TOP; | | 110 | static int synaptics_edge_top = SYNAPTICS_EDGE_TOP; |
111 | static int synaptics_edge_bottom = SYNAPTICS_EDGE_BOTTOM; | | 111 | static int synaptics_edge_bottom = SYNAPTICS_EDGE_BOTTOM; |
112 | static int synaptics_edge_motion_delta = 32; | | 112 | static int synaptics_edge_motion_delta = 32; |
113 | static u_int synaptics_finger_high = SYNAPTICS_FINGER_LIGHT + 5; | | 113 | static u_int synaptics_finger_high = SYNAPTICS_FINGER_LIGHT + 5; |
114 | static u_int synaptics_finger_low = SYNAPTICS_FINGER_LIGHT - 10; | | 114 | static u_int synaptics_finger_low = SYNAPTICS_FINGER_LIGHT - 10; |
115 | static int synaptics_horiz_pct = 0; | | 115 | static int synaptics_hscroll_pct = 0; |
116 | static int synaptics_vert_pct = 0; | | 116 | static int synaptics_vscroll_pct = 0; |
117 | static int synaptics_button_pct = 30; | | 117 | static int synaptics_button_pct = 0; |
118 | static int synaptics_button_boundary; | | 118 | static int synaptics_button_boundary = SYNAPTICS_EDGE_BOTTOM; |
119 | static int synaptics_button2; | | 119 | static int synaptics_button2; |
120 | static int synaptics_button3; | | 120 | static int synaptics_button3; |
121 | static int synaptics_two_fingers_emul = 0; | | 121 | static int synaptics_two_fingers_emul = 0; |
122 | static int synaptics_scale_x = 8; | | 122 | static int synaptics_scale_x = 8; |
123 | static int synaptics_scale_y = 8; | | 123 | static int synaptics_scale_y = 8; |
124 | static int synaptics_scale_z = 32; | | 124 | static int synaptics_scale_z = 32; |
125 | static int synaptics_max_speed_x = 32; | | 125 | static int synaptics_max_speed_x = 32; |
126 | static int synaptics_max_speed_y = 32; | | 126 | static int synaptics_max_speed_y = 32; |
127 | static int synaptics_max_speed_z = 2; | | 127 | static int synaptics_max_speed_z = 2; |
128 | static int synaptics_movement_threshold = 4; | | 128 | static int synaptics_movement_threshold = 4; |
129 | static int synaptics_movement_enable = 1; | | 129 | static int synaptics_movement_enable = 1; |
130 | static int synaptics_button_region_movement = 1; | | 130 | static int synaptics_button_region_movement = 1; |
131 | static bool synaptics_aux_mid_button_scroll = TRUE; | | 131 | static 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 |
156 | static int synaptics_finger_high_nodenum; | | 156 | static int synaptics_finger_high_nodenum; |
157 | static int synaptics_finger_low_nodenum; | | 157 | static int synaptics_finger_low_nodenum; |
158 | static int synaptics_two_fingers_emul_nodenum; | | 158 | static int synaptics_two_fingers_emul_nodenum; |
159 | static int synaptics_scale_x_nodenum; | | 159 | static int synaptics_scale_x_nodenum; |
160 | static int synaptics_scale_y_nodenum; | | 160 | static int synaptics_scale_y_nodenum; |
161 | static int synaptics_scale_z_nodenum; | | 161 | static int synaptics_scale_z_nodenum; |
162 | static int synaptics_max_speed_x_nodenum; | | 162 | static int synaptics_max_speed_x_nodenum; |
163 | static int synaptics_max_speed_y_nodenum; | | 163 | static int synaptics_max_speed_y_nodenum; |
164 | static int synaptics_max_speed_z_nodenum; | | 164 | static int synaptics_max_speed_z_nodenum; |
165 | static int synaptics_movement_threshold_nodenum; | | 165 | static int synaptics_movement_threshold_nodenum; |
166 | static int synaptics_movement_enable_nodenum; | | 166 | static int synaptics_movement_enable_nodenum; |
167 | static int synaptics_button_region_movement_nodenum; | | 167 | static int synaptics_button_region_movement_nodenum; |
168 | static int synaptics_aux_mid_button_scroll_nodenum; | | 168 | static int synaptics_aux_mid_button_scroll_nodenum; |
169 | static int synaptics_horiz_pct_nodenum; | | 169 | static int synaptics_hscroll_pct_nodenum; |
170 | static int synaptics_vert_pct_nodenum; | | 170 | static int synaptics_vscroll_pct_nodenum; |
171 | static int synaptics_button_pct_nodenum; | | 171 | static 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 | */ |
177 | static int synaptics_actual_edge_right; | | 177 | static int synaptics_true_edge_right; |
178 | static int synaptics_actual_edge_bottom; | | 178 | static int synaptics_true_edge_bottom; |
179 | | | 179 | |
180 | static int synaptics_old_vert_pct = 0; | | 180 | /* |
181 | static int synaptics_old_horiz_pct = 0; | | 181 | * invalid old values, recalculate everything |
182 | static int synaptics_old_button_pct = 0; | | 182 | */ |
183 | static int synaptics_old_button_boundary = SYNAPTICS_EDGE_BOTTOM; | | 183 | static int synaptics_old_vscroll_pct = -1; |
184 | static int synaptics_old_horiz_edge = SYNAPTICS_EDGE_BOTTOM; | | 184 | static int synaptics_old_hscroll_pct = -1; |
185 | static int synaptics_old_vert_edge = SYNAPTICS_EDGE_RIGHT; | | 185 | static int synaptics_old_button_pct = -1; |
| | | 186 | static int synaptics_old_button_boundary = -1; |
| | | 187 | static int synaptics_old_edge_right = -1; |
| | | 188 | static 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 | */ |
192 | static struct synaptics_packet packet; | | 195 | static struct synaptics_packet packet; |
193 | | | 196 | |
194 | static int | | 197 | static int |
195 | synaptics_poll_cmd(struct pms_softc *psc, ...) | | 198 | synaptics_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 | |
215 | static int | | 218 | static int |
216 | synaptics_poll_reset(struct pms_softc *psc) | | 219 | synaptics_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 | |
229 | static int | | 232 | static int |
230 | synaptics_special_read(struct pms_softc *psc, u_char slice, u_char resp[3]) | | 233 | synaptics_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 | |
| | | 257 | static int |
| | | 258 | synaptics_value(int pct, int low, int high) |
| | | 259 | { |
| | | 260 | return low + pct * (high - low) / 100UL; |
| | | 261 | } |
| | | 262 | |
| | | 263 | static int |
| | | 264 | synaptics_percentage(int val, int low, int high) |
| | | 265 | { |
| | | 266 | return ((val - low) * 100UL + high - low - 1) / (high - low); |
| | | 267 | } |
| | | 268 | |
254 | static void | | 269 | static void |
255 | pms_synaptics_set_boundaries(void) | | 270 | pms_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 | |
335 | static void | | 348 | static void |
336 | pms_synaptics_probe_extended(struct pms_softc *psc) | | 349 | pms_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 | |
| | | 633 | done: |
620 | pms_synaptics_set_boundaries(); | | 634 | pms_synaptics_set_boundaries(); |
621 | | | 635 | |
622 | done: | | | |
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 | |
630 | void | | 643 | void |
631 | pms_synaptics_enable(void *vsc) | | 644 | pms_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 | } |