LCOV - code coverage report
Current view: top level - dev/usb - uwacom.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 103 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: uwacom.c,v 1.1 2016/09/12 08:12:06 mpi Exp $  */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2016 Frank Groeneveld <frank@frankgroeneveld.nl>
       5             :  *
       6             :  * Permission to use, copy, modify, and distribute this software for any
       7             :  * purpose with or without fee is hereby granted, provided that the above
       8             :  * copyright notice and this permission notice appear in all copies.
       9             :  *
      10             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCAIMS ALL WARRANTIES
      11             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      12             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      13             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      14             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      15             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      16             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      17             :  */
      18             : 
      19             : /* Driver for USB Wacom tablets */
      20             : 
      21             : #include <sys/param.h>
      22             : #include <sys/systm.h>
      23             : #include <sys/device.h>
      24             : 
      25             : #include <dev/usb/usb.h>
      26             : #include <dev/usb/usbhid.h>
      27             : 
      28             : #include <dev/usb/usbdi.h>
      29             : #include <dev/usb/usbdevs.h>
      30             : #include <dev/usb/uhidev.h>
      31             : 
      32             : #include <dev/wscons/wsconsio.h>
      33             : #include <dev/wscons/wsmousevar.h>
      34             : 
      35             : #include <dev/hid/hidmsvar.h>
      36             : 
      37             : struct uwacom_softc {
      38             :         struct uhidev           sc_hdev;
      39             :         struct hidms            sc_ms;
      40             :         struct hid_location     sc_loc_tip_press;
      41             : };
      42             : 
      43             : struct cfdriver uwacom_cd = {
      44             :         NULL, "uwacom", DV_DULL
      45             : };
      46             : 
      47             : 
      48             : const struct usb_devno uwacom_devs[] = {
      49             :         { USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOS_DRAW }
      50             : };
      51             : 
      52             : int     uwacom_match(struct device *, void *, void *);
      53             : void    uwacom_attach(struct device *, struct device *, void *);
      54             : int     uwacom_detach(struct device *, int);
      55             : void    uwacom_intr(struct uhidev *, void *, u_int);
      56             : int     uwacom_enable(void *);
      57             : void    uwacom_disable(void *);
      58             : int     uwacom_ioctl(void *, u_long, caddr_t, int, struct proc *);
      59             : 
      60             : const struct cfattach uwacom_ca = {
      61             :         sizeof(struct uwacom_softc), uwacom_match, uwacom_attach, uwacom_detach
      62             : };
      63             : 
      64             : const struct wsmouse_accessops uwacom_accessops = {
      65             :         uwacom_enable,
      66             :         uwacom_ioctl,
      67             :         uwacom_disable,
      68             : };
      69             : 
      70             : int
      71           0 : uwacom_match(struct device *parent, void *match, void *aux)
      72             : {
      73           0 :         struct uhidev_attach_arg *uha = aux;
      74           0 :         int size;
      75           0 :         void *desc;
      76             : 
      77           0 :         if (usb_lookup(uwacom_devs, uha->uaa->vendor,
      78           0 :             uha->uaa->product) == NULL)
      79           0 :                 return (UMATCH_NONE);
      80             : 
      81           0 :         uhidev_get_report_desc(uha->parent, &desc, &size);
      82             : 
      83           0 :         if (!hid_locate(desc, size, HID_USAGE2(HUP_WACOM, HUG_POINTER),
      84           0 :             uha->reportid, hid_input, NULL, NULL))
      85           0 :                 return (UMATCH_NONE);
      86             : 
      87           0 :         return (UMATCH_IFACECLASS);
      88           0 : }
      89             : 
      90             : void
      91           0 : uwacom_attach(struct device *parent, struct device *self, void *aux)
      92             : {
      93           0 :         struct uwacom_softc *sc = (struct uwacom_softc *)self;
      94           0 :         struct hidms *ms = &sc->sc_ms;
      95           0 :         struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
      96           0 :         struct usb_attach_arg *uaa = uha->uaa;
      97           0 :         int size, repid;
      98           0 :         void *desc;
      99             : 
     100           0 :         sc->sc_hdev.sc_intr = uwacom_intr;
     101           0 :         sc->sc_hdev.sc_parent = uha->parent;
     102           0 :         sc->sc_hdev.sc_udev = uaa->device;
     103           0 :         sc->sc_hdev.sc_report_id = uha->reportid;
     104             : 
     105           0 :         uhidev_get_report_desc(uha->parent, &desc, &size);
     106           0 :         repid = uha->reportid;
     107           0 :         sc->sc_hdev.sc_isize = hid_report_size(desc, size, hid_input, repid);
     108           0 :         sc->sc_hdev.sc_osize = hid_report_size(desc, size, hid_output, repid);
     109           0 :         sc->sc_hdev.sc_fsize = hid_report_size(desc, size, hid_feature, repid);
     110             : 
     111           0 :         ms->sc_device = self;
     112           0 :         ms->sc_rawmode = 1;
     113           0 :         ms->sc_flags = HIDMS_ABSX | HIDMS_ABSY;
     114           0 :         ms->sc_num_buttons = 3;
     115           0 :         ms->sc_loc_x.pos = 8;
     116           0 :         ms->sc_loc_x.size = 16;
     117           0 :         ms->sc_loc_y.pos = 24;
     118           0 :         ms->sc_loc_y.size = 16;
     119             : 
     120           0 :         ms->sc_tsscale.minx = 0;
     121           0 :         ms->sc_tsscale.maxx = 7600;
     122           0 :         ms->sc_tsscale.miny = 0;
     123           0 :         ms->sc_tsscale.maxy = 4750;
     124             : 
     125           0 :         ms->sc_loc_btn[0].pos = 0;
     126           0 :         ms->sc_loc_btn[0].size = 1;
     127           0 :         ms->sc_loc_btn[1].pos = 1;
     128           0 :         ms->sc_loc_btn[1].size = 1;
     129           0 :         ms->sc_loc_btn[2].pos = 2;
     130           0 :         ms->sc_loc_btn[2].size = 1;
     131             : 
     132           0 :         sc->sc_loc_tip_press.pos = 43;
     133           0 :         sc->sc_loc_tip_press.size = 8;
     134             : 
     135           0 :         hidms_attach(ms, &uwacom_accessops);
     136           0 : }
     137             : 
     138             : int
     139           0 : uwacom_detach(struct device *self, int flags)
     140             : {
     141           0 :         struct uwacom_softc *sc = (struct uwacom_softc *)self;
     142           0 :         struct hidms *ms = &sc->sc_ms;
     143             : 
     144           0 :         return hidms_detach(ms, flags);
     145             : }
     146             : 
     147             : void
     148           0 : uwacom_intr(struct uhidev *addr, void *buf, u_int len)
     149             : {
     150           0 :         struct uwacom_softc *sc = (struct uwacom_softc *)addr;
     151           0 :         struct hidms *ms = &sc->sc_ms;
     152             :         u_int32_t buttons = 0;
     153             :         uint8_t *data = (uint8_t *)buf;
     154             :         int i, x, y, pressure;
     155             : 
     156           0 :         if (ms->sc_enabled == 0)
     157           0 :                 return;
     158             : 
     159             :         /* ignore proximity, it will cause invalid button 2 events */
     160           0 :         if ((data[0] & 0xf0) == 0xc0)
     161           0 :                 return;
     162             : 
     163           0 :         x = be16toh(hid_get_data(data, len, &ms->sc_loc_x));
     164           0 :         y = be16toh(hid_get_data(data, len, &ms->sc_loc_y));
     165           0 :         pressure = hid_get_data(data, len, &sc->sc_loc_tip_press);
     166             : 
     167           0 :         for (i = 0; i < ms->sc_num_buttons; i++)
     168           0 :                 if (hid_get_data(data, len, &ms->sc_loc_btn[i]))
     169           0 :                         buttons |= (1 << i);
     170             : 
     171             :         /* button 0 reporting is flaky, use tip pressure for it */
     172           0 :         if (pressure > 10)
     173           0 :                 buttons |= 1;
     174             :         else
     175           0 :                 buttons &= ~1;
     176             : 
     177           0 :         if (x != 0 || y != 0 || buttons != ms->sc_buttons) {
     178           0 :                 wsmouse_position(ms->sc_wsmousedev, x, y);
     179           0 :                 wsmouse_buttons(ms->sc_wsmousedev, buttons);
     180           0 :                 wsmouse_input_sync(ms->sc_wsmousedev);
     181           0 :         }
     182           0 : }
     183             : 
     184             : int
     185           0 : uwacom_enable(void *v)
     186             : {
     187           0 :         struct uwacom_softc *sc = v;
     188           0 :         struct hidms *ms = &sc->sc_ms;
     189             :         int rv;
     190             : 
     191           0 :         if (usbd_is_dying(sc->sc_hdev.sc_udev))
     192           0 :                 return EIO;
     193             : 
     194           0 :         if ((rv = hidms_enable(ms)) != 0)
     195           0 :                 return rv;
     196             : 
     197           0 :         return uhidev_open(&sc->sc_hdev);
     198           0 : }
     199             : 
     200             : void
     201           0 : uwacom_disable(void *v)
     202             : {
     203           0 :         struct uwacom_softc *sc = v;
     204           0 :         struct hidms *ms = &sc->sc_ms;
     205             : 
     206           0 :         hidms_disable(ms);
     207           0 :         uhidev_close(&sc->sc_hdev);
     208           0 : }
     209             : 
     210             : int
     211           0 : uwacom_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
     212             : {
     213           0 :         struct uwacom_softc *sc = v;
     214           0 :         struct hidms *ms = &sc->sc_ms;
     215             :         int rc;
     216             : 
     217           0 :         switch (cmd) {
     218             :         case WSMOUSEIO_GTYPE:
     219           0 :                 *(u_int *)data = WSMOUSE_TYPE_TPANEL;
     220           0 :                 return 0;
     221             :         }
     222             : 
     223           0 :         rc = uhidev_ioctl(&sc->sc_hdev, cmd, data, flag, p);
     224           0 :         if (rc != -1)
     225           0 :                 return rc;
     226             : 
     227           0 :         return hidms_ioctl(ms, cmd, data, flag, p);
     228           0 : }
     229             : 

Generated by: LCOV version 1.13