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