1/*	$NetBSD$	*/
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$");
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
129struct 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 */
185static int  btmagic_match(device_t, cfdata_t, void *);
186static void btmagic_attach(device_t, device_t, void *);
187static int  btmagic_detach(device_t, int);
188static int  btmagic_listen(struct btmagic_softc *);
189static int  btmagic_connect(struct btmagic_softc *);
190static int  btmagic_sysctl_resolution(SYSCTLFN_PROTO);
191static int  btmagic_sysctl_scale(SYSCTLFN_PROTO);
192
193CFATTACH_DECL_NEW(btmagic, sizeof(struct btmagic_softc),
194    btmagic_match, btmagic_attach, btmagic_detach, NULL);
195
196/* wsmouse(4) accessops */
197static int btmagic_wsmouse_enable(void *);
198static int btmagic_wsmouse_ioctl(void *, unsigned long, void *, int, struct lwp *);
199static void btmagic_wsmouse_disable(void *);
200
201static 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 */
208static void  btmagic_connecting(void *);
209static void  btmagic_ctl_connected(void *);
210static void  btmagic_int_connected(void *);
211static void  btmagic_ctl_disconnected(void *, int);
212static void  btmagic_int_disconnected(void *, int);
213static void *btmagic_ctl_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
214static void *btmagic_int_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
215static void  btmagic_complete(void *, int);
216static void  btmagic_linkmode(void *, int);
217static void  btmagic_input(void *, struct mbuf *);
218static void  btmagic_input_basic(struct btmagic_softc *, uint8_t *, size_t);
219static void  btmagic_input_magic(struct btmagic_softc *, uint8_t *, size_t);
220
221static 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
231static 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 */
242static void btmagic_timeout(void *);
243static int  btmagic_ctl_send(struct btmagic_softc *, const uint8_t *, size_t);
244static void btmagic_enable(struct btmagic_softc *);
245static void btmagic_check_battery(struct btmagic_softc *);
246static int  btmagic_scale(int, int *, int);
247
248
249/*****************************************************************************
250 *
251 *	Magic Mouse autoconf(9) routines
252 */
253
254static int
255btmagic_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
268static void
269btmagic_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			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			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
402static int
403btmagic_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 */
460static int
461btmagic_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 */
520static int
521btmagic_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 */
567static int
568btmagic_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 */
592static int
593btmagic_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
621static int
622btmagic_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
634static int
635btmagic_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
655static void
656btmagic_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
670static void
671btmagic_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 */
713static int
714btmagic_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 */
744static void
745btmagic_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 */
766static void
767btmagic_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 */
781static int
782btmagic_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
800static void
801btmagic_connecting(void *arg)
802{
803
804	/* dont care */
805}
806
807static void
808btmagic_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
849fail:
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
856static void
857btmagic_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 */
882static void
883btmagic_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
908static void
909btmagic_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 */
939static void *
940btmagic_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
965static void *
966btmagic_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
991static void
992btmagic_complete(void *arg, int count)
993{
994
995	/* dont care */
996}
997
998static void
999btmagic_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 */
1026static void
1027btmagic_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
1114release:
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 */
1131static 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
1143static void
1144btmagic_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
1201static 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
1219static 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
1256static void
1257btmagic_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