xref: /netbsd-src/sys/dev/bluetooth/btmagic.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*	$NetBSD: btmagic.c,v 1.7 2014/05/20 18:25:54 rmind 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.7 2014/05/20 18:25:54 rmind 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 	int err;
276 
277 	/*
278 	 * Init softc
279 	 */
280 	sc->sc_dev = self;
281 	sc->sc_state = BTMAGIC_CLOSED;
282 	callout_init(&sc->sc_timeout, 0);
283 	callout_setfunc(&sc->sc_timeout, btmagic_timeout, sc);
284 	sockopt_init(&sc->sc_mode, BTPROTO_L2CAP, SO_L2CAP_LM, 0);
285 
286 	/*
287 	 * extract config from proplist
288 	 */
289 	obj = prop_dictionary_get(aux, BTDEVladdr);
290 	bdaddr_copy(&sc->sc_laddr, prop_data_data_nocopy(obj));
291 
292 	obj = prop_dictionary_get(aux, BTDEVraddr);
293 	bdaddr_copy(&sc->sc_raddr, prop_data_data_nocopy(obj));
294 
295 	obj = prop_dictionary_get(aux, BTDEVmode);
296 	if (prop_object_type(obj) == PROP_TYPE_STRING) {
297 		if (prop_string_equals_cstring(obj, BTDEVauth))
298 			sockopt_setint(&sc->sc_mode, L2CAP_LM_AUTH);
299 		else if (prop_string_equals_cstring(obj, BTDEVencrypt))
300 			sockopt_setint(&sc->sc_mode, L2CAP_LM_ENCRYPT);
301 		else if (prop_string_equals_cstring(obj, BTDEVsecure))
302 			sockopt_setint(&sc->sc_mode, L2CAP_LM_SECURE);
303 		else  {
304 			aprint_error(" unknown %s\n", BTDEVmode);
305 			return;
306 		}
307 
308 		aprint_verbose(" %s %s", BTDEVmode,
309 		    prop_string_cstring_nocopy(obj));
310 	} else
311 		sockopt_setint(&sc->sc_mode, 0);
312 
313 	aprint_normal(": 3 buttons, W and Z dirs\n");
314 	aprint_naive("\n");
315 
316 	/*
317 	 * set defaults
318 	 */
319 	sc->sc_resolution = 650;
320 	sc->sc_firm = 6;
321 	sc->sc_dist = 130;
322 	sc->sc_scale = 20;
323 
324 	sysctl_createv(&sc->sc_log, 0, NULL, &node,
325 		0,
326 		CTLTYPE_NODE, device_xname(self),
327 		NULL,
328 		NULL, 0,
329 		NULL, 0,
330 		CTL_HW,
331 		CTL_CREATE, CTL_EOL);
332 
333 	if (node != NULL) {
334 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
335 			CTLFLAG_READWRITE,
336 			CTLTYPE_INT, "soft_resolution",
337 			NULL,
338 			btmagic_sysctl_resolution, 0,
339 			(void *)sc, 0,
340 			CTL_HW, node->sysctl_num,
341 			CTL_CREATE, CTL_EOL);
342 
343 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
344 			CTLFLAG_READWRITE,
345 			CTLTYPE_INT, "firm_touch_threshold",
346 			NULL,
347 			NULL, 0,
348 			&sc->sc_firm, sizeof(sc->sc_firm),
349 			CTL_HW, node->sysctl_num,
350 			CTL_CREATE, CTL_EOL);
351 
352 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
353 			CTLFLAG_READWRITE,
354 			CTLTYPE_INT, "scroll_distance_threshold",
355 			NULL,
356 			NULL, 0,
357 			&sc->sc_dist, sizeof(sc->sc_dist),
358 			CTL_HW, node->sysctl_num,
359 			CTL_CREATE, CTL_EOL);
360 
361 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
362 			CTLFLAG_READWRITE,
363 			CTLTYPE_INT, "scroll_downscale_factor",
364 			NULL,
365 			btmagic_sysctl_scale, 0,
366 			(void *)sc, 0,
367 			CTL_HW, node->sysctl_num,
368 			CTL_CREATE, CTL_EOL);
369 	}
370 
371 	/*
372 	 * attach the wsmouse
373 	 */
374 	wsma.accessops = &btmagic_wsmouse_accessops;
375 	wsma.accesscookie = self;
376 	sc->sc_wsmouse = config_found(self, &wsma, wsmousedevprint);
377 	if (sc->sc_wsmouse == NULL) {
378 		aprint_error_dev(self, "failed to attach wsmouse\n");
379 		return;
380 	}
381 
382 	pmf_device_register(self, NULL, NULL);
383 
384 	/*
385 	 * start bluetooth connections
386 	 */
387 	mutex_enter(bt_lock);
388 	if ((err = btmagic_listen(sc)) != 0)
389 		aprint_error_dev(self, "failed to listen (%d)\n", err);
390 	btmagic_connect(sc);
391 	mutex_exit(bt_lock);
392 }
393 
394 static int
395 btmagic_detach(device_t self, int flags)
396 {
397 	struct btmagic_softc *sc = device_private(self);
398 	int err = 0;
399 
400 	mutex_enter(bt_lock);
401 
402 	/* release interrupt listen */
403 	if (sc->sc_int_l != NULL) {
404 		l2cap_detach_pcb(&sc->sc_int_l);
405 		sc->sc_int_l = NULL;
406 	}
407 
408 	/* release control listen */
409 	if (sc->sc_ctl_l != NULL) {
410 		l2cap_detach_pcb(&sc->sc_ctl_l);
411 		sc->sc_ctl_l = NULL;
412 	}
413 
414 	/* close interrupt channel */
415 	if (sc->sc_int != NULL) {
416 		l2cap_disconnect(sc->sc_int, 0);
417 		l2cap_detach_pcb(&sc->sc_int);
418 		sc->sc_int = NULL;
419 	}
420 
421 	/* close control channel */
422 	if (sc->sc_ctl != NULL) {
423 		l2cap_disconnect(sc->sc_ctl, 0);
424 		l2cap_detach_pcb(&sc->sc_ctl);
425 		sc->sc_ctl = NULL;
426 	}
427 
428 	callout_halt(&sc->sc_timeout, bt_lock);
429 	callout_destroy(&sc->sc_timeout);
430 
431 	mutex_exit(bt_lock);
432 
433 	pmf_device_deregister(self);
434 
435 	sockopt_destroy(&sc->sc_mode);
436 
437 	sysctl_teardown(&sc->sc_log);
438 
439 	if (sc->sc_wsmouse != NULL) {
440 		err = config_detach(sc->sc_wsmouse, flags);
441 		sc->sc_wsmouse = NULL;
442 	}
443 
444 	return err;
445 }
446 
447 /*
448  * listen for our device
449  *
450  * bt_lock is held
451  */
452 static int
453 btmagic_listen(struct btmagic_softc *sc)
454 {
455 	struct sockaddr_bt sa;
456 	int err;
457 
458 	memset(&sa, 0, sizeof(sa));
459 	sa.bt_len = sizeof(sa);
460 	sa.bt_family = AF_BLUETOOTH;
461 	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
462 
463 	/*
464 	 * Listen on control PSM
465 	 */
466 	err = l2cap_attach_pcb(&sc->sc_ctl_l, &btmagic_ctl_proto, sc);
467 	if (err)
468 		return err;
469 
470 	err = l2cap_setopt(sc->sc_ctl_l, &sc->sc_mode);
471 	if (err)
472 		return err;
473 
474 	sa.bt_psm = L2CAP_PSM_HID_CNTL;
475 	err = l2cap_bind(sc->sc_ctl_l, &sa);
476 	if (err)
477 		return err;
478 
479 	err = l2cap_listen(sc->sc_ctl_l);
480 	if (err)
481 		return err;
482 
483 	/*
484 	 * Listen on interrupt PSM
485 	 */
486 	err = l2cap_attach_pcb(&sc->sc_int_l, &btmagic_int_proto, sc);
487 	if (err)
488 		return err;
489 
490 	err = l2cap_setopt(sc->sc_int_l, &sc->sc_mode);
491 	if (err)
492 		return err;
493 
494 	sa.bt_psm = L2CAP_PSM_HID_INTR;
495 	err = l2cap_bind(sc->sc_int_l, &sa);
496 	if (err)
497 		return err;
498 
499 	err = l2cap_listen(sc->sc_int_l);
500 	if (err)
501 		return err;
502 
503 	sc->sc_state = BTMAGIC_WAIT_CTL;
504 	return 0;
505 }
506 
507 /*
508  * start connecting to our device
509  *
510  * bt_lock is held
511  */
512 static int
513 btmagic_connect(struct btmagic_softc *sc)
514 {
515 	struct sockaddr_bt sa;
516 	int err;
517 
518 	memset(&sa, 0, sizeof(sa));
519 	sa.bt_len = sizeof(sa);
520 	sa.bt_family = AF_BLUETOOTH;
521 
522 	err = l2cap_attach_pcb(&sc->sc_ctl, &btmagic_ctl_proto, sc);
523 	if (err) {
524 		printf("%s: l2cap_attach failed (%d)\n",
525 		    device_xname(sc->sc_dev), err);
526 		return err;
527 	}
528 
529 	err = l2cap_setopt(sc->sc_ctl, &sc->sc_mode);
530 	if (err) {
531 		printf("%s: l2cap_setopt failed (%d)\n",
532 		    device_xname(sc->sc_dev), err);
533 		return err;
534 	}
535 
536 	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
537 	err = l2cap_bind(sc->sc_ctl, &sa);
538 	if (err) {
539 		printf("%s: l2cap_bind failed (%d)\n",
540 		    device_xname(sc->sc_dev), err);
541 		return err;
542 	}
543 
544 	sa.bt_psm = L2CAP_PSM_HID_CNTL;
545 	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
546 	err = l2cap_connect(sc->sc_ctl, &sa);
547 	if (err) {
548 		printf("%s: l2cap_connect failed (%d)\n",
549 		    device_xname(sc->sc_dev), err);
550 		return err;
551 	}
552 
553 	SET(sc->sc_flags, BTMAGIC_CONNECTING);
554 	sc->sc_state = BTMAGIC_WAIT_CTL;
555 	return 0;
556 }
557 
558 /* validate soft_resolution */
559 static int
560 btmagic_sysctl_resolution(SYSCTLFN_ARGS)
561 {
562 	struct sysctlnode node;
563 	struct btmagic_softc *sc;
564 	int t, error;
565 
566 	node = *rnode;
567 	sc = node.sysctl_data;
568 
569 	t = sc->sc_resolution;
570 	node.sysctl_data = &t;
571 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
572 	if (error || newp == NULL)
573 		return error;
574 
575 	if (t < 100 || t > 4000 || (t / sc->sc_scale) == 0)
576 		return EINVAL;
577 
578 	sc->sc_resolution = t;
579 	DPRINTF(sc, "sc_resolution = %u", t);
580 	return 0;
581 }
582 
583 /* validate scroll_downscale_factor */
584 static int
585 btmagic_sysctl_scale(SYSCTLFN_ARGS)
586 {
587 	struct sysctlnode node;
588 	struct btmagic_softc *sc;
589 	int t, error;
590 
591 	node = *rnode;
592 	sc = node.sysctl_data;
593 
594 	t = sc->sc_scale;
595 	node.sysctl_data = &t;
596 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
597 	if (error || newp == NULL)
598 		return error;
599 
600 	if (t < 1 || t > 40 || (sc->sc_resolution / t) == 0)
601 		return EINVAL;
602 
603 	sc->sc_scale = t;
604 	DPRINTF(sc, "sc_scale = %u", t);
605 	return 0;
606 }
607 
608 /*****************************************************************************
609  *
610  *	wsmouse(4) accessops
611  */
612 
613 static int
614 btmagic_wsmouse_enable(void *self)
615 {
616 	struct btmagic_softc *sc = device_private(self);
617 
618 	if (sc->sc_enabled)
619 		return EBUSY;
620 
621 	sc->sc_enabled = 1;
622 	DPRINTF(sc, "enable");
623 	return 0;
624 }
625 
626 static int
627 btmagic_wsmouse_ioctl(void *self, unsigned long cmd, void *data,
628     int flag, struct lwp *l)
629 {
630 	/* struct btmagic_softc *sc = device_private(self); */
631 	int err;
632 
633 	switch (cmd) {
634 	case WSMOUSEIO_GTYPE:
635 		*(uint *)data = WSMOUSE_TYPE_BLUETOOTH;
636 		err = 0;
637 		break;
638 
639 	default:
640 		err = EPASSTHROUGH;
641 		break;
642 	}
643 
644 	return err;
645 }
646 
647 static void
648 btmagic_wsmouse_disable(void *self)
649 {
650 	struct btmagic_softc *sc = device_private(self);
651 
652 	DPRINTF(sc, "disable");
653 	sc->sc_enabled = 0;
654 }
655 
656 
657 /*****************************************************************************
658  *
659  *	setup routines
660  */
661 
662 static void
663 btmagic_timeout(void *arg)
664 {
665 	struct btmagic_softc *sc = arg;
666 
667 	mutex_enter(bt_lock);
668 	callout_ack(&sc->sc_timeout);
669 
670 	switch (sc->sc_state) {
671 	case BTMAGIC_CLOSED:
672 		if (sc->sc_int != NULL) {
673 			l2cap_disconnect(sc->sc_int, 0);
674 			break;
675 		}
676 
677 		if (sc->sc_ctl != NULL) {
678 			l2cap_disconnect(sc->sc_ctl, 0);
679 			break;
680 		}
681 		break;
682 
683 	case BTMAGIC_OPEN:
684 		if (!ISSET(sc->sc_flags, BTMAGIC_ENABLED)) {
685 			btmagic_enable(sc);
686 			break;
687 		}
688 
689 		btmagic_check_battery(sc);
690 		break;
691 
692 	case BTMAGIC_WAIT_CTL:
693 	case BTMAGIC_WAIT_INT:
694 	default:
695 		break;
696 	}
697 	mutex_exit(bt_lock);
698 }
699 
700 /*
701  * Send report on control channel
702  *
703  * bt_lock is held
704  */
705 static int
706 btmagic_ctl_send(struct btmagic_softc *sc, const uint8_t *data, size_t len)
707 {
708 	struct mbuf *m;
709 
710 	if (len > MLEN)
711 		return EINVAL;
712 
713 	m = m_gethdr(M_DONTWAIT, MT_DATA);
714 	if (m == NULL)
715 		return ENOMEM;
716 
717 #ifdef BTMAGIC_DEBUG
718 	printf("%s: send", device_xname(sc->sc_dev));
719 	for (size_t i = 0; i < len; i++)
720 		printf(" 0x%02x", data[i]);
721 	printf("\n");
722 #endif
723 
724 	memcpy(mtod(m, uint8_t *), data, len);
725 	m->m_pkthdr.len = m->m_len = len;
726 	return l2cap_send(sc->sc_ctl, m);
727 }
728 
729 /*
730  * Enable touch reports by sending the following report
731  *
732  *	 SET_REPORT(FEATURE, 0xd7) = 0x01
733  *
734  * bt_lock is held
735  */
736 static void
737 btmagic_enable(struct btmagic_softc *sc)
738 {
739 	static const uint8_t rep[] = { 0x53, 0xd7, 0x01 };
740 
741 	if (btmagic_ctl_send(sc, rep, sizeof(rep)) != 0) {
742 		printf("%s: cannot enable touch reports\n",
743 		    device_xname(sc->sc_dev));
744 
745 		return;
746 	}
747 
748 	SET(sc->sc_flags, BTMAGIC_ENABLED);
749 }
750 
751 /*
752  * Request the battery level by sending the following report
753  *
754  *	GET_REPORT(FEATURE, 0x47)
755  *
756  * bt_lock is held
757  */
758 static void
759 btmagic_check_battery(struct btmagic_softc *sc)
760 {
761 	static const uint8_t rep[] = { 0x43, 0x47 };
762 
763 	if (btmagic_ctl_send(sc, rep, sizeof(rep)) != 0)
764 		printf("%s: cannot request battery level\n",
765 		    device_xname(sc->sc_dev));
766 }
767 
768 /*
769  * the Magic Mouse has a base resolution of 1300dpi which is rather flighty. We
770  * scale the output to the requested resolution, taking care to account for the
771  * remainders to prevent loss of small deltas.
772  */
773 static int
774 btmagic_scale(int delta, int *remainder, int resolution)
775 {
776 	int new;
777 
778 	delta += *remainder;
779 	new = delta * resolution / 1300;
780 	*remainder = delta - new * 1300 / resolution;
781 	return new;
782 }
783 
784 
785 /*****************************************************************************
786  *
787  *	bluetooth(9) callback methods for L2CAP
788  *
789  *	All these are called from Bluetooth Protocol code, holding bt_lock.
790  */
791 
792 static void
793 btmagic_connecting(void *arg)
794 {
795 
796 	/* dont care */
797 }
798 
799 static void
800 btmagic_ctl_connected(void *arg)
801 {
802 	struct sockaddr_bt sa;
803 	struct btmagic_softc *sc = arg;
804 	int err;
805 
806 	if (sc->sc_state != BTMAGIC_WAIT_CTL)
807 		return;
808 
809 	KASSERT(sc->sc_ctl != NULL);
810 	KASSERT(sc->sc_int == NULL);
811 
812 	if (ISSET(sc->sc_flags, BTMAGIC_CONNECTING)) {
813 		/* initiate connect on interrupt PSM */
814 		err = l2cap_attach_pcb(&sc->sc_int, &btmagic_int_proto, sc);
815 		if (err)
816 			goto fail;
817 
818 		err = l2cap_setopt(sc->sc_int, &sc->sc_mode);
819 		if (err)
820 			goto fail;
821 
822 		memset(&sa, 0, sizeof(sa));
823 		sa.bt_len = sizeof(sa);
824 		sa.bt_family = AF_BLUETOOTH;
825 		bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
826 
827 		err = l2cap_bind(sc->sc_int, &sa);
828 		if (err)
829 			goto fail;
830 
831 		sa.bt_psm = L2CAP_PSM_HID_INTR;
832 		bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
833 		err = l2cap_connect(sc->sc_int, &sa);
834 		if (err)
835 			goto fail;
836 	}
837 
838 	sc->sc_state = BTMAGIC_WAIT_INT;
839 	return;
840 
841 fail:
842 	l2cap_detach_pcb(&sc->sc_ctl);
843 	sc->sc_ctl = NULL;
844 
845 	printf("%s: connect failed (%d)\n", device_xname(sc->sc_dev), err);
846 }
847 
848 static void
849 btmagic_int_connected(void *arg)
850 {
851 	struct btmagic_softc *sc = arg;
852 
853 	if (sc->sc_state != BTMAGIC_WAIT_INT)
854 		return;
855 
856 	KASSERT(sc->sc_ctl != NULL);
857 	KASSERT(sc->sc_int != NULL);
858 
859 	printf("%s: connected\n", device_xname(sc->sc_dev));
860 	CLR(sc->sc_flags, BTMAGIC_CONNECTING);
861 	sc->sc_state = BTMAGIC_OPEN;
862 
863 	/* trigger the setup */
864 	CLR(sc->sc_flags, BTMAGIC_ENABLED);
865 	callout_schedule(&sc->sc_timeout, hz);
866 }
867 
868 /*
869  * Disconnected
870  *
871  * Depending on our state, this could mean several things, but essentially
872  * we are lost. If both channels are closed, schedule another connection.
873  */
874 static void
875 btmagic_ctl_disconnected(void *arg, int err)
876 {
877 	struct btmagic_softc *sc = arg;
878 
879 	if (sc->sc_ctl != NULL) {
880 		l2cap_detach_pcb(&sc->sc_ctl);
881 		sc->sc_ctl = NULL;
882 	}
883 
884 	if (sc->sc_int == NULL) {
885 		printf("%s: disconnected (%d)\n", device_xname(sc->sc_dev), err);
886 		CLR(sc->sc_flags, BTMAGIC_CONNECTING);
887 		sc->sc_state = BTMAGIC_WAIT_CTL;
888 	} else {
889 		/*
890 		 * The interrupt channel should have been closed first,
891 		 * but its potentially unsafe to detach that from here.
892 		 * Give them a second to do the right thing or let the
893 		 * callout handle it.
894 		 */
895 		sc->sc_state = BTMAGIC_CLOSED;
896 		callout_schedule(&sc->sc_timeout, hz);
897 	}
898 }
899 
900 static void
901 btmagic_int_disconnected(void *arg, int err)
902 {
903 	struct btmagic_softc *sc = arg;
904 
905 	if (sc->sc_int != NULL) {
906 		l2cap_detach_pcb(&sc->sc_int);
907 		sc->sc_int = NULL;
908 	}
909 
910 	if (sc->sc_ctl == NULL) {
911 		printf("%s: disconnected (%d)\n", device_xname(sc->sc_dev), err);
912 		CLR(sc->sc_flags, BTMAGIC_CONNECTING);
913 		sc->sc_state = BTMAGIC_WAIT_CTL;
914 	} else {
915 		/*
916 		 * The control channel should be closing also, allow
917 		 * them a chance to do that before we force it.
918 		 */
919 		sc->sc_state = BTMAGIC_CLOSED;
920 		callout_schedule(&sc->sc_timeout, hz);
921 	}
922 }
923 
924 /*
925  * New Connections
926  *
927  * We give a new L2CAP handle back if this matches the BDADDR we are
928  * listening for and we are in the right state. btmagic_connected will
929  * be called when the connection is open, so nothing else to do here
930  */
931 static void *
932 btmagic_ctl_newconn(void *arg, struct sockaddr_bt *laddr,
933     struct sockaddr_bt *raddr)
934 {
935 	struct btmagic_softc *sc = arg;
936 
937 	if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0)
938 		return NULL;
939 
940 	if (sc->sc_state != BTMAGIC_WAIT_CTL
941 	    || ISSET(sc->sc_flags, BTMAGIC_CONNECTING)
942 	    || sc->sc_ctl != NULL
943 	    || sc->sc_int != NULL) {
944 		DPRINTF(sc, "reject ctl newconn %s%s%s%s",
945 		    (sc->sc_state == BTMAGIC_WAIT_CTL) ? " (WAITING)": "",
946 		    ISSET(sc->sc_flags, BTMAGIC_CONNECTING) ? " (CONNECTING)" : "",
947 		    (sc->sc_ctl != NULL) ? " (GOT CONTROL)" : "",
948 		    (sc->sc_int != NULL) ? " (GOT INTERRUPT)" : "");
949 
950 		return NULL;
951 	}
952 
953 	l2cap_attach_pcb(&sc->sc_ctl, &btmagic_ctl_proto, sc);
954 	return sc->sc_ctl;
955 }
956 
957 static void *
958 btmagic_int_newconn(void *arg, struct sockaddr_bt *laddr,
959     struct sockaddr_bt *raddr)
960 {
961 	struct btmagic_softc *sc = arg;
962 
963 	if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0)
964 		return NULL;
965 
966 	if (sc->sc_state != BTMAGIC_WAIT_INT
967 	    || ISSET(sc->sc_flags, BTMAGIC_CONNECTING)
968 	    || sc->sc_ctl == NULL
969 	    || sc->sc_int != NULL) {
970 		DPRINTF(sc, "reject int newconn %s%s%s%s",
971 		    (sc->sc_state == BTMAGIC_WAIT_INT) ? " (WAITING)": "",
972 		    ISSET(sc->sc_flags, BTMAGIC_CONNECTING) ? " (CONNECTING)" : "",
973 		    (sc->sc_ctl == NULL) ? " (NO CONTROL)" : "",
974 		    (sc->sc_int != NULL) ? " (GOT INTERRUPT)" : "");
975 
976 		return NULL;
977 	}
978 
979 	l2cap_attach_pcb(&sc->sc_int, &btmagic_int_proto, sc);
980 	return sc->sc_int;
981 }
982 
983 static void
984 btmagic_complete(void *arg, int count)
985 {
986 
987 	/* dont care */
988 }
989 
990 static void
991 btmagic_linkmode(void *arg, int new)
992 {
993 	struct btmagic_softc *sc = arg;
994 	int mode;
995 
996 	(void)sockopt_getint(&sc->sc_mode, &mode);
997 
998 	if (ISSET(mode, L2CAP_LM_AUTH) && !ISSET(new, L2CAP_LM_AUTH))
999 		printf("%s: auth failed\n", device_xname(sc->sc_dev));
1000 	else if (ISSET(mode, L2CAP_LM_ENCRYPT) && !ISSET(new, L2CAP_LM_ENCRYPT))
1001 		printf("%s: encrypt off\n", device_xname(sc->sc_dev));
1002 	else if (ISSET(mode, L2CAP_LM_SECURE) && !ISSET(new, L2CAP_LM_SECURE))
1003 		printf("%s: insecure\n", device_xname(sc->sc_dev));
1004 	else
1005 		return;
1006 
1007 	if (sc->sc_int != NULL)
1008 		l2cap_disconnect(sc->sc_int, 0);
1009 
1010 	if (sc->sc_ctl != NULL)
1011 		l2cap_disconnect(sc->sc_ctl, 0);
1012 }
1013 
1014 /*
1015  * Receive transaction from the mouse. We don't differentiate between
1016  * interrupt and control channel here, there is no need.
1017  */
1018 static void
1019 btmagic_input(void *arg, struct mbuf *m)
1020 {
1021 	struct btmagic_softc *sc = arg;
1022 	uint8_t *data;
1023 	size_t len;
1024 
1025 	if (sc->sc_state != BTMAGIC_OPEN
1026 	    || sc->sc_wsmouse == NULL
1027 	    || sc->sc_enabled == 0)
1028 		goto release;
1029 
1030 	if (m->m_pkthdr.len > m->m_len)
1031 		printf("%s: truncating input\n", device_xname(sc->sc_dev));
1032 
1033 	data = mtod(m, uint8_t *);
1034 	len = m->m_len;
1035 
1036 	if (len < 1)
1037 		goto release;
1038 
1039 	switch (BTHID_TYPE(data[0])) {
1040 	case BTHID_HANDSHAKE:
1041 		DPRINTF(sc, "Handshake: 0x%x", BTHID_HANDSHAKE_PARAM(data[0]));
1042 		callout_schedule(&sc->sc_timeout, hz);
1043 		break;
1044 
1045 	case BTHID_DATA:
1046 		if (len < 2)
1047 			break;
1048 
1049 		switch (data[1]) {
1050 		case 0x10: /* Basic mouse (input) */
1051 			btmagic_input_basic(sc, data + 2, len - 2);
1052 			break;
1053 
1054 		case 0x29: /* Magic touch (input) */
1055 			btmagic_input_magic(sc, data + 2, len - 2);
1056 			break;
1057 
1058 		case 0x30: /* Battery status (input) */
1059 			if (len != 3)
1060 				break;
1061 
1062 			printf("%s: Battery ", device_xname(sc->sc_dev));
1063 			switch (data[2]) {
1064 			case 0:	printf("Ok\n");			break;
1065 			case 1:	printf("Warning\n");		break;
1066 			case 2:	printf("Critical\n");		break;
1067 			default: printf("0x%02x\n", data[2]);	break;
1068 			}
1069 			break;
1070 
1071 		case 0x47: /* Battery strength (feature) */
1072 			if (len != 3)
1073 				break;
1074 
1075 			printf("%s: Battery %d%%\n", device_xname(sc->sc_dev),
1076 			    data[2]);
1077 			break;
1078 
1079 		case 0x61: /* Surface detection (input) */
1080 			if (len != 3)
1081 				break;
1082 
1083 			DPRINTF(sc, "Mouse %s",
1084 			    (data[2] == 0 ? "lowered" : "raised"));
1085 			break;
1086 
1087 		case 0x60: /* unknown (input) */
1088 		case 0xf0: /* unknown (feature) */
1089 		case 0xf1: /* unknown (feature) */
1090 		default:
1091 #if BTMAGIC_DEBUG
1092 			printf("%s: recv", device_xname(sc->sc_dev));
1093 			for (size_t i = 0; i < len; i++)
1094 				printf(" 0x%02x", data[i]);
1095 			printf("\n");
1096 #endif
1097 			break;
1098 		}
1099 		break;
1100 
1101 	default:
1102 		DPRINTF(sc, "transaction (type 0x%x)", BTHID_TYPE(data[0]));
1103 		break;
1104 	}
1105 
1106 release:
1107 	m_freem(m);
1108 }
1109 
1110 /*
1111  * parse the Basic report (0x10), which according to the provided
1112  * HID descriptor is in the following format
1113  *
1114  *	button 1	1-bit
1115  *	button 2	1-bit
1116  *	padding		6-bits
1117  *	dX		16-bits (signed)
1118  *	dY		16-bits (signed)
1119  *
1120  * Even when the magic touch reports are enabled, the basic report is
1121  * sent for mouse move events where no touches are detected.
1122  */
1123 static const struct {
1124 	struct hid_location button1;
1125 	struct hid_location button2;
1126 	struct hid_location dX;
1127 	struct hid_location dY;
1128 } basic = {
1129 	.button1 = { .pos =  0, .size = 1 },
1130 	.button2 = { .pos =  1, .size = 1 },
1131 	.dX = { .pos =  8, .size = 16 },
1132 	.dY = { .pos = 24, .size = 16 },
1133 };
1134 
1135 static void
1136 btmagic_input_basic(struct btmagic_softc *sc, uint8_t *data, size_t len)
1137 {
1138 	int dx, dy;
1139 	uint32_t mb;
1140 	int s;
1141 
1142 	if (len != 5)
1143 		return;
1144 
1145 	dx = hid_get_data(data, &basic.dX);
1146 	dx = btmagic_scale(dx, &sc->sc_rx, sc->sc_resolution);
1147 
1148 	dy = hid_get_data(data, &basic.dY);
1149 	dy = btmagic_scale(dy, &sc->sc_ry, sc->sc_resolution);
1150 
1151 	mb = 0;
1152 	if (hid_get_udata(data, &basic.button1))
1153 		mb |= __BIT(0);
1154 	if (hid_get_udata(data, &basic.button2))
1155 		mb |= __BIT(2);
1156 
1157 	if (dx != 0 || dy != 0 || mb != sc->sc_mb) {
1158 		sc->sc_mb = mb;
1159 
1160 		s = spltty();
1161 		wsmouse_input(sc->sc_wsmouse, mb,
1162 		    dx, -dy, 0, 0, WSMOUSE_INPUT_DELTA);
1163 		splx(s);
1164 	}
1165 }
1166 
1167 /*
1168  * the Magic touch report (0x29), according to the Linux driver
1169  * written by Michael Poole, is variable length starting with the
1170  * fixed 40-bit header
1171  *
1172  *	dX lsb		8-bits (signed)
1173  *	dY lsb		8-bits (signed)
1174  *	button 1	1-bit
1175  *	button 2	1-bit
1176  *	dX msb		2-bits (signed)
1177  *	dY msb		2-bits (signed)
1178  *	timestamp	18-bits
1179  *
1180  * followed by (up to 5?) touch reports of 64-bits each
1181  *
1182  *	abs W		12-bits (signed)
1183  *	abs Z		12-bits (signed)
1184  *	axis major	8-bits
1185  *	axis minor	8-bits
1186  *	pressure	6-bits
1187  *	id		4-bits
1188  *	angle		6-bits	(from E(0)->N(32)->W(64))
1189  *	unknown		4-bits
1190  *	phase		4-bits
1191  */
1192 
1193 static const struct {
1194 	struct hid_location dXl;
1195 	struct hid_location dYl;
1196 	struct hid_location button1;
1197 	struct hid_location button2;
1198 	struct hid_location dXm;
1199 	struct hid_location dYm;
1200 	struct hid_location timestamp;
1201 } magic = {
1202 	.dXl = { .pos = 0, .size = 8 },
1203 	.dYl = { .pos = 8, .size = 8 },
1204 	.button1 = { .pos = 16, .size = 1 },
1205 	.button2 = { .pos = 17, .size = 1 },
1206 	.dXm = { .pos = 18, .size = 2 },
1207 	.dYm = { .pos = 20, .size = 2 },
1208 	.timestamp = { .pos = 22, .size = 18 },
1209 };
1210 
1211 static const struct {
1212 	struct hid_location aW;
1213 	struct hid_location aZ;
1214 	struct hid_location major;
1215 	struct hid_location minor;
1216 	struct hid_location pressure;
1217 	struct hid_location id;
1218 	struct hid_location angle;
1219 	struct hid_location unknown;
1220 	struct hid_location phase;
1221 } touch = {
1222 	.aW = { .pos = 0, .size = 12 },
1223 	.aZ = { .pos = 12, .size = 12 },
1224 	.major = { .pos = 24, .size = 8 },
1225 	.minor = { .pos = 32, .size = 8 },
1226 	.pressure = { .pos = 40, .size = 6 },
1227 	.id = { .pos = 46, .size = 4 },
1228 	.angle = { .pos = 50, .size = 6 },
1229 	.unknown = { .pos = 56, .size = 4 },
1230 	.phase = { .pos = 60, .size = 4 },
1231 };
1232 
1233 /*
1234  * the phase of the touch starts at 0x01 as the finger is first detected
1235  * approaching the mouse, increasing to 0x04 while the finger is touching,
1236  * then increases towards 0x07 as the finger is lifted, and we get 0x00
1237  * when the touch is cancelled. The values below seem to be produced for
1238  * every touch, the others less consistently depending on how fast the
1239  * approach or departure is.
1240  *
1241  * In fact we ignore touches unless they are in the steady 0x04 phase.
1242  */
1243 #define BTMAGIC_PHASE_START	0x3
1244 #define BTMAGIC_PHASE_CONT	0x4
1245 #define BTMAGIC_PHASE_END	0x7
1246 #define BTMAGIC_PHASE_CANCEL	0x0
1247 
1248 static void
1249 btmagic_input_magic(struct btmagic_softc *sc, uint8_t *data, size_t len)
1250 {
1251 	uint32_t mb;
1252 	int dx, dy, dz, dw;
1253 	int id, nf, az, aw, tz, tw;
1254 	int s;
1255 
1256 	if (((len - 5) % 8) != 0)
1257 		return;
1258 
1259 	dx = (hid_get_data(data, &magic.dXm) << 8)
1260 	    | (hid_get_data(data, &magic.dXl) & 0xff);
1261 	dx = btmagic_scale(dx, &sc->sc_rx, sc->sc_resolution);
1262 
1263 	dy = (hid_get_data(data, &magic.dYm) << 8)
1264 	    | (hid_get_data(data, &magic.dYl) & 0xff);
1265 	dy = btmagic_scale(dy, &sc->sc_ry, sc->sc_resolution);
1266 
1267 	mb = 0;
1268 	if (hid_get_udata(data, &magic.button1))
1269 		mb |= __BIT(0);
1270 	if (hid_get_udata(data, &magic.button2))
1271 		mb |= __BIT(2);
1272 
1273 	nf = 0;
1274 	dz = 0;
1275 	dw = 0;
1276 	len = (len - 5) / 8;
1277 	for (data += 5; len-- > 0; data += 8) {
1278 		id = hid_get_udata(data, &touch.id);
1279 		az = hid_get_data(data, &touch.aZ);
1280 		aw = hid_get_data(data, &touch.aW);
1281 
1282 		/*
1283 		 * scrolling is triggered by an established touch moving
1284 		 * beyond a minimum distance from its start point and is
1285 		 * cancelled as the touch starts to fade.
1286 		 *
1287 		 * Multiple touches may be scrolling simultaneously, the
1288 		 * effect is cumulative.
1289 		 */
1290 
1291 		switch (hid_get_udata(data, &touch.phase)) {
1292 		case BTMAGIC_PHASE_CONT:
1293 			tz = az - sc->sc_az[id];
1294 			tw = aw - sc->sc_aw[id];
1295 
1296 			if (ISSET(sc->sc_smask, id)) {
1297 				/* scrolling finger */
1298 				dz += btmagic_scale(tz, &sc->sc_rz,
1299 				    sc->sc_resolution / sc->sc_scale);
1300 				dw += btmagic_scale(tw, &sc->sc_rw,
1301 				    sc->sc_resolution / sc->sc_scale);
1302 			} else if (abs(tz) > sc->sc_dist
1303 			    || abs(tw) > sc->sc_dist) {
1304 				/* new scrolling finger */
1305 				if (sc->sc_smask == 0) {
1306 					sc->sc_rz = 0;
1307 					sc->sc_rw = 0;
1308 				}
1309 
1310 				SET(sc->sc_smask, id);
1311 			} else {
1312 				/* not scrolling finger */
1313 				az = sc->sc_az[id];
1314 				aw = sc->sc_aw[id];
1315 			}
1316 
1317 			/* count firm touches for middle-click */
1318 			if (hid_get_udata(data, &touch.pressure) > sc->sc_firm)
1319 				nf++;
1320 
1321 			break;
1322 
1323 		default:
1324 			CLR(sc->sc_smask, id);
1325 			break;
1326 		}
1327 
1328 		sc->sc_az[id] = az;
1329 		sc->sc_aw[id] = aw;
1330 	}
1331 
1332 	/*
1333 	 * The mouse only has one click detector, and says left or right but
1334 	 * never both. We convert multiple firm touches while clicking into
1335 	 * a middle button press, and cancel any scroll effects while click
1336 	 * is active.
1337 	 */
1338 	if (mb != 0) {
1339 		if (sc->sc_mb != 0)
1340 			mb = sc->sc_mb;
1341 		else if (nf > 1)
1342 			mb = __BIT(1);
1343 
1344 		sc->sc_smask = 0;
1345 		dz = 0;
1346 		dw = 0;
1347 	}
1348 
1349 	if (dx != 0 || dy != 0 || dz != 0 || dw != 0 || mb != sc->sc_mb) {
1350 		sc->sc_mb = mb;
1351 
1352 		s = spltty();
1353 		wsmouse_input(sc->sc_wsmouse, mb,
1354 		    dx, -dy, -dz, dw, WSMOUSE_INPUT_DELTA);
1355 		splx(s);
1356 	}
1357 }
1358