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