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