LCOV - code coverage report
Current view: top level - dev/i2c - ims.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 70 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: ims.c,v 1.2 2018/09/01 20:50:16 jcs Exp $ */
       2             : /*
       3             :  * HID-over-i2c mouse/trackpad driver
       4             :  *
       5             :  * Copyright (c) 2015, 2016 joshua stein <jcs@openbsd.org>
       6             :  *
       7             :  * Permission to use, copy, modify, and distribute this software for any
       8             :  * purpose with or without fee is hereby granted, provided that the above
       9             :  * copyright notice and this permission notice appear in all copies.
      10             :  *
      11             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      12             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      13             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      14             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      15             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      16             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      17             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      18             :  */
      19             : 
      20             : #include <sys/param.h>
      21             : #include <sys/systm.h>
      22             : #include <sys/kernel.h>
      23             : #include <sys/device.h>
      24             : #include <sys/ioctl.h>
      25             : 
      26             : #include <dev/i2c/i2cvar.h>
      27             : #include <dev/i2c/ihidev.h>
      28             : 
      29             : #include <dev/wscons/wsconsio.h>
      30             : #include <dev/wscons/wsmousevar.h>
      31             : 
      32             : #include <dev/hid/hid.h>
      33             : #include <dev/hid/hidmsvar.h>
      34             : 
      35             : struct ims_softc {
      36             :         struct ihidev   sc_hdev;
      37             :         struct hidms    sc_ms;
      38             : };
      39             : 
      40             : void    ims_intr(struct ihidev *addr, void *ibuf, u_int len);
      41             : 
      42             : int     ims_enable(void *);
      43             : void    ims_disable(void *);
      44             : int     ims_ioctl(void *, u_long, caddr_t, int, struct proc *);
      45             : 
      46             : const struct wsmouse_accessops ims_accessops = {
      47             :         ims_enable,
      48             :         ims_ioctl,
      49             :         ims_disable,
      50             : };
      51             : 
      52             : int     ims_match(struct device *, void *, void *);
      53             : void    ims_attach(struct device *, struct device *, void *);
      54             : int     ims_detach(struct device *, int);
      55             : 
      56             : struct cfdriver ims_cd = {
      57             :         NULL, "ims", DV_DULL
      58             : };
      59             : 
      60             : const struct cfattach ims_ca = {
      61             :         sizeof(struct ims_softc),
      62             :         ims_match,
      63             :         ims_attach,
      64             :         ims_detach
      65             : };
      66             : 
      67             : int
      68           0 : ims_match(struct device *parent, void *match, void *aux)
      69             : {
      70           0 :         struct ihidev_attach_arg *iha = (struct ihidev_attach_arg *)aux;
      71           0 :         int size;
      72           0 :         void *desc;
      73             : 
      74           0 :         ihidev_get_report_desc(iha->parent, &desc, &size);
      75             : 
      76           0 :         if (hid_is_collection(desc, size, iha->reportid,
      77             :             HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_POINTER)))
      78           0 :                 return (IMATCH_IFACECLASS);
      79             : 
      80           0 :         if (hid_is_collection(desc, size, iha->reportid,
      81             :             HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
      82           0 :                 return (IMATCH_IFACECLASS);
      83             : 
      84           0 :         if (hid_is_collection(desc, size, iha->reportid,
      85             :             HID_USAGE2(HUP_DIGITIZERS, HUD_PEN)))
      86           0 :                 return (IMATCH_IFACECLASS);
      87             : 
      88           0 :         if (hid_is_collection(desc, size, iha->reportid,
      89           0 :             HID_USAGE2(HUP_DIGITIZERS, HUD_TOUCHSCREEN)) &&
      90           0 :             hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
      91           0 :             iha->reportid, hid_input, NULL, NULL))
      92           0 :                 return (IMATCH_IFACECLASS);
      93             : 
      94           0 :         return (IMATCH_NONE);
      95           0 : }
      96             : 
      97             : void
      98           0 : ims_attach(struct device *parent, struct device *self, void *aux)
      99             : {
     100           0 :         struct ims_softc *sc = (struct ims_softc *)self;
     101           0 :         struct hidms *ms = &sc->sc_ms;
     102           0 :         struct ihidev_attach_arg *iha = (struct ihidev_attach_arg *)aux;
     103           0 :         int size, repid;
     104           0 :         void *desc;
     105             : 
     106           0 :         sc->sc_hdev.sc_intr = ims_intr;
     107           0 :         sc->sc_hdev.sc_parent = iha->parent;
     108           0 :         sc->sc_hdev.sc_report_id = iha->reportid;
     109             : 
     110           0 :         ihidev_get_report_desc(iha->parent, &desc, &size);
     111           0 :         repid = iha->reportid;
     112           0 :         sc->sc_hdev.sc_isize = hid_report_size(desc, size, hid_input, repid);
     113           0 :         sc->sc_hdev.sc_osize = hid_report_size(desc, size, hid_output, repid);
     114           0 :         sc->sc_hdev.sc_fsize = hid_report_size(desc, size, hid_feature, repid);
     115             : 
     116           0 :         if (hidms_setup(self, ms, 0, iha->reportid, desc, size) != 0)
     117           0 :                 return;
     118             : 
     119           0 :         hidms_attach(ms, &ims_accessops);
     120           0 : }
     121             : 
     122             : int
     123           0 : ims_detach(struct device *self, int flags)
     124             : {
     125           0 :         struct ims_softc *sc = (struct ims_softc *)self;
     126           0 :         struct hidms *ms = &sc->sc_ms;
     127             : 
     128           0 :         return hidms_detach(ms, flags);
     129             : }
     130             : 
     131             : void
     132           0 : ims_intr(struct ihidev *addr, void *buf, u_int len)
     133             : {
     134           0 :         struct ims_softc *sc = (struct ims_softc *)addr;
     135           0 :         struct hidms *ms = &sc->sc_ms;
     136             : 
     137           0 :         if (ms->sc_enabled != 0)
     138           0 :                 hidms_input(ms, (uint8_t *)buf, len);
     139           0 : }
     140             : 
     141             : int
     142           0 : ims_enable(void *v)
     143             : {
     144           0 :         struct ims_softc *sc = v;
     145           0 :         struct hidms *ms = &sc->sc_ms;
     146             :         int rv;
     147             : 
     148           0 :         if ((rv = hidms_enable(ms)) != 0)
     149           0 :                 return rv;
     150             : 
     151           0 :         return ihidev_open(&sc->sc_hdev);
     152           0 : }
     153             : 
     154             : void
     155           0 : ims_disable(void *v)
     156             : {
     157           0 :         struct ims_softc *sc = v;
     158           0 :         struct hidms *ms = &sc->sc_ms;
     159             : 
     160           0 :         hidms_disable(ms);
     161           0 :         ihidev_close(&sc->sc_hdev);
     162           0 : }
     163             : 
     164             : int
     165           0 : ims_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
     166             : {
     167           0 :         struct ims_softc *sc = v;
     168           0 :         struct hidms *ms = &sc->sc_ms;
     169             :         int rc;
     170             : 
     171             : #if 0
     172             :         rc = ihidev_ioctl(&sc->sc_hdev, cmd, data, flag, p);
     173             :         if (rc != -1)
     174             :                 return rc;
     175             : #endif
     176             : 
     177           0 :         rc = hidms_ioctl(ms, cmd, data, flag, p);
     178           0 :         if (rc != -1)
     179           0 :                 return rc;
     180             : 
     181           0 :         switch (cmd) {
     182             :         case WSMOUSEIO_GTYPE:
     183             :                 /* XXX: should we set something else? */
     184           0 :                 *(u_int *)data = WSMOUSE_TYPE_USB;
     185           0 :                 return 0;
     186             :         default:
     187           0 :                 return -1;
     188             :         }
     189           0 : }

Generated by: LCOV version 1.13