xref: /netbsd-src/sys/dev/bluetooth/btmagic.c (revision b757af438b42b93f8c6571f026d8b8ef3eaf5fc9)
1 /*	$NetBSD: btmagic.c,v 1.2 2012/04/03 09:32:53 plunky Exp $	*/
2 
3 /*-
4  * Copyright (c) 2010 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Iain Hibbert.
9  *
10  * This code is derived from software contributed to The NetBSD Foundation
11  * by Lennart Augustsson (lennart@augustsson.net) at
12  * Carlstedt Research & Technology.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 /*-
36  * Copyright (c) 2006 Itronix Inc.
37  * All rights reserved.
38  *
39  * Written by Iain Hibbert for Itronix Inc.
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  * 1. Redistributions of source code must retain the above copyright
45  *    notice, this list of conditions and the following disclaimer.
46  * 2. Redistributions in binary form must reproduce the above copyright
47  *    notice, this list of conditions and the following disclaimer in the
48  *    documentation and/or other materials provided with the distribution.
49  * 3. The name of Itronix Inc. may not be used to endorse
50  *    or promote products derived from this software without specific
51  *    prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
55  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
57  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
58  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
60  * ON ANY THEORY OF LIABILITY, WHETHER IN
61  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
62  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
63  * POSSIBILITY OF SUCH DAMAGE.
64  */
65 
66 
67 /*****************************************************************************
68  *
69  *		Apple Bluetooth Magic Mouse driver
70  *
71  * The Apple Magic Mouse is a HID device but it doesn't provide a proper HID
72  * descriptor, and requires extra initializations to enable the proprietary
73  * touch reports. We match against the vendor-id and product-id and provide
74  * our own Bluetooth connection handling as the bthidev driver does not cater
75  * for such complications.
76  *
77  * This driver interprets the touch reports only as far as emulating a
78  * middle mouse button and providing horizontal and vertical scroll action.
79  * Full gesture support would be more complicated and is left as an exercise
80  * for the reader.
81  *
82  * Credit for decoding the proprietary touch reports goes to Michael Poole
83  * who wrote the Linux hid-magicmouse input driver.
84  *
85  *****************************************************************************/
86 
87 #include <sys/cdefs.h>
88 __KERNEL_RCSID(0, "$NetBSD: btmagic.c,v 1.2 2012/04/03 09:32:53 plunky Exp $");
89 
90 #include <sys/param.h>
91 #include <sys/conf.h>
92 #include <sys/device.h>
93 #include <sys/fcntl.h>
94 #include <sys/kernel.h>
95 #include <sys/malloc.h>
96 #include <sys/mbuf.h>
97 #include <sys/proc.h>
98 #include <sys/socketvar.h>
99 #include <sys/systm.h>
100 #include <sys/sysctl.h>
101 
102 #include <prop/proplib.h>
103 
104 #include <netbt/bluetooth.h>
105 #include <netbt/l2cap.h>
106 
107 #include <dev/bluetooth/btdev.h>
108 #include <dev/bluetooth/bthid.h>
109 #include <dev/bluetooth/bthidev.h>
110 
111 #include <dev/usb/hid.h>
112 #include <dev/usb/usb.h>
113 #include <dev/usb/usbdevs.h>
114 
115 #include <dev/wscons/wsconsio.h>
116 #include <dev/wscons/wsmousevar.h>
117 
118 #undef	DPRINTF
119 #ifdef	BTMAGIC_DEBUG
120 #define	DPRINTF(sc, ...) do {				\
121 	printf("%s: ", device_xname((sc)->sc_dev));	\
122 	printf(__VA_ARGS__);				\
123 	printf("\n");					\
124 } while (/*CONSTCOND*/0)
125 #else
126 #define	DPRINTF(...)	(void)0
127 #endif
128 
129 struct btmagic_softc {
130 	bdaddr_t		sc_laddr;	/* local address */
131 	bdaddr_t		sc_raddr;	/* remote address */
132 	struct sockopt		sc_mode;	/* link mode */
133 
134 	device_t		sc_dev;
135 	uint16_t		sc_state;
136 	uint16_t		sc_flags;
137 
138 	callout_t		sc_timeout;
139 
140 	/* control */
141 	struct l2cap_channel	*sc_ctl;
142 	struct l2cap_channel	*sc_ctl_l;
143 
144 	/* interrupt */
145 	struct l2cap_channel	*sc_int;
146 	struct l2cap_channel	*sc_int_l;
147 
148 	/* wsmouse child */
149 	device_t		sc_wsmouse;
150 	int			sc_enabled;
151 
152 	/* config */
153 	int			sc_resolution;	/* for soft scaling */
154 	int			sc_firm;	/* firm touch threshold */
155 	int			sc_dist;	/* scroll distance threshold */
156 	int			sc_scale;	/* scroll descaling */
157 	struct sysctllog	*sc_log;	/* sysctl teardown log */
158 
159 	/* remainders */
160 	int			sc_rx;
161 	int			sc_ry;
162 	int			sc_rz;
163 	int			sc_rw;
164 
165 	/* previous touches */
166 	uint32_t		sc_smask;	/* scrolling */
167 	int			sc_az[16];
168 	int			sc_aw[16];
169 
170 	/* previous mouse buttons */
171 	uint32_t		sc_mb;
172 };
173 
174 /* sc_flags */
175 #define BTMAGIC_CONNECTING	__BIT(0) /* we are connecting */
176 #define BTMAGIC_ENABLED		__BIT(1) /* touch reports enabled */
177 
178 /* sc_state */
179 #define BTMAGIC_CLOSED		0
180 #define BTMAGIC_WAIT_CTL	1
181 #define BTMAGIC_WAIT_INT	2
182 #define BTMAGIC_OPEN		3
183 
184 /* autoconf(9) glue */
185 static int  btmagic_match(device_t, cfdata_t, void *);
186 static void btmagic_attach(device_t, device_t, void *);
187 static int  btmagic_detach(device_t, int);
188 static int  btmagic_listen(struct btmagic_softc *);
189 static int  btmagic_connect(struct btmagic_softc *);
190 static int  btmagic_sysctl_resolution(SYSCTLFN_PROTO);
191 static int  btmagic_sysctl_scale(SYSCTLFN_PROTO);
192 
193 CFATTACH_DECL_NEW(btmagic, sizeof(struct btmagic_softc),
194     btmagic_match, btmagic_attach, btmagic_detach, NULL);
195 
196 /* wsmouse(4) accessops */
197 static int btmagic_wsmouse_enable(void *);
198 static int btmagic_wsmouse_ioctl(void *, unsigned long, void *, int, struct lwp *);
199 static void btmagic_wsmouse_disable(void *);
200 
201 static const struct wsmouse_accessops btmagic_wsmouse_accessops = {
202 	btmagic_wsmouse_enable,
203 	btmagic_wsmouse_ioctl,
204 	btmagic_wsmouse_disable,
205 };
206 
207 /* bluetooth(9) protocol methods for L2CAP */
208 static void  btmagic_connecting(void *);
209 static void  btmagic_ctl_connected(void *);
210 static void  btmagic_int_connected(void *);
211 static void  btmagic_ctl_disconnected(void *, int);
212 static void  btmagic_int_disconnected(void *, int);
213 static void *btmagic_ctl_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
214 static void *btmagic_int_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
215 static void  btmagic_complete(void *, int);
216 static void  btmagic_linkmode(void *, int);
217 static void  btmagic_input(void *, struct mbuf *);
218 static void  btmagic_input_basic(struct btmagic_softc *, uint8_t *, size_t);
219 static void  btmagic_input_magic(struct btmagic_softc *, uint8_t *, size_t);
220 
221 static const struct btproto btmagic_ctl_proto = {
222 	btmagic_connecting,
223 	btmagic_ctl_connected,
224 	btmagic_ctl_disconnected,
225 	btmagic_ctl_newconn,
226 	btmagic_complete,
227 	btmagic_linkmode,
228 	btmagic_input,
229 };
230 
231 static const struct btproto btmagic_int_proto = {
232 	btmagic_connecting,
233 	btmagic_int_connected,
234 	btmagic_int_disconnected,
235 	btmagic_int_newconn,
236 	btmagic_complete,
237 	btmagic_linkmode,
238 	btmagic_input,
239 };
240 
241 /* btmagic internals */
242 static void btmagic_timeout(void *);
243 static int  btmagic_ctl_send(struct btmagic_softc *, const uint8_t *, size_t);
244 static void btmagic_enable(struct btmagic_softc *);
245 static void btmagic_check_battery(struct btmagic_softc *);
246 static int  btmagic_scale(int, int *, int);
247 
248 
249 /*****************************************************************************
250  *
251  *	Magic Mouse autoconf(9) routines
252  */
253 
254 static int
255 btmagic_match(device_t self, cfdata_t cfdata, void *aux)
256 {
257 	uint16_t v, p;
258 
259 	if (prop_dictionary_get_uint16(aux, BTDEVvendor, &v)
260 	    && prop_dictionary_get_uint16(aux, BTDEVproduct, &p)
261 	    && v == USB_VENDOR_APPLE
262 	    && p == USB_PRODUCT_APPLE_MAGICMOUSE)
263 		return 2;	/* trump bthidev(4) */
264 
265 	return 0;
266 }
267 
268 static void
269 btmagic_attach(device_t parent, device_t self, void *aux)
270 {
271 	struct btmagic_softc *sc = device_private(self);
272 	struct wsmousedev_attach_args wsma;
273 	const struct sysctlnode *node;
274 	prop_object_t obj;
275 
276 	/*
277 	 * Init softc
278 	 */
279 	sc->sc_dev = self;
280 	sc->sc_state = BTMAGIC_CLOSED;
281 	callout_init(&sc->sc_timeout, 0);
282 	callout_setfunc(&sc->sc_timeout, btmagic_timeout, sc);
283 	sockopt_init(&sc->sc_mode, BTPROTO_L2CAP, SO_L2CAP_LM, 0);
284 
285 	/*
286 	 * extract config from proplist
287 	 */
288 	obj = prop_dictionary_get(aux, BTDEVladdr);
289 	bdaddr_copy(&sc->sc_laddr, prop_data_data_nocopy(obj));
290 
291 	obj = prop_dictionary_get(aux, BTDEVraddr);
292 	bdaddr_copy(&sc->sc_raddr, prop_data_data_nocopy(obj));
293 
294 	obj = prop_dictionary_get(aux, BTDEVmode);
295 	if (prop_object_type(obj) == PROP_TYPE_STRING) {
296 		if (prop_string_equals_cstring(obj, BTDEVauth))
297 			sockopt_setint(&sc->sc_mode, L2CAP_LM_AUTH);
298 		else if (prop_string_equals_cstring(obj, BTDEVencrypt))
299 			sockopt_setint(&sc->sc_mode, L2CAP_LM_ENCRYPT);
300 		else if (prop_string_equals_cstring(obj, BTDEVsecure))
301 			sockopt_setint(&sc->sc_mode, L2CAP_LM_SECURE);
302 		else  {
303 			aprint_error(" unknown %s\n", BTDEVmode);
304 			return;
305 		}
306 
307 		aprint_verbose(" %s %s", BTDEVmode,
308 		    prop_string_cstring_nocopy(obj));
309 	}
310 
311 	aprint_normal(": 3 buttons, W and Z dirs\n");
312 	aprint_naive("\n");
313 
314 	/*
315 	 * set defaults
316 	 */
317 	sc->sc_resolution = 650;
318 	sc->sc_firm = 6;
319 	sc->sc_dist = 130;
320 	sc->sc_scale = 20;
321 
322 	sysctl_createv(&sc->sc_log, 0, NULL, NULL,
323 		CTLFLAG_PERMANENT,
324 		CTLTYPE_NODE, "hw",
325 		NULL,
326 		NULL, 0,
327 		NULL, 0,
328 		CTL_HW, CTL_EOL);
329 
330 	sysctl_createv(&sc->sc_log, 0, NULL, &node,
331 		0,
332 		CTLTYPE_NODE, device_xname(self),
333 		NULL,
334 		NULL, 0,
335 		NULL, 0,
336 		CTL_HW,
337 		CTL_CREATE, CTL_EOL);
338 
339 	if (node != NULL) {
340 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
341 			CTLFLAG_READWRITE,
342 			CTLTYPE_INT, "soft_resolution",
343 			NULL,
344 			btmagic_sysctl_resolution, 0,
345 			sc, 0,
346 			CTL_HW, node->sysctl_num,
347 			CTL_CREATE, CTL_EOL);
348 
349 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
350 			CTLFLAG_READWRITE,
351 			CTLTYPE_INT, "firm_touch_threshold",
352 			NULL,
353 			NULL, 0,
354 			&sc->sc_firm, sizeof(sc->sc_firm),
355 			CTL_HW, node->sysctl_num,
356 			CTL_CREATE, CTL_EOL);
357 
358 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
359 			CTLFLAG_READWRITE,
360 			CTLTYPE_INT, "scroll_distance_threshold",
361 			NULL,
362 			NULL, 0,
363 			&sc->sc_dist, sizeof(sc->sc_dist),
364 			CTL_HW, node->sysctl_num,
365 			CTL_CREATE, CTL_EOL);
366 
367 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
368 			CTLFLAG_READWRITE,
369 			CTLTYPE_INT, "scroll_downscale_factor",
370 			NULL,
371 			btmagic_sysctl_scale, 0,
372 			sc, 0,
373 			CTL_HW, node->sysctl_num,
374 			CTL_CREATE, CTL_EOL);
375 	}
376 
377 	/*
378 	 * attach the wsmouse
379 	 */
380 	wsma.accessops = &btmagic_wsmouse_accessops;
381 	wsma.accesscookie = self;
382 	sc->sc_wsmouse = config_found(self, &wsma, wsmousedevprint);
383 	if (sc->sc_wsmouse == NULL) {
384 		aprint_error_dev(self, "failed to attach wsmouse\n");
385 		return;
386 	}
387 
388 	pmf_device_register(self, NULL, NULL);
389 
390 	/*
391 	 * start bluetooth connections
392 	 */
393 	mutex_enter(bt_lock);
394 	btmagic_listen(sc);
395 	btmagic_connect(sc);
396 	mutex_exit(bt_lock);
397 }
398 
399 static int
400 btmagic_detach(device_t self, int flags)
401 {
402 	struct btmagic_softc *sc = device_private(self);
403 	int err = 0;
404 
405 	mutex_enter(bt_lock);
406 
407 	/* release interrupt listen */
408 	if (sc->sc_int_l != NULL) {
409 		l2cap_detach(&sc->sc_int_l);
410 		sc->sc_int_l = NULL;
411 	}
412 
413 	/* release control listen */
414 	if (sc->sc_ctl_l != NULL) {
415 		l2cap_detach(&sc->sc_ctl_l);
416 		sc->sc_ctl_l = NULL;
417 	}
418 
419 	/* close interrupt channel */
420 	if (sc->sc_int != NULL) {
421 		l2cap_disconnect(sc->sc_int, 0);
422 		l2cap_detach(&sc->sc_int);
423 		sc->sc_int = NULL;
424 	}
425 
426 	/* close control channel */
427 	if (sc->sc_ctl != NULL) {
428 		l2cap_disconnect(sc->sc_ctl, 0);
429 		l2cap_detach(&sc->sc_ctl);
430 		sc->sc_ctl = NULL;
431 	}
432 
433 	callout_halt(&sc->sc_timeout, bt_lock);
434 	callout_destroy(&sc->sc_timeout);
435 
436 	mutex_exit(bt_lock);
437 
438 	pmf_device_deregister(self);
439 
440 	sockopt_destroy(&sc->sc_mode);
441 
442 	sysctl_teardown(&sc->sc_log);
443 
444 	if (sc->sc_wsmouse != NULL) {
445 		err = config_detach(sc->sc_wsmouse, flags);
446 		sc->sc_wsmouse = NULL;
447 	}
448 
449 	return err;
450 }
451 
452 /*
453  * listen for our device
454  *
455  * bt_lock is held
456  */
457 static int
458 btmagic_listen(struct btmagic_softc *sc)
459 {
460 	struct sockaddr_bt sa;
461 	int err;
462 
463 	memset(&sa, 0, sizeof(sa));
464 	sa.bt_len = sizeof(sa);
465 	sa.bt_family = AF_BLUETOOTH;
466 	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
467 
468 	/*
469 	 * Listen on control PSM
470 	 */
471 	err = l2cap_attach(&sc->sc_ctl_l, &btmagic_ctl_proto, sc);
472 	if (err)
473 		return err;
474 
475 	err = l2cap_setopt(sc->sc_ctl_l, &sc->sc_mode);
476 	if (err)
477 		return err;
478 
479 	sa.bt_psm = L2CAP_PSM_HID_CNTL;
480 	err = l2cap_bind(sc->sc_ctl_l, &sa);
481 	if (err)
482 		return err;
483 
484 	err = l2cap_listen(sc->sc_ctl_l);
485 	if (err)
486 		return err;
487 
488 	/*
489 	 * Listen on interrupt PSM
490 	 */
491 	err = l2cap_attach(&sc->sc_int_l, &btmagic_int_proto, sc);
492 	if (err)
493 		return err;
494 
495 	err = l2cap_setopt(sc->sc_int_l, &sc->sc_mode);
496 	if (err)
497 		return err;
498 
499 	sa.bt_psm = L2CAP_PSM_HID_INTR;
500 	err = l2cap_bind(sc->sc_int_l, &sa);
501 	if (err)
502 		return err;
503 
504 	err = l2cap_listen(sc->sc_int_l);
505 	if (err)
506 		return err;
507 
508 	sc->sc_state = BTMAGIC_WAIT_CTL;
509 	return 0;
510 }
511 
512 /*
513  * start connecting to our device
514  *
515  * bt_lock is held
516  */
517 static int
518 btmagic_connect(struct btmagic_softc *sc)
519 {
520 	struct sockaddr_bt sa;
521 	int err;
522 
523 	memset(&sa, 0, sizeof(sa));
524 	sa.bt_len = sizeof(sa);
525 	sa.bt_family = AF_BLUETOOTH;
526 
527 	err = l2cap_attach(&sc->sc_ctl, &btmagic_ctl_proto, sc);
528 	if (err) {
529 		printf("%s: l2cap_attach failed (%d)\n",
530 		    device_xname(sc->sc_dev), err);
531 		return err;
532 	}
533 
534 	err = l2cap_setopt(sc->sc_ctl, &sc->sc_mode);
535 	if (err)
536 		return err;
537 
538 	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
539 	err = l2cap_bind(sc->sc_ctl, &sa);
540 	if (err) {
541 		printf("%s: l2cap_bind failed (%d)\n",
542 		    device_xname(sc->sc_dev), err);
543 		return err;
544 	}
545 
546 	sa.bt_psm = L2CAP_PSM_HID_CNTL;
547 	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
548 	err = l2cap_connect(sc->sc_ctl, &sa);
549 	if (err) {
550 		printf("%s: l2cap_connect failed (%d)\n",
551 		    device_xname(sc->sc_dev), err);
552 		return err;
553 	}
554 
555 	SET(sc->sc_flags, BTMAGIC_CONNECTING);
556 	sc->sc_state = BTMAGIC_WAIT_CTL;
557 	return 0;
558 }
559 
560 /* validate soft_resolution */
561 static int
562 btmagic_sysctl_resolution(SYSCTLFN_ARGS)
563 {
564 	struct sysctlnode node;
565 	struct btmagic_softc *sc;
566 	int t, error;
567 
568 	node = *rnode;
569 	sc = node.sysctl_data;
570 
571 	t = sc->sc_resolution;
572 	node.sysctl_data = &t;
573 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
574 	if (error || newp == NULL)
575 		return error;
576 
577 	if (t < 100 || t > 4000 || (t / sc->sc_scale) == 0)
578 		return EINVAL;
579 
580 	sc->sc_resolution = t;
581 	DPRINTF(sc, "sc_resolution = %u", t);
582 	return 0;
583 }
584 
585 /* validate scroll_downscale_factor */
586 static int
587 btmagic_sysctl_scale(SYSCTLFN_ARGS)
588 {
589 	struct sysctlnode node;
590 	struct btmagic_softc *sc;
591 	int t, error;
592 
593 	node = *rnode;
594 	sc = node.sysctl_data;
595 
596 	t = sc->sc_scale;
597 	node.sysctl_data = &t;
598 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
599 	if (error || newp == NULL)
600 		return error;
601 
602 	if (t < 1 || t > 40 || (sc->sc_resolution / t) == 0)
603 		return EINVAL;
604 
605 	sc->sc_scale = t;
606 	DPRINTF(sc, "sc_scale = %u", t);
607 	return 0;
608 }
609 
610 /*****************************************************************************
611  *
612  *	wsmouse(4) accessops
613  */
614 
615 static int
616 btmagic_wsmouse_enable(void *self)
617 {
618 	struct btmagic_softc *sc = device_private(self);
619 
620 	if (sc->sc_enabled)
621 		return EBUSY;
622 
623 	sc->sc_enabled = 1;
624 	DPRINTF(sc, "enable");
625 	return 0;
626 }
627 
628 static int
629 btmagic_wsmouse_ioctl(void *self, unsigned long cmd, void *data,
630     int flag, struct lwp *l)
631 {
632 	/* struct btmagic_softc *sc = device_private(self); */
633 	int err;
634 
635 	switch (cmd) {
636 	case WSMOUSEIO_GTYPE:
637 		*(uint *)data = WSMOUSE_TYPE_BLUETOOTH;
638 		err = 0;
639 		break;
640 
641 	default:
642 		err = EPASSTHROUGH;
643 		break;
644 	}
645 
646 	return err;
647 }
648 
649 static void
650 btmagic_wsmouse_disable(void *self)
651 {
652 	struct btmagic_softc *sc = device_private(self);
653 
654 	DPRINTF(sc, "disable");
655 	sc->sc_enabled = 0;
656 }
657 
658 
659 /*****************************************************************************
660  *
661  *	setup routines
662  */
663 
664 static void
665 btmagic_timeout(void *arg)
666 {
667 	struct btmagic_softc *sc = arg;
668 
669 	mutex_enter(bt_lock);
670 	callout_ack(&sc->sc_timeout);
671 
672 	switch (sc->sc_state) {
673 	case BTMAGIC_CLOSED:
674 		if (sc->sc_int != NULL) {
675 			l2cap_disconnect(sc->sc_int, 0);
676 			break;
677 		}
678 
679 		if (sc->sc_ctl != NULL) {
680 			l2cap_disconnect(sc->sc_ctl, 0);
681 			break;
682 		}
683 		break;
684 
685 	case BTMAGIC_OPEN:
686 		if (!ISSET(sc->sc_flags, BTMAGIC_ENABLED)) {
687 			btmagic_enable(sc);
688 			break;
689 		}
690 
691 		btmagic_check_battery(sc);
692 		break;
693 
694 	case BTMAGIC_WAIT_CTL:
695 	case BTMAGIC_WAIT_INT:
696 	default:
697 		break;
698 	}
699 	mutex_exit(bt_lock);
700 }
701 
702 /*
703  * Send report on control channel
704  *
705  * bt_lock is held
706  */
707 static int
708 btmagic_ctl_send(struct btmagic_softc *sc, const uint8_t *data, size_t len)
709 {
710 	struct mbuf *m;
711 
712 	if (len > MLEN)
713 		return EINVAL;
714 
715 	m = m_gethdr(M_DONTWAIT, MT_DATA);
716 	if (m == NULL)
717 		return ENOMEM;
718 
719 #ifdef BTMAGIC_DEBUG
720 	printf("%s: send", device_xname(sc->sc_dev));
721 	for (size_t i = 0; i < len; i++)
722 		printf(" 0x%02x", data[i]);
723 	printf("\n");
724 #endif
725 
726 	memcpy(mtod(m, uint8_t *), data, len);
727 	m->m_pkthdr.len = m->m_len = len;
728 	return l2cap_send(sc->sc_ctl, m);
729 }
730 
731 /*
732  * Enable touch reports by sending the following report
733  *
734  *	 SET_REPORT(FEATURE, 0xd7) = 0x01
735  *
736  * bt_lock is held
737  */
738 static void
739 btmagic_enable(struct btmagic_softc *sc)
740 {
741 	static const uint8_t rep[] = { 0x53, 0xd7, 0x01 };
742 
743 	if (btmagic_ctl_send(sc, rep, sizeof(rep)) != 0) {
744 		printf("%s: cannot enable touch reports\n",
745 		    device_xname(sc->sc_dev));
746 
747 		return;
748 	}
749 
750 	SET(sc->sc_flags, BTMAGIC_ENABLED);
751 }
752 
753 /*
754  * Request the battery level by sending the following report
755  *
756  *	GET_REPORT(FEATURE, 0x47)
757  *
758  * bt_lock is held
759  */
760 static void
761 btmagic_check_battery(struct btmagic_softc *sc)
762 {
763 	static const uint8_t rep[] = { 0x43, 0x47 };
764 
765 	if (btmagic_ctl_send(sc, rep, sizeof(rep)) != 0)
766 		printf("%s: cannot request battery level\n",
767 		    device_xname(sc->sc_dev));
768 }
769 
770 /*
771  * the Magic Mouse has a base resolution of 1300dpi which is rather flighty. We
772  * scale the output to the requested resolution, taking care to account for the
773  * remainders to prevent loss of small deltas.
774  */
775 static int
776 btmagic_scale(int delta, int *remainder, int resolution)
777 {
778 	int new;
779 
780 	delta += *remainder;
781 	new = delta * resolution / 1300;
782 	*remainder = delta - new * 1300 / resolution;
783 	return new;
784 }
785 
786 
787 /*****************************************************************************
788  *
789  *	bluetooth(9) callback methods for L2CAP
790  *
791  *	All these are called from Bluetooth Protocol code, holding bt_lock.
792  */
793 
794 static void
795 btmagic_connecting(void *arg)
796 {
797 
798 	/* dont care */
799 }
800 
801 static void
802 btmagic_ctl_connected(void *arg)
803 {
804 	struct sockaddr_bt sa;
805 	struct btmagic_softc *sc = arg;
806 	int err;
807 
808 	if (sc->sc_state != BTMAGIC_WAIT_CTL)
809 		return;
810 
811 	KASSERT(sc->sc_ctl != NULL);
812 	KASSERT(sc->sc_int == NULL);
813 
814 	if (ISSET(sc->sc_flags, BTMAGIC_CONNECTING)) {
815 		/* initiate connect on interrupt PSM */
816 		err = l2cap_attach(&sc->sc_int, &btmagic_int_proto, sc);
817 		if (err)
818 			goto fail;
819 
820 		err = l2cap_setopt(sc->sc_int, &sc->sc_mode);
821 		if (err)
822 			goto fail;
823 
824 		memset(&sa, 0, sizeof(sa));
825 		sa.bt_len = sizeof(sa);
826 		sa.bt_family = AF_BLUETOOTH;
827 		bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
828 
829 		err = l2cap_bind(sc->sc_int, &sa);
830 		if (err)
831 			goto fail;
832 
833 		sa.bt_psm = L2CAP_PSM_HID_INTR;
834 		bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
835 		err = l2cap_connect(sc->sc_int, &sa);
836 		if (err)
837 			goto fail;
838 	}
839 
840 	sc->sc_state = BTMAGIC_WAIT_INT;
841 	return;
842 
843 fail:
844 	l2cap_detach(&sc->sc_ctl);
845 	sc->sc_ctl = NULL;
846 
847 	printf("%s: connect failed (%d)\n", device_xname(sc->sc_dev), err);
848 }
849 
850 static void
851 btmagic_int_connected(void *arg)
852 {
853 	struct btmagic_softc *sc = arg;
854 
855 	if (sc->sc_state != BTMAGIC_WAIT_INT)
856 		return;
857 
858 	KASSERT(sc->sc_ctl != NULL);
859 	KASSERT(sc->sc_int != NULL);
860 
861 	printf("%s: connected\n", device_xname(sc->sc_dev));
862 	CLR(sc->sc_flags, BTMAGIC_CONNECTING);
863 	sc->sc_state = BTMAGIC_OPEN;
864 
865 	/* trigger the setup */
866 	CLR(sc->sc_flags, BTMAGIC_ENABLED);
867 	callout_schedule(&sc->sc_timeout, hz);
868 }
869 
870 /*
871  * Disconnected
872  *
873  * Depending on our state, this could mean several things, but essentially
874  * we are lost. If both channels are closed, schedule another connection.
875  */
876 static void
877 btmagic_ctl_disconnected(void *arg, int err)
878 {
879 	struct btmagic_softc *sc = arg;
880 
881 	if (sc->sc_ctl != NULL) {
882 		l2cap_detach(&sc->sc_ctl);
883 		sc->sc_ctl = NULL;
884 	}
885 
886 	if (sc->sc_int == NULL) {
887 		printf("%s: disconnected\n", device_xname(sc->sc_dev));
888 		CLR(sc->sc_flags, BTMAGIC_CONNECTING);
889 		sc->sc_state = BTMAGIC_WAIT_CTL;
890 	} else {
891 		/*
892 		 * The interrupt channel should have been closed first,
893 		 * but its potentially unsafe to detach that from here.
894 		 * Give them a second to do the right thing or let the
895 		 * callout handle it.
896 		 */
897 		sc->sc_state = BTMAGIC_CLOSED;
898 		callout_schedule(&sc->sc_timeout, hz);
899 	}
900 }
901 
902 static void
903 btmagic_int_disconnected(void *arg, int err)
904 {
905 	struct btmagic_softc *sc = arg;
906 
907 	if (sc->sc_int != NULL) {
908 		l2cap_detach(&sc->sc_int);
909 		sc->sc_int = NULL;
910 	}
911 
912 	if (sc->sc_ctl == NULL) {
913 		printf("%s: disconnected\n", device_xname(sc->sc_dev));
914 		CLR(sc->sc_flags, BTMAGIC_CONNECTING);
915 		sc->sc_state = BTMAGIC_WAIT_CTL;
916 	} else {
917 		/*
918 		 * The control channel should be closing also, allow
919 		 * them a chance to do that before we force it.
920 		 */
921 		sc->sc_state = BTMAGIC_CLOSED;
922 		callout_schedule(&sc->sc_timeout, hz);
923 	}
924 }
925 
926 /*
927  * New Connections
928  *
929  * We give a new L2CAP handle back if this matches the BDADDR we are
930  * listening for and we are in the right state. btmagic_connected will
931  * be called when the connection is open, so nothing else to do here
932  */
933 static void *
934 btmagic_ctl_newconn(void *arg, struct sockaddr_bt *laddr,
935     struct sockaddr_bt *raddr)
936 {
937 	struct btmagic_softc *sc = arg;
938 
939 	if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0)
940 		return NULL;
941 
942 	if (sc->sc_state != BTMAGIC_WAIT_CTL
943 	    || ISSET(sc->sc_flags, BTMAGIC_CONNECTING)
944 	    || sc->sc_ctl != NULL
945 	    || sc->sc_int != NULL) {
946 		DPRINTF(sc, "reject ctl newconn %s%s%s%s",
947 		    (sc->sc_state == BTMAGIC_WAIT_CTL) ? " (WAITING)": "",
948 		    ISSET(sc->sc_flags, BTMAGIC_CONNECTING) ? " (CONNECTING)" : "",
949 		    (sc->sc_ctl != NULL) ? " (GOT CONTROL)" : "",
950 		    (sc->sc_int != NULL) ? " (GOT INTERRUPT)" : "");
951 
952 		return NULL;
953 	}
954 
955 	l2cap_attach(&sc->sc_ctl, &btmagic_ctl_proto, sc);
956 	return sc->sc_ctl;
957 }
958 
959 static void *
960 btmagic_int_newconn(void *arg, struct sockaddr_bt *laddr,
961     struct sockaddr_bt *raddr)
962 {
963 	struct btmagic_softc *sc = arg;
964 
965 	if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0)
966 		return NULL;
967 
968 	if (sc->sc_state != BTMAGIC_WAIT_INT
969 	    || ISSET(sc->sc_flags, BTMAGIC_CONNECTING)
970 	    || sc->sc_ctl == NULL
971 	    || sc->sc_int != NULL) {
972 		DPRINTF(sc, "reject int newconn %s%s%s%s",
973 		    (sc->sc_state == BTMAGIC_WAIT_INT) ? " (WAITING)": "",
974 		    ISSET(sc->sc_flags, BTMAGIC_CONNECTING) ? " (CONNECTING)" : "",
975 		    (sc->sc_ctl == NULL) ? " (NO CONTROL)" : "",
976 		    (sc->sc_int != NULL) ? " (GOT INTERRUPT)" : "");
977 
978 		return NULL;
979 	}
980 
981 	l2cap_attach(&sc->sc_int, &btmagic_int_proto, sc);
982 	return sc->sc_int;
983 }
984 
985 static void
986 btmagic_complete(void *arg, int count)
987 {
988 
989 	/* dont care */
990 }
991 
992 static void
993 btmagic_linkmode(void *arg, int new)
994 {
995 	struct btmagic_softc *sc = arg;
996 	int mode;
997 
998 	(void)sockopt_getint(&sc->sc_mode, &mode);
999 
1000 	if (ISSET(mode, L2CAP_LM_AUTH) && !ISSET(new, L2CAP_LM_AUTH))
1001 		printf("%s: auth failed\n", device_xname(sc->sc_dev));
1002 	else if (ISSET(mode, L2CAP_LM_ENCRYPT) && !ISSET(new, L2CAP_LM_ENCRYPT))
1003 		printf("%s: encrypt off\n", device_xname(sc->sc_dev));
1004 	else if (ISSET(mode, L2CAP_LM_SECURE) && !ISSET(new, L2CAP_LM_SECURE))
1005 		printf("%s: insecure\n", device_xname(sc->sc_dev));
1006 	else
1007 		return;
1008 
1009 	if (sc->sc_int != NULL)
1010 		l2cap_disconnect(sc->sc_int, 0);
1011 
1012 	if (sc->sc_ctl != NULL)
1013 		l2cap_disconnect(sc->sc_ctl, 0);
1014 }
1015 
1016 /*
1017  * Receive transaction from the mouse. We don't differentiate between
1018  * interrupt and control channel here, there is no need.
1019  */
1020 static void
1021 btmagic_input(void *arg, struct mbuf *m)
1022 {
1023 	struct btmagic_softc *sc = arg;
1024 	uint8_t *data;
1025 	size_t len;
1026 
1027 	if (sc->sc_state != BTMAGIC_OPEN
1028 	    || sc->sc_wsmouse == NULL
1029 	    || sc->sc_enabled == 0)
1030 		goto release;
1031 
1032 	if (m->m_pkthdr.len > m->m_len)
1033 		printf("%s: truncating input\n", device_xname(sc->sc_dev));
1034 
1035 	data = mtod(m, uint8_t *);
1036 	len = m->m_len;
1037 
1038 	if (len < 1)
1039 		goto release;
1040 
1041 	switch (BTHID_TYPE(data[0])) {
1042 	case BTHID_HANDSHAKE:
1043 		DPRINTF(sc, "Handshake: 0x%x", BTHID_HANDSHAKE_PARAM(data[0]));
1044 		callout_schedule(&sc->sc_timeout, hz);
1045 		break;
1046 
1047 	case BTHID_DATA:
1048 		if (len < 2)
1049 			break;
1050 
1051 		switch (data[1]) {
1052 		case 0x10: /* Basic mouse (input) */
1053 			btmagic_input_basic(sc, data + 2, len - 2);
1054 			break;
1055 
1056 		case 0x29: /* Magic touch (input) */
1057 			btmagic_input_magic(sc, data + 2, len - 2);
1058 			break;
1059 
1060 		case 0x30: /* Battery status (input) */
1061 			if (len != 3)
1062 				break;
1063 
1064 			printf("%s: Battery ", device_xname(sc->sc_dev));
1065 			switch (data[2]) {
1066 			case 0:	printf("Ok\n");			break;
1067 			case 1:	printf("Warning\n");		break;
1068 			case 2:	printf("Critical\n");		break;
1069 			default: printf("0x%02x\n", data[2]);	break;
1070 			}
1071 			break;
1072 
1073 		case 0x47: /* Battery strength (feature) */
1074 			if (len != 3)
1075 				break;
1076 
1077 			printf("%s: Battery %d%%\n", device_xname(sc->sc_dev),
1078 			    data[2]);
1079 			break;
1080 
1081 		case 0x61: /* Surface detection (input) */
1082 			if (len != 3)
1083 				break;
1084 
1085 			DPRINTF(sc, "Mouse %s",
1086 			    (data[2] == 0 ? "lowered" : "raised"));
1087 			break;
1088 
1089 		case 0x60: /* unknown (input) */
1090 		case 0xf0: /* unknown (feature) */
1091 		case 0xf1: /* unknown (feature) */
1092 		default:
1093 #if BTMAGIC_DEBUG
1094 			printf("%s: recv", device_xname(sc->sc_dev));
1095 			for (size_t i = 0; i < len; i++)
1096 				printf(" 0x%02x", data[i]);
1097 			printf("\n");
1098 #endif
1099 			break;
1100 		}
1101 		break;
1102 
1103 	default:
1104 		DPRINTF(sc, "transaction (type 0x%x)", BTHID_TYPE(data[0]));
1105 		break;
1106 	}
1107 
1108 release:
1109 	m_freem(m);
1110 }
1111 
1112 /*
1113  * parse the Basic report (0x10), which according to the provided
1114  * HID descriptor is in the following format
1115  *
1116  *	button 1	1-bit
1117  *	button 2	1-bit
1118  *	padding		6-bits
1119  *	dX		16-bits (signed)
1120  *	dY		16-bits (signed)
1121  *
1122  * Even when the magic touch reports are enabled, the basic report is
1123  * sent for mouse move events where no touches are detected.
1124  */
1125 static const struct {
1126 	struct hid_location button1;
1127 	struct hid_location button2;
1128 	struct hid_location dX;
1129 	struct hid_location dY;
1130 } basic = {
1131 	.button1 = { .pos =  0, .size = 1 },
1132 	.button2 = { .pos =  1, .size = 1 },
1133 	.dX = { .pos =  8, .size = 16 },
1134 	.dY = { .pos = 24, .size = 16 },
1135 };
1136 
1137 static void
1138 btmagic_input_basic(struct btmagic_softc *sc, uint8_t *data, size_t len)
1139 {
1140 	int dx, dy;
1141 	uint32_t mb;
1142 	int s;
1143 
1144 	if (len != 5)
1145 		return;
1146 
1147 	dx = hid_get_data(data, &basic.dX);
1148 	dx = btmagic_scale(dx, &sc->sc_rx, sc->sc_resolution);
1149 
1150 	dy = hid_get_data(data, &basic.dY);
1151 	dy = btmagic_scale(dy, &sc->sc_ry, sc->sc_resolution);
1152 
1153 	mb = 0;
1154 	if (hid_get_udata(data, &basic.button1))
1155 		mb |= __BIT(0);
1156 	if (hid_get_udata(data, &basic.button2))
1157 		mb |= __BIT(2);
1158 
1159 	if (dx != 0 || dy != 0 || mb != sc->sc_mb) {
1160 		sc->sc_mb = mb;
1161 
1162 		s = spltty();
1163 		wsmouse_input(sc->sc_wsmouse, mb,
1164 		    dx, -dy, 0, 0, WSMOUSE_INPUT_DELTA);
1165 		splx(s);
1166 	}
1167 }
1168 
1169 /*
1170  * the Magic touch report (0x29), according to the Linux driver
1171  * written by Michael Poole, is variable length starting with the
1172  * fixed 40-bit header
1173  *
1174  *	dX lsb		8-bits (signed)
1175  *	dY lsb		8-bits (signed)
1176  *	button 1	1-bit
1177  *	button 2	1-bit
1178  *	dX msb		2-bits (signed)
1179  *	dY msb		2-bits (signed)
1180  *	timestamp	18-bits
1181  *
1182  * followed by (up to 5?) touch reports of 64-bits each
1183  *
1184  *	abs W		12-bits (signed)
1185  *	abs Z		12-bits (signed)
1186  *	axis major	8-bits
1187  *	axis minor	8-bits
1188  *	pressure	6-bits
1189  *	id		4-bits
1190  *	angle		6-bits	(from E(0)->N(32)->W(64))
1191  *	unknown		4-bits
1192  *	phase		4-bits
1193  */
1194 
1195 static const struct {
1196 	struct hid_location dXl;
1197 	struct hid_location dYl;
1198 	struct hid_location button1;
1199 	struct hid_location button2;
1200 	struct hid_location dXm;
1201 	struct hid_location dYm;
1202 	struct hid_location timestamp;
1203 } magic = {
1204 	.dXl = { .pos = 0, .size = 8 },
1205 	.dYl = { .pos = 8, .size = 8 },
1206 	.button1 = { .pos = 16, .size = 1 },
1207 	.button2 = { .pos = 17, .size = 1 },
1208 	.dXm = { .pos = 18, .size = 2 },
1209 	.dYm = { .pos = 20, .size = 2 },
1210 	.timestamp = { .pos = 22, .size = 18 },
1211 };
1212 
1213 static const struct {
1214 	struct hid_location aW;
1215 	struct hid_location aZ;
1216 	struct hid_location major;
1217 	struct hid_location minor;
1218 	struct hid_location pressure;
1219 	struct hid_location id;
1220 	struct hid_location angle;
1221 	struct hid_location unknown;
1222 	struct hid_location phase;
1223 } touch = {
1224 	.aW = { .pos = 0, .size = 12 },
1225 	.aZ = { .pos = 12, .size = 12 },
1226 	.major = { .pos = 24, .size = 8 },
1227 	.minor = { .pos = 32, .size = 8 },
1228 	.pressure = { .pos = 40, .size = 6 },
1229 	.id = { .pos = 46, .size = 4 },
1230 	.angle = { .pos = 50, .size = 6 },
1231 	.unknown = { .pos = 56, .size = 4 },
1232 	.phase = { .pos = 60, .size = 4 },
1233 };
1234 
1235 /*
1236  * the phase of the touch starts at 0x01 as the finger is first detected
1237  * approaching the mouse, increasing to 0x04 while the finger is touching,
1238  * then increases towards 0x07 as the finger is lifted, and we get 0x00
1239  * when the touch is cancelled. The values below seem to be produced for
1240  * every touch, the others less consistently depending on how fast the
1241  * approach or departure is.
1242  *
1243  * In fact we ignore touches unless they are in the steady 0x04 phase.
1244  */
1245 #define BTMAGIC_PHASE_START	0x3
1246 #define BTMAGIC_PHASE_CONT	0x4
1247 #define BTMAGIC_PHASE_END	0x7
1248 #define BTMAGIC_PHASE_CANCEL	0x0
1249 
1250 static void
1251 btmagic_input_magic(struct btmagic_softc *sc, uint8_t *data, size_t len)
1252 {
1253 	uint32_t mb;
1254 	int dx, dy, dz, dw;
1255 	int id, nf, az, aw, tz, tw;
1256 	int s;
1257 
1258 	if (((len - 5) % 8) != 0)
1259 		return;
1260 
1261 	dx = (hid_get_data(data, &magic.dXm) << 8)
1262 	    | (hid_get_data(data, &magic.dXl) & 0xff);
1263 	dx = btmagic_scale(dx, &sc->sc_rx, sc->sc_resolution);
1264 
1265 	dy = (hid_get_data(data, &magic.dYm) << 8)
1266 	    | (hid_get_data(data, &magic.dYl) & 0xff);
1267 	dy = btmagic_scale(dy, &sc->sc_ry, sc->sc_resolution);
1268 
1269 	mb = 0;
1270 	if (hid_get_udata(data, &magic.button1))
1271 		mb |= __BIT(0);
1272 	if (hid_get_udata(data, &magic.button2))
1273 		mb |= __BIT(2);
1274 
1275 	nf = 0;
1276 	dz = 0;
1277 	dw = 0;
1278 	len = (len - 5) / 8;
1279 	for (data += 5; len-- > 0; data += 8) {
1280 		id = hid_get_udata(data, &touch.id);
1281 		az = hid_get_data(data, &touch.aZ);
1282 		aw = hid_get_data(data, &touch.aW);
1283 
1284 		/*
1285 		 * scrolling is triggered by an established touch moving
1286 		 * beyond a minimum distance from its start point and is
1287 		 * cancelled as the touch starts to fade.
1288 		 *
1289 		 * Multiple touches may be scrolling simultaneously, the
1290 		 * effect is cumulative.
1291 		 */
1292 
1293 		switch (hid_get_udata(data, &touch.phase)) {
1294 		case BTMAGIC_PHASE_CONT:
1295 			tz = az - sc->sc_az[id];
1296 			tw = aw - sc->sc_aw[id];
1297 
1298 			if (ISSET(sc->sc_smask, id)) {
1299 				/* scrolling finger */
1300 				dz += btmagic_scale(tz, &sc->sc_rz,
1301 				    sc->sc_resolution / sc->sc_scale);
1302 				dw += btmagic_scale(tw, &sc->sc_rw,
1303 				    sc->sc_resolution / sc->sc_scale);
1304 			} else if (abs(tz) > sc->sc_dist
1305 			    || abs(tw) > sc->sc_dist) {
1306 				/* new scrolling finger */
1307 				if (sc->sc_smask == 0) {
1308 					sc->sc_rz = 0;
1309 					sc->sc_rw = 0;
1310 				}
1311 
1312 				SET(sc->sc_smask, id);
1313 			} else {
1314 				/* not scrolling finger */
1315 				az = sc->sc_az[id];
1316 				aw = sc->sc_aw[id];
1317 			}
1318 
1319 			/* count firm touches for middle-click */
1320 			if (hid_get_udata(data, &touch.pressure) > sc->sc_firm)
1321 				nf++;
1322 
1323 			break;
1324 
1325 		default:
1326 			CLR(sc->sc_smask, id);
1327 			break;
1328 		}
1329 
1330 		sc->sc_az[id] = az;
1331 		sc->sc_aw[id] = aw;
1332 	}
1333 
1334 	/*
1335 	 * The mouse only has one click detector, and says left or right but
1336 	 * never both. We convert multiple firm touches while clicking into
1337 	 * a middle button press, and cancel any scroll effects while click
1338 	 * is active.
1339 	 */
1340 	if (mb != 0) {
1341 		if (sc->sc_mb != 0)
1342 			mb = sc->sc_mb;
1343 		else if (nf > 1)
1344 			mb = __BIT(1);
1345 
1346 		sc->sc_smask = 0;
1347 		dz = 0;
1348 		dw = 0;
1349 	}
1350 
1351 	if (dx != 0 || dy != 0 || dz != 0 || dw != 0 || mb != sc->sc_mb) {
1352 		sc->sc_mb = mb;
1353 
1354 		s = spltty();
1355 		wsmouse_input(sc->sc_wsmouse, mb,
1356 		    dx, -dy, -dz, dw, WSMOUSE_INPUT_DELTA);
1357 		splx(s);
1358 	}
1359 }
1360