Lines 29-34
Link Here
|
29 |
#include <sys/cdefs.h> |
29 |
#include <sys/cdefs.h> |
30 |
__FBSDID("$FreeBSD$"); |
30 |
__FBSDID("$FreeBSD$"); |
31 |
|
31 |
|
|
|
32 |
#include "opt_evdev.h" |
33 |
|
32 |
#include <sys/param.h> |
34 |
#include <sys/param.h> |
33 |
#include <sys/systm.h> |
35 |
#include <sys/systm.h> |
34 |
#include <sys/kernel.h> |
36 |
#include <sys/kernel.h> |
Lines 56-61
__FBSDID("$FreeBSD$");
Link Here
|
56 |
#define USB_DEBUG_VAR wsp_debug |
58 |
#define USB_DEBUG_VAR wsp_debug |
57 |
#include <dev/usb/usb_debug.h> |
59 |
#include <dev/usb/usb_debug.h> |
58 |
|
60 |
|
|
|
61 |
#ifdef EVDEV_SUPPORT |
62 |
#include <dev/evdev/input.h> |
63 |
#include <dev/evdev/evdev.h> |
64 |
#endif |
65 |
|
59 |
#include <sys/mouse.h> |
66 |
#include <sys/mouse.h> |
60 |
|
67 |
|
61 |
#define WSP_DRIVER_NAME "wsp" |
68 |
#define WSP_DRIVER_NAME "wsp" |
Lines 169-175
enum tp_type {
Link Here
|
169 |
TYPE1, /* plain trackpad */ |
176 |
TYPE1, /* plain trackpad */ |
170 |
TYPE2, /* button integrated in trackpad */ |
177 |
TYPE2, /* button integrated in trackpad */ |
171 |
TYPE3, /* additional header fields since June 2013 */ |
178 |
TYPE3, /* additional header fields since June 2013 */ |
172 |
TYPE4 /* additional header field for pressure data */ |
179 |
TYPE4, /* additional header field for pressure data */ |
|
|
180 |
TYPE_CNT |
173 |
}; |
181 |
}; |
174 |
|
182 |
|
175 |
/* trackpad finger data offsets, le16-aligned */ |
183 |
/* trackpad finger data offsets, le16-aligned */ |
Lines 192-197
enum tp_type {
Link Here
|
192 |
#define FSIZE_TYPE3 (14 * 2) |
200 |
#define FSIZE_TYPE3 (14 * 2) |
193 |
#define FSIZE_TYPE4 (15 * 2) |
201 |
#define FSIZE_TYPE4 (15 * 2) |
194 |
|
202 |
|
|
|
203 |
struct tp { |
204 |
uint8_t caps; /* device capability bitmask */ |
205 |
uint8_t button; /* offset to button data */ |
206 |
uint8_t offset; /* offset to trackpad finger data */ |
207 |
uint8_t fsize; /* bytes in single finger block */ |
208 |
uint8_t delta; /* offset from header to finger struct */ |
209 |
uint8_t iface_index; |
210 |
uint8_t um_size; /* usb control message length */ |
211 |
uint8_t um_req_idx; /* usb control message index */ |
212 |
uint8_t um_switch_idx; /* usb control message mode switch index */ |
213 |
uint8_t um_switch_on; /* usb control message mode switch on */ |
214 |
uint8_t um_switch_off; /* usb control message mode switch off */ |
215 |
} const static tp[TYPE_CNT] = { |
216 |
[TYPE1] = { |
217 |
.caps = 0, |
218 |
.button = 0, |
219 |
.offset = FINGER_TYPE1, |
220 |
.fsize = FSIZE_TYPE1, |
221 |
.delta = 0, |
222 |
.iface_index = 0, |
223 |
.um_size = 8, |
224 |
.um_req_idx = 0x00, |
225 |
.um_switch_idx = 0, |
226 |
.um_switch_on = 0x01, |
227 |
.um_switch_off = 0x08, |
228 |
}, |
229 |
[TYPE2] = { |
230 |
.caps = HAS_INTEGRATED_BUTTON, |
231 |
.button = BUTTON_TYPE2, |
232 |
.offset = FINGER_TYPE2, |
233 |
.fsize = FSIZE_TYPE2, |
234 |
.delta = 0, |
235 |
.iface_index = 0, |
236 |
.um_size = 8, |
237 |
.um_req_idx = 0x00, |
238 |
.um_switch_idx = 0, |
239 |
.um_switch_on = 0x01, |
240 |
.um_switch_off = 0x08, |
241 |
}, |
242 |
[TYPE3] = { |
243 |
.caps = HAS_INTEGRATED_BUTTON, |
244 |
.button = BUTTON_TYPE3, |
245 |
.offset = FINGER_TYPE3, |
246 |
.fsize = FSIZE_TYPE3, |
247 |
.delta = 0, |
248 |
}, |
249 |
[TYPE4] = { |
250 |
.caps = HAS_INTEGRATED_BUTTON, |
251 |
.button = BUTTON_TYPE4, |
252 |
.offset = FINGER_TYPE4, |
253 |
.fsize = FSIZE_TYPE4, |
254 |
.delta = 2, |
255 |
.iface_index = 2, |
256 |
.um_size = 2, |
257 |
.um_req_idx = 0x02, |
258 |
.um_switch_idx = 1, |
259 |
.um_switch_on = 0x01, |
260 |
.um_switch_off = 0x00, |
261 |
}, |
262 |
}; |
263 |
|
195 |
/* trackpad finger header - little endian */ |
264 |
/* trackpad finger header - little endian */ |
196 |
struct tp_header { |
265 |
struct tp_header { |
197 |
uint8_t flag; |
266 |
uint8_t flag; |
Lines 226-234
struct tp_finger {
Link Here
|
226 |
} __packed; |
295 |
} __packed; |
227 |
|
296 |
|
228 |
/* trackpad finger data size, empirically at least ten fingers */ |
297 |
/* trackpad finger data size, empirically at least ten fingers */ |
|
|
298 |
#ifdef EVDEV_SUPPORT |
299 |
#define MAX_FINGERS MAX_MT_SLOTS |
300 |
#else |
229 |
#define MAX_FINGERS 16 |
301 |
#define MAX_FINGERS 16 |
|
|
302 |
#endif |
230 |
#define SIZEOF_FINGER sizeof(struct tp_finger) |
303 |
#define SIZEOF_FINGER sizeof(struct tp_finger) |
231 |
#define SIZEOF_ALL_FINGERS (MAX_FINGERS * SIZEOF_FINGER) |
304 |
#define SIZEOF_ALL_FINGERS (MAX_FINGERS * SIZEOF_FINGER) |
|
|
305 |
#define MAX_FINGER_ORIENTATION 16384 |
232 |
|
306 |
|
233 |
#if (WSP_BUFFER_MAX < ((MAX_FINGERS * FSIZE_TYPE4) + FINGER_TYPE4)) |
307 |
#if (WSP_BUFFER_MAX < ((MAX_FINGERS * FSIZE_TYPE4) + FINGER_TYPE4)) |
234 |
#error "WSP_BUFFER_MAX is too small" |
308 |
#error "WSP_BUFFER_MAX is too small" |
Lines 251-467
enum {
Link Here
|
251 |
WSP_FLAG_MAX, |
325 |
WSP_FLAG_MAX, |
252 |
}; |
326 |
}; |
253 |
|
327 |
|
|
|
328 |
/* device-specific parameters */ |
329 |
struct wsp_param { |
330 |
int snratio; /* signal-to-noise ratio */ |
331 |
int min; /* device minimum reading */ |
332 |
int max; /* device maximum reading */ |
333 |
}; |
334 |
|
254 |
/* device-specific configuration */ |
335 |
/* device-specific configuration */ |
255 |
struct wsp_dev_params { |
336 |
struct wsp_dev_params { |
256 |
uint8_t caps; /* device capability bitmask */ |
337 |
const struct tp* tp; |
257 |
uint8_t tp_type; /* type of trackpad interface */ |
338 |
struct wsp_param p; /* finger pressure limits */ |
258 |
uint8_t tp_button; /* offset to button data */ |
339 |
struct wsp_param w; /* finger width limits */ |
259 |
uint8_t tp_offset; /* offset to trackpad finger data */ |
340 |
struct wsp_param x; /* horizontal limits */ |
260 |
uint8_t tp_fsize; /* bytes in single finger block */ |
341 |
struct wsp_param y; /* vertical limits */ |
261 |
uint8_t tp_delta; /* offset from header to finger struct */ |
342 |
struct wsp_param o; /* orientation limits */ |
262 |
uint8_t iface_index; |
|
|
263 |
uint8_t um_size; /* usb control message length */ |
264 |
uint8_t um_req_val; /* usb control message value */ |
265 |
uint8_t um_req_idx; /* usb control message index */ |
266 |
uint8_t um_switch_idx; /* usb control message mode switch index */ |
267 |
uint8_t um_switch_on; /* usb control message mode switch on */ |
268 |
uint8_t um_switch_off; /* usb control message mode switch off */ |
269 |
}; |
343 |
}; |
270 |
|
344 |
|
|
|
345 |
/* logical signal quality */ |
346 |
#define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ |
347 |
#define SN_WIDTH 25 /* width signal-to-noise ratio */ |
348 |
#define SN_COORD 250 /* coordinate signal-to-noise ratio */ |
349 |
#define SN_ORIENT 10 /* orientation signal-to-noise ratio */ |
350 |
|
271 |
static const struct wsp_dev_params wsp_dev_params[WSP_FLAG_MAX] = { |
351 |
static const struct wsp_dev_params wsp_dev_params[WSP_FLAG_MAX] = { |
272 |
[WSP_FLAG_WELLSPRING1] = { |
352 |
[WSP_FLAG_WELLSPRING1] = { |
273 |
.caps = 0, |
353 |
.tp = tp + TYPE1, |
274 |
.tp_type = TYPE1, |
354 |
.p = { SN_PRESSURE, 0, 256 }, |
275 |
.tp_button = 0, |
355 |
.w = { SN_WIDTH, 0, 2048 }, |
276 |
.tp_offset = FINGER_TYPE1, |
356 |
.x = { SN_COORD, -4824, 5342 }, |
277 |
.tp_fsize = FSIZE_TYPE1, |
357 |
.y = { SN_COORD, -172, 5820 }, |
278 |
.tp_delta = 0, |
358 |
.o = { SN_ORIENT, |
279 |
.iface_index = 0, |
359 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
280 |
.um_size = 8, |
|
|
281 |
.um_req_val = 0x03, |
282 |
.um_req_idx = 0x00, |
283 |
.um_switch_idx = 0, |
284 |
.um_switch_on = 0x01, |
285 |
.um_switch_off = 0x08, |
286 |
}, |
360 |
}, |
287 |
[WSP_FLAG_WELLSPRING2] = { |
361 |
[WSP_FLAG_WELLSPRING2] = { |
288 |
.caps = 0, |
362 |
.tp = tp + TYPE1, |
289 |
.tp_type = TYPE1, |
363 |
.p = { SN_PRESSURE, 0, 256 }, |
290 |
.tp_button = 0, |
364 |
.w = { SN_WIDTH, 0, 2048 }, |
291 |
.tp_offset = FINGER_TYPE1, |
365 |
.x = { SN_COORD, -4824, 4824 }, |
292 |
.tp_fsize = FSIZE_TYPE1, |
366 |
.y = { SN_COORD, -172, 4290 }, |
293 |
.tp_delta = 0, |
367 |
.o = { SN_ORIENT, |
294 |
.iface_index = 0, |
368 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
295 |
.um_size = 8, |
|
|
296 |
.um_req_val = 0x03, |
297 |
.um_req_idx = 0x00, |
298 |
.um_switch_idx = 0, |
299 |
.um_switch_on = 0x01, |
300 |
.um_switch_off = 0x08, |
301 |
}, |
369 |
}, |
302 |
[WSP_FLAG_WELLSPRING3] = { |
370 |
[WSP_FLAG_WELLSPRING3] = { |
303 |
.caps = HAS_INTEGRATED_BUTTON, |
371 |
.tp = tp + TYPE2, |
304 |
.tp_type = TYPE2, |
372 |
.p = { SN_PRESSURE, 0, 300 }, |
305 |
.tp_button = BUTTON_TYPE2, |
373 |
.w = { SN_WIDTH, 0, 2048 }, |
306 |
.tp_offset = FINGER_TYPE2, |
374 |
.x = { SN_COORD, -4460, 5166 }, |
307 |
.tp_fsize = FSIZE_TYPE2, |
375 |
.y = { SN_COORD, -75, 6700 }, |
308 |
.tp_delta = 0, |
376 |
.o = { SN_ORIENT, |
309 |
.iface_index = 0, |
377 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
310 |
.um_size = 8, |
|
|
311 |
.um_req_val = 0x03, |
312 |
.um_req_idx = 0x00, |
313 |
.um_switch_idx = 0, |
314 |
.um_switch_on = 0x01, |
315 |
.um_switch_off = 0x08, |
316 |
}, |
378 |
}, |
317 |
[WSP_FLAG_WELLSPRING4] = { |
379 |
[WSP_FLAG_WELLSPRING4] = { |
318 |
.caps = HAS_INTEGRATED_BUTTON, |
380 |
.tp = tp + TYPE2, |
319 |
.tp_type = TYPE2, |
381 |
.p = { SN_PRESSURE, 0, 300 }, |
320 |
.tp_button = BUTTON_TYPE2, |
382 |
.w = { SN_WIDTH, 0, 2048 }, |
321 |
.tp_offset = FINGER_TYPE2, |
383 |
.x = { SN_COORD, -4620, 5140 }, |
322 |
.tp_fsize = FSIZE_TYPE2, |
384 |
.y = { SN_COORD, -150, 6600 }, |
323 |
.tp_delta = 0, |
385 |
.o = { SN_ORIENT, |
324 |
.iface_index = 0, |
386 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
325 |
.um_size = 8, |
|
|
326 |
.um_req_val = 0x03, |
327 |
.um_req_idx = 0x00, |
328 |
.um_switch_idx = 0, |
329 |
.um_switch_on = 0x01, |
330 |
.um_switch_off = 0x08, |
331 |
}, |
387 |
}, |
332 |
[WSP_FLAG_WELLSPRING4A] = { |
388 |
[WSP_FLAG_WELLSPRING4A] = { |
333 |
.caps = HAS_INTEGRATED_BUTTON, |
389 |
.tp = tp + TYPE2, |
334 |
.tp_type = TYPE2, |
390 |
.p = { SN_PRESSURE, 0, 300 }, |
335 |
.tp_button = BUTTON_TYPE2, |
391 |
.w = { SN_WIDTH, 0, 2048 }, |
336 |
.tp_offset = FINGER_TYPE2, |
392 |
.x = { SN_COORD, -4616, 5112 }, |
337 |
.tp_fsize = FSIZE_TYPE2, |
393 |
.y = { SN_COORD, -142, 5234 }, |
338 |
.tp_delta = 0, |
394 |
.o = { SN_ORIENT, |
339 |
.iface_index = 0, |
395 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
340 |
.um_size = 8, |
|
|
341 |
.um_req_val = 0x03, |
342 |
.um_req_idx = 0x00, |
343 |
.um_switch_idx = 0, |
344 |
.um_switch_on = 0x01, |
345 |
.um_switch_off = 0x08, |
346 |
}, |
396 |
}, |
347 |
[WSP_FLAG_WELLSPRING5] = { |
397 |
[WSP_FLAG_WELLSPRING5] = { |
348 |
.caps = HAS_INTEGRATED_BUTTON, |
398 |
.tp = tp + TYPE2, |
349 |
.tp_type = TYPE2, |
399 |
.p = { SN_PRESSURE, 0, 300 }, |
350 |
.tp_button = BUTTON_TYPE2, |
400 |
.w = { SN_WIDTH, 0, 2048 }, |
351 |
.tp_offset = FINGER_TYPE2, |
401 |
.x = { SN_COORD, -4415, 5050 }, |
352 |
.tp_fsize = FSIZE_TYPE2, |
402 |
.y = { SN_COORD, -55, 6680 }, |
353 |
.tp_delta = 0, |
403 |
.o = { SN_ORIENT, |
354 |
.iface_index = 0, |
404 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
355 |
.um_size = 8, |
|
|
356 |
.um_req_val = 0x03, |
357 |
.um_req_idx = 0x00, |
358 |
.um_switch_idx = 0, |
359 |
.um_switch_on = 0x01, |
360 |
.um_switch_off = 0x08, |
361 |
}, |
405 |
}, |
362 |
[WSP_FLAG_WELLSPRING6] = { |
406 |
[WSP_FLAG_WELLSPRING6] = { |
363 |
.caps = HAS_INTEGRATED_BUTTON, |
407 |
.tp = tp + TYPE2, |
364 |
.tp_type = TYPE2, |
408 |
.p = { SN_PRESSURE, 0, 300 }, |
365 |
.tp_button = BUTTON_TYPE2, |
409 |
.w = { SN_WIDTH, 0, 2048 }, |
366 |
.tp_offset = FINGER_TYPE2, |
410 |
.x = { SN_COORD, -4620, 5140 }, |
367 |
.tp_fsize = FSIZE_TYPE2, |
411 |
.y = { SN_COORD, -150, 6600 }, |
368 |
.tp_delta = 0, |
412 |
.o = { SN_ORIENT, |
369 |
.iface_index = 0, |
413 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
370 |
.um_size = 8, |
|
|
371 |
.um_req_val = 0x03, |
372 |
.um_req_idx = 0x00, |
373 |
.um_switch_idx = 0, |
374 |
.um_switch_on = 0x01, |
375 |
.um_switch_off = 0x08, |
376 |
}, |
414 |
}, |
377 |
[WSP_FLAG_WELLSPRING5A] = { |
415 |
[WSP_FLAG_WELLSPRING5A] = { |
378 |
.caps = HAS_INTEGRATED_BUTTON, |
416 |
.tp = tp + TYPE2, |
379 |
.tp_type = TYPE2, |
417 |
.p = { SN_PRESSURE, 0, 300 }, |
380 |
.tp_button = BUTTON_TYPE2, |
418 |
.w = { SN_WIDTH, 0, 2048 }, |
381 |
.tp_offset = FINGER_TYPE2, |
419 |
.x = { SN_COORD, -4750, 5280 }, |
382 |
.tp_fsize = FSIZE_TYPE2, |
420 |
.y = { SN_COORD, -150, 6730 }, |
383 |
.tp_delta = 0, |
421 |
.o = { SN_ORIENT, |
384 |
.iface_index = 0, |
422 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
385 |
.um_size = 8, |
|
|
386 |
.um_req_val = 0x03, |
387 |
.um_req_idx = 0x00, |
388 |
.um_switch_idx = 0, |
389 |
.um_switch_on = 0x01, |
390 |
.um_switch_off = 0x08, |
391 |
}, |
423 |
}, |
392 |
[WSP_FLAG_WELLSPRING6A] = { |
424 |
[WSP_FLAG_WELLSPRING6A] = { |
393 |
.caps = HAS_INTEGRATED_BUTTON, |
425 |
.tp = tp + TYPE2, |
394 |
.tp_type = TYPE2, |
426 |
.p = { SN_PRESSURE, 0, 300 }, |
395 |
.tp_button = BUTTON_TYPE2, |
427 |
.w = { SN_WIDTH, 0, 2048 }, |
396 |
.tp_offset = FINGER_TYPE2, |
428 |
.x = { SN_COORD, -4620, 5140 }, |
397 |
.tp_fsize = FSIZE_TYPE2, |
429 |
.y = { SN_COORD, -150, 6600 }, |
398 |
.tp_delta = 0, |
430 |
.o = { SN_ORIENT, |
399 |
.um_size = 8, |
431 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
400 |
.um_req_val = 0x03, |
|
|
401 |
.um_req_idx = 0x00, |
402 |
.um_switch_idx = 0, |
403 |
.um_switch_on = 0x01, |
404 |
.um_switch_off = 0x08, |
405 |
}, |
432 |
}, |
406 |
[WSP_FLAG_WELLSPRING7] = { |
433 |
[WSP_FLAG_WELLSPRING7] = { |
407 |
.caps = HAS_INTEGRATED_BUTTON, |
434 |
.tp = tp + TYPE2, |
408 |
.tp_type = TYPE2, |
435 |
.p = { SN_PRESSURE, 0, 300 }, |
409 |
.tp_button = BUTTON_TYPE2, |
436 |
.w = { SN_WIDTH, 0, 2048 }, |
410 |
.tp_offset = FINGER_TYPE2, |
437 |
.x = { SN_COORD, -4750, 5280 }, |
411 |
.tp_fsize = FSIZE_TYPE2, |
438 |
.y = { SN_COORD, -150, 6730 }, |
412 |
.tp_delta = 0, |
439 |
.o = { SN_ORIENT, |
413 |
.iface_index = 0, |
440 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
414 |
.um_size = 8, |
|
|
415 |
.um_req_val = 0x03, |
416 |
.um_req_idx = 0x00, |
417 |
.um_switch_idx = 0, |
418 |
.um_switch_on = 0x01, |
419 |
.um_switch_off = 0x08, |
420 |
}, |
441 |
}, |
421 |
[WSP_FLAG_WELLSPRING7A] = { |
442 |
[WSP_FLAG_WELLSPRING7A] = { |
422 |
.caps = HAS_INTEGRATED_BUTTON, |
443 |
.tp = tp + TYPE2, |
423 |
.tp_type = TYPE2, |
444 |
.p = { SN_PRESSURE, 0, 300 }, |
424 |
.tp_button = BUTTON_TYPE2, |
445 |
.w = { SN_WIDTH, 0, 2048 }, |
425 |
.tp_offset = FINGER_TYPE2, |
446 |
.x = { SN_COORD, -4750, 5280 }, |
426 |
.tp_fsize = FSIZE_TYPE2, |
447 |
.y = { SN_COORD, -150, 6730 }, |
427 |
.tp_delta = 0, |
448 |
.o = { SN_ORIENT, |
428 |
.iface_index = 0, |
449 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
429 |
.um_size = 8, |
|
|
430 |
.um_req_val = 0x03, |
431 |
.um_req_idx = 0x00, |
432 |
.um_switch_idx = 0, |
433 |
.um_switch_on = 0x01, |
434 |
.um_switch_off = 0x08, |
435 |
}, |
450 |
}, |
436 |
[WSP_FLAG_WELLSPRING8] = { |
451 |
[WSP_FLAG_WELLSPRING8] = { |
437 |
.caps = HAS_INTEGRATED_BUTTON, |
452 |
.tp = tp + TYPE3, |
438 |
.tp_type = TYPE3, |
453 |
.p = { SN_PRESSURE, 0, 300 }, |
439 |
.tp_button = BUTTON_TYPE3, |
454 |
.w = { SN_WIDTH, 0, 2048 }, |
440 |
.tp_offset = FINGER_TYPE3, |
455 |
.x = { SN_COORD, -4620, 5140 }, |
441 |
.tp_fsize = FSIZE_TYPE3, |
456 |
.y = { SN_COORD, -150, 6600 }, |
442 |
.tp_delta = 0, |
457 |
.o = { SN_ORIENT, |
443 |
.iface_index = 0, |
458 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
444 |
.um_size = 8, |
|
|
445 |
.um_req_val = 0x03, |
446 |
.um_req_idx = 0x00, |
447 |
.um_switch_idx = 0, |
448 |
.um_switch_on = 0x01, |
449 |
.um_switch_off = 0x08, |
450 |
}, |
459 |
}, |
451 |
[WSP_FLAG_WELLSPRING9] = { |
460 |
[WSP_FLAG_WELLSPRING9] = { |
452 |
.caps = HAS_INTEGRATED_BUTTON, |
461 |
.tp = tp + TYPE4, |
453 |
.tp_type = TYPE4, |
462 |
.p = { SN_PRESSURE, 0, 300 }, |
454 |
.tp_button = BUTTON_TYPE4, |
463 |
.w = { SN_WIDTH, 0, 2048 }, |
455 |
.tp_offset = FINGER_TYPE4, |
464 |
.x = { SN_COORD, -4828, 5345 }, |
456 |
.tp_fsize = FSIZE_TYPE4, |
465 |
.y = { SN_COORD, -203, 6803 }, |
457 |
.tp_delta = 2, |
466 |
.o = { SN_ORIENT, |
458 |
.iface_index = 2, |
467 |
-MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }, |
459 |
.um_size = 2, |
|
|
460 |
.um_req_val = 0x03, |
461 |
.um_req_idx = 0x02, |
462 |
.um_switch_idx = 1, |
463 |
.um_switch_on = 0x01, |
464 |
.um_switch_off = 0x00, |
465 |
}, |
468 |
}, |
466 |
}; |
469 |
}; |
467 |
#define WSP_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } |
470 |
#define WSP_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } |
Lines 550-561
struct wsp_softc {
Link Here
|
550 |
|
553 |
|
551 |
const struct wsp_dev_params *sc_params; /* device configuration */ |
554 |
const struct wsp_dev_params *sc_params; /* device configuration */ |
552 |
|
555 |
|
|
|
556 |
#ifdef EVDEV_SUPPORT |
557 |
struct evdev_dev *sc_evdev; |
558 |
#endif |
553 |
mousehw_t sc_hw; |
559 |
mousehw_t sc_hw; |
554 |
mousemode_t sc_mode; |
560 |
mousemode_t sc_mode; |
555 |
u_int sc_pollrate; |
561 |
u_int sc_pollrate; |
556 |
mousestatus_t sc_status; |
562 |
mousestatus_t sc_status; |
|
|
563 |
int sc_fflags; |
557 |
u_int sc_state; |
564 |
u_int sc_state; |
558 |
#define WSP_ENABLED 0x01 |
565 |
#define WSP_ENABLED 0x01 |
|
|
566 |
#define WSP_EVDEV_OPENED 0x02 |
559 |
|
567 |
|
560 |
struct tp_finger *index[MAX_FINGERS]; /* finger index data */ |
568 |
struct tp_finger *index[MAX_FINGERS]; /* finger index data */ |
561 |
int16_t pos_x[MAX_FINGERS]; /* position array */ |
569 |
int16_t pos_x[MAX_FINGERS]; /* position array */ |
Lines 596-603
struct wsp_softc {
Link Here
|
596 |
/* |
604 |
/* |
597 |
* function prototypes |
605 |
* function prototypes |
598 |
*/ |
606 |
*/ |
599 |
static usb_fifo_cmd_t wsp_start_read; |
607 |
static usb_fifo_cmd_t wsp_fifo_start_read; |
600 |
static usb_fifo_cmd_t wsp_stop_read; |
608 |
static usb_fifo_cmd_t wsp_fifo_stop_read; |
601 |
static usb_fifo_open_t wsp_open; |
609 |
static usb_fifo_open_t wsp_open; |
602 |
static usb_fifo_close_t wsp_close; |
610 |
static usb_fifo_close_t wsp_close; |
603 |
static usb_fifo_ioctl_t wsp_ioctl; |
611 |
static usb_fifo_ioctl_t wsp_ioctl; |
Lines 606-616
static struct usb_fifo_methods wsp_fifo_methods = {
Link Here
|
606 |
.f_open = &wsp_open, |
614 |
.f_open = &wsp_open, |
607 |
.f_close = &wsp_close, |
615 |
.f_close = &wsp_close, |
608 |
.f_ioctl = &wsp_ioctl, |
616 |
.f_ioctl = &wsp_ioctl, |
609 |
.f_start_read = &wsp_start_read, |
617 |
.f_start_read = &wsp_fifo_start_read, |
610 |
.f_stop_read = &wsp_stop_read, |
618 |
.f_stop_read = &wsp_fifo_stop_read, |
611 |
.basename[0] = WSP_DRIVER_NAME, |
619 |
.basename[0] = WSP_DRIVER_NAME, |
612 |
}; |
620 |
}; |
613 |
|
621 |
|
|
|
622 |
#ifdef EVDEV_SUPPORT |
623 |
static evdev_open_t wsp_ev_open; |
624 |
static evdev_close_t wsp_ev_close; |
625 |
static const struct evdev_methods wsp_evdev_methods = { |
626 |
.ev_open = &wsp_ev_open, |
627 |
.ev_close = &wsp_ev_close, |
628 |
}; |
629 |
#endif |
630 |
|
614 |
/* device initialization and shutdown */ |
631 |
/* device initialization and shutdown */ |
615 |
static int wsp_enable(struct wsp_softc *sc); |
632 |
static int wsp_enable(struct wsp_softc *sc); |
616 |
static void wsp_disable(struct wsp_softc *sc); |
633 |
static void wsp_disable(struct wsp_softc *sc); |
Lines 647-658
wsp_set_device_mode(struct wsp_softc *sc, uint8_t on)
Link Here
|
647 |
usb_error_t err; |
664 |
usb_error_t err; |
648 |
|
665 |
|
649 |
/* Type 3 does not require a mode switch */ |
666 |
/* Type 3 does not require a mode switch */ |
650 |
if (params->tp_type == TYPE3) |
667 |
if (params->tp == tp + TYPE3) |
651 |
return 0; |
668 |
return 0; |
652 |
|
669 |
|
653 |
err = usbd_req_get_report(sc->sc_usb_device, NULL, |
670 |
err = usbd_req_get_report(sc->sc_usb_device, NULL, |
654 |
mode_bytes, params->um_size, params->iface_index, |
671 |
mode_bytes, params->tp->um_size, params->tp->iface_index, |
655 |
params->um_req_val, params->um_req_idx); |
672 |
UHID_FEATURE_REPORT, params->tp->um_req_idx); |
656 |
|
673 |
|
657 |
if (err != USB_ERR_NORMAL_COMPLETION) { |
674 |
if (err != USB_ERR_NORMAL_COMPLETION) { |
658 |
DPRINTF("Failed to read device mode (%d)\n", err); |
675 |
DPRINTF("Failed to read device mode (%d)\n", err); |
Lines 667-678
wsp_set_device_mode(struct wsp_softc *sc, uint8_t on)
Link Here
|
667 |
*/ |
684 |
*/ |
668 |
pause("WHW", hz / 4); |
685 |
pause("WHW", hz / 4); |
669 |
|
686 |
|
670 |
mode_bytes[params->um_switch_idx] = |
687 |
mode_bytes[params->tp->um_switch_idx] = |
671 |
on ? params->um_switch_on : params->um_switch_off; |
688 |
on ? params->tp->um_switch_on : params->tp->um_switch_off; |
672 |
|
689 |
|
673 |
return (usbd_req_set_report(sc->sc_usb_device, NULL, |
690 |
return (usbd_req_set_report(sc->sc_usb_device, NULL, |
674 |
mode_bytes, params->um_size, params->iface_index, |
691 |
mode_bytes, params->tp->um_size, params->tp->iface_index, |
675 |
params->um_req_val, params->um_req_idx)); |
692 |
UHID_FEATURE_REPORT, params->tp->um_req_idx)); |
676 |
} |
693 |
} |
677 |
|
694 |
|
678 |
static int |
695 |
static int |
Lines 720-726
wsp_probe(device_t self)
Link Here
|
720 |
/* check if we are attaching to the first match */ |
737 |
/* check if we are attaching to the first match */ |
721 |
if (uaa->info.bIfaceIndex != i) |
738 |
if (uaa->info.bIfaceIndex != i) |
722 |
return (ENXIO); |
739 |
return (ENXIO); |
723 |
return (usbd_lookup_id_by_uaa(wsp_devs, sizeof(wsp_devs), uaa)); |
740 |
if (usbd_lookup_id_by_uaa(wsp_devs, sizeof(wsp_devs), uaa) != 0) |
|
|
741 |
return (ENXIO); |
742 |
|
743 |
return (BUS_PROBE_DEFAULT); |
724 |
} |
744 |
} |
725 |
|
745 |
|
726 |
static int |
746 |
static int |
Lines 816-821
wsp_attach(device_t dev)
Link Here
|
816 |
sc->sc_touch = WSP_UNTOUCH; |
836 |
sc->sc_touch = WSP_UNTOUCH; |
817 |
sc->scr_mode = WSP_SCR_NONE; |
837 |
sc->scr_mode = WSP_SCR_NONE; |
818 |
|
838 |
|
|
|
839 |
#ifdef EVDEV_SUPPORT |
840 |
sc->sc_evdev = evdev_alloc(); |
841 |
evdev_set_name(sc->sc_evdev, device_get_desc(dev)); |
842 |
evdev_set_phys(sc->sc_evdev, device_get_nameunit(dev)); |
843 |
evdev_set_id(sc->sc_evdev, BUS_USB, uaa->info.idVendor, |
844 |
uaa->info.idProduct, 0); |
845 |
evdev_set_serial(sc->sc_evdev, usb_get_serial(uaa->device)); |
846 |
evdev_set_methods(sc->sc_evdev, sc, &wsp_evdev_methods); |
847 |
evdev_support_prop(sc->sc_evdev, INPUT_PROP_POINTER); |
848 |
evdev_support_event(sc->sc_evdev, EV_SYN); |
849 |
evdev_support_event(sc->sc_evdev, EV_ABS); |
850 |
evdev_support_event(sc->sc_evdev, EV_KEY); |
851 |
|
852 |
#define WSP_SUPPORT_ABS(evdev, code, param) \ |
853 |
evdev_support_abs((evdev), (code), (param).min, (param).max, \ |
854 |
((param).max - (param).min) / (param).snratio, 0, 0); |
855 |
|
856 |
/* finger position */ |
857 |
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_POSITION_X, sc->sc_params->x); |
858 |
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_POSITION_Y, sc->sc_params->y); |
859 |
/* finger pressure */ |
860 |
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_PRESSURE, sc->sc_params->p); |
861 |
/* finger touch area */ |
862 |
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_TOUCH_MAJOR, sc->sc_params->w); |
863 |
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_TOUCH_MINOR, sc->sc_params->w); |
864 |
/* finger approach area */ |
865 |
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_WIDTH_MAJOR, sc->sc_params->w); |
866 |
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_WIDTH_MINOR, sc->sc_params->w); |
867 |
/* finger orientation */ |
868 |
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_ORIENTATION, sc->sc_params->o); |
869 |
/* button properties */ |
870 |
evdev_support_key(sc->sc_evdev, BTN_LEFT); |
871 |
if ((sc->sc_params->tp->caps & HAS_INTEGRATED_BUTTON) != 0) |
872 |
evdev_support_prop(sc->sc_evdev, INPUT_PROP_BUTTONPAD); |
873 |
/* Enable automatic touch assignment for type B MT protocol */ |
874 |
evdev_support_abs(sc->sc_evdev, ABS_MT_SLOT, |
875 |
0, MAX_FINGERS - 1, 0, 0, 0); |
876 |
evdev_support_abs(sc->sc_evdev, ABS_MT_TRACKING_ID, |
877 |
-1, MAX_FINGERS - 1, 0, 0, 0); |
878 |
evdev_set_flag(sc->sc_evdev, EVDEV_FLAG_MT_TRACK); |
879 |
evdev_set_flag(sc->sc_evdev, EVDEV_FLAG_MT_AUTOREL); |
880 |
/* Synaptics compatibility events */ |
881 |
evdev_set_flag(sc->sc_evdev, EVDEV_FLAG_MT_STCOMPAT); |
882 |
|
883 |
err = evdev_register(sc->sc_evdev); |
884 |
if (err) |
885 |
goto detach; |
886 |
#endif |
887 |
|
819 |
return (0); |
888 |
return (0); |
820 |
|
889 |
|
821 |
detach: |
890 |
detach: |
Lines 837-842
wsp_detach(device_t dev)
Link Here
|
837 |
|
906 |
|
838 |
usb_fifo_detach(&sc->sc_fifo); |
907 |
usb_fifo_detach(&sc->sc_fifo); |
839 |
|
908 |
|
|
|
909 |
#ifdef EVDEV_SUPPORT |
910 |
evdev_free(sc->sc_evdev); |
911 |
#endif |
912 |
|
840 |
usbd_transfer_unsetup(sc->sc_xfer, WSP_N_TRANSFER); |
913 |
usbd_transfer_unsetup(sc->sc_xfer, WSP_N_TRANSFER); |
841 |
|
914 |
|
842 |
mtx_destroy(&sc->sc_mutex); |
915 |
mtx_destroy(&sc->sc_mutex); |
Lines 863-868
wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
Link Here
|
863 |
int rdz = 0; |
936 |
int rdz = 0; |
864 |
int len; |
937 |
int len; |
865 |
int i; |
938 |
int i; |
|
|
939 |
#ifdef EVDEV_SUPPORT |
940 |
int slot = 0; |
941 |
#endif |
866 |
|
942 |
|
867 |
wsp_runing_rangecheck(&tun); |
943 |
wsp_runing_rangecheck(&tun); |
868 |
|
944 |
|
Lines 878-885
wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
Link Here
|
878 |
pc = usbd_xfer_get_frame(xfer, 0); |
954 |
pc = usbd_xfer_get_frame(xfer, 0); |
879 |
usbd_copy_out(pc, 0, sc->tp_data, len); |
955 |
usbd_copy_out(pc, 0, sc->tp_data, len); |
880 |
|
956 |
|
881 |
if ((len < params->tp_offset + params->tp_fsize) || |
957 |
if ((len < params->tp->offset + params->tp->fsize) || |
882 |
((len - params->tp_offset) % params->tp_fsize) != 0) { |
958 |
((len - params->tp->offset) % params->tp->fsize) != 0) { |
883 |
DPRINTFN(WSP_LLEVEL_INFO, "Invalid length: %d, %x, %x\n", |
959 |
DPRINTFN(WSP_LLEVEL_INFO, "Invalid length: %d, %x, %x\n", |
884 |
len, sc->tp_data[0], sc->tp_data[1]); |
960 |
len, sc->tp_data[0], sc->tp_data[1]); |
885 |
goto tr_setup; |
961 |
goto tr_setup; |
Lines 892-901
wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
Link Here
|
892 |
|
968 |
|
893 |
h = (struct tp_header *)(sc->tp_data); |
969 |
h = (struct tp_header *)(sc->tp_data); |
894 |
|
970 |
|
895 |
if (params->tp_type >= TYPE2) { |
971 |
if (params->tp != tp + TYPE1) { |
896 |
ibt = sc->tp_data[params->tp_button]; |
972 |
ibt = sc->tp_data[params->tp->button]; |
897 |
ntouch = sc->tp_data[params->tp_button - 1]; |
973 |
ntouch = sc->tp_data[params->tp->button - 1]; |
898 |
} |
974 |
} else |
|
|
975 |
ntouch = (len - params->tp->offset) / params->tp->fsize; |
976 |
|
899 |
/* range check */ |
977 |
/* range check */ |
900 |
if (ntouch < 0) |
978 |
if (ntouch < 0) |
901 |
ntouch = 0; |
979 |
ntouch = 0; |
Lines 903-909
wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
Link Here
|
903 |
ntouch = MAX_FINGERS; |
981 |
ntouch = MAX_FINGERS; |
904 |
|
982 |
|
905 |
for (i = 0; i != ntouch; i++) { |
983 |
for (i = 0; i != ntouch; i++) { |
906 |
f = (struct tp_finger *)(sc->tp_data + params->tp_offset + params->tp_delta + i * params->tp_fsize); |
984 |
f = (struct tp_finger *)(sc->tp_data + params->tp->offset + params->tp->delta + i * params->tp->fsize); |
907 |
/* swap endianness, if any */ |
985 |
/* swap endianness, if any */ |
908 |
if (le16toh(0x1234) != 0x1234) { |
986 |
if (le16toh(0x1234) != 0x1234) { |
909 |
f->origin = le16toh((uint16_t)f->origin); |
987 |
f->origin = le16toh((uint16_t)f->origin); |
Lines 929-945
wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
Link Here
|
929 |
sc->pos_x[i] = f->abs_x; |
1007 |
sc->pos_x[i] = f->abs_x; |
930 |
sc->pos_y[i] = -f->abs_y; |
1008 |
sc->pos_y[i] = -f->abs_y; |
931 |
sc->index[i] = f; |
1009 |
sc->index[i] = f; |
|
|
1010 |
#ifdef EVDEV_SUPPORT |
1011 |
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE && f->touch_major != 0) { |
1012 |
union evdev_mt_slot slot_data = { |
1013 |
.id = slot, |
1014 |
.x = f->abs_x, |
1015 |
.y = params->y.min + params->y.max - f->abs_y, |
1016 |
.p = f->pressure, |
1017 |
.maj = f->touch_major << 1, |
1018 |
.min = f->touch_minor << 1, |
1019 |
.w_maj = f->tool_major << 1, |
1020 |
.w_min = f->tool_minor << 1, |
1021 |
.ori = params->o.max - f->orientation, |
1022 |
}; |
1023 |
evdev_mt_push_slot(sc->sc_evdev, slot, &slot_data); |
1024 |
slot++; |
1025 |
} |
1026 |
#endif |
932 |
} |
1027 |
} |
933 |
|
1028 |
|
|
|
1029 |
#ifdef EVDEV_SUPPORT |
1030 |
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) { |
1031 |
evdev_push_key(sc->sc_evdev, BTN_LEFT, ibt); |
1032 |
evdev_sync(sc->sc_evdev); |
1033 |
} |
1034 |
#endif |
934 |
sc->sc_status.flags &= ~MOUSE_POSCHANGED; |
1035 |
sc->sc_status.flags &= ~MOUSE_POSCHANGED; |
935 |
sc->sc_status.flags &= ~MOUSE_STDBUTTONSCHANGED; |
1036 |
sc->sc_status.flags &= ~MOUSE_STDBUTTONSCHANGED; |
936 |
sc->sc_status.obutton = sc->sc_status.button; |
1037 |
sc->sc_status.obutton = sc->sc_status.button; |
937 |
sc->sc_status.button = 0; |
1038 |
sc->sc_status.button = 0; |
938 |
|
1039 |
|
939 |
if (ibt != 0) { |
1040 |
if (ibt != 0) { |
940 |
if ((params->caps & HAS_INTEGRATED_BUTTON) && ntouch == 2) |
1041 |
if ((params->tp->caps & HAS_INTEGRATED_BUTTON) && ntouch == 2) |
941 |
sc->sc_status.button |= MOUSE_BUTTON3DOWN; |
1042 |
sc->sc_status.button |= MOUSE_BUTTON3DOWN; |
942 |
else if ((params->caps & HAS_INTEGRATED_BUTTON) && ntouch == 3) |
1043 |
else if ((params->tp->caps & HAS_INTEGRATED_BUTTON) && ntouch == 3) |
943 |
sc->sc_status.button |= MOUSE_BUTTON2DOWN; |
1044 |
sc->sc_status.button |= MOUSE_BUTTON2DOWN; |
944 |
else |
1045 |
else |
945 |
sc->sc_status.button |= MOUSE_BUTTON1DOWN; |
1046 |
sc->sc_status.button |= MOUSE_BUTTON1DOWN; |
Lines 986-992
wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
Link Here
|
986 |
*/ |
1087 |
*/ |
987 |
switch (sc->ntaps) { |
1088 |
switch (sc->ntaps) { |
988 |
case 1: |
1089 |
case 1: |
989 |
if (!(params->caps & HAS_INTEGRATED_BUTTON) || tun.enable_single_tap_clicks) { |
1090 |
if (!(params->tp->caps & HAS_INTEGRATED_BUTTON) || tun.enable_single_tap_clicks) { |
990 |
wsp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON1DOWN); |
1091 |
wsp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON1DOWN); |
991 |
DPRINTFN(WSP_LLEVEL_INFO, "LEFT CLICK!\n"); |
1092 |
DPRINTFN(WSP_LLEVEL_INFO, "LEFT CLICK!\n"); |
992 |
} |
1093 |
} |
Lines 1235-1243
wsp_reset_buf(struct wsp_softc *sc)
Link Here
|
1235 |
} |
1336 |
} |
1236 |
|
1337 |
|
1237 |
static void |
1338 |
static void |
1238 |
wsp_start_read(struct usb_fifo *fifo) |
1339 |
wsp_start_read(struct wsp_softc *sc) |
1239 |
{ |
1340 |
{ |
1240 |
struct wsp_softc *sc = usb_fifo_softc(fifo); |
|
|
1241 |
int rate; |
1341 |
int rate; |
1242 |
|
1342 |
|
1243 |
/* Check if we should override the default polling interval */ |
1343 |
/* Check if we should override the default polling interval */ |
Lines 1258-1306
wsp_start_read(struct usb_fifo *fifo)
Link Here
|
1258 |
} |
1358 |
} |
1259 |
|
1359 |
|
1260 |
static void |
1360 |
static void |
1261 |
wsp_stop_read(struct usb_fifo *fifo) |
1361 |
wsp_stop_read(struct wsp_softc *sc) |
1262 |
{ |
1362 |
{ |
1263 |
struct wsp_softc *sc = usb_fifo_softc(fifo); |
|
|
1264 |
|
1265 |
usbd_transfer_stop(sc->sc_xfer[WSP_INTR_DT]); |
1363 |
usbd_transfer_stop(sc->sc_xfer[WSP_INTR_DT]); |
1266 |
} |
1364 |
} |
1267 |
|
1365 |
|
1268 |
static int |
1366 |
static int |
1269 |
wsp_open(struct usb_fifo *fifo, int fflags) |
1367 |
wsp_open(struct usb_fifo *fifo, int fflags) |
1270 |
{ |
1368 |
{ |
1271 |
DPRINTFN(WSP_LLEVEL_INFO, "\n"); |
1369 |
struct wsp_softc *sc = usb_fifo_softc(fifo); |
|
|
1370 |
int rc = 0; |
1272 |
|
1371 |
|
1273 |
if (fflags & FREAD) { |
1372 |
DPRINTFN(WSP_LLEVEL_INFO, "\n"); |
1274 |
struct wsp_softc *sc = usb_fifo_softc(fifo); |
|
|
1275 |
int rc; |
1276 |
|
1373 |
|
1277 |
if (sc->sc_state & WSP_ENABLED) |
1374 |
if (sc->sc_fflags & fflags) |
1278 |
return (EBUSY); |
1375 |
return (EBUSY); |
1279 |
|
1376 |
|
|
|
1377 |
if (fflags & FREAD) { |
1280 |
if (usb_fifo_alloc_buffer(fifo, |
1378 |
if (usb_fifo_alloc_buffer(fifo, |
1281 |
WSP_FIFO_BUF_SIZE, WSP_FIFO_QUEUE_MAXLEN)) { |
1379 |
WSP_FIFO_BUF_SIZE, WSP_FIFO_QUEUE_MAXLEN)) { |
1282 |
return (ENOMEM); |
1380 |
return (ENOMEM); |
1283 |
} |
1381 |
} |
1284 |
rc = wsp_enable(sc); |
1382 |
#ifdef EVDEV_SUPPORT |
|
|
1383 |
if ((sc->sc_state & WSP_EVDEV_OPENED) == 0) |
1384 |
#endif |
1385 |
rc = wsp_enable(sc); |
1285 |
if (rc != 0) { |
1386 |
if (rc != 0) { |
1286 |
usb_fifo_free_buffer(fifo); |
1387 |
usb_fifo_free_buffer(fifo); |
1287 |
return (rc); |
1388 |
return (rc); |
1288 |
} |
1389 |
} |
1289 |
} |
1390 |
} |
|
|
1391 |
sc->sc_fflags |= fflags & (FREAD | FWRITE); |
1290 |
return (0); |
1392 |
return (0); |
1291 |
} |
1393 |
} |
1292 |
|
1394 |
|
1293 |
static void |
1395 |
static void |
1294 |
wsp_close(struct usb_fifo *fifo, int fflags) |
1396 |
wsp_close(struct usb_fifo *fifo, int fflags) |
1295 |
{ |
1397 |
{ |
1296 |
if (fflags & FREAD) { |
1398 |
struct wsp_softc *sc = usb_fifo_softc(fifo); |
1297 |
struct wsp_softc *sc = usb_fifo_softc(fifo); |
|
|
1298 |
|
1399 |
|
1299 |
wsp_disable(sc); |
1400 |
if (fflags & FREAD) { |
|
|
1401 |
#ifdef EVDEV_SUPPORT |
1402 |
if ((sc->sc_state & WSP_EVDEV_OPENED) == 0) |
1403 |
#endif |
1404 |
wsp_disable(sc); |
1300 |
usb_fifo_free_buffer(fifo); |
1405 |
usb_fifo_free_buffer(fifo); |
1301 |
} |
1406 |
} |
|
|
1407 |
|
1408 |
sc->sc_fflags &= ~(fflags & (FREAD | FWRITE)); |
1302 |
} |
1409 |
} |
1303 |
|
1410 |
|
|
|
1411 |
static void |
1412 |
wsp_fifo_start_read(struct usb_fifo *fifo) |
1413 |
{ |
1414 |
struct wsp_softc *sc = usb_fifo_softc(fifo); |
1415 |
|
1416 |
wsp_start_read(sc); |
1417 |
} |
1418 |
|
1419 |
static void |
1420 |
wsp_fifo_stop_read(struct usb_fifo *fifo) |
1421 |
{ |
1422 |
struct wsp_softc *sc = usb_fifo_softc(fifo); |
1423 |
|
1424 |
#ifdef EVDEV_SUPPORT |
1425 |
if ((sc->sc_state & WSP_EVDEV_OPENED) == 0) |
1426 |
#endif |
1427 |
wsp_stop_read(sc); |
1428 |
} |
1429 |
|
1430 |
#ifdef EVDEV_SUPPORT |
1431 |
static int |
1432 |
wsp_ev_open(struct evdev_dev *evdev) |
1433 |
{ |
1434 |
struct wsp_softc *sc = evdev_get_softc(evdev); |
1435 |
int rc = 0; |
1436 |
|
1437 |
mtx_lock(&sc->sc_mutex); |
1438 |
if (sc->sc_fflags == 0) |
1439 |
rc = wsp_enable(sc); |
1440 |
if (rc == 0) { |
1441 |
wsp_start_read(sc); |
1442 |
sc->sc_state |= WSP_EVDEV_OPENED; |
1443 |
} |
1444 |
mtx_unlock(&sc->sc_mutex); |
1445 |
|
1446 |
return (rc); |
1447 |
} |
1448 |
|
1449 |
static int |
1450 |
wsp_ev_close(struct evdev_dev *evdev) |
1451 |
{ |
1452 |
struct wsp_softc *sc = evdev_get_softc(evdev); |
1453 |
|
1454 |
mtx_lock(&sc->sc_mutex); |
1455 |
sc->sc_state &= ~WSP_EVDEV_OPENED; |
1456 |
if (sc->sc_fflags == 0) |
1457 |
wsp_stop_read(sc); |
1458 |
mtx_unlock(&sc->sc_mutex); |
1459 |
|
1460 |
return (0); |
1461 |
} |
1462 |
#endif |
1463 |
|
1304 |
int |
1464 |
int |
1305 |
wsp_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags) |
1465 |
wsp_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, int fflags) |
1306 |
{ |
1466 |
{ |
Lines 1412-1416
static devclass_t wsp_devclass;
Link Here
|
1412 |
DRIVER_MODULE(wsp, uhub, wsp_driver, wsp_devclass, NULL, 0); |
1572 |
DRIVER_MODULE(wsp, uhub, wsp_driver, wsp_devclass, NULL, 0); |
1413 |
MODULE_DEPEND(wsp, usb, 1, 1, 1); |
1573 |
MODULE_DEPEND(wsp, usb, 1, 1, 1); |
1414 |
MODULE_DEPEND(wsp, hid, 1, 1, 1); |
1574 |
MODULE_DEPEND(wsp, hid, 1, 1, 1); |
|
|
1575 |
#ifdef EVDEV_SUPPORT |
1576 |
MODULE_DEPEND(wsp, evdev, 1, 1, 1); |
1577 |
#endif |
1415 |
MODULE_VERSION(wsp, 1); |
1578 |
MODULE_VERSION(wsp, 1); |
1416 |
USB_PNP_HOST_INFO(wsp_devs); |
1579 |
USB_PNP_HOST_INFO(wsp_devs); |