The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/iicbus/iichid.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2018-2019 Marc Priggemeyer <marc.priggemeyer@gmail.com>
    3  * Copyright (c) 2019-2020 Vladimir Kondratyev <wulf@FreeBSD.org>
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 /*
   28  * I2C HID transport backend.
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD$");
   33 
   34 #include "opt_hid.h"
   35 
   36 #include <sys/param.h>
   37 #include <sys/bus.h>
   38 #include <sys/callout.h>
   39 #include <sys/endian.h>
   40 #include <sys/kernel.h>
   41 #include <sys/lock.h>
   42 #include <sys/malloc.h>
   43 #include <sys/module.h>
   44 #include <sys/rman.h>
   45 #include <sys/sysctl.h>
   46 #include <sys/systm.h>
   47 #include <sys/taskqueue.h>
   48 
   49 #include <machine/resource.h>
   50 
   51 #include <contrib/dev/acpica/include/acpi.h>
   52 #include <contrib/dev/acpica/include/accommon.h>
   53 #include <dev/acpica/acpivar.h>
   54 
   55 #include <dev/evdev/input.h>
   56 
   57 #include <dev/hid/hid.h>
   58 #include <dev/hid/hidquirk.h>
   59 
   60 #include <dev/iicbus/iic.h>
   61 #include <dev/iicbus/iicbus.h>
   62 #include <dev/iicbus/iiconf.h>
   63 
   64 #include "hid_if.h"
   65 
   66 #ifdef IICHID_DEBUG
   67 static int iichid_debug = 0;
   68 
   69 static SYSCTL_NODE(_hw, OID_AUTO, iichid, CTLFLAG_RW, 0, "I2C HID");
   70 SYSCTL_INT(_hw_iichid, OID_AUTO, debug, CTLFLAG_RWTUN,
   71     &iichid_debug, 1, "Debug level");
   72 
   73 #define DPRINTFN(sc, n, ...) do {                       \
   74         if (iichid_debug >= (n))                        \
   75                 device_printf((sc)->dev, __VA_ARGS__);  \
   76 } while (0)
   77 #define DPRINTF(sc, ...)        DPRINTFN(sc, 1, __VA_ARGS__)
   78 #else
   79 #define DPRINTFN(...)           do {} while (0)
   80 #define DPRINTF(...)            do {} while (0)
   81 #endif
   82 
   83 typedef hid_size_t      iichid_size_t;
   84 #define IICHID_SIZE_MAX (UINT16_MAX - 2)
   85 
   86 /* 7.2 */
   87 enum {
   88         I2C_HID_CMD_DESCR       = 0x0,
   89         I2C_HID_CMD_RESET       = 0x1,
   90         I2C_HID_CMD_GET_REPORT  = 0x2,
   91         I2C_HID_CMD_SET_REPORT  = 0x3,
   92         I2C_HID_CMD_GET_IDLE    = 0x4,
   93         I2C_HID_CMD_SET_IDLE    = 0x5,
   94         I2C_HID_CMD_GET_PROTO   = 0x6,
   95         I2C_HID_CMD_SET_PROTO   = 0x7,
   96         I2C_HID_CMD_SET_POWER   = 0x8,
   97 };
   98 
   99 #define I2C_HID_POWER_ON                0x0
  100 #define I2C_HID_POWER_OFF               0x1
  101 
  102 /*
  103  * Since interrupt resource acquisition is not always possible (in case of GPIO
  104  * interrupts) iichid now supports a sampling_mode.
  105  * Set dev.iichid.<unit>.sampling_rate_slow to a value greater then 0
  106  * to activate sampling. A value of 0 is possible but will not reset the
  107  * callout and, thereby, disable further report requests. Do not set the
  108  * sampling_rate_fast value too high as it may result in periodical lags of
  109  * cursor motion.
  110  */
  111 #define IICHID_SAMPLING_RATE_FAST       60
  112 #define IICHID_SAMPLING_RATE_SLOW       10
  113 #define IICHID_SAMPLING_HYSTERESIS      1
  114 
  115 /* 5.1.1 - HID Descriptor Format */
  116 struct i2c_hid_desc {
  117         uint16_t wHIDDescLength;
  118         uint16_t bcdVersion;
  119         uint16_t wReportDescLength;
  120         uint16_t wReportDescRegister;
  121         uint16_t wInputRegister;
  122         uint16_t wMaxInputLength;
  123         uint16_t wOutputRegister;
  124         uint16_t wMaxOutputLength;
  125         uint16_t wCommandRegister;
  126         uint16_t wDataRegister;
  127         uint16_t wVendorID;
  128         uint16_t wProductID;
  129         uint16_t wVersionID;
  130         uint32_t reserved;
  131 } __packed;
  132 
  133 #define IICHID_REG_NONE -1
  134 #define IICHID_REG_ACPI (UINT16_MAX + 1)
  135 #define IICHID_REG_ELAN 0x0001
  136 
  137 static const struct iichid_id {
  138         char *id;
  139         int reg;
  140 } iichid_ids[] = {
  141         { "ELAN0000",   IICHID_REG_ELAN },
  142         { "PNP0C50",    IICHID_REG_ACPI },
  143         { "ACPI0C50",   IICHID_REG_ACPI },
  144         { NULL,         0 },
  145 };
  146 
  147 enum iichid_powerstate_how {
  148         IICHID_PS_NULL,
  149         IICHID_PS_ON,
  150         IICHID_PS_OFF,
  151 };
  152 
  153 /*
  154  * Locking: no internal locks are used. To serialize access to shared members,
  155  * external iicbus lock should be taken.  That allows to make locking greatly
  156  * simple at the cost of running front interrupt handlers with locked bus.
  157  */
  158 struct iichid_softc {
  159         device_t                dev;
  160 
  161         bool                    probe_done;
  162         int                     probe_result;
  163 
  164         struct hid_device_info  hw;
  165         uint16_t                addr;   /* Shifted left by 1 */
  166         struct i2c_hid_desc     desc;
  167 
  168         hid_intr_t              *intr_handler;
  169         void                    *intr_ctx;
  170         uint8_t                 *intr_buf;
  171         iichid_size_t           intr_bufsize;
  172 
  173         int                     irq_rid;
  174         struct resource         *irq_res;
  175         void                    *irq_cookie;
  176 
  177 #ifdef IICHID_SAMPLING
  178         int                     sampling_rate_slow;     /* iicbus lock */
  179         int                     sampling_rate_fast;
  180         int                     sampling_hysteresis;
  181         int                     missing_samples;        /* iicbus lock */
  182         struct timeout_task     periodic_task;          /* iicbus lock */
  183         bool                    callout_setup;          /* iicbus lock */
  184         struct taskqueue        *taskqueue;
  185         struct task             event_task;
  186 #endif
  187 
  188         struct task             suspend_task;
  189         bool                    open;                   /* iicbus lock */
  190         bool                    suspend;                /* iicbus lock */
  191         bool                    power_on;               /* iicbus lock */
  192 };
  193 
  194 static device_probe_t   iichid_probe;
  195 static device_attach_t  iichid_attach;
  196 static device_detach_t  iichid_detach;
  197 static device_resume_t  iichid_resume;
  198 static device_suspend_t iichid_suspend;
  199 
  200 static void     iichid_suspend_task(void *, int);
  201 
  202 #ifdef IICHID_SAMPLING
  203 static int      iichid_setup_callout(struct iichid_softc *);
  204 static int      iichid_reset_callout(struct iichid_softc *);
  205 static void     iichid_teardown_callout(struct iichid_softc *);
  206 #endif
  207 
  208 static inline int
  209 acpi_is_iichid(ACPI_HANDLE handle)
  210 {
  211         const struct iichid_id *ids;
  212         UINT32  sta;
  213         int reg;
  214 
  215         for (ids = iichid_ids; ids->id != NULL; ids++) {
  216                 if (acpi_MatchHid(handle, ids->id)) {
  217                         reg = ids->reg;
  218                         break;
  219                 }
  220         }
  221         if (ids->id == NULL)
  222                 return (IICHID_REG_NONE);
  223 
  224         /*
  225          * If no _STA method or if it failed, then assume that
  226          * the device is present.
  227          */
  228         if (ACPI_FAILURE(acpi_GetInteger(handle, "_STA", &sta)) ||
  229             ACPI_DEVICE_PRESENT(sta))
  230                 return (reg);
  231 
  232         return (IICHID_REG_NONE);
  233 }
  234 
  235 static ACPI_STATUS
  236 iichid_get_config_reg(ACPI_HANDLE handle, uint16_t *config_reg)
  237 {
  238         ACPI_OBJECT *result;
  239         ACPI_BUFFER acpi_buf;
  240         ACPI_STATUS status;
  241 
  242         /*
  243          * function (_DSM) to be evaluated to retrieve the address of
  244          * the configuration register of the HID device.
  245          */
  246         /* 3cdff6f7-4267-4555-ad05-b30a3d8938de */
  247         static uint8_t dsm_guid[ACPI_UUID_LENGTH] = {
  248                 0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45,
  249                 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE,
  250         };
  251 
  252         status = acpi_EvaluateDSMTyped(handle, dsm_guid, 1, 1, NULL, &acpi_buf,
  253             ACPI_TYPE_INTEGER);
  254         if (ACPI_FAILURE(status)) {
  255                 printf("%s: error evaluating _DSM\n", __func__);
  256                 return (status);
  257         }
  258         result = (ACPI_OBJECT *) acpi_buf.Pointer;
  259         *config_reg = result->Integer.Value & 0xFFFF;
  260 
  261         AcpiOsFree(result);
  262         return (status);
  263 }
  264 
  265 static int
  266 iichid_cmd_read(struct iichid_softc* sc, void *buf, iichid_size_t maxlen,
  267     iichid_size_t *actual_len)
  268 {
  269         /*
  270          * 6.1.3 - Retrieval of Input Reports
  271          * DEVICE returns the length (2 Bytes) and the entire Input Report.
  272          */
  273         uint8_t actbuf[2] = { 0, 0 };
  274         /* Read actual input report length. */
  275         struct iic_msg msgs[] = {
  276             { sc->addr, IIC_M_RD | IIC_M_NOSTOP, sizeof(actbuf), actbuf },
  277         };
  278         uint16_t actlen;
  279         int error;
  280 
  281         error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
  282         if (error != 0)
  283                 return (error);
  284 
  285         actlen = actbuf[0] | actbuf[1] << 8;
  286         if (actlen <= 2 || actlen == 0xFFFF || maxlen == 0) {
  287                 /* Read and discard 1 byte to send I2C STOP condition. */
  288                 msgs[0] = (struct iic_msg)
  289                     { sc->addr, IIC_M_RD | IIC_M_NOSTART, 1, actbuf };
  290                 actlen = 0;
  291         } else {
  292                 actlen -= 2;
  293                 if (actlen > maxlen) {
  294                         DPRINTF(sc, "input report too big. requested=%d "
  295                             "received=%d\n", maxlen, actlen);
  296                         actlen = maxlen;
  297                 }
  298                 /* Read input report itself. */
  299                 msgs[0] = (struct iic_msg)
  300                     { sc->addr, IIC_M_RD | IIC_M_NOSTART, actlen, buf };
  301         }
  302 
  303         error = iicbus_transfer(sc->dev, msgs, 1);
  304         if (error == 0 && actual_len != NULL)
  305                 *actual_len = actlen;
  306 
  307         DPRINTFN(sc, 5,
  308             "%*D - %*D\n", 2, actbuf, " ", msgs[0].len, msgs[0].buf, " ");
  309 
  310         return (error);
  311 }
  312 
  313 static int
  314 iichid_cmd_write(struct iichid_softc *sc, const void *buf, iichid_size_t len)
  315 {
  316         /* 6.2.3 - Sending Output Reports. */
  317         uint8_t *cmdreg = (uint8_t *)&sc->desc.wOutputRegister;
  318         uint16_t replen = 2 + len;
  319         uint8_t cmd[4] = { cmdreg[0], cmdreg[1], replen & 0xFF, replen >> 8 };
  320         struct iic_msg msgs[] = {
  321             {sc->addr, IIC_M_WR | IIC_M_NOSTOP, sizeof(cmd), cmd},
  322             {sc->addr, IIC_M_WR | IIC_M_NOSTART, len, __DECONST(void *, buf)},
  323         };
  324 
  325         if (le16toh(sc->desc.wMaxOutputLength) == 0)
  326                 return (IIC_ENOTSUPP);
  327         if (len < 2)
  328                 return (IIC_ENOTSUPP);
  329 
  330         DPRINTF(sc, "HID command I2C_HID_CMD_WRITE (len %d): "
  331             "%*D\n", len, len, buf, " ");
  332 
  333         return (iicbus_transfer(sc->dev, msgs, nitems(msgs)));
  334 }
  335 
  336 static int
  337 iichid_cmd_get_hid_desc(struct iichid_softc *sc, uint16_t config_reg,
  338     struct i2c_hid_desc *hid_desc)
  339 {
  340         /*
  341          * 5.2.2 - HID Descriptor Retrieval
  342          * register is passed from the controller.
  343          */
  344         uint16_t cmd = htole16(config_reg);
  345         struct iic_msg msgs[] = {
  346             { sc->addr, IIC_M_WR | IIC_M_NOSTOP, 2, (uint8_t *)&cmd },
  347             { sc->addr, IIC_M_RD, sizeof(*hid_desc), (uint8_t *)hid_desc },
  348         };
  349         int error;
  350 
  351         DPRINTF(sc, "HID command I2C_HID_CMD_DESCR at 0x%x\n", config_reg);
  352 
  353         error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
  354         if (error != 0)
  355                 return (error);
  356 
  357         DPRINTF(sc, "HID descriptor: %*D\n",
  358             (int)sizeof(struct i2c_hid_desc), hid_desc, " ");
  359 
  360         return (0);
  361 }
  362 
  363 static int
  364 iichid_set_power(struct iichid_softc *sc, uint8_t param)
  365 {
  366         uint8_t *cmdreg = (uint8_t *)&sc->desc.wCommandRegister;
  367         uint8_t cmd[] = { cmdreg[0], cmdreg[1], param, I2C_HID_CMD_SET_POWER };
  368         struct iic_msg msgs[] = {
  369             { sc->addr, IIC_M_WR, sizeof(cmd), cmd },
  370         };
  371 
  372         DPRINTF(sc, "HID command I2C_HID_CMD_SET_POWER(%d)\n", param);
  373 
  374         return (iicbus_transfer(sc->dev, msgs, nitems(msgs)));
  375 }
  376 
  377 static int
  378 iichid_reset(struct iichid_softc *sc)
  379 {
  380         uint8_t *cmdreg = (uint8_t *)&sc->desc.wCommandRegister;
  381         uint8_t cmd[] = { cmdreg[0], cmdreg[1], 0, I2C_HID_CMD_RESET };
  382         struct iic_msg msgs[] = {
  383             { sc->addr, IIC_M_WR, sizeof(cmd), cmd },
  384         };
  385 
  386         DPRINTF(sc, "HID command I2C_HID_CMD_RESET\n");
  387 
  388         return (iicbus_transfer(sc->dev, msgs, nitems(msgs)));
  389 }
  390 
  391 static int
  392 iichid_cmd_get_report_desc(struct iichid_softc* sc, void *buf,
  393     iichid_size_t len)
  394 {
  395         uint16_t cmd = sc->desc.wReportDescRegister;
  396         struct iic_msg msgs[] = {
  397             { sc->addr, IIC_M_WR | IIC_M_NOSTOP, 2, (uint8_t *)&cmd },
  398             { sc->addr, IIC_M_RD, len, buf },
  399         };
  400         int error;
  401 
  402         DPRINTF(sc, "HID command I2C_HID_REPORT_DESCR at 0x%x with size %d\n",
  403             le16toh(cmd), len);
  404 
  405         error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
  406         if (error != 0)
  407                 return (error);
  408 
  409         DPRINTF(sc, "HID report descriptor: %*D\n", len, buf, " ");
  410 
  411         return (0);
  412 }
  413 
  414 static int
  415 iichid_cmd_get_report(struct iichid_softc* sc, void *buf, iichid_size_t maxlen,
  416     iichid_size_t *actual_len, uint8_t type, uint8_t id)
  417 {
  418         /*
  419          * 7.2.2.4 - "The protocol is optimized for Report < 15.  If a
  420          * report ID >= 15 is necessary, then the Report ID in the Low Byte
  421          * must be set to 1111 and a Third Byte is appended to the protocol.
  422          * This Third Byte contains the entire/actual report ID."
  423          */
  424         uint8_t *dtareg = (uint8_t *)&sc->desc.wDataRegister;
  425         uint8_t *cmdreg = (uint8_t *)&sc->desc.wCommandRegister;
  426         uint8_t cmd[] = {   /*________|______id>=15_____|______id<15______*/
  427                                                     cmdreg[0]              ,
  428                                                     cmdreg[1]              ,
  429                             (id >= 15 ? 15 | (type << 4): id | (type << 4)),
  430                                               I2C_HID_CMD_GET_REPORT       ,
  431                             (id >= 15 ?         id      :    dtareg[0]    ),
  432                             (id >= 15 ?    dtareg[0]    :    dtareg[1]    ),
  433                             (id >= 15 ?    dtareg[1]    :       0         ),
  434                         };
  435         int cmdlen    =     (id >= 15 ?         7       :       6         );
  436         uint8_t actbuf[2] = { 0, 0 };
  437         uint16_t actlen;
  438         int d, error;
  439         struct iic_msg msgs[] = {
  440             { sc->addr, IIC_M_WR | IIC_M_NOSTOP, cmdlen, cmd },
  441             { sc->addr, IIC_M_RD | IIC_M_NOSTOP, 2, actbuf },
  442             { sc->addr, IIC_M_RD | IIC_M_NOSTART, maxlen, buf },
  443         };
  444 
  445         if (maxlen == 0)
  446                 return (EINVAL);
  447 
  448         DPRINTF(sc, "HID command I2C_HID_CMD_GET_REPORT %d "
  449             "(type %d, len %d)\n", id, type, maxlen);
  450 
  451         /*
  452          * 7.2.2.2 - Response will be a 2-byte length value, the report
  453          * id (1 byte, if defined in Report Descriptor), and then the report.
  454          */
  455         error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
  456         if (error != 0)
  457                 return (error);
  458 
  459         actlen = actbuf[0] | actbuf[1] << 8;
  460         if (actlen != maxlen + 2)
  461                 DPRINTF(sc, "response size %d != expected length %d\n",
  462                     actlen, maxlen + 2);
  463 
  464         if (actlen <= 2 || actlen == 0xFFFF)
  465                 return (ENOMSG);
  466 
  467         d = id != 0 ? *(uint8_t *)buf : 0;
  468         if (d != id) {
  469                 DPRINTF(sc, "response report id %d != %d\n", d, id);
  470                 return (EBADMSG);
  471         }
  472 
  473         actlen -= 2;
  474         if (actlen > maxlen)
  475                 actlen = maxlen;
  476         if (actual_len != NULL)
  477                 *actual_len = actlen;
  478 
  479         DPRINTF(sc, "response: %*D %*D\n", 2, actbuf, " ", actlen, buf, " ");
  480 
  481         return (0);
  482 }
  483 
  484 static int
  485 iichid_cmd_set_report(struct iichid_softc* sc, const void *buf,
  486     iichid_size_t len, uint8_t type, uint8_t id)
  487 {
  488         /*
  489          * 7.2.2.4 - "The protocol is optimized for Report < 15.  If a
  490          * report ID >= 15 is necessary, then the Report ID in the Low Byte
  491          * must be set to 1111 and a Third Byte is appended to the protocol.
  492          * This Third Byte contains the entire/actual report ID."
  493          */
  494         uint8_t *dtareg = (uint8_t *)&sc->desc.wDataRegister;
  495         uint8_t *cmdreg = (uint8_t *)&sc->desc.wCommandRegister;
  496         uint16_t replen = 2 + len;
  497         uint8_t cmd[] = {   /*________|______id>=15_____|______id<15______*/
  498                                                     cmdreg[0]              ,
  499                                                     cmdreg[1]              ,
  500                             (id >= 15 ? 15 | (type << 4): id | (type << 4)),
  501                                               I2C_HID_CMD_SET_REPORT       ,
  502                             (id >= 15 ?         id      :    dtareg[0]    ),
  503                             (id >= 15 ?    dtareg[0]    :    dtareg[1]    ),
  504                             (id >= 15 ?    dtareg[1]    :   replen & 0xff ),
  505                             (id >= 15 ?   replen & 0xff :   replen >> 8   ),
  506                             (id >= 15 ?   replen >> 8   :       0         ),
  507                         };
  508         int cmdlen    =     (id >= 15 ?         9       :       8         );
  509         struct iic_msg msgs[] = {
  510             {sc->addr, IIC_M_WR | IIC_M_NOSTOP, cmdlen, cmd},
  511             {sc->addr, IIC_M_WR | IIC_M_NOSTART, len, __DECONST(void *, buf)},
  512         };
  513 
  514         DPRINTF(sc, "HID command I2C_HID_CMD_SET_REPORT %d (type %d, len %d): "
  515             "%*D\n", id, type, len, len, buf, " ");
  516 
  517         return (iicbus_transfer(sc->dev, msgs, nitems(msgs)));
  518 }
  519 
  520 #ifdef IICHID_SAMPLING
  521 static void
  522 iichid_event_task(void *context, int pending)
  523 {
  524         struct iichid_softc *sc;
  525         device_t parent;
  526         iichid_size_t actual;
  527         bool bus_requested;
  528         int error;
  529 
  530         sc = context;
  531         parent = device_get_parent(sc->dev);
  532 
  533         bus_requested = false;
  534         if (iicbus_request_bus(parent, sc->dev, IIC_WAIT) != 0)
  535                 goto rearm;
  536         bus_requested = true;
  537 
  538         if (!sc->power_on)
  539                 goto out;
  540 
  541         error = iichid_cmd_read(sc, sc->intr_buf, sc->intr_bufsize, &actual);
  542         if (error == 0) {
  543                 if (actual > 0) {
  544                         sc->intr_handler(sc->intr_ctx, sc->intr_buf, actual);
  545                         sc->missing_samples = 0;
  546                 } else
  547                         ++sc->missing_samples;
  548         } else
  549                 DPRINTF(sc, "read error occurred: %d\n", error);
  550 
  551 rearm:
  552         if (sc->callout_setup && sc->sampling_rate_slow > 0) {
  553                 if (sc->missing_samples == sc->sampling_hysteresis)
  554                         sc->intr_handler(sc->intr_ctx, sc->intr_buf, 0);
  555                 taskqueue_enqueue_timeout(sc->taskqueue, &sc->periodic_task,
  556                     hz / MAX(sc->missing_samples >= sc->sampling_hysteresis ?
  557                       sc->sampling_rate_slow : sc->sampling_rate_fast, 1));
  558         }
  559 out:
  560         if (bus_requested)
  561                 iicbus_release_bus(parent, sc->dev);
  562 }
  563 #endif  /* IICHID_SAMPLING */
  564 
  565 static void
  566 iichid_intr(void *context)
  567 {
  568         struct iichid_softc *sc;
  569         device_t parent;
  570         iichid_size_t maxlen, actual;
  571         int error;
  572 
  573         sc = context;
  574         parent = device_get_parent(sc->dev);
  575 
  576         /*
  577          * Designware(IG4) driver-specific hack.
  578          * Requesting of an I2C bus with IIC_DONTWAIT parameter enables polled
  579          * mode in the driver, making possible iicbus_transfer execution from
  580          * interrupt handlers and callouts.
  581          */
  582         if (iicbus_request_bus(parent, sc->dev, IIC_DONTWAIT) != 0)
  583                 return;
  584 
  585         /*
  586          * Reading of input reports of I2C devices residing in SLEEP state is
  587          * not allowed and often returns a garbage.  If a HOST needs to
  588          * communicate with the DEVICE it MUST issue a SET POWER command
  589          * (to ON) before any other command. As some hardware requires reads to
  590          * acknowledge interrupts we fetch only length header and discard it.
  591          */
  592         maxlen = sc->power_on ? sc->intr_bufsize : 0;
  593         error = iichid_cmd_read(sc, sc->intr_buf, maxlen, &actual);
  594         if (error == 0) {
  595                 if (sc->power_on) {
  596                         if (actual != 0)
  597                                 sc->intr_handler(sc->intr_ctx, sc->intr_buf,
  598                                     actual);
  599                         else
  600                                 DPRINTF(sc, "no data received\n");
  601                 }
  602         } else
  603                 DPRINTF(sc, "read error occurred: %d\n", error);
  604 
  605         iicbus_release_bus(parent, sc->dev);
  606 }
  607 
  608 static int
  609 iichid_set_power_state(struct iichid_softc *sc,
  610      enum iichid_powerstate_how how_open,
  611      enum iichid_powerstate_how how_suspend)
  612 {
  613         device_t parent;
  614         int error;
  615         int how_request;
  616         bool power_on;
  617 
  618         /*
  619          * Request iicbus early as sc->suspend and sc->power_on
  620          * are protected by iicbus internal lock.
  621          */
  622         parent = device_get_parent(sc->dev);
  623         /* Allow to interrupt open()/close() handlers by SIGINT */
  624         how_request = how_open == IICHID_PS_NULL ? IIC_WAIT : IIC_INTRWAIT;
  625         error = iicbus_request_bus(parent, sc->dev, how_request);
  626         if (error != 0)
  627                 return (error);
  628 
  629         switch (how_open) {
  630         case IICHID_PS_ON:
  631                 sc->open = true;
  632                 break;
  633         case IICHID_PS_OFF:
  634                 sc->open = false;
  635                 break;
  636         case IICHID_PS_NULL:
  637         default:
  638                 break;
  639         }
  640 
  641         switch (how_suspend) {
  642         case IICHID_PS_ON:
  643                 sc->suspend = false;
  644                 break;
  645         case IICHID_PS_OFF:
  646                 sc->suspend = true;
  647                 break;
  648         case IICHID_PS_NULL:
  649         default:
  650                 break;
  651         }
  652 
  653         power_on = sc->open & !sc->suspend;
  654 
  655         if (power_on != sc->power_on) {
  656                 error = iichid_set_power(sc,
  657                     power_on ? I2C_HID_POWER_ON : I2C_HID_POWER_OFF);
  658 
  659                 sc->power_on = power_on;
  660 #ifdef IICHID_SAMPLING
  661                 if (sc->sampling_rate_slow >= 0 && sc->intr_handler != NULL) {
  662                         if (power_on) {
  663                                 iichid_setup_callout(sc);
  664                                 iichid_reset_callout(sc);
  665                         } else
  666                                 iichid_teardown_callout(sc);
  667                 }
  668 #endif
  669         }
  670 
  671         iicbus_release_bus(parent, sc->dev);
  672 
  673         return (error);
  674 }
  675 
  676 static int
  677 iichid_setup_interrupt(struct iichid_softc *sc)
  678 {
  679         sc->irq_cookie = 0;
  680 
  681         int error = bus_setup_intr(sc->dev, sc->irq_res,
  682             INTR_TYPE_TTY|INTR_MPSAFE, NULL, iichid_intr, sc, &sc->irq_cookie);
  683         if (error != 0)
  684                 DPRINTF(sc, "Could not setup interrupt handler\n");
  685         else
  686                 DPRINTF(sc, "successfully setup interrupt\n");
  687 
  688         return (error);
  689 }
  690 
  691 static void
  692 iichid_teardown_interrupt(struct iichid_softc *sc)
  693 {
  694         if (sc->irq_cookie)
  695                 bus_teardown_intr(sc->dev, sc->irq_res, sc->irq_cookie);
  696 
  697         sc->irq_cookie = 0;
  698 }
  699 
  700 #ifdef IICHID_SAMPLING
  701 static int
  702 iichid_setup_callout(struct iichid_softc *sc)
  703 {
  704 
  705         if (sc->sampling_rate_slow < 0) {
  706                 DPRINTF(sc, "sampling_rate is below 0, can't setup callout\n");
  707                 return (EINVAL);
  708         }
  709 
  710         sc->callout_setup = true;
  711         DPRINTF(sc, "successfully setup callout\n");
  712         return (0);
  713 }
  714 
  715 static int
  716 iichid_reset_callout(struct iichid_softc *sc)
  717 {
  718 
  719         if (sc->sampling_rate_slow <= 0) {
  720                 DPRINTF(sc, "sampling_rate is below or equal to 0, "
  721                     "can't reset callout\n");
  722                 return (EINVAL);
  723         }
  724 
  725         if (!sc->callout_setup)
  726                 return (EINVAL);
  727 
  728         /* Start with slow sampling. */
  729         sc->missing_samples = sc->sampling_hysteresis;
  730         taskqueue_enqueue(sc->taskqueue, &sc->event_task);
  731 
  732         return (0);
  733 }
  734 
  735 static void
  736 iichid_teardown_callout(struct iichid_softc *sc)
  737 {
  738 
  739         sc->callout_setup = false;
  740         taskqueue_cancel_timeout(sc->taskqueue, &sc->periodic_task, NULL);
  741         DPRINTF(sc, "tore callout down\n");
  742 }
  743 
  744 static int
  745 iichid_sysctl_sampling_rate_handler(SYSCTL_HANDLER_ARGS)
  746 {
  747         struct iichid_softc *sc;
  748         device_t parent;
  749         int error, oldval, value;
  750 
  751         sc = arg1;
  752 
  753         value = sc->sampling_rate_slow;
  754         error = sysctl_handle_int(oidp, &value, 0, req);
  755 
  756         if (error != 0 || req->newptr == NULL ||
  757             value == sc->sampling_rate_slow)
  758                 return (error);
  759 
  760         /* Can't switch to interrupt mode if it is not supported. */
  761         if (sc->irq_res == NULL && value < 0)
  762                 return (EINVAL);
  763 
  764         parent = device_get_parent(sc->dev);
  765         error = iicbus_request_bus(parent, sc->dev, IIC_WAIT);
  766         if (error != 0)
  767                 return (iic2errno(error));
  768 
  769         oldval = sc->sampling_rate_slow;
  770         sc->sampling_rate_slow = value;
  771 
  772         if (oldval < 0 && value >= 0) {
  773                 iichid_teardown_interrupt(sc);
  774                 if (sc->power_on)
  775                         iichid_setup_callout(sc);
  776         } else if (oldval >= 0 && value < 0) {
  777                 if (sc->power_on)
  778                         iichid_teardown_callout(sc);
  779                 iichid_setup_interrupt(sc);
  780         }
  781 
  782         if (sc->power_on && value > 0)
  783                 iichid_reset_callout(sc);
  784 
  785         iicbus_release_bus(parent, sc->dev);
  786 
  787         DPRINTF(sc, "new sampling_rate value: %d\n", value);
  788 
  789         return (0);
  790 }
  791 #endif /* IICHID_SAMPLING */
  792 
  793 static void
  794 iichid_intr_setup(device_t dev, hid_intr_t intr, void *context,
  795     struct hid_rdesc_info *rdesc)
  796 {
  797         struct iichid_softc *sc;
  798 
  799         if (intr == NULL)
  800                 return;
  801 
  802         sc = device_get_softc(dev);
  803         /*
  804          * Do not rely on wMaxInputLength, as some devices may set it to
  805          * a wrong length. Find the longest input report in report descriptor.
  806          */
  807         rdesc->rdsize = rdesc->isize;
  808         /* Write and get/set_report sizes are limited by I2C-HID protocol. */
  809         rdesc->grsize = rdesc->srsize = IICHID_SIZE_MAX;
  810         rdesc->wrsize = IICHID_SIZE_MAX;
  811 
  812         sc->intr_handler = intr;
  813         sc->intr_ctx = context;
  814         sc->intr_buf = malloc(rdesc->rdsize, M_DEVBUF, M_WAITOK | M_ZERO);
  815         sc->intr_bufsize = rdesc->rdsize;
  816 #ifdef IICHID_SAMPLING
  817         taskqueue_start_threads(&sc->taskqueue, 1, PI_TTY,
  818             "%s taskq", device_get_nameunit(sc->dev));
  819 #endif
  820 }
  821 
  822 static void
  823 iichid_intr_unsetup(device_t dev)
  824 {
  825         struct iichid_softc *sc;
  826 
  827         sc = device_get_softc(dev);
  828 #ifdef IICHID_SAMPLING
  829         taskqueue_drain_all(sc->taskqueue);
  830 #endif
  831         free(sc->intr_buf, M_DEVBUF);
  832 }
  833 
  834 static int
  835 iichid_intr_start(device_t dev)
  836 {
  837         struct iichid_softc *sc;
  838 
  839         sc = device_get_softc(dev);
  840         DPRINTF(sc, "iichid device open\n");
  841         iichid_set_power_state(sc, IICHID_PS_ON, IICHID_PS_NULL);
  842 
  843         return (0);
  844 }
  845 
  846 static int
  847 iichid_intr_stop(device_t dev)
  848 {
  849         struct iichid_softc *sc;
  850 
  851         sc = device_get_softc(dev);
  852         DPRINTF(sc, "iichid device close\n");
  853         /*
  854          * 8.2 - The HOST determines that there are no active applications
  855          * that are currently using the specific HID DEVICE.  The HOST
  856          * is recommended to issue a HIPO command to the DEVICE to force
  857          * the DEVICE in to a lower power state.
  858          */
  859         iichid_set_power_state(sc, IICHID_PS_OFF, IICHID_PS_NULL);
  860 
  861         return (0);
  862 }
  863 
  864 static void
  865 iichid_intr_poll(device_t dev)
  866 {
  867         struct iichid_softc *sc;
  868         iichid_size_t actual;
  869         int error;
  870 
  871         sc = device_get_softc(dev);
  872         error = iichid_cmd_read(sc, sc->intr_buf, sc->intr_bufsize, &actual);
  873         if (error == 0 && actual != 0)
  874                 sc->intr_handler(sc->intr_ctx, sc->intr_buf, actual);
  875 }
  876 
  877 /*
  878  * HID interface
  879  */
  880 static int
  881 iichid_get_rdesc(device_t dev, void *buf, hid_size_t len)
  882 {
  883         struct iichid_softc *sc;
  884         int error;
  885 
  886         sc = device_get_softc(dev);
  887         error = iichid_cmd_get_report_desc(sc, buf, len);
  888         if (error)
  889                 DPRINTF(sc, "failed to fetch report descriptor: %d\n", error);
  890 
  891         return (iic2errno(error));
  892 }
  893 
  894 static int
  895 iichid_read(device_t dev, void *buf, hid_size_t maxlen, hid_size_t *actlen)
  896 {
  897         struct iichid_softc *sc;
  898         device_t parent;
  899         int error;
  900 
  901         if (maxlen > IICHID_SIZE_MAX)
  902                 return (EMSGSIZE);
  903         sc = device_get_softc(dev);
  904         parent = device_get_parent(sc->dev);
  905         error = iicbus_request_bus(parent, sc->dev, IIC_WAIT);
  906         if (error == 0) {
  907                 error = iichid_cmd_read(sc, buf, maxlen, actlen);
  908                 iicbus_release_bus(parent, sc->dev);
  909         }
  910         return (iic2errno(error));
  911 }
  912 
  913 static int
  914 iichid_write(device_t dev, const void *buf, hid_size_t len)
  915 {
  916         struct iichid_softc *sc;
  917 
  918         if (len > IICHID_SIZE_MAX)
  919                 return (EMSGSIZE);
  920         sc = device_get_softc(dev);
  921         return (iic2errno(iichid_cmd_write(sc, buf, len)));
  922 }
  923 
  924 static int
  925 iichid_get_report(device_t dev, void *buf, hid_size_t maxlen,
  926     hid_size_t *actlen, uint8_t type, uint8_t id)
  927 {
  928         struct iichid_softc *sc;
  929 
  930         if (maxlen > IICHID_SIZE_MAX)
  931                 return (EMSGSIZE);
  932         sc = device_get_softc(dev);
  933         return (iic2errno(
  934             iichid_cmd_get_report(sc, buf, maxlen, actlen, type, id)));
  935 }
  936 
  937 static int
  938 iichid_set_report(device_t dev, const void *buf, hid_size_t len, uint8_t type,
  939     uint8_t id)
  940 {
  941         struct iichid_softc *sc;
  942 
  943         if (len > IICHID_SIZE_MAX)
  944                 return (EMSGSIZE);
  945         sc = device_get_softc(dev);
  946         return (iic2errno(iichid_cmd_set_report(sc, buf, len, type, id)));
  947 }
  948 
  949 static int
  950 iichid_set_idle(device_t dev, uint16_t duration, uint8_t id)
  951 {
  952         return (ENOTSUP);
  953 }
  954 
  955 static int
  956 iichid_set_protocol(device_t dev, uint16_t protocol)
  957 {
  958         return (ENOTSUP);
  959 }
  960 
  961 static int
  962 iichid_ioctl(device_t dev, unsigned long cmd, uintptr_t data)
  963 {
  964         int error;
  965 
  966         switch (cmd) {
  967         case I2CRDWR:
  968                 error = iic2errno(iicbus_transfer(dev,
  969                     ((struct iic_rdwr_data *)data)->msgs,
  970                     ((struct iic_rdwr_data *)data)->nmsgs));
  971                 break;
  972         default:
  973                 error = EINVAL;
  974         }
  975 
  976         return (error);
  977 }
  978 
  979 static int
  980 iichid_fill_device_info(struct i2c_hid_desc *desc, ACPI_HANDLE handle,
  981     struct hid_device_info *hw)
  982 {
  983         ACPI_DEVICE_INFO *device_info;
  984 
  985         hw->idBus = BUS_I2C;
  986         hw->idVendor = le16toh(desc->wVendorID);
  987         hw->idProduct = le16toh(desc->wProductID);
  988         hw->idVersion = le16toh(desc->wVersionID);
  989 
  990         /* get ACPI HID. It is a base part of the device name. */
  991         if (ACPI_FAILURE(AcpiGetObjectInfo(handle, &device_info)))
  992                 return (ENXIO);
  993 
  994         if (device_info->Valid & ACPI_VALID_HID)
  995                 strlcpy(hw->idPnP, device_info->HardwareId.String,
  996                     HID_PNP_ID_SIZE);
  997         snprintf(hw->name, sizeof(hw->name), "%s:%02lX %04X:%04X",
  998             (device_info->Valid & ACPI_VALID_HID) ?
  999             device_info->HardwareId.String : "Unknown",
 1000             (device_info->Valid & ACPI_VALID_UID) ?
 1001             strtoul(device_info->UniqueId.String, NULL, 10) : 0UL,
 1002             le16toh(desc->wVendorID), le16toh(desc->wProductID));
 1003 
 1004         AcpiOsFree(device_info);
 1005 
 1006         strlcpy(hw->serial, "", sizeof(hw->serial));
 1007         hw->rdescsize = le16toh(desc->wReportDescLength);
 1008         if (desc->wOutputRegister == 0 || desc->wMaxOutputLength == 0)
 1009                 hid_add_dynamic_quirk(hw, HQ_NOWRITE);
 1010 
 1011         return (0);
 1012 }
 1013 
 1014 static int
 1015 iichid_probe(device_t dev)
 1016 {
 1017         struct iichid_softc *sc;
 1018         ACPI_HANDLE handle;
 1019         char buf[80];
 1020         uint16_t config_reg;
 1021         int error, reg;
 1022 
 1023         sc = device_get_softc(dev);
 1024         sc->dev = dev;
 1025         if (sc->probe_done)
 1026                 goto done;
 1027 
 1028         sc->probe_done = true;
 1029         sc->probe_result = ENXIO;
 1030 
 1031         if (acpi_disabled("iichid"))
 1032                 return (ENXIO);
 1033 
 1034         sc->addr = iicbus_get_addr(dev) << 1;
 1035         if (sc->addr == 0)
 1036                 return (ENXIO);
 1037 
 1038         handle = acpi_get_handle(dev);
 1039         if (handle == NULL)
 1040                 return (ENXIO);
 1041 
 1042         reg = acpi_is_iichid(handle);
 1043         if (reg == IICHID_REG_NONE)
 1044                 return (ENXIO);
 1045 
 1046         if (reg == IICHID_REG_ACPI) {
 1047                 if (ACPI_FAILURE(iichid_get_config_reg(handle, &config_reg)))
 1048                         return (ENXIO);
 1049         } else
 1050                 config_reg = (uint16_t)reg;
 1051 
 1052         DPRINTF(sc, "  IICbus addr       : 0x%02X\n", sc->addr >> 1);
 1053         DPRINTF(sc, "  HID descriptor reg: 0x%02X\n", config_reg);
 1054 
 1055         error = iichid_cmd_get_hid_desc(sc, config_reg, &sc->desc);
 1056         if (error) {
 1057                 DPRINTF(sc, "could not retrieve HID descriptor from the "
 1058                     "device: %d\n", error);
 1059                 return (ENXIO);
 1060         }
 1061 
 1062         if (le16toh(sc->desc.wHIDDescLength) != 30 ||
 1063             le16toh(sc->desc.bcdVersion) != 0x100) {
 1064                 DPRINTF(sc, "HID descriptor is broken\n");
 1065                 return (ENXIO);
 1066         }
 1067 
 1068         /* Setup hid_device_info so we can figure out quirks for the device. */
 1069         if (iichid_fill_device_info(&sc->desc, handle, &sc->hw) != 0) {
 1070                 DPRINTF(sc, "error evaluating AcpiGetObjectInfo\n");
 1071                 return (ENXIO);
 1072         }
 1073 
 1074         if (hid_test_quirk(&sc->hw, HQ_HID_IGNORE))
 1075                 return (ENXIO);
 1076 
 1077         sc->probe_result = BUS_PROBE_DEFAULT;
 1078 done:
 1079         if (sc->probe_result <= BUS_PROBE_SPECIFIC) {
 1080                 snprintf(buf, sizeof(buf), "%s I2C HID device", sc->hw.name);
 1081                 device_set_desc_copy(dev, buf);
 1082         }
 1083         return (sc->probe_result);
 1084 }
 1085 
 1086 static int
 1087 iichid_attach(device_t dev)
 1088 {
 1089         struct iichid_softc *sc;
 1090         device_t child;
 1091         int error;
 1092 
 1093         sc = device_get_softc(dev);
 1094         error = iichid_set_power(sc, I2C_HID_POWER_ON);
 1095         if (error) {
 1096                 device_printf(dev, "failed to power on: %d\n", error);
 1097                 return (ENXIO);
 1098         }
 1099         /*
 1100          * Windows driver sleeps for 1ms between the SET_POWER and RESET
 1101          * commands. So we too as some devices may depend on this.
 1102          */
 1103         pause("iichid", (hz + 999) / 1000);
 1104 
 1105         error = iichid_reset(sc);
 1106         if (error) {
 1107                 device_printf(dev, "failed to reset hardware: %d\n", error);
 1108                 error = ENXIO;
 1109                 goto done;
 1110         }
 1111 
 1112         sc->power_on = true;
 1113 
 1114         TASK_INIT(&sc->suspend_task, 0, iichid_suspend_task, sc);
 1115 #ifdef IICHID_SAMPLING
 1116         TASK_INIT(&sc->event_task, 0, iichid_event_task, sc);
 1117         /* taskqueue_create can't fail with M_WAITOK mflag passed. */
 1118         sc->taskqueue = taskqueue_create("iichid_tq", M_WAITOK | M_ZERO,
 1119             taskqueue_thread_enqueue, &sc->taskqueue);
 1120         TIMEOUT_TASK_INIT(sc->taskqueue, &sc->periodic_task, 0,
 1121             iichid_event_task, sc);
 1122 
 1123         sc->sampling_rate_slow = -1;
 1124         sc->sampling_rate_fast = IICHID_SAMPLING_RATE_FAST;
 1125         sc->sampling_hysteresis = IICHID_SAMPLING_HYSTERESIS;
 1126 #endif
 1127 
 1128         sc->irq_rid = 0;
 1129         sc->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
 1130             &sc->irq_rid, RF_ACTIVE);
 1131 
 1132         if (sc->irq_res != NULL) {
 1133                 DPRINTF(sc, "allocated irq at %p and rid %d\n",
 1134                     sc->irq_res, sc->irq_rid);
 1135                 error = iichid_setup_interrupt(sc);
 1136         }
 1137 
 1138         if (sc->irq_res == NULL || error != 0) {
 1139 #ifdef IICHID_SAMPLING
 1140                 device_printf(sc->dev,
 1141                     "Interrupt setup failed. Fallback to sampling\n");
 1142                 sc->sampling_rate_slow = IICHID_SAMPLING_RATE_SLOW;
 1143 #else
 1144                 device_printf(sc->dev, "Interrupt setup failed\n");
 1145                 if (sc->irq_res != NULL)
 1146                         bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
 1147                             sc->irq_res);
 1148                 error = ENXIO;
 1149                 goto done;
 1150 #endif
 1151         }
 1152 
 1153 #ifdef IICHID_SAMPLING
 1154         SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev),
 1155                 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
 1156                 OID_AUTO, "sampling_rate_slow", CTLTYPE_INT | CTLFLAG_RWTUN,
 1157                 sc, 0, iichid_sysctl_sampling_rate_handler, "I",
 1158                 "idle sampling rate in num/second");
 1159         SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->dev),
 1160                 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
 1161                 OID_AUTO, "sampling_rate_fast", CTLFLAG_RWTUN,
 1162                 &sc->sampling_rate_fast, 0,
 1163                 "active sampling rate in num/second");
 1164         SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->dev),
 1165                 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
 1166                 OID_AUTO, "sampling_hysteresis", CTLFLAG_RWTUN,
 1167                 &sc->sampling_hysteresis, 0,
 1168                 "number of missing samples before enabling of slow mode");
 1169         hid_add_dynamic_quirk(&sc->hw, HQ_IICHID_SAMPLING);
 1170 
 1171         if (sc->sampling_rate_slow >= 0) {
 1172                 pause("iichid", (hz + 999) / 1000);
 1173                 (void)iichid_cmd_read(sc, NULL, 0, NULL);
 1174         }
 1175 #endif /* IICHID_SAMPLING */
 1176 
 1177         child = device_add_child(dev, "hidbus", -1);
 1178         if (child == NULL) {
 1179                 device_printf(sc->dev, "Could not add I2C device\n");
 1180                 iichid_detach(dev);
 1181                 error = ENOMEM;
 1182                 goto done;
 1183         }
 1184 
 1185         device_set_ivars(child, &sc->hw);
 1186         error = bus_generic_attach(dev);
 1187         if (error) {
 1188                 device_printf(dev, "failed to attach child: error %d\n", error);
 1189                 iichid_detach(dev);
 1190         }
 1191 done:
 1192         (void)iichid_set_power(sc, I2C_HID_POWER_OFF);
 1193         sc->power_on = false;
 1194         return (error);
 1195 }
 1196 
 1197 static int
 1198 iichid_detach(device_t dev)
 1199 {
 1200         struct iichid_softc *sc;
 1201         int error;
 1202 
 1203         sc = device_get_softc(dev);
 1204         error = device_delete_children(dev);
 1205         if (error)
 1206                 return (error);
 1207         iichid_teardown_interrupt(sc);
 1208         if (sc->irq_res != NULL)
 1209                 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
 1210                     sc->irq_res);
 1211 #ifdef IICHID_SAMPLING
 1212         if (sc->taskqueue != NULL)
 1213                 taskqueue_free(sc->taskqueue);
 1214         sc->taskqueue = NULL;
 1215 #endif
 1216         return (0);
 1217 }
 1218 
 1219 static void
 1220 iichid_suspend_task(void *context, int pending)
 1221 {
 1222         struct iichid_softc *sc = context;
 1223 
 1224         iichid_teardown_interrupt(sc);
 1225 }
 1226 
 1227 static int
 1228 iichid_suspend(device_t dev)
 1229 {
 1230         struct iichid_softc *sc;
 1231         int error;
 1232 
 1233         sc = device_get_softc(dev);
 1234         (void)bus_generic_suspend(dev);
 1235         /*
 1236          * 8.2 - The HOST is going into a deep power optimized state and wishes
 1237          * to put all the devices into a low power state also.  The HOST
 1238          * is recommended to issue a HIPO command to the DEVICE to force
 1239          * the DEVICE in to a lower power state.
 1240          */
 1241         DPRINTF(sc, "Suspend called, setting device to power_state 1\n");
 1242         error = iichid_set_power_state(sc, IICHID_PS_NULL, IICHID_PS_OFF);
 1243         if (error != 0)
 1244                 DPRINTF(sc, "Could not set power_state, error: %d\n", error);
 1245         else
 1246                 DPRINTF(sc, "Successfully set power_state\n");
 1247 
 1248 #ifdef IICHID_SAMPLING
 1249         if (sc->sampling_rate_slow < 0)
 1250 #endif
 1251         {
 1252                 /*
 1253                  * bus_teardown_intr can not be executed right here as it wants
 1254                  * to run on certain CPU to interacts with LAPIC while suspend
 1255                  * thread is bound to CPU0. So run it from taskqueue context.
 1256                  */
 1257 #ifdef IICHID_SAMPLING
 1258 #define suspend_thread  sc->taskqueue
 1259 #else
 1260 #define suspend_thread  taskqueue_thread
 1261 #endif
 1262                 taskqueue_enqueue(suspend_thread, &sc->suspend_task);
 1263                 taskqueue_drain(suspend_thread, &sc->suspend_task);
 1264         }
 1265 
 1266         return (0);
 1267 }
 1268 
 1269 static int
 1270 iichid_resume(device_t dev)
 1271 {
 1272         struct iichid_softc *sc;
 1273         int error;
 1274 
 1275         sc = device_get_softc(dev);
 1276 #ifdef IICHID_SAMPLING
 1277         if (sc->sampling_rate_slow < 0)
 1278 #endif
 1279                 iichid_setup_interrupt(sc);
 1280 
 1281         DPRINTF(sc, "Resume called, setting device to power_state 0\n");
 1282         error = iichid_set_power_state(sc, IICHID_PS_NULL, IICHID_PS_ON);
 1283         if (error != 0)
 1284                 DPRINTF(sc, "Could not set power_state, error: %d\n", error);
 1285         else
 1286                 DPRINTF(sc, "Successfully set power_state\n");
 1287         (void)bus_generic_resume(dev);
 1288 
 1289         return (0);
 1290 }
 1291 
 1292 static device_method_t iichid_methods[] = {
 1293         DEVMETHOD(device_probe,         iichid_probe),
 1294         DEVMETHOD(device_attach,        iichid_attach),
 1295         DEVMETHOD(device_detach,        iichid_detach),
 1296         DEVMETHOD(device_suspend,       iichid_suspend),
 1297         DEVMETHOD(device_resume,        iichid_resume),
 1298 
 1299         DEVMETHOD(hid_intr_setup,       iichid_intr_setup),
 1300         DEVMETHOD(hid_intr_unsetup,     iichid_intr_unsetup),
 1301         DEVMETHOD(hid_intr_start,       iichid_intr_start),
 1302         DEVMETHOD(hid_intr_stop,        iichid_intr_stop),
 1303         DEVMETHOD(hid_intr_poll,        iichid_intr_poll),
 1304 
 1305         /* HID interface */
 1306         DEVMETHOD(hid_get_rdesc,        iichid_get_rdesc),
 1307         DEVMETHOD(hid_read,             iichid_read),
 1308         DEVMETHOD(hid_write,            iichid_write),
 1309         DEVMETHOD(hid_get_report,       iichid_get_report),
 1310         DEVMETHOD(hid_set_report,       iichid_set_report),
 1311         DEVMETHOD(hid_set_idle,         iichid_set_idle),
 1312         DEVMETHOD(hid_set_protocol,     iichid_set_protocol),
 1313         DEVMETHOD(hid_ioctl,            iichid_ioctl),
 1314 
 1315         DEVMETHOD_END
 1316 };
 1317 
 1318 static driver_t iichid_driver = {
 1319         .name = "iichid",
 1320         .methods = iichid_methods,
 1321         .size = sizeof(struct iichid_softc),
 1322 };
 1323 
 1324 DRIVER_MODULE(iichid, iicbus, iichid_driver, NULL, NULL);
 1325 MODULE_DEPEND(iichid, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
 1326 MODULE_DEPEND(iichid, acpi, 1, 1, 1);
 1327 MODULE_DEPEND(iichid, hid, 1, 1, 1);
 1328 MODULE_DEPEND(iichid, hidbus, 1, 1, 1);
 1329 MODULE_VERSION(iichid, 1);
 1330 IICBUS_ACPI_PNP_INFO(iichid_ids);

Cache object: c54a894996a6030a3f6b62a0e450a538


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.