xref: /netbsd/sys/dev/bluetooth/btmagic.c (revision beecddb6)
1 /*	$NetBSD: btmagic.c,v 1.21 2021/08/07 16:19:09 thorpej 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.21 2021/08/07 16:19:09 thorpej 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/hid/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;	/* active IDs */
167 	int			sc_nfingers;	/* number of active IDs */
168 	int			sc_ax[16];
169 	int			sc_ay[16];
170 
171 	/* previous mouse buttons */
172 	int			sc_mb_id; /* which ID selects the button */
173 	uint32_t		sc_mb;
174 	/* button emulation with tap */
175 	int			sc_tapmb_id; /* which ID selects the button */
176 	struct timeval		sc_taptime;
177 	int			sc_taptimeout;
178 	callout_t		sc_tapcallout;
179 };
180 
181 /* sc_flags */
182 #define BTMAGIC_CONNECTING	__BIT(0) /* we are connecting */
183 #define BTMAGIC_ENABLED		__BIT(1) /* touch reports enabled */
184 
185 /* sc_state */
186 #define BTMAGIC_CLOSED		0
187 #define BTMAGIC_WAIT_CTL	1
188 #define BTMAGIC_WAIT_INT	2
189 #define BTMAGIC_OPEN		3
190 
191 /* autoconf(9) glue */
192 static int  btmagic_match(device_t, cfdata_t, void *);
193 static void btmagic_attach(device_t, device_t, void *);
194 static int  btmagic_detach(device_t, int);
195 static int  btmagic_listen(struct btmagic_softc *);
196 static int  btmagic_connect(struct btmagic_softc *);
197 static int  btmagic_sysctl_resolution(SYSCTLFN_PROTO);
198 static int  btmagic_sysctl_scale(SYSCTLFN_PROTO);
199 static int  btmagic_tap(struct btmagic_softc *, int);
200 static int  btmagic_sysctl_taptimeout(SYSCTLFN_PROTO);
201 
202 CFATTACH_DECL_NEW(btmagic, sizeof(struct btmagic_softc),
203     btmagic_match, btmagic_attach, btmagic_detach, NULL);
204 
205 /* wsmouse(4) accessops */
206 static int  btmagic_wsmouse_enable(void *);
207 static int  btmagic_wsmouse_ioctl(void *, unsigned long, void *, int, struct lwp *);
208 static void btmagic_wsmouse_disable(void *);
209 
210 static const struct wsmouse_accessops btmagic_wsmouse_accessops = {
211 	btmagic_wsmouse_enable,
212 	btmagic_wsmouse_ioctl,
213 	btmagic_wsmouse_disable,
214 };
215 
216 /* bluetooth(9) protocol methods for L2CAP */
217 static void  btmagic_connecting(void *);
218 static void  btmagic_ctl_connected(void *);
219 static void  btmagic_int_connected(void *);
220 static void  btmagic_ctl_disconnected(void *, int);
221 static void  btmagic_int_disconnected(void *, int);
222 static void *btmagic_ctl_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
223 static void *btmagic_int_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
224 static void  btmagic_complete(void *, int);
225 static void  btmagic_linkmode(void *, int);
226 static void  btmagic_input(void *, struct mbuf *);
227 static void  btmagic_input_basic(struct btmagic_softc *, uint8_t *, size_t);
228 static void  btmagic_input_magicm(struct btmagic_softc *, uint8_t *, size_t);
229 static void  btmagic_input_magict(struct btmagic_softc *, uint8_t *, size_t);
230 static void  btmagic_tapcallout(void *);
231 
232 /* report types (data[1]) */
233 #define BASIC_REPORT_ID		0x10
234 #define TRACKPAD_REPORT_ID	0x28
235 #define MOUSE_REPORT_ID		0x29
236 #define BATT_STAT_REPORT_ID	0x30
237 #define BATT_STRENGTH_REPORT_ID	0x47
238 #define SURFACE_REPORT_ID	0x61
239 
240 static const struct btproto btmagic_ctl_proto = {
241 	btmagic_connecting,
242 	btmagic_ctl_connected,
243 	btmagic_ctl_disconnected,
244 	btmagic_ctl_newconn,
245 	btmagic_complete,
246 	btmagic_linkmode,
247 	btmagic_input,
248 };
249 
250 static const struct btproto btmagic_int_proto = {
251 	btmagic_connecting,
252 	btmagic_int_connected,
253 	btmagic_int_disconnected,
254 	btmagic_int_newconn,
255 	btmagic_complete,
256 	btmagic_linkmode,
257 	btmagic_input,
258 };
259 
260 /* btmagic internals */
261 static void btmagic_timeout(void *);
262 static int  btmagic_ctl_send(struct btmagic_softc *, const uint8_t *, size_t);
263 static void btmagic_enable(struct btmagic_softc *);
264 static void btmagic_check_battery(struct btmagic_softc *);
265 static int  btmagic_scale(int, int *, int);
266 
267 
268 /*****************************************************************************
269  *
270  *	Magic Mouse autoconf(9) routines
271  */
272 
273 static int
btmagic_match(device_t self,cfdata_t cfdata,void * aux)274 btmagic_match(device_t self, cfdata_t cfdata, void *aux)
275 {
276 	uint16_t v, p;
277 
278 	if (prop_dictionary_get_uint16(aux, BTDEVvendor, &v)
279 	    && prop_dictionary_get_uint16(aux, BTDEVproduct, &p)
280 	    && v == USB_VENDOR_APPLE
281 	    && (p == USB_PRODUCT_APPLE_MAGICMOUSE ||
282 		p == USB_PRODUCT_APPLE_MAGICTRACKPAD))
283 		return 2;	/* trump bthidev(4) */
284 
285 	return 0;
286 }
287 
288 static void
btmagic_attach(device_t parent,device_t self,void * aux)289 btmagic_attach(device_t parent, device_t self, void *aux)
290 {
291 	struct btmagic_softc *sc = device_private(self);
292 	struct wsmousedev_attach_args wsma;
293 	const struct sysctlnode *node;
294 	prop_object_t obj;
295 	int err;
296 
297 	/*
298 	 * Init softc
299 	 */
300 	sc->sc_dev = self;
301 	sc->sc_state = BTMAGIC_CLOSED;
302 	sc->sc_mb_id = -1;
303 	sc->sc_tapmb_id = -1;
304 	callout_init(&sc->sc_timeout, 0);
305 	callout_setfunc(&sc->sc_timeout, btmagic_timeout, sc);
306 	callout_init(&sc->sc_tapcallout, 0);
307 	callout_setfunc(&sc->sc_tapcallout, btmagic_tapcallout, sc);
308 	sockopt_init(&sc->sc_mode, BTPROTO_L2CAP, SO_L2CAP_LM, 0);
309 
310 	/*
311 	 * extract config from proplist
312 	 */
313 	obj = prop_dictionary_get(aux, BTDEVladdr);
314 	bdaddr_copy(&sc->sc_laddr, prop_data_value(obj));
315 
316 	obj = prop_dictionary_get(aux, BTDEVraddr);
317 	bdaddr_copy(&sc->sc_raddr, prop_data_value(obj));
318 
319 	obj = prop_dictionary_get(aux, BTDEVmode);
320 	if (prop_object_type(obj) == PROP_TYPE_STRING) {
321 		if (prop_string_equals_string(obj, BTDEVauth))
322 			sockopt_setint(&sc->sc_mode, L2CAP_LM_AUTH);
323 		else if (prop_string_equals_string(obj, BTDEVencrypt))
324 			sockopt_setint(&sc->sc_mode, L2CAP_LM_ENCRYPT);
325 		else if (prop_string_equals_string(obj, BTDEVsecure))
326 			sockopt_setint(&sc->sc_mode, L2CAP_LM_SECURE);
327 		else  {
328 			aprint_error(" unknown %s\n", BTDEVmode);
329 			return;
330 		}
331 
332 		aprint_verbose(" %s %s", BTDEVmode,
333 		    prop_string_value(obj));
334 	} else
335 		sockopt_setint(&sc->sc_mode, 0);
336 
337 	aprint_normal(": 3 buttons, W and Z dirs\n");
338 	aprint_naive("\n");
339 
340 	/*
341 	 * set defaults
342 	 */
343 	sc->sc_resolution = 650;
344 	sc->sc_firm = 6;
345 	sc->sc_dist = 130;
346 	sc->sc_scale = 20;
347 	sc->sc_taptimeout = 100;
348 
349 	sysctl_createv(&sc->sc_log, 0, NULL, &node,
350 		0,
351 		CTLTYPE_NODE, device_xname(self),
352 		NULL,
353 		NULL, 0,
354 		NULL, 0,
355 		CTL_HW,
356 		CTL_CREATE, CTL_EOL);
357 
358 	if (node != NULL) {
359 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
360 			CTLFLAG_READWRITE,
361 			CTLTYPE_INT, "soft_resolution",
362 			NULL,
363 			btmagic_sysctl_resolution, 0,
364 			(void *)sc, 0,
365 			CTL_HW, node->sysctl_num,
366 			CTL_CREATE, CTL_EOL);
367 
368 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
369 			CTLFLAG_READWRITE,
370 			CTLTYPE_INT, "firm_touch_threshold",
371 			NULL,
372 			NULL, 0,
373 			&sc->sc_firm, sizeof(sc->sc_firm),
374 			CTL_HW, node->sysctl_num,
375 			CTL_CREATE, CTL_EOL);
376 
377 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
378 			CTLFLAG_READWRITE,
379 			CTLTYPE_INT, "scroll_distance_threshold",
380 			NULL,
381 			NULL, 0,
382 			&sc->sc_dist, sizeof(sc->sc_dist),
383 			CTL_HW, node->sysctl_num,
384 			CTL_CREATE, CTL_EOL);
385 
386 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
387 			CTLFLAG_READWRITE,
388 			CTLTYPE_INT, "scroll_downscale_factor",
389 			NULL,
390 			btmagic_sysctl_scale, 0,
391 			(void *)sc, 0,
392 			CTL_HW, node->sysctl_num,
393 			CTL_CREATE, CTL_EOL);
394 		sysctl_createv(&sc->sc_log, 0, NULL, NULL,
395 			CTLFLAG_READWRITE,
396 			CTLTYPE_INT, "taptimeout",
397 			"timeout for tap detection in milliseconds",
398 			btmagic_sysctl_taptimeout, 0,
399 			(void *)sc, 0,
400 			CTL_HW, node->sysctl_num,
401 			CTL_CREATE, CTL_EOL);
402 	}
403 
404 	/*
405 	 * attach the wsmouse
406 	 */
407 	wsma.accessops = &btmagic_wsmouse_accessops;
408 	wsma.accesscookie = self;
409 	sc->sc_wsmouse = config_found(self, &wsma, wsmousedevprint, CFARGS_NONE);
410 	if (sc->sc_wsmouse == NULL) {
411 		aprint_error_dev(self, "failed to attach wsmouse\n");
412 		return;
413 	}
414 
415 	pmf_device_register(self, NULL, NULL);
416 
417 	/*
418 	 * start bluetooth connections
419 	 */
420 	mutex_enter(bt_lock);
421 	if ((err = btmagic_listen(sc)) != 0)
422 		aprint_error_dev(self, "failed to listen (%d)\n", err);
423 	btmagic_connect(sc);
424 	mutex_exit(bt_lock);
425 }
426 
427 static int
btmagic_detach(device_t self,int flags)428 btmagic_detach(device_t self, int flags)
429 {
430 	struct btmagic_softc *sc = device_private(self);
431 	int err = 0;
432 
433 	mutex_enter(bt_lock);
434 
435 	/* release interrupt listen */
436 	if (sc->sc_int_l != NULL) {
437 		l2cap_detach_pcb(&sc->sc_int_l);
438 		sc->sc_int_l = NULL;
439 	}
440 
441 	/* release control listen */
442 	if (sc->sc_ctl_l != NULL) {
443 		l2cap_detach_pcb(&sc->sc_ctl_l);
444 		sc->sc_ctl_l = NULL;
445 	}
446 
447 	/* close interrupt channel */
448 	if (sc->sc_int != NULL) {
449 		l2cap_disconnect_pcb(sc->sc_int, 0);
450 		l2cap_detach_pcb(&sc->sc_int);
451 		sc->sc_int = NULL;
452 	}
453 
454 	/* close control channel */
455 	if (sc->sc_ctl != NULL) {
456 		l2cap_disconnect_pcb(sc->sc_ctl, 0);
457 		l2cap_detach_pcb(&sc->sc_ctl);
458 		sc->sc_ctl = NULL;
459 	}
460 
461 	callout_halt(&sc->sc_tapcallout, bt_lock);
462 	callout_destroy(&sc->sc_tapcallout);
463 	callout_halt(&sc->sc_timeout, bt_lock);
464 	callout_destroy(&sc->sc_timeout);
465 
466 	mutex_exit(bt_lock);
467 
468 	pmf_device_deregister(self);
469 
470 	sockopt_destroy(&sc->sc_mode);
471 
472 	sysctl_teardown(&sc->sc_log);
473 
474 	if (sc->sc_wsmouse != NULL) {
475 		err = config_detach(sc->sc_wsmouse, flags);
476 		sc->sc_wsmouse = NULL;
477 	}
478 
479 	return err;
480 }
481 
482 /*
483  * listen for our device
484  *
485  * bt_lock is held
486  */
487 static int
btmagic_listen(struct btmagic_softc * sc)488 btmagic_listen(struct btmagic_softc *sc)
489 {
490 	struct sockaddr_bt sa;
491 	int err;
492 
493 	memset(&sa, 0, sizeof(sa));
494 	sa.bt_len = sizeof(sa);
495 	sa.bt_family = AF_BLUETOOTH;
496 	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
497 
498 	/*
499 	 * Listen on control PSM
500 	 */
501 	err = l2cap_attach_pcb(&sc->sc_ctl_l, &btmagic_ctl_proto, sc);
502 	if (err)
503 		return err;
504 
505 	err = l2cap_setopt(sc->sc_ctl_l, &sc->sc_mode);
506 	if (err)
507 		return err;
508 
509 	sa.bt_psm = L2CAP_PSM_HID_CNTL;
510 	err = l2cap_bind_pcb(sc->sc_ctl_l, &sa);
511 	if (err)
512 		return err;
513 
514 	err = l2cap_listen_pcb(sc->sc_ctl_l);
515 	if (err)
516 		return err;
517 
518 	/*
519 	 * Listen on interrupt PSM
520 	 */
521 	err = l2cap_attach_pcb(&sc->sc_int_l, &btmagic_int_proto, sc);
522 	if (err)
523 		return err;
524 
525 	err = l2cap_setopt(sc->sc_int_l, &sc->sc_mode);
526 	if (err)
527 		return err;
528 
529 	sa.bt_psm = L2CAP_PSM_HID_INTR;
530 	err = l2cap_bind_pcb(sc->sc_int_l, &sa);
531 	if (err)
532 		return err;
533 
534 	err = l2cap_listen_pcb(sc->sc_int_l);
535 	if (err)
536 		return err;
537 
538 	sc->sc_state = BTMAGIC_WAIT_CTL;
539 	return 0;
540 }
541 
542 /*
543  * start connecting to our device
544  *
545  * bt_lock is held
546  */
547 static int
btmagic_connect(struct btmagic_softc * sc)548 btmagic_connect(struct btmagic_softc *sc)
549 {
550 	struct sockaddr_bt sa;
551 	int err;
552 
553 	memset(&sa, 0, sizeof(sa));
554 	sa.bt_len = sizeof(sa);
555 	sa.bt_family = AF_BLUETOOTH;
556 
557 	err = l2cap_attach_pcb(&sc->sc_ctl, &btmagic_ctl_proto, sc);
558 	if (err) {
559 		printf("%s: l2cap_attach failed (%d)\n",
560 		    device_xname(sc->sc_dev), err);
561 		return err;
562 	}
563 
564 	err = l2cap_setopt(sc->sc_ctl, &sc->sc_mode);
565 	if (err) {
566 		printf("%s: l2cap_setopt failed (%d)\n",
567 		    device_xname(sc->sc_dev), err);
568 		return err;
569 	}
570 
571 	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
572 	err = l2cap_bind_pcb(sc->sc_ctl, &sa);
573 	if (err) {
574 		printf("%s: l2cap_bind_pcb failed (%d)\n",
575 		    device_xname(sc->sc_dev), err);
576 		return err;
577 	}
578 
579 	sa.bt_psm = L2CAP_PSM_HID_CNTL;
580 	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
581 	err = l2cap_connect_pcb(sc->sc_ctl, &sa);
582 	if (err) {
583 		printf("%s: l2cap_connect_pcb failed (%d)\n",
584 		    device_xname(sc->sc_dev), err);
585 		return err;
586 	}
587 
588 	SET(sc->sc_flags, BTMAGIC_CONNECTING);
589 	sc->sc_state = BTMAGIC_WAIT_CTL;
590 	return 0;
591 }
592 
593 /* validate soft_resolution */
594 static int
btmagic_sysctl_resolution(SYSCTLFN_ARGS)595 btmagic_sysctl_resolution(SYSCTLFN_ARGS)
596 {
597 	struct sysctlnode node;
598 	struct btmagic_softc *sc;
599 	int t, error;
600 
601 	node = *rnode;
602 	sc = node.sysctl_data;
603 
604 	t = sc->sc_resolution;
605 	node.sysctl_data = &t;
606 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
607 	if (error || newp == NULL)
608 		return error;
609 
610 	if (t < 100 || t > 4000 || (t / sc->sc_scale) == 0)
611 		return EINVAL;
612 
613 	sc->sc_resolution = t;
614 	DPRINTF(sc, "sc_resolution = %u", t);
615 	return 0;
616 }
617 
618 /* validate scroll_downscale_factor */
619 static int
btmagic_sysctl_scale(SYSCTLFN_ARGS)620 btmagic_sysctl_scale(SYSCTLFN_ARGS)
621 {
622 	struct sysctlnode node;
623 	struct btmagic_softc *sc;
624 	int t, error;
625 
626 	node = *rnode;
627 	sc = node.sysctl_data;
628 
629 	t = sc->sc_scale;
630 	node.sysctl_data = &t;
631 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
632 	if (error || newp == NULL)
633 		return error;
634 
635 	if (t < 1 || t > 40 || (sc->sc_resolution / t) == 0)
636 		return EINVAL;
637 
638 	sc->sc_scale = t;
639 	DPRINTF(sc, "sc_scale = %u", t);
640 	return 0;
641 }
642 
643 /* validate tap timeout */
644 static int
btmagic_sysctl_taptimeout(SYSCTLFN_ARGS)645 btmagic_sysctl_taptimeout(SYSCTLFN_ARGS)
646 {
647 	struct sysctlnode node;
648 	struct btmagic_softc *sc;
649 	int t, error;
650 
651 	node = *rnode;
652 	sc = node.sysctl_data;
653 
654 	t = sc->sc_taptimeout;
655 	node.sysctl_data = &t;
656 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
657 	if (error || newp == NULL)
658 		return error;
659 
660 	if (t < uimax(1000 / hz, 1) || t > 999)
661 		return EINVAL;
662 
663 	sc->sc_taptimeout = t;
664 	DPRINTF(sc, "taptimeout = %u", t);
665 	return 0;
666 }
667 
668 /*****************************************************************************
669  *
670  *	wsmouse(4) accessops
671  */
672 
673 static int
btmagic_wsmouse_enable(void * self)674 btmagic_wsmouse_enable(void *self)
675 {
676 	struct btmagic_softc *sc = device_private(self);
677 
678 	if (sc->sc_enabled)
679 		return EBUSY;
680 
681 	sc->sc_enabled = 1;
682 	DPRINTF(sc, "enable");
683 	return 0;
684 }
685 
686 static int
btmagic_wsmouse_ioctl(void * self,unsigned long cmd,void * data,int flag,struct lwp * l)687 btmagic_wsmouse_ioctl(void *self, unsigned long cmd, void *data,
688     int flag, struct lwp *l)
689 {
690 	/* struct btmagic_softc *sc = device_private(self); */
691 	int err;
692 
693 	switch (cmd) {
694 	case WSMOUSEIO_GTYPE:
695 		*(uint *)data = WSMOUSE_TYPE_BLUETOOTH;
696 		err = 0;
697 		break;
698 
699 	default:
700 		err = EPASSTHROUGH;
701 		break;
702 	}
703 
704 	return err;
705 }
706 
707 static void
btmagic_wsmouse_disable(void * self)708 btmagic_wsmouse_disable(void *self)
709 {
710 	struct btmagic_softc *sc = device_private(self);
711 
712 	DPRINTF(sc, "disable");
713 	sc->sc_enabled = 0;
714 }
715 
716 
717 /*****************************************************************************
718  *
719  *	setup routines
720  */
721 
722 static void
btmagic_timeout(void * arg)723 btmagic_timeout(void *arg)
724 {
725 	struct btmagic_softc *sc = arg;
726 
727 	mutex_enter(bt_lock);
728 	callout_ack(&sc->sc_timeout);
729 
730 	switch (sc->sc_state) {
731 	case BTMAGIC_CLOSED:
732 		if (sc->sc_int != NULL) {
733 			l2cap_disconnect_pcb(sc->sc_int, 0);
734 			break;
735 		}
736 
737 		if (sc->sc_ctl != NULL) {
738 			l2cap_disconnect_pcb(sc->sc_ctl, 0);
739 			break;
740 		}
741 		break;
742 
743 	case BTMAGIC_OPEN:
744 		if (!ISSET(sc->sc_flags, BTMAGIC_ENABLED)) {
745 			btmagic_enable(sc);
746 			break;
747 		}
748 
749 		btmagic_check_battery(sc);
750 		break;
751 
752 	case BTMAGIC_WAIT_CTL:
753 	case BTMAGIC_WAIT_INT:
754 	default:
755 		break;
756 	}
757 	mutex_exit(bt_lock);
758 }
759 
760 /*
761  * Send report on control channel
762  *
763  * bt_lock is held
764  */
765 static int
btmagic_ctl_send(struct btmagic_softc * sc,const uint8_t * data,size_t len)766 btmagic_ctl_send(struct btmagic_softc *sc, const uint8_t *data, size_t len)
767 {
768 	struct mbuf *m;
769 
770 	if (len > MLEN)
771 		return EINVAL;
772 
773 	m = m_gethdr(M_DONTWAIT, MT_DATA);
774 	if (m == NULL)
775 		return ENOMEM;
776 
777 #ifdef BTMAGIC_DEBUG
778 	printf("%s: send", device_xname(sc->sc_dev));
779 	for (size_t i = 0; i < len; i++)
780 		printf(" 0x%02x", data[i]);
781 	printf("\n");
782 #endif
783 
784 	memcpy(mtod(m, uint8_t *), data, len);
785 	m->m_pkthdr.len = m->m_len = len;
786 	return l2cap_send_pcb(sc->sc_ctl, m);
787 }
788 
789 /*
790  * Enable touch reports by sending the following report
791  *
792  *	 SET_REPORT(FEATURE, 0xd7) = 0x01
793  *
794  * bt_lock is held
795  */
796 static void
btmagic_enable(struct btmagic_softc * sc)797 btmagic_enable(struct btmagic_softc *sc)
798 {
799 	static const uint8_t rep[] = { 0x53, 0xd7, 0x01 };
800 
801 	if (btmagic_ctl_send(sc, rep, sizeof(rep)) != 0) {
802 		printf("%s: cannot enable touch reports\n",
803 		    device_xname(sc->sc_dev));
804 
805 		return;
806 	}
807 
808 	SET(sc->sc_flags, BTMAGIC_ENABLED);
809 }
810 
811 /*
812  * Request the battery level by sending the following report
813  *
814  *	GET_REPORT(FEATURE, 0x47)
815  *
816  * bt_lock is held
817  */
818 static void
btmagic_check_battery(struct btmagic_softc * sc)819 btmagic_check_battery(struct btmagic_softc *sc)
820 {
821 	static const uint8_t rep[] = { 0x43, 0x47 };
822 
823 	if (btmagic_ctl_send(sc, rep, sizeof(rep)) != 0)
824 		printf("%s: cannot request battery level\n",
825 		    device_xname(sc->sc_dev));
826 }
827 
828 /*
829  * the Magic Mouse has a base resolution of 1300dpi which is rather flighty. We
830  * scale the output to the requested resolution, taking care to account for the
831  * remainders to prevent loss of small deltas.
832  */
833 static int
btmagic_scale(int delta,int * remainder,int resolution)834 btmagic_scale(int delta, int *remainder, int resolution)
835 {
836 	int new;
837 
838 	delta += *remainder;
839 	new = delta * resolution / 1300;
840 	*remainder = delta - new * 1300 / resolution;
841 	return new;
842 }
843 
844 
845 /*****************************************************************************
846  *
847  *	bluetooth(9) callback methods for L2CAP
848  *
849  *	All these are called from Bluetooth Protocol code, holding bt_lock.
850  */
851 
852 static void
btmagic_connecting(void * arg)853 btmagic_connecting(void *arg)
854 {
855 
856 	/* dont care */
857 }
858 
859 static void
btmagic_ctl_connected(void * arg)860 btmagic_ctl_connected(void *arg)
861 {
862 	struct sockaddr_bt sa;
863 	struct btmagic_softc *sc = arg;
864 	int err;
865 
866 	if (sc->sc_state != BTMAGIC_WAIT_CTL)
867 		return;
868 
869 	KASSERT(sc->sc_ctl != NULL);
870 	KASSERT(sc->sc_int == NULL);
871 
872 	if (ISSET(sc->sc_flags, BTMAGIC_CONNECTING)) {
873 		/* initiate connect on interrupt PSM */
874 		err = l2cap_attach_pcb(&sc->sc_int, &btmagic_int_proto, sc);
875 		if (err)
876 			goto fail;
877 
878 		err = l2cap_setopt(sc->sc_int, &sc->sc_mode);
879 		if (err)
880 			goto fail;
881 
882 		memset(&sa, 0, sizeof(sa));
883 		sa.bt_len = sizeof(sa);
884 		sa.bt_family = AF_BLUETOOTH;
885 		bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
886 
887 		err = l2cap_bind_pcb(sc->sc_int, &sa);
888 		if (err)
889 			goto fail;
890 
891 		sa.bt_psm = L2CAP_PSM_HID_INTR;
892 		bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
893 		err = l2cap_connect_pcb(sc->sc_int, &sa);
894 		if (err)
895 			goto fail;
896 	}
897 
898 	sc->sc_state = BTMAGIC_WAIT_INT;
899 	return;
900 
901 fail:
902 	l2cap_detach_pcb(&sc->sc_ctl);
903 	sc->sc_ctl = NULL;
904 
905 	printf("%s: connect failed (%d)\n", device_xname(sc->sc_dev), err);
906 }
907 
908 static void
btmagic_int_connected(void * arg)909 btmagic_int_connected(void *arg)
910 {
911 	struct btmagic_softc *sc = arg;
912 
913 	if (sc->sc_state != BTMAGIC_WAIT_INT)
914 		return;
915 
916 	KASSERT(sc->sc_ctl != NULL);
917 	KASSERT(sc->sc_int != NULL);
918 
919 	printf("%s: connected\n", device_xname(sc->sc_dev));
920 	CLR(sc->sc_flags, BTMAGIC_CONNECTING);
921 	sc->sc_state = BTMAGIC_OPEN;
922 
923 	/* trigger the setup */
924 	CLR(sc->sc_flags, BTMAGIC_ENABLED);
925 	callout_schedule(&sc->sc_timeout, hz);
926 }
927 
928 /*
929  * Disconnected
930  *
931  * Depending on our state, this could mean several things, but essentially
932  * we are lost. If both channels are closed, schedule another connection.
933  */
934 static void
btmagic_ctl_disconnected(void * arg,int err)935 btmagic_ctl_disconnected(void *arg, int err)
936 {
937 	struct btmagic_softc *sc = arg;
938 
939 	if (sc->sc_ctl != NULL) {
940 		l2cap_detach_pcb(&sc->sc_ctl);
941 		sc->sc_ctl = NULL;
942 	}
943 
944 	if (sc->sc_int == NULL) {
945 		printf("%s: disconnected (%d)\n", device_xname(sc->sc_dev), err);
946 		CLR(sc->sc_flags, BTMAGIC_CONNECTING);
947 		sc->sc_state = BTMAGIC_WAIT_CTL;
948 	} else {
949 		/*
950 		 * The interrupt channel should have been closed first,
951 		 * but its potentially unsafe to detach that from here.
952 		 * Give them a second to do the right thing or let the
953 		 * callout handle it.
954 		 */
955 		sc->sc_state = BTMAGIC_CLOSED;
956 		callout_schedule(&sc->sc_timeout, hz);
957 	}
958 }
959 
960 static void
btmagic_int_disconnected(void * arg,int err)961 btmagic_int_disconnected(void *arg, int err)
962 {
963 	struct btmagic_softc *sc = arg;
964 
965 	if (sc->sc_int != NULL) {
966 		l2cap_detach_pcb(&sc->sc_int);
967 		sc->sc_int = NULL;
968 	}
969 
970 	if (sc->sc_ctl == NULL) {
971 		printf("%s: disconnected (%d)\n", device_xname(sc->sc_dev), err);
972 		CLR(sc->sc_flags, BTMAGIC_CONNECTING);
973 		sc->sc_state = BTMAGIC_WAIT_CTL;
974 	} else {
975 		/*
976 		 * The control channel should be closing also, allow
977 		 * them a chance to do that before we force it.
978 		 */
979 		sc->sc_state = BTMAGIC_CLOSED;
980 		callout_schedule(&sc->sc_timeout, hz);
981 	}
982 }
983 
984 /*
985  * New Connections
986  *
987  * We give a new L2CAP handle back if this matches the BDADDR we are
988  * listening for and we are in the right state. btmagic_connected will
989  * be called when the connection is open, so nothing else to do here
990  */
991 static void *
btmagic_ctl_newconn(void * arg,struct sockaddr_bt * laddr,struct sockaddr_bt * raddr)992 btmagic_ctl_newconn(void *arg, struct sockaddr_bt *laddr,
993     struct sockaddr_bt *raddr)
994 {
995 	struct btmagic_softc *sc = arg;
996 
997 	if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0)
998 		return NULL;
999 
1000 	if (sc->sc_state != BTMAGIC_WAIT_CTL
1001 	    || ISSET(sc->sc_flags, BTMAGIC_CONNECTING)
1002 	    || sc->sc_ctl != NULL
1003 	    || sc->sc_int != NULL) {
1004 		DPRINTF(sc, "reject ctl newconn %s%s%s%s",
1005 		    (sc->sc_state == BTMAGIC_WAIT_CTL) ? " (WAITING)": "",
1006 		    ISSET(sc->sc_flags, BTMAGIC_CONNECTING) ? " (CONNECTING)" : "",
1007 		    (sc->sc_ctl != NULL) ? " (GOT CONTROL)" : "",
1008 		    (sc->sc_int != NULL) ? " (GOT INTERRUPT)" : "");
1009 
1010 		return NULL;
1011 	}
1012 
1013 	l2cap_attach_pcb(&sc->sc_ctl, &btmagic_ctl_proto, sc);
1014 	return sc->sc_ctl;
1015 }
1016 
1017 static void *
btmagic_int_newconn(void * arg,struct sockaddr_bt * laddr,struct sockaddr_bt * raddr)1018 btmagic_int_newconn(void *arg, struct sockaddr_bt *laddr,
1019     struct sockaddr_bt *raddr)
1020 {
1021 	struct btmagic_softc *sc = arg;
1022 
1023 	if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0)
1024 		return NULL;
1025 
1026 	if (sc->sc_state != BTMAGIC_WAIT_INT
1027 	    || ISSET(sc->sc_flags, BTMAGIC_CONNECTING)
1028 	    || sc->sc_ctl == NULL
1029 	    || sc->sc_int != NULL) {
1030 		DPRINTF(sc, "reject int newconn %s%s%s%s",
1031 		    (sc->sc_state == BTMAGIC_WAIT_INT) ? " (WAITING)": "",
1032 		    ISSET(sc->sc_flags, BTMAGIC_CONNECTING) ? " (CONNECTING)" : "",
1033 		    (sc->sc_ctl == NULL) ? " (NO CONTROL)" : "",
1034 		    (sc->sc_int != NULL) ? " (GOT INTERRUPT)" : "");
1035 
1036 		return NULL;
1037 	}
1038 
1039 	l2cap_attach_pcb(&sc->sc_int, &btmagic_int_proto, sc);
1040 	return sc->sc_int;
1041 }
1042 
1043 static void
btmagic_complete(void * arg,int count)1044 btmagic_complete(void *arg, int count)
1045 {
1046 
1047 	/* dont care */
1048 }
1049 
1050 static void
btmagic_linkmode(void * arg,int new)1051 btmagic_linkmode(void *arg, int new)
1052 {
1053 	struct btmagic_softc *sc = arg;
1054 	int mode;
1055 
1056 	(void)sockopt_getint(&sc->sc_mode, &mode);
1057 
1058 	if (ISSET(mode, L2CAP_LM_AUTH) && !ISSET(new, L2CAP_LM_AUTH))
1059 		printf("%s: auth failed\n", device_xname(sc->sc_dev));
1060 	else if (ISSET(mode, L2CAP_LM_ENCRYPT) && !ISSET(new, L2CAP_LM_ENCRYPT))
1061 		printf("%s: encrypt off\n", device_xname(sc->sc_dev));
1062 	else if (ISSET(mode, L2CAP_LM_SECURE) && !ISSET(new, L2CAP_LM_SECURE))
1063 		printf("%s: insecure\n", device_xname(sc->sc_dev));
1064 	else
1065 		return;
1066 
1067 	if (sc->sc_int != NULL)
1068 		l2cap_disconnect_pcb(sc->sc_int, 0);
1069 
1070 	if (sc->sc_ctl != NULL)
1071 		l2cap_disconnect_pcb(sc->sc_ctl, 0);
1072 }
1073 
1074 /*
1075  * Receive transaction from the mouse. We don't differentiate between
1076  * interrupt and control channel here, there is no need.
1077  */
1078 static void
btmagic_input(void * arg,struct mbuf * m)1079 btmagic_input(void *arg, struct mbuf *m)
1080 {
1081 	struct btmagic_softc *sc = arg;
1082 	uint8_t *data;
1083 	size_t len;
1084 
1085 	if (sc->sc_state != BTMAGIC_OPEN
1086 	    || sc->sc_wsmouse == NULL
1087 	    || sc->sc_enabled == 0)
1088 		goto release;
1089 
1090 	if (m->m_pkthdr.len > m->m_len)
1091 		printf("%s: truncating input\n", device_xname(sc->sc_dev));
1092 
1093 	data = mtod(m, uint8_t *);
1094 	len = m->m_len;
1095 
1096 	if (len < 1)
1097 		goto release;
1098 
1099 	switch (BTHID_TYPE(data[0])) {
1100 	case BTHID_HANDSHAKE:
1101 		DPRINTF(sc, "Handshake: 0x%x", BTHID_HANDSHAKE_PARAM(data[0]));
1102 		callout_schedule(&sc->sc_timeout, hz);
1103 		break;
1104 
1105 	case BTHID_DATA:
1106 		if (len < 2)
1107 			break;
1108 
1109 		switch (data[1]) {
1110 		case BASIC_REPORT_ID: /* Basic mouse (input) */
1111 			btmagic_input_basic(sc, data + 2, len - 2);
1112 			break;
1113 
1114 		case TRACKPAD_REPORT_ID: /* Magic trackpad (input) */
1115 			btmagic_input_magict(sc, data + 2, len - 2);
1116 			break;
1117 
1118 		case MOUSE_REPORT_ID: /* Magic touch (input) */
1119 			btmagic_input_magicm(sc, data + 2, len - 2);
1120 			break;
1121 
1122 		case BATT_STAT_REPORT_ID: /* Battery status (input) */
1123 			if (len != 3)
1124 				break;
1125 
1126 			printf("%s: Battery ", device_xname(sc->sc_dev));
1127 			switch (data[2]) {
1128 			case 0:	printf("Ok\n");			break;
1129 			case 1:	printf("Warning\n");		break;
1130 			case 2:	printf("Critical\n");		break;
1131 			default: printf("0x%02x\n", data[2]);	break;
1132 			}
1133 			break;
1134 
1135 		case BATT_STRENGTH_REPORT_ID: /* Battery strength (feature) */
1136 			if (len != 3)
1137 				break;
1138 
1139 			printf("%s: Battery %d%%\n", device_xname(sc->sc_dev),
1140 			    data[2]);
1141 			break;
1142 
1143 		case SURFACE_REPORT_ID: /* Surface detection (input) */
1144 			if (len != 3)
1145 				break;
1146 
1147 			DPRINTF(sc, "Mouse %s",
1148 			    (data[2] == 0 ? "lowered" : "raised"));
1149 			break;
1150 
1151 		case 0x60: /* unknown (input) */
1152 		case 0xf0: /* unknown (feature) */
1153 		case 0xf1: /* unknown (feature) */
1154 		default:
1155 #if BTMAGIC_DEBUG
1156 			printf("%s: recv", device_xname(sc->sc_dev));
1157 			for (size_t i = 0; i < len; i++)
1158 				printf(" 0x%02x", data[i]);
1159 			printf("\n");
1160 #endif
1161 			break;
1162 		}
1163 		break;
1164 
1165 	default:
1166 		DPRINTF(sc, "transaction (type 0x%x)", BTHID_TYPE(data[0]));
1167 		break;
1168 	}
1169 
1170 release:
1171 	m_freem(m);
1172 }
1173 
1174 /*
1175  * parse the Basic report (0x10), which according to the provided
1176  * HID descriptor is in the following format
1177  *
1178  *	button 1	1-bit
1179  *	button 2	1-bit
1180  *	padding		6-bits
1181  *	dX		16-bits (signed)
1182  *	dY		16-bits (signed)
1183  *
1184  * Even when the magic touch reports are enabled, the basic report is
1185  * sent for mouse move events where no touches are detected.
1186  */
1187 static const struct {
1188 	struct hid_location button1;
1189 	struct hid_location button2;
1190 	struct hid_location dX;
1191 	struct hid_location dY;
1192 } basic = {
1193 	.button1 = { .pos =  0, .size = 1 },
1194 	.button2 = { .pos =  1, .size = 1 },
1195 	.dX = { .pos =  8, .size = 16 },
1196 	.dY = { .pos = 24, .size = 16 },
1197 };
1198 
1199 static void
btmagic_input_basic(struct btmagic_softc * sc,uint8_t * data,size_t len)1200 btmagic_input_basic(struct btmagic_softc *sc, uint8_t *data, size_t len)
1201 {
1202 	int dx, dy;
1203 	uint32_t mb;
1204 	int s;
1205 
1206 	if (len != 5)
1207 		return;
1208 
1209 	dx = hid_get_data(data, &basic.dX);
1210 	dx = btmagic_scale(dx, &sc->sc_rx, sc->sc_resolution);
1211 
1212 	dy = hid_get_data(data, &basic.dY);
1213 	dy = btmagic_scale(dy, &sc->sc_ry, sc->sc_resolution);
1214 
1215 	mb = 0;
1216 	if (hid_get_udata(data, &basic.button1))
1217 		mb |= __BIT(0);
1218 	if (hid_get_udata(data, &basic.button2))
1219 		mb |= __BIT(2);
1220 
1221 	if (dx != 0 || dy != 0 || mb != sc->sc_mb) {
1222 		sc->sc_mb = mb;
1223 
1224 		s = spltty();
1225 		wsmouse_input(sc->sc_wsmouse, mb,
1226 		    dx, -dy, 0, 0, WSMOUSE_INPUT_DELTA);
1227 		splx(s);
1228 	}
1229 }
1230 
1231 /*
1232  * the Magic touch report (0x29), according to the Linux driver
1233  * written by Michael Poole, is variable length starting with the
1234  * fixed 40-bit header
1235  *
1236  *	dX lsb		8-bits (signed)
1237  *	dY lsb		8-bits (signed)
1238  *	button 1	1-bit
1239  *	button 2	1-bit
1240  *	dX msb		2-bits (signed)
1241  *	dY msb		2-bits (signed)
1242  *	timestamp	18-bits
1243  *
1244  * followed by (up to 5?) touch reports of 64-bits each
1245  *
1246  *	abs W		12-bits (signed)
1247  *	abs Z		12-bits (signed)
1248  *	axis major	8-bits
1249  *	axis minor	8-bits
1250  *	pressure	6-bits
1251  *	id		4-bits
1252  *	angle		6-bits	(from E(0)->N(32)->W(64))
1253  *	unknown		4-bits
1254  *	phase		4-bits
1255  */
1256 
1257 static const struct {
1258 	struct hid_location dXl;
1259 	struct hid_location dYl;
1260 	struct hid_location button1;
1261 	struct hid_location button2;
1262 	struct hid_location dXm;
1263 	struct hid_location dYm;
1264 	struct hid_location timestamp;
1265 } magic = {
1266 	.dXl = { .pos = 0, .size = 8 },
1267 	.dYl = { .pos = 8, .size = 8 },
1268 	.button1 = { .pos = 16, .size = 1 },
1269 	.button2 = { .pos = 17, .size = 1 },
1270 	.dXm = { .pos = 18, .size = 2 },
1271 	.dYm = { .pos = 20, .size = 2 },
1272 	.timestamp = { .pos = 22, .size = 18 },
1273 };
1274 
1275 static const struct {
1276 	struct hid_location aW;
1277 	struct hid_location aZ;
1278 	struct hid_location major;
1279 	struct hid_location minor;
1280 	struct hid_location pressure;
1281 	struct hid_location id;
1282 	struct hid_location angle;
1283 	struct hid_location unknown;
1284 	struct hid_location phase;
1285 } touch = {
1286 	.aW = { .pos = 0, .size = 12 },
1287 	.aZ = { .pos = 12, .size = 12 },
1288 	.major = { .pos = 24, .size = 8 },
1289 	.minor = { .pos = 32, .size = 8 },
1290 	.pressure = { .pos = 40, .size = 6 },
1291 	.id = { .pos = 46, .size = 4 },
1292 	.angle = { .pos = 50, .size = 6 },
1293 	.unknown = { .pos = 56, .size = 4 },
1294 	.phase = { .pos = 60, .size = 4 },
1295 };
1296 
1297 /*
1298  * the phase of the touch starts at 0x01 as the finger is first detected
1299  * approaching the mouse, increasing to 0x04 while the finger is touching,
1300  * then increases towards 0x07 as the finger is lifted, and we get 0x00
1301  * when the touch is cancelled. The values below seem to be produced for
1302  * every touch, the others less consistently depending on how fast the
1303  * approach or departure is.
1304  *
1305  * In fact we ignore touches unless they are in the steady 0x04 phase.
1306  */
1307 #define BTMAGIC_PHASE_START	0x3
1308 #define BTMAGIC_PHASE_CONT	0x4
1309 #define BTMAGIC_PHASE_END	0x7
1310 #define BTMAGIC_PHASE_CANCEL	0x0
1311 
1312 static void
btmagic_input_magicm(struct btmagic_softc * sc,uint8_t * data,size_t len)1313 btmagic_input_magicm(struct btmagic_softc *sc, uint8_t *data, size_t len)
1314 {
1315 	uint32_t mb;
1316 	int dx, dy, dz, dw;
1317 	int id, nf, az, aw, tz, tw;
1318 	int s;
1319 
1320 	if (((len - 5) % 8) != 0)
1321 		return;
1322 
1323 	dx = (hid_get_data(data, &magic.dXm) << 8)
1324 	    | (hid_get_data(data, &magic.dXl) & 0xff);
1325 	dx = btmagic_scale(dx, &sc->sc_rx, sc->sc_resolution);
1326 
1327 	dy = (hid_get_data(data, &magic.dYm) << 8)
1328 	    | (hid_get_data(data, &magic.dYl) & 0xff);
1329 	dy = btmagic_scale(dy, &sc->sc_ry, sc->sc_resolution);
1330 
1331 	mb = 0;
1332 	if (hid_get_udata(data, &magic.button1))
1333 		mb |= __BIT(0);
1334 	if (hid_get_udata(data, &magic.button2))
1335 		mb |= __BIT(2);
1336 
1337 	nf = 0;
1338 	dz = 0;
1339 	dw = 0;
1340 	len = (len - 5) / 8;
1341 	for (data += 5; len-- > 0; data += 8) {
1342 		id = hid_get_udata(data, &touch.id);
1343 		az = hid_get_data(data, &touch.aZ);
1344 		aw = hid_get_data(data, &touch.aW);
1345 
1346 		/*
1347 		 * scrolling is triggered by an established touch moving
1348 		 * beyond a minimum distance from its start point and is
1349 		 * cancelled as the touch starts to fade.
1350 		 *
1351 		 * Multiple touches may be scrolling simultaneously, the
1352 		 * effect is cumulative.
1353 		 */
1354 
1355 		switch (hid_get_udata(data, &touch.phase)) {
1356 		case BTMAGIC_PHASE_CONT:
1357 #define sc_az sc_ay
1358 #define sc_aw sc_ax
1359 			tz = az - sc->sc_az[id];
1360 			tw = aw - sc->sc_aw[id];
1361 
1362 			if (ISSET(sc->sc_smask, __BIT(id))) {
1363 				/* scrolling finger */
1364 				dz += btmagic_scale(tz, &sc->sc_rz,
1365 				    sc->sc_resolution / sc->sc_scale);
1366 				dw += btmagic_scale(tw, &sc->sc_rw,
1367 				    sc->sc_resolution / sc->sc_scale);
1368 			} else if (abs(tz) > sc->sc_dist
1369 			    || abs(tw) > sc->sc_dist) {
1370 				/* new scrolling finger */
1371 				if (sc->sc_smask == 0) {
1372 					sc->sc_rz = 0;
1373 					sc->sc_rw = 0;
1374 				}
1375 
1376 				SET(sc->sc_smask, __BIT(id));
1377 			} else {
1378 				/* not scrolling finger */
1379 				az = sc->sc_az[id];
1380 				aw = sc->sc_aw[id];
1381 			}
1382 
1383 			/* count firm touches for middle-click */
1384 			if (hid_get_udata(data, &touch.pressure) > sc->sc_firm)
1385 				nf++;
1386 
1387 			break;
1388 
1389 		default:
1390 			CLR(sc->sc_smask, __BIT(id));
1391 			break;
1392 		}
1393 
1394 		sc->sc_az[id] = az;
1395 		sc->sc_aw[id] = aw;
1396 #undef sc_az
1397 #undef sc_aw
1398 	}
1399 
1400 	/*
1401 	 * The mouse only has one click detector, and says left or right but
1402 	 * never both. We convert multiple firm touches while clicking into
1403 	 * a middle button press, and cancel any scroll effects while click
1404 	 * is active.
1405 	 */
1406 	if (mb != 0) {
1407 		if (sc->sc_mb != 0)
1408 			mb = sc->sc_mb;
1409 		else if (nf > 1)
1410 			mb = __BIT(1);
1411 
1412 		sc->sc_smask = 0;
1413 		dz = 0;
1414 		dw = 0;
1415 	}
1416 
1417 	if (dx != 0 || dy != 0 || dz != 0 || dw != 0 || mb != sc->sc_mb) {
1418 		sc->sc_mb = mb;
1419 
1420 		s = spltty();
1421 		wsmouse_input(sc->sc_wsmouse, mb,
1422 		    dx, -dy, -dz, dw, WSMOUSE_INPUT_DELTA);
1423 		splx(s);
1424 	}
1425 }
1426 
1427 /*
1428  * the Magic touch trackpad report (0x28), according to the Linux driver
1429  * written by Michael Poole and Chase Douglas, is variable length starting
1430  * with the fixed 24-bit header
1431  *
1432  *	button 1	1-bit
1433  *      unknown		5-bits
1434  *	timestamp	18-bits
1435  *
1436  * followed by (up to 5?) touch reports of 72-bits each
1437  *
1438  *	abs X		13-bits (signed)
1439  *	abs Y		13-bits (signed)
1440  * 	unknown		6-bits
1441  *	axis major	8-bits
1442  *	axis minor	8-bits
1443  *	pressure	6-bits
1444  *	id		4-bits
1445  *	angle		6-bits	(from E(0)->N(32)->W(64))
1446  *	unknown		4-bits
1447  *	phase		4-bits
1448  */
1449 
1450 static const struct {
1451 	struct hid_location button;
1452 	struct hid_location timestamp;
1453 } magict = {
1454 	.button = { .pos =  0, .size = 1 },
1455 	.timestamp = { .pos = 6, .size = 18 },
1456 };
1457 
1458 static const struct {
1459 	struct hid_location aX;
1460 	struct hid_location aY;
1461 	struct hid_location major;
1462 	struct hid_location minor;
1463 	struct hid_location pressure;
1464 	struct hid_location id;
1465 	struct hid_location angle;
1466 	struct hid_location unknown;
1467 	struct hid_location phase;
1468 } toucht = {
1469 	.aX = { .pos = 0, .size = 13 },
1470 	.aY = { .pos = 13, .size = 13 },
1471 	.major = { .pos = 32, .size = 8 },
1472 	.minor = { .pos = 40, .size = 8 },
1473 	.pressure = { .pos = 48, .size = 6 },
1474 	.id = { .pos = 54, .size = 4 },
1475 	.angle = { .pos = 58, .size = 6 },
1476 	.unknown = { .pos = 64, .size = 4 },
1477 	.phase = { .pos = 68, .size = 4 },
1478 };
1479 
1480 /*
1481  * as for btmagic_input_magicm,
1482  * the phase of the touch starts at 0x01 as the finger is first detected
1483  * approaching the mouse, increasing to 0x04 while the finger is touching,
1484  * then increases towards 0x07 as the finger is lifted, and we get 0x00
1485  * when the touch is cancelled. The values below seem to be produced for
1486  * every touch, the others less consistently depending on how fast the
1487  * approach or departure is.
1488  *
1489  * In fact we ignore touches unless they are in the steady 0x04 phase.
1490  */
1491 
1492 /* min and max values reported */
1493 #define MAGICT_X_MIN	(-2910)
1494 #define MAGICT_X_MAX	(3170)
1495 #define MAGICT_Y_MIN	(-2565)
1496 #define MAGICT_Y_MAX	(2455)
1497 
1498 /*
1499  * area for detecting the buttons: divide in 3 areas on X,
1500  * below -1900 on y
1501  */
1502 #define MAGICT_B_YMAX	(-1900)
1503 #define MAGICT_B_XSIZE	((MAGICT_X_MAX - MAGICT_X_MIN) / 3)
1504 #define MAGICT_B_X1MAX	(MAGICT_X_MIN + MAGICT_B_XSIZE)
1505 #define MAGICT_B_X2MAX	(MAGICT_X_MIN + MAGICT_B_XSIZE * 2)
1506 
1507 static void
btmagic_input_magict(struct btmagic_softc * sc,uint8_t * data,size_t len)1508 btmagic_input_magict(struct btmagic_softc *sc, uint8_t *data, size_t len)
1509 {
1510 	bool bpress;
1511 	uint32_t mb;
1512 	int id, ax, ay, tx, ty;
1513 	int dx, dy, dz, dw;
1514 	int s;
1515 
1516 	if (((len - 3) % 9) != 0)
1517 		return;
1518 
1519 	bpress = 0;
1520 	if (hid_get_udata(data, &magict.button))
1521 		bpress = 1;
1522 
1523 	dx = dy = dz = dw = 0;
1524 	mb = 0;
1525 
1526 	len = (len - 3) / 9;
1527 	for (data += 3; len-- > 0; data += 9) {
1528 		id = hid_get_udata(data, &toucht.id);
1529 		ax = hid_get_data(data, &toucht.aX);
1530 		ay = hid_get_data(data, &toucht.aY);
1531 
1532 		DPRINTF(sc,
1533 		    "btmagic_input_magict: id %d ax %d ay %d phase %ld %s\n",
1534 		    id, ax, ay, hid_get_udata(data, &toucht.phase),
1535 		    bpress ? "button pressed" : "");
1536 
1537 		/*
1538 		 * a single touch is interpreted as a mouse move.
1539 		 * If a button is pressed, the touch in the button area
1540 		 * defined above defines the button; a second touch is
1541 		 * interpreted as a mouse move.
1542 		 */
1543 
1544 		switch (hid_get_udata(data, &toucht.phase)) {
1545 		case BTMAGIC_PHASE_CONT:
1546 			if (bpress) {
1547 				if (sc->sc_mb == 0 && ay < MAGICT_B_YMAX) {
1548 					/*
1549 					 * we have a new button press,
1550 					 * and this id tells which one
1551 					 */
1552 					if (ax < MAGICT_B_X1MAX)
1553 						mb = __BIT(0);
1554 					else if (ax > MAGICT_B_X2MAX)
1555 						mb = __BIT(2);
1556 					else
1557 						mb = __BIT(1);
1558 					sc->sc_mb_id = id;
1559 				} else {
1560 					/* keep previous state */
1561 					mb = sc->sc_mb;
1562 				}
1563 			} else {
1564 				/* no button pressed */
1565 				mb = 0;
1566 				sc->sc_mb_id = -1;
1567 			}
1568 			if (id == sc->sc_mb_id) {
1569 				/*
1570 				 * this id selects the button
1571 				 * ignore for move/scroll
1572 				 */
1573 				 continue;
1574 			}
1575 			if (id >= __arraycount(sc->sc_ax))
1576 				continue;
1577 
1578 			tx = ax - sc->sc_ax[id];
1579 			ty = ay - sc->sc_ay[id];
1580 
1581 			if (ISSET(sc->sc_smask, __BIT(id))) {
1582 				struct timeval now_tv;
1583 				getmicrotime(&now_tv);
1584 				if (sc->sc_nfingers == 1 && mb == 0 &&
1585 				    timercmp(&sc->sc_taptime, &now_tv, >)) {
1586 					/* still detecting a tap */
1587 					continue;
1588 				}
1589 
1590 				if (sc->sc_nfingers == 1 || mb != 0) {
1591 					/* single finger moving */
1592 					dx += btmagic_scale(tx, &sc->sc_rx,
1593 					    sc->sc_resolution);
1594 					dy += btmagic_scale(ty, &sc->sc_ry,
1595 					    sc->sc_resolution);
1596 				} else {
1597 					/* scrolling fingers */
1598 					dz += btmagic_scale(ty, &sc->sc_rz,
1599 					    sc->sc_resolution / sc->sc_scale);
1600 					dw += btmagic_scale(tx, &sc->sc_rw,
1601 					    sc->sc_resolution / sc->sc_scale);
1602 				}
1603 			} else if (ay > MAGICT_B_YMAX) { /* new finger */
1604 				sc->sc_rx = 0;
1605 				sc->sc_ry = 0;
1606 				sc->sc_rz = 0;
1607 				sc->sc_rw = 0;
1608 				KASSERT(!ISSET(sc->sc_smask, __BIT(id)));
1609 				SET(sc->sc_smask, __BIT(id));
1610 				sc->sc_nfingers++;
1611 				if (sc->sc_tapmb_id == -1 &&
1612 				    mb == 0 && sc->sc_mb == 0) {
1613 					sc->sc_tapmb_id = id;
1614 					getmicrotime(&sc->sc_taptime);
1615 					sc->sc_taptime.tv_usec +=
1616 					    sc->sc_taptimeout * 1000;
1617 					if (sc->sc_taptime.tv_usec > 1000000) {
1618 						sc->sc_taptime.tv_usec -=
1619 						    1000000;
1620 						sc->sc_taptime.tv_sec++;
1621 					}
1622 				}
1623 
1624 			}
1625 
1626 			break;
1627 		default:
1628 			if (ISSET(sc->sc_smask, __BIT(id))) {
1629 				CLR(sc->sc_smask, __BIT(id));
1630 				sc->sc_nfingers--;
1631 				KASSERT(sc->sc_nfingers >= 0);
1632 				if (id == sc->sc_tapmb_id) {
1633 					mb = btmagic_tap(sc, id);
1634 				}
1635 			}
1636 			break;
1637 		}
1638 
1639 		if (id >= __arraycount(sc->sc_ax))
1640 			continue;
1641 
1642 		sc->sc_ax[id] = ax;
1643 		sc->sc_ay[id] = ay;
1644 	}
1645 
1646 	if (dx != 0 || dy != 0 || dz != 0 || dw != 0 || mb != sc->sc_mb) {
1647 		sc->sc_mb = mb;
1648 
1649 		s = spltty();
1650 		wsmouse_input(sc->sc_wsmouse, mb,
1651 		    dx, dy, -dz, dw, WSMOUSE_INPUT_DELTA);
1652 		splx(s);
1653 	}
1654 }
1655 
1656 static int
btmagic_tap(struct btmagic_softc * sc,int id)1657 btmagic_tap(struct btmagic_softc *sc, int id)
1658 {
1659 	struct timeval now_tv;
1660 
1661 	sc->sc_tapmb_id = -1;
1662 	getmicrotime(&now_tv);
1663 	if (timercmp(&sc->sc_taptime, &now_tv, >)) {
1664 		/* got a tap */
1665 		callout_schedule(
1666 		    &sc->sc_tapcallout,
1667 		    mstohz(sc->sc_taptimeout));
1668 		return __BIT(0);
1669 	}
1670 	return 0;
1671 }
1672 
1673 static void
btmagic_tapcallout(void * arg)1674 btmagic_tapcallout(void *arg)
1675 {
1676 	struct btmagic_softc *sc = arg;
1677 	int s;
1678 
1679 	mutex_enter(bt_lock);
1680 	callout_ack(&sc->sc_tapcallout);
1681 	if ((sc->sc_mb & __BIT(0)) != 0) {
1682 		sc->sc_mb &= ~__BIT(0);
1683 		s = spltty();
1684 		wsmouse_input(sc->sc_wsmouse, sc->sc_mb,
1685 		    0, 0, 0, 0, WSMOUSE_INPUT_DELTA);
1686 		splx(s);
1687 	}
1688 	mutex_exit(bt_lock);
1689 }
1690