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/glxiic/glxiic.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) 2011 Henrik Brix Andersen <brix@FreeBSD.org>
    3  * All rights reserved.
    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 ``AS IS'' AND ANY EXPRESS OR
   15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   24  */
   25 
   26 #include <sys/cdefs.h>
   27 __FBSDID("$FreeBSD: releng/10.0/sys/dev/glxiic/glxiic.c 241885 2012-10-22 13:06:09Z eadler $");
   28 /*
   29  * AMD Geode LX CS5536 System Management Bus controller.
   30  *
   31  * Although AMD refers to this device as an SMBus controller, it
   32  * really is an I2C controller (It lacks SMBus ALERT# and Alert
   33  * Response support).
   34  *
   35  * The driver is implemented as an interrupt-driven state machine,
   36  * supporting both master and slave mode.
   37  */
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/bus.h>
   41 #include <sys/kernel.h>
   42 #include <sys/module.h>
   43 #include <sys/lock.h>
   44 #include <sys/mutex.h>
   45 #include <sys/sysctl.h>
   46 #ifdef GLXIIC_DEBUG
   47 #include <sys/syslog.h>
   48 #endif
   49 
   50 #include <dev/pci/pcireg.h>
   51 #include <dev/pci/pcivar.h>
   52 
   53 #include <machine/bus.h>
   54 #include <sys/rman.h>
   55 #include <machine/resource.h>
   56 
   57 #include <dev/iicbus/iiconf.h>
   58 #include <dev/iicbus/iicbus.h>
   59 
   60 #include "iicbus_if.h"
   61 
   62 /* CS5536 PCI-ISA ID. */
   63 #define GLXIIC_CS5536_DEV_ID            0x20901022
   64 
   65 /* MSRs. */
   66 #define GLXIIC_MSR_PIC_YSEL_HIGH        0x51400021
   67 
   68 /* Bus speeds. */
   69 #define GLXIIC_SLOW     0x0258  /*  10 kHz. */
   70 #define GLXIIC_FAST     0x0078  /*  50 kHz. */
   71 #define GLXIIC_FASTEST  0x003c  /* 100 kHz. */
   72 
   73 /* Default bus activity timeout in milliseconds. */
   74 #define GLXIIC_DEFAULT_TIMEOUT  35
   75 
   76 /* GPIO register offsets. */
   77 #define GLXIIC_GPIOL_OUT_AUX1_SEL       0x10
   78 #define GLXIIC_GPIOL_IN_AUX1_SEL        0x34
   79 
   80 /* GPIO 14 (SMB_CLK) and 15 (SMB_DATA) bitmasks. */
   81 #define GLXIIC_GPIO_14_15_ENABLE        0x0000c000
   82 #define GLXIIC_GPIO_14_15_DISABLE       0xc0000000
   83 
   84 /* SMB register offsets. */
   85 #define GLXIIC_SMB_SDA                          0x00
   86 #define GLXIIC_SMB_STS                          0x01
   87 #define         GLXIIC_SMB_STS_SLVSTP_BIT       (1 << 7)
   88 #define         GLXIIC_SMB_STS_SDAST_BIT        (1 << 6)
   89 #define         GLXIIC_SMB_STS_BER_BIT          (1 << 5)
   90 #define         GLXIIC_SMB_STS_NEGACK_BIT       (1 << 4)
   91 #define         GLXIIC_SMB_STS_STASTR_BIT       (1 << 3)
   92 #define         GLXIIC_SMB_STS_NMATCH_BIT       (1 << 2)
   93 #define         GLXIIC_SMB_STS_MASTER_BIT       (1 << 1)
   94 #define         GLXIIC_SMB_STS_XMIT_BIT         (1 << 0)
   95 #define GLXIIC_SMB_CTRL_STS                     0x02
   96 #define         GLXIIC_SMB_CTRL_STS_TGSCL_BIT   (1 << 5)
   97 #define         GLXIIC_SMB_CTRL_STS_TSDA_BIT    (1 << 4)
   98 #define         GLXIIC_SMB_CTRL_STS_GCMTCH_BIT  (1 << 3)
   99 #define         GLXIIC_SMB_CTRL_STS_MATCH_BIT   (1 << 2)
  100 #define         GLXIIC_SMB_CTRL_STS_BB_BIT      (1 << 1)
  101 #define         GLXIIC_SMB_CTRL_STS_BUSY_BIT    (1 << 0)
  102 #define GLXIIC_SMB_CTRL1                        0x03
  103 #define         GLXIIC_SMB_CTRL1_STASTRE_BIT    (1 << 7)
  104 #define         GLXIIC_SMB_CTRL1_NMINTE_BIT     (1 << 6)
  105 #define         GLXIIC_SMB_CTRL1_GCMEN_BIT      (1 << 5)
  106 #define         GLXIIC_SMB_CTRL1_ACK_BIT        (1 << 4)
  107 #define         GLXIIC_SMB_CTRL1_INTEN_BIT      (1 << 2)
  108 #define         GLXIIC_SMB_CTRL1_STOP_BIT       (1 << 1)
  109 #define         GLXIIC_SMB_CTRL1_START_BIT      (1 << 0)
  110 #define GLXIIC_SMB_ADDR                         0x04
  111 #define         GLXIIC_SMB_ADDR_SAEN_BIT        (1 << 7)
  112 #define GLXIIC_SMB_CTRL2                        0x05
  113 #define         GLXIIC_SMB_CTRL2_EN_BIT         (1 << 0)
  114 #define GLXIIC_SMB_CTRL3                        0x06
  115 
  116 typedef enum {
  117         GLXIIC_STATE_IDLE,
  118         GLXIIC_STATE_SLAVE_TX,
  119         GLXIIC_STATE_SLAVE_RX,
  120         GLXIIC_STATE_MASTER_ADDR,
  121         GLXIIC_STATE_MASTER_TX,
  122         GLXIIC_STATE_MASTER_RX,
  123         GLXIIC_STATE_MASTER_STOP,
  124         GLXIIC_STATE_MAX,
  125 } glxiic_state_t;
  126 
  127 struct glxiic_softc {
  128         device_t         dev;           /* Myself. */
  129         device_t         iicbus;        /* IIC bus. */
  130         struct mtx       mtx;           /* Lock. */
  131         glxiic_state_t   state;         /* Driver state. */
  132         struct callout   callout;       /* Driver state timeout callout. */
  133         int              timeout;       /* Driver state timeout (ms). */
  134 
  135         int              smb_rid;       /* SMB controller resource ID. */
  136         struct resource *smb_res;       /* SMB controller resource. */
  137         int              gpio_rid;      /* GPIO resource ID. */
  138         struct resource *gpio_res;      /* GPIO resource. */
  139 
  140         int              irq_rid;       /* IRQ resource ID. */
  141         struct resource *irq_res;       /* IRQ resource. */
  142         void            *irq_handler;   /* IRQ handler cookie. */
  143         int              old_irq;       /* IRQ mapped by board firmware. */
  144 
  145         struct iic_msg  *msg;           /* Current master mode message. */
  146         uint32_t         nmsgs;         /* Number of messages remaining. */
  147         uint8_t         *data;          /* Current master mode data byte. */
  148         uint16_t         ndata;         /* Number of data bytes remaining. */
  149         int              error;         /* Last master mode error. */
  150 
  151         uint8_t          addr;          /* Own address. */
  152         uint16_t         sclfrq;        /* Bus frequency. */
  153 };
  154 
  155 #ifdef GLXIIC_DEBUG
  156 #define GLXIIC_DEBUG_LOG(fmt, args...)  \
  157         log(LOG_DEBUG, "%s: " fmt "\n" , __func__ , ## args)
  158 #else
  159 #define GLXIIC_DEBUG_LOG(fmt, args...)
  160 #endif
  161 
  162 #define GLXIIC_SCLFRQ(n)                ((n << 1))
  163 #define GLXIIC_SMBADDR(n)               ((n >> 1))
  164 #define GLXIIC_SMB_IRQ_TO_MAP(n)        ((n << 16))
  165 #define GLXIIC_MAP_TO_SMB_IRQ(n)        ((n >> 16) & 0xf)
  166 
  167 #define GLXIIC_LOCK(_sc)                mtx_lock(&_sc->mtx)
  168 #define GLXIIC_UNLOCK(_sc)              mtx_unlock(&_sc->mtx)
  169 #define GLXIIC_LOCK_INIT(_sc)           \
  170         mtx_init(&_sc->mtx, device_get_nameunit(_sc->dev), "glxiic", MTX_DEF)
  171 #define GLXIIC_SLEEP(_sc)               \
  172         mtx_sleep(_sc, &_sc->mtx, IICPRI, "glxiic", 0)
  173 #define GLXIIC_WAKEUP(_sc)              wakeup(_sc);
  174 #define GLXIIC_LOCK_DESTROY(_sc)        mtx_destroy(&_sc->mtx);
  175 #define GLXIIC_ASSERT_LOCKED(_sc)       mtx_assert(&_sc->mtx, MA_OWNED);
  176 
  177 typedef int (glxiic_state_callback_t)(struct glxiic_softc *sc,
  178     uint8_t status);
  179 
  180 static glxiic_state_callback_t  glxiic_state_idle_callback;
  181 static glxiic_state_callback_t  glxiic_state_slave_tx_callback;
  182 static glxiic_state_callback_t  glxiic_state_slave_rx_callback;
  183 static glxiic_state_callback_t  glxiic_state_master_addr_callback;
  184 static glxiic_state_callback_t  glxiic_state_master_tx_callback;
  185 static glxiic_state_callback_t  glxiic_state_master_rx_callback;
  186 static glxiic_state_callback_t  glxiic_state_master_stop_callback;
  187 
  188 struct glxiic_state_table_entry {
  189         glxiic_state_callback_t *callback;
  190         boolean_t master;
  191 };
  192 typedef struct glxiic_state_table_entry glxiic_state_table_entry_t;
  193 
  194 static glxiic_state_table_entry_t glxiic_state_table[GLXIIC_STATE_MAX] = {
  195         [GLXIIC_STATE_IDLE] = {
  196                 .callback = &glxiic_state_idle_callback,
  197                 .master = FALSE,
  198         },
  199 
  200         [GLXIIC_STATE_SLAVE_TX] = {
  201                 .callback = &glxiic_state_slave_tx_callback,
  202                 .master = FALSE,
  203         },
  204 
  205         [GLXIIC_STATE_SLAVE_RX] = {
  206                 .callback = &glxiic_state_slave_rx_callback,
  207                 .master = FALSE,
  208         },
  209 
  210         [GLXIIC_STATE_MASTER_ADDR] = {
  211                 .callback = &glxiic_state_master_addr_callback,
  212                 .master = TRUE,
  213         },
  214 
  215         [GLXIIC_STATE_MASTER_TX] = {
  216                 .callback = &glxiic_state_master_tx_callback,
  217                 .master = TRUE,
  218         },
  219 
  220         [GLXIIC_STATE_MASTER_RX] = {
  221                 .callback = &glxiic_state_master_rx_callback,
  222                 .master = TRUE,
  223         },
  224 
  225         [GLXIIC_STATE_MASTER_STOP] = {
  226                 .callback = &glxiic_state_master_stop_callback,
  227                 .master = TRUE,
  228         },
  229 };
  230 
  231 static void     glxiic_identify(driver_t *driver, device_t parent);
  232 static int      glxiic_probe(device_t dev);
  233 static int      glxiic_attach(device_t dev);
  234 static int      glxiic_detach(device_t dev);
  235 
  236 static uint8_t  glxiic_read_status_locked(struct glxiic_softc *sc);
  237 static void     glxiic_stop_locked(struct glxiic_softc *sc);
  238 static void     glxiic_timeout(void *arg);
  239 static void     glxiic_start_timeout_locked(struct glxiic_softc *sc);
  240 static void     glxiic_set_state_locked(struct glxiic_softc *sc,
  241     glxiic_state_t state);
  242 static int      glxiic_handle_slave_match_locked(struct glxiic_softc *sc,
  243     uint8_t status);
  244 static void     glxiic_intr(void *arg);
  245 
  246 static int      glxiic_reset(device_t dev, u_char speed, u_char addr,
  247     u_char *oldaddr);
  248 static int      glxiic_transfer(device_t dev, struct iic_msg *msgs,
  249     uint32_t nmsgs);
  250 
  251 static void     glxiic_smb_map_interrupt(int irq);
  252 static void     glxiic_gpio_enable(struct glxiic_softc *sc);
  253 static void     glxiic_gpio_disable(struct glxiic_softc *sc);
  254 static void     glxiic_smb_enable(struct glxiic_softc *sc, uint8_t speed,
  255     uint8_t addr);
  256 static void     glxiic_smb_disable(struct glxiic_softc *sc);
  257 
  258 static device_method_t glxiic_methods[] = {
  259         DEVMETHOD(device_identify,      glxiic_identify),
  260         DEVMETHOD(device_probe,         glxiic_probe),
  261         DEVMETHOD(device_attach,        glxiic_attach),
  262         DEVMETHOD(device_detach,        glxiic_detach),
  263 
  264         DEVMETHOD(iicbus_reset,         glxiic_reset),
  265         DEVMETHOD(iicbus_transfer,      glxiic_transfer),
  266         DEVMETHOD(iicbus_callback,      iicbus_null_callback),
  267 
  268         { 0, 0 }
  269 };
  270 
  271 static driver_t glxiic_driver = {
  272         "glxiic",
  273         glxiic_methods,
  274         sizeof(struct glxiic_softc),
  275 };
  276 
  277 static devclass_t glxiic_devclass;
  278 
  279 DRIVER_MODULE(glxiic, isab, glxiic_driver, glxiic_devclass, 0, 0);
  280 DRIVER_MODULE(iicbus, glxiic, iicbus_driver, iicbus_devclass, 0, 0);
  281 MODULE_DEPEND(glxiic, iicbus, 1, 1, 1);
  282 
  283 static void
  284 glxiic_identify(driver_t *driver, device_t parent)
  285 {
  286 
  287         /* Prevent child from being added more than once. */
  288         if (device_find_child(parent, driver->name, -1) != NULL)
  289                 return;
  290 
  291         if (pci_get_devid(parent) == GLXIIC_CS5536_DEV_ID) {
  292                 if (device_add_child(parent, driver->name, -1) == NULL)
  293                         device_printf(parent, "Could not add glxiic child\n");
  294         }
  295 }
  296 
  297 static int
  298 glxiic_probe(device_t dev)
  299 {
  300 
  301         if (resource_disabled("glxiic", device_get_unit(dev)))
  302                 return (ENXIO);
  303 
  304         device_set_desc(dev, "AMD Geode CS5536 SMBus controller");
  305 
  306         return (BUS_PROBE_DEFAULT);
  307 }
  308 
  309 static int
  310 glxiic_attach(device_t dev)
  311 {
  312         struct glxiic_softc *sc;
  313         struct sysctl_ctx_list *ctx;
  314         struct sysctl_oid *tree;
  315         int error, irq, unit;
  316         uint32_t irq_map;
  317         char tn[32];
  318 
  319         sc = device_get_softc(dev);
  320         sc->dev = dev;
  321         sc->state = GLXIIC_STATE_IDLE;
  322         error = 0;
  323 
  324         GLXIIC_LOCK_INIT(sc);
  325         callout_init_mtx(&sc->callout, &sc->mtx, 0);
  326 
  327         sc->smb_rid = PCIR_BAR(0);
  328         sc->smb_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->smb_rid,
  329             RF_ACTIVE);
  330         if (sc->smb_res == NULL) {
  331                 device_printf(dev, "Could not allocate SMBus I/O port\n");
  332                 error = ENXIO;
  333                 goto out;
  334         }
  335 
  336         sc->gpio_rid = PCIR_BAR(1);
  337         sc->gpio_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
  338             &sc->gpio_rid, RF_SHAREABLE | RF_ACTIVE);
  339         if (sc->gpio_res == NULL) {
  340                 device_printf(dev, "Could not allocate GPIO I/O port\n");
  341                 error = ENXIO;
  342                 goto out;
  343         }
  344 
  345         /* Ensure the controller is not enabled by firmware. */
  346         glxiic_smb_disable(sc);
  347 
  348         /* Read the existing IRQ map. */
  349         irq_map = rdmsr(GLXIIC_MSR_PIC_YSEL_HIGH);
  350         sc->old_irq = GLXIIC_MAP_TO_SMB_IRQ(irq_map);
  351 
  352         unit = device_get_unit(dev);
  353         if (resource_int_value("glxiic", unit, "irq", &irq) == 0) {
  354                 if (irq < 1 || irq > 15) {
  355                         device_printf(dev, "Bad value %d for glxiic.%d.irq\n",
  356                             irq, unit);
  357                         error = ENXIO;
  358                         goto out;
  359                 }
  360 
  361                 if (bootverbose)
  362                         device_printf(dev, "Using irq %d set by hint\n", irq);
  363         } else if (sc->old_irq != 0) {
  364                 if (bootverbose)
  365                         device_printf(dev, "Using irq %d set by firmware\n",
  366                             irq);
  367                 irq = sc->old_irq;
  368         } else {
  369                 device_printf(dev, "No irq mapped by firmware");
  370                 printf(" and no glxiic.%d.irq hint provided\n", unit);
  371                 error = ENXIO;
  372                 goto out;
  373         }
  374 
  375         /* Map the SMBus interrupt to the requested legacy IRQ. */
  376         glxiic_smb_map_interrupt(irq);
  377 
  378         sc->irq_rid = 0;
  379         sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
  380             irq, irq, 1, RF_SHAREABLE | RF_ACTIVE);
  381         if (sc->irq_res == NULL) {
  382                 device_printf(dev, "Could not allocate IRQ %d\n", irq);
  383                 error = ENXIO;
  384                 goto out;
  385         }
  386 
  387         error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
  388             NULL, glxiic_intr, sc, &(sc->irq_handler));
  389         if (error != 0) {
  390                 device_printf(dev, "Could not setup IRQ handler\n");
  391                 error = ENXIO;
  392                 goto out;
  393         }
  394 
  395         if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) {
  396                 device_printf(dev, "Could not allocate iicbus instance\n");
  397                 error = ENXIO;
  398                 goto out;
  399         }
  400 
  401         ctx = device_get_sysctl_ctx(dev);
  402         tree = device_get_sysctl_tree(dev);
  403 
  404         sc->timeout = GLXIIC_DEFAULT_TIMEOUT;
  405         snprintf(tn, sizeof(tn), "dev.glxiic.%d.timeout", unit);
  406         TUNABLE_INT_FETCH(tn, &sc->timeout);
  407         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
  408             "timeout", CTLFLAG_RW | CTLFLAG_TUN, &sc->timeout, 0,
  409             "activity timeout in ms");
  410 
  411         glxiic_gpio_enable(sc);
  412         glxiic_smb_enable(sc, IIC_FASTEST, 0);
  413 
  414         error = bus_generic_attach(dev);
  415         if (error != 0) {
  416                 device_printf(dev, "Could not probe and attach children\n");
  417                 error = ENXIO;
  418         }
  419 out:
  420         if (error != 0) {
  421                 callout_drain(&sc->callout);
  422 
  423                 if (sc->iicbus != NULL)
  424                         device_delete_child(dev, sc->iicbus);
  425                 if (sc->smb_res != NULL) {
  426                         glxiic_smb_disable(sc);
  427                         bus_release_resource(dev, SYS_RES_IOPORT, sc->smb_rid,
  428                             sc->smb_res);
  429                 }
  430                 if (sc->gpio_res != NULL) {
  431                         glxiic_gpio_disable(sc);
  432                         bus_release_resource(dev, SYS_RES_IOPORT, sc->gpio_rid,
  433                             sc->gpio_res);
  434                 }
  435                 if (sc->irq_handler != NULL)
  436                         bus_teardown_intr(dev, sc->irq_res, sc->irq_handler);
  437                 if (sc->irq_res != NULL)
  438                         bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
  439                             sc->irq_res);
  440 
  441                 /* Restore the old SMBus interrupt mapping. */
  442                 glxiic_smb_map_interrupt(sc->old_irq);
  443 
  444                 GLXIIC_LOCK_DESTROY(sc);
  445         }
  446 
  447         return (error);
  448 }
  449 
  450 static int
  451 glxiic_detach(device_t dev)
  452 {
  453         struct glxiic_softc *sc;
  454         int error;
  455 
  456         sc = device_get_softc(dev);
  457 
  458         error = bus_generic_detach(dev);
  459         if (error != 0)
  460                 goto out;
  461         if (sc->iicbus != NULL)
  462                 error = device_delete_child(dev, sc->iicbus);
  463 
  464 out:
  465         callout_drain(&sc->callout);
  466 
  467         if (sc->smb_res != NULL) {
  468                 glxiic_smb_disable(sc);
  469                 bus_release_resource(dev, SYS_RES_IOPORT, sc->smb_rid,
  470                     sc->smb_res);
  471         }
  472         if (sc->gpio_res != NULL) {
  473                 glxiic_gpio_disable(sc);
  474                 bus_release_resource(dev, SYS_RES_IOPORT, sc->gpio_rid,
  475                     sc->gpio_res);
  476         }
  477         if (sc->irq_handler != NULL)
  478                 bus_teardown_intr(dev, sc->irq_res, sc->irq_handler);
  479         if (sc->irq_res != NULL)
  480                 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
  481                     sc->irq_res);
  482 
  483         /* Restore the old SMBus interrupt mapping. */
  484         glxiic_smb_map_interrupt(sc->old_irq);
  485 
  486         GLXIIC_LOCK_DESTROY(sc);
  487 
  488         return (error);
  489 }
  490 
  491 static uint8_t
  492 glxiic_read_status_locked(struct glxiic_softc *sc)
  493 {
  494         uint8_t status;
  495 
  496         GLXIIC_ASSERT_LOCKED(sc);
  497 
  498         status = bus_read_1(sc->smb_res, GLXIIC_SMB_STS);
  499 
  500         /* Clear all status flags except SDAST and STASTR after reading. */
  501         bus_write_1(sc->smb_res, GLXIIC_SMB_STS, (GLXIIC_SMB_STS_SLVSTP_BIT |
  502                 GLXIIC_SMB_STS_BER_BIT | GLXIIC_SMB_STS_NEGACK_BIT |
  503                 GLXIIC_SMB_STS_NMATCH_BIT));
  504 
  505         return (status);
  506 }
  507 
  508 static void
  509 glxiic_stop_locked(struct glxiic_softc *sc)
  510 {
  511         uint8_t status, ctrl1;
  512 
  513         GLXIIC_ASSERT_LOCKED(sc);
  514 
  515         status = glxiic_read_status_locked(sc);
  516 
  517         ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1);
  518         bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1,
  519             ctrl1 | GLXIIC_SMB_CTRL1_STOP_BIT);
  520 
  521         /*
  522          * Perform a dummy read of SDA in master receive mode to clear
  523          * SDAST if set.
  524          */
  525         if ((status & GLXIIC_SMB_STS_XMIT_BIT) == 0 &&
  526             (status & GLXIIC_SMB_STS_SDAST_BIT) != 0)
  527                 bus_read_1(sc->smb_res, GLXIIC_SMB_SDA);
  528 
  529         /* Check stall after start bit and clear if needed */
  530         if ((status & GLXIIC_SMB_STS_STASTR_BIT) != 0) {
  531                 bus_write_1(sc->smb_res, GLXIIC_SMB_STS,
  532                     GLXIIC_SMB_STS_STASTR_BIT);
  533         }
  534 }
  535 
  536 static void
  537 glxiic_timeout(void *arg)
  538 {
  539         struct glxiic_softc *sc;
  540         uint8_t error;
  541 
  542         sc = (struct glxiic_softc *)arg;
  543 
  544         GLXIIC_DEBUG_LOG("timeout in state %d", sc->state);
  545 
  546         if (glxiic_state_table[sc->state].master) {
  547                 sc->error = IIC_ETIMEOUT;
  548                 GLXIIC_WAKEUP(sc);
  549         } else {
  550                 error = IIC_ETIMEOUT;
  551                 iicbus_intr(sc->iicbus, INTR_ERROR, &error);
  552         }
  553 
  554         glxiic_smb_disable(sc);
  555         glxiic_smb_enable(sc, IIC_UNKNOWN, sc->addr);
  556         glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  557 }
  558 
  559 static void
  560 glxiic_start_timeout_locked(struct glxiic_softc *sc)
  561 {
  562 
  563         GLXIIC_ASSERT_LOCKED(sc);
  564 
  565         callout_reset(&sc->callout, sc->timeout * 1000 / hz, glxiic_timeout,
  566             sc);
  567 }
  568 
  569 static void
  570 glxiic_set_state_locked(struct glxiic_softc *sc, glxiic_state_t state)
  571 {
  572 
  573         GLXIIC_ASSERT_LOCKED(sc);
  574 
  575         if (state == GLXIIC_STATE_IDLE)
  576                 callout_stop(&sc->callout);
  577         else if (sc->timeout > 0)
  578                 glxiic_start_timeout_locked(sc);
  579 
  580         sc->state = state;
  581 }
  582 
  583 static int
  584 glxiic_handle_slave_match_locked(struct glxiic_softc *sc, uint8_t status)
  585 {
  586         uint8_t ctrl_sts, addr;
  587 
  588         GLXIIC_ASSERT_LOCKED(sc);
  589 
  590         ctrl_sts = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL_STS);
  591 
  592         if ((ctrl_sts & GLXIIC_SMB_CTRL_STS_MATCH_BIT) != 0) {
  593                 if ((status & GLXIIC_SMB_STS_XMIT_BIT) != 0) {
  594                         addr = sc->addr | LSB;
  595                         glxiic_set_state_locked(sc,
  596                             GLXIIC_STATE_SLAVE_TX);
  597                 } else {
  598                         addr = sc->addr & ~LSB;
  599                         glxiic_set_state_locked(sc,
  600                             GLXIIC_STATE_SLAVE_RX);
  601                 }
  602                 iicbus_intr(sc->iicbus, INTR_START, &addr);
  603         } else if ((ctrl_sts & GLXIIC_SMB_CTRL_STS_GCMTCH_BIT) != 0) {
  604                 addr = 0;
  605                 glxiic_set_state_locked(sc, GLXIIC_STATE_SLAVE_RX);
  606                 iicbus_intr(sc->iicbus, INTR_GENERAL, &addr);
  607         } else {
  608                 GLXIIC_DEBUG_LOG("unknown slave match");
  609                 return (IIC_ESTATUS);
  610         }
  611 
  612         return (IIC_NOERR);
  613 }
  614 
  615 static int
  616 glxiic_state_idle_callback(struct glxiic_softc *sc, uint8_t status)
  617 {
  618 
  619         GLXIIC_ASSERT_LOCKED(sc);
  620 
  621         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  622                 GLXIIC_DEBUG_LOG("bus error in idle");
  623                 return (IIC_EBUSERR);
  624         }
  625 
  626         if ((status & GLXIIC_SMB_STS_NMATCH_BIT) != 0) {
  627                 return (glxiic_handle_slave_match_locked(sc, status));
  628         }
  629 
  630         return (IIC_NOERR);
  631 }
  632 
  633 static int
  634 glxiic_state_slave_tx_callback(struct glxiic_softc *sc, uint8_t status)
  635 {
  636         uint8_t data;
  637 
  638         GLXIIC_ASSERT_LOCKED(sc);
  639 
  640         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  641                 GLXIIC_DEBUG_LOG("bus error in slave tx");
  642                 return (IIC_EBUSERR);
  643         }
  644 
  645         if ((status & GLXIIC_SMB_STS_SLVSTP_BIT) != 0) {
  646                 iicbus_intr(sc->iicbus, INTR_STOP, NULL);
  647                 glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  648                 return (IIC_NOERR);
  649         }
  650 
  651         if ((status & GLXIIC_SMB_STS_NEGACK_BIT) != 0) {
  652                 iicbus_intr(sc->iicbus, INTR_NOACK, NULL);
  653                 return (IIC_NOERR);
  654         }
  655 
  656         if ((status & GLXIIC_SMB_STS_NMATCH_BIT) != 0) {
  657                 /* Handle repeated start in slave mode. */
  658                 return (glxiic_handle_slave_match_locked(sc, status));
  659         }
  660 
  661         if ((status & GLXIIC_SMB_STS_SDAST_BIT) == 0) {
  662                 GLXIIC_DEBUG_LOG("not awaiting data in slave tx");
  663                 return (IIC_ESTATUS);
  664         }
  665 
  666         iicbus_intr(sc->iicbus, INTR_TRANSMIT, &data);
  667         bus_write_1(sc->smb_res, GLXIIC_SMB_SDA, data);
  668 
  669         glxiic_start_timeout_locked(sc);
  670 
  671         return (IIC_NOERR);
  672 }
  673 
  674 static int
  675 glxiic_state_slave_rx_callback(struct glxiic_softc *sc, uint8_t status)
  676 {
  677         uint8_t data;
  678 
  679         GLXIIC_ASSERT_LOCKED(sc);
  680 
  681         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  682                 GLXIIC_DEBUG_LOG("bus error in slave rx");
  683                 return (IIC_EBUSERR);
  684         }
  685 
  686         if ((status & GLXIIC_SMB_STS_SLVSTP_BIT) != 0) {
  687                 iicbus_intr(sc->iicbus, INTR_STOP, NULL);
  688                 glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  689                 return (IIC_NOERR);
  690         }
  691 
  692         if ((status & GLXIIC_SMB_STS_NMATCH_BIT) != 0) {
  693                 /* Handle repeated start in slave mode. */
  694                 return (glxiic_handle_slave_match_locked(sc, status));
  695         }
  696 
  697         if ((status & GLXIIC_SMB_STS_SDAST_BIT) == 0) {
  698                 GLXIIC_DEBUG_LOG("no pending data in slave rx");
  699                 return (IIC_ESTATUS);
  700         }
  701 
  702         data = bus_read_1(sc->smb_res, GLXIIC_SMB_SDA);
  703         iicbus_intr(sc->iicbus, INTR_RECEIVE, &data);
  704 
  705         glxiic_start_timeout_locked(sc);
  706 
  707         return (IIC_NOERR);
  708 }
  709 
  710 static int
  711 glxiic_state_master_addr_callback(struct glxiic_softc *sc, uint8_t status)
  712 {
  713         uint8_t slave;
  714 
  715         GLXIIC_ASSERT_LOCKED(sc);
  716 
  717         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  718                 GLXIIC_DEBUG_LOG("bus error after master start");
  719                 return (IIC_EBUSERR);
  720         }
  721 
  722         if ((status & GLXIIC_SMB_STS_MASTER_BIT) == 0) {
  723                 GLXIIC_DEBUG_LOG("not bus master after master start");
  724                 return (IIC_ESTATUS);
  725         }
  726 
  727         if ((status & GLXIIC_SMB_STS_SDAST_BIT) == 0) {
  728                 GLXIIC_DEBUG_LOG("not awaiting address in master addr");
  729                 return (IIC_ESTATUS);
  730         }
  731 
  732         if ((sc->msg->flags & IIC_M_RD) != 0) {
  733                 slave = sc->msg->slave | LSB;
  734                 glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_RX);
  735         } else {
  736                 slave = sc->msg->slave & ~LSB;
  737                 glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_TX);
  738         }
  739 
  740         sc->data = sc->msg->buf;
  741         sc->ndata = sc->msg->len;
  742 
  743         /* Handle address-only transfer. */
  744         if (sc->ndata == 0)
  745                 glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_STOP);
  746 
  747         bus_write_1(sc->smb_res, GLXIIC_SMB_SDA, slave);
  748 
  749         return (IIC_NOERR);
  750 }
  751 
  752 static int
  753 glxiic_state_master_tx_callback(struct glxiic_softc *sc, uint8_t status)
  754 {
  755 
  756         GLXIIC_ASSERT_LOCKED(sc);
  757 
  758         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  759                 GLXIIC_DEBUG_LOG("bus error in master tx");
  760                 return (IIC_EBUSERR);
  761         }
  762 
  763         if ((status & GLXIIC_SMB_STS_MASTER_BIT) == 0) {
  764                 GLXIIC_DEBUG_LOG("not bus master in master tx");
  765                 return (IIC_ESTATUS);
  766         }
  767 
  768         if ((status & GLXIIC_SMB_STS_NEGACK_BIT) != 0) {
  769                 GLXIIC_DEBUG_LOG("slave nack in master tx");
  770                 return (IIC_ENOACK);
  771         }
  772 
  773         if ((status & GLXIIC_SMB_STS_STASTR_BIT) != 0) {
  774                 bus_write_1(sc->smb_res, GLXIIC_SMB_STS,
  775                     GLXIIC_SMB_STS_STASTR_BIT);
  776         }
  777 
  778         if ((status & GLXIIC_SMB_STS_SDAST_BIT) == 0) {
  779                 GLXIIC_DEBUG_LOG("not awaiting data in master tx");
  780                 return (IIC_ESTATUS);
  781         }
  782 
  783         bus_write_1(sc->smb_res, GLXIIC_SMB_SDA, *sc->data++);
  784         if (--sc->ndata == 0)
  785                 glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_STOP);
  786         else
  787                 glxiic_start_timeout_locked(sc);
  788 
  789         return (IIC_NOERR);
  790 }
  791 
  792 static int
  793 glxiic_state_master_rx_callback(struct glxiic_softc *sc, uint8_t status)
  794 {
  795         uint8_t ctrl1;
  796 
  797         GLXIIC_ASSERT_LOCKED(sc);
  798 
  799         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  800                 GLXIIC_DEBUG_LOG("bus error in master rx");
  801                 return (IIC_EBUSERR);
  802         }
  803 
  804         if ((status & GLXIIC_SMB_STS_MASTER_BIT) == 0) {
  805                 GLXIIC_DEBUG_LOG("not bus master in master rx");
  806                 return (IIC_ESTATUS);
  807         }
  808 
  809         if ((status & GLXIIC_SMB_STS_NEGACK_BIT) != 0) {
  810                 GLXIIC_DEBUG_LOG("slave nack in rx");
  811                 return (IIC_ENOACK);
  812         }
  813 
  814         if (sc->ndata == 1) {
  815                 /* Last byte from slave, set NACK. */
  816                 ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1);
  817                 bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1,
  818                     ctrl1 | GLXIIC_SMB_CTRL1_ACK_BIT);
  819         }
  820 
  821         if ((status & GLXIIC_SMB_STS_STASTR_BIT) != 0) {
  822                 /* Bus is stalled, clear and wait for data. */
  823                 bus_write_1(sc->smb_res, GLXIIC_SMB_STS,
  824                     GLXIIC_SMB_STS_STASTR_BIT);
  825                 return (IIC_NOERR);
  826         }
  827 
  828         if ((status & GLXIIC_SMB_STS_SDAST_BIT) == 0) {
  829                 GLXIIC_DEBUG_LOG("no pending data in master rx");
  830                 return (IIC_ESTATUS);
  831         }
  832 
  833         *sc->data++ = bus_read_1(sc->smb_res, GLXIIC_SMB_SDA);
  834         if (--sc->ndata == 0) {
  835                 /* Proceed with stop on reading last byte. */
  836                 glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_STOP);
  837                 return (glxiic_state_table[sc->state].callback(sc, status));
  838         }
  839 
  840         glxiic_start_timeout_locked(sc);
  841 
  842         return (IIC_NOERR);
  843 }
  844 
  845 static int
  846 glxiic_state_master_stop_callback(struct glxiic_softc *sc, uint8_t status)
  847 {
  848         uint8_t ctrl1;
  849 
  850         GLXIIC_ASSERT_LOCKED(sc);
  851 
  852         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  853                 GLXIIC_DEBUG_LOG("bus error in master stop");
  854                 return (IIC_EBUSERR);
  855         }
  856 
  857         if ((status & GLXIIC_SMB_STS_MASTER_BIT) == 0) {
  858                 GLXIIC_DEBUG_LOG("not bus master in master stop");
  859                 return (IIC_ESTATUS);
  860         }
  861 
  862         if ((status & GLXIIC_SMB_STS_NEGACK_BIT) != 0) {
  863                 GLXIIC_DEBUG_LOG("slave nack in master stop");
  864                 return (IIC_ENOACK);
  865         }
  866 
  867         if (--sc->nmsgs > 0) {
  868                 /* Start transfer of next message. */
  869                 if ((sc->msg->flags & IIC_M_NOSTOP) == 0) {
  870                         glxiic_stop_locked(sc);
  871                 }
  872 
  873                 ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1);
  874                 bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1,
  875                     ctrl1 | GLXIIC_SMB_CTRL1_START_BIT);
  876 
  877                 glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_ADDR);
  878                 sc->msg++;
  879         } else {
  880                 /* Last message. */
  881                 glxiic_stop_locked(sc);
  882                 glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  883                 sc->error = IIC_NOERR;
  884                 GLXIIC_WAKEUP(sc);
  885         }
  886 
  887         return (IIC_NOERR);
  888 }
  889 
  890 static void
  891 glxiic_intr(void *arg)
  892 {
  893         struct glxiic_softc *sc;
  894         int error;
  895         uint8_t status, data;
  896 
  897         sc = (struct glxiic_softc *)arg;
  898 
  899         GLXIIC_LOCK(sc);
  900 
  901         status = glxiic_read_status_locked(sc);
  902 
  903         /* Check if this interrupt originated from the SMBus. */
  904         if ((status &
  905                 ~(GLXIIC_SMB_STS_MASTER_BIT | GLXIIC_SMB_STS_XMIT_BIT)) != 0) {
  906 
  907                 error = glxiic_state_table[sc->state].callback(sc, status);
  908 
  909                 if (error != IIC_NOERR) {
  910                         if (glxiic_state_table[sc->state].master) {
  911                                 glxiic_stop_locked(sc);
  912                                 glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  913                                 sc->error = error;
  914                                 GLXIIC_WAKEUP(sc);
  915                         } else {
  916                                 data = error & 0xff;
  917                                 iicbus_intr(sc->iicbus, INTR_ERROR, &data);
  918                                 glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  919                         }
  920                 }
  921         }
  922 
  923         GLXIIC_UNLOCK(sc);
  924 }
  925 
  926 static int
  927 glxiic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
  928 {
  929         struct glxiic_softc *sc;
  930 
  931         sc = device_get_softc(dev);
  932 
  933         GLXIIC_LOCK(sc);
  934 
  935         if (oldaddr != NULL)
  936                 *oldaddr = sc->addr;
  937         sc->addr = addr;
  938 
  939         /* A disable/enable cycle resets the controller. */
  940         glxiic_smb_disable(sc);
  941         glxiic_smb_enable(sc, speed, addr);
  942 
  943         if (glxiic_state_table[sc->state].master) {
  944                 sc->error = IIC_ESTATUS;
  945                 GLXIIC_WAKEUP(sc);
  946         }
  947         glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  948 
  949         GLXIIC_UNLOCK(sc);
  950 
  951         return (IIC_NOERR);
  952 }
  953 
  954 static int
  955 glxiic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
  956 {
  957         struct glxiic_softc *sc;
  958         int error;
  959         uint8_t ctrl1;
  960 
  961         sc = device_get_softc(dev);
  962 
  963         GLXIIC_LOCK(sc);
  964 
  965         if (sc->state != GLXIIC_STATE_IDLE) {
  966                 error = IIC_EBUSBSY;
  967                 goto out;
  968         }
  969 
  970         sc->msg = msgs;
  971         sc->nmsgs = nmsgs;
  972         glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_ADDR);
  973 
  974         /* Set start bit and let glxiic_intr() handle the transfer. */
  975         ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1);
  976         bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1,
  977             ctrl1 | GLXIIC_SMB_CTRL1_START_BIT);
  978 
  979         GLXIIC_SLEEP(sc);
  980         error = sc->error;
  981 out:
  982         GLXIIC_UNLOCK(sc);
  983 
  984         return (error);
  985 }
  986 
  987 static void
  988 glxiic_smb_map_interrupt(int irq)
  989 {
  990         uint32_t irq_map;
  991         int old_irq;
  992 
  993         /* Protect the read-modify-write operation. */
  994         critical_enter();
  995 
  996         irq_map = rdmsr(GLXIIC_MSR_PIC_YSEL_HIGH);
  997         old_irq = GLXIIC_MAP_TO_SMB_IRQ(irq_map);
  998 
  999         if (irq != old_irq) {
 1000                 irq_map &= ~GLXIIC_SMB_IRQ_TO_MAP(old_irq);
 1001                 irq_map |= GLXIIC_SMB_IRQ_TO_MAP(irq);
 1002                 wrmsr(GLXIIC_MSR_PIC_YSEL_HIGH, irq_map);
 1003         }
 1004 
 1005         critical_exit();
 1006 }
 1007 
 1008 static void
 1009 glxiic_gpio_enable(struct glxiic_softc *sc)
 1010 {
 1011 
 1012         bus_write_4(sc->gpio_res, GLXIIC_GPIOL_IN_AUX1_SEL,
 1013             GLXIIC_GPIO_14_15_ENABLE);
 1014         bus_write_4(sc->gpio_res, GLXIIC_GPIOL_OUT_AUX1_SEL,
 1015             GLXIIC_GPIO_14_15_ENABLE);
 1016 }
 1017 
 1018 static void
 1019 glxiic_gpio_disable(struct glxiic_softc *sc)
 1020 {
 1021 
 1022         bus_write_4(sc->gpio_res, GLXIIC_GPIOL_OUT_AUX1_SEL,
 1023             GLXIIC_GPIO_14_15_DISABLE);
 1024         bus_write_4(sc->gpio_res, GLXIIC_GPIOL_IN_AUX1_SEL,
 1025             GLXIIC_GPIO_14_15_DISABLE);
 1026 }
 1027 
 1028 static void
 1029 glxiic_smb_enable(struct glxiic_softc *sc, uint8_t speed, uint8_t addr)
 1030 {
 1031         uint8_t ctrl1;
 1032 
 1033         ctrl1 = 0;
 1034 
 1035         switch (speed) {
 1036         case IIC_SLOW:
 1037                 sc->sclfrq = GLXIIC_SLOW;
 1038                 break;
 1039         case IIC_FAST:
 1040                 sc->sclfrq = GLXIIC_FAST;
 1041                 break;
 1042         case IIC_FASTEST:
 1043                 sc->sclfrq = GLXIIC_FASTEST;
 1044                 break;
 1045         case IIC_UNKNOWN:
 1046         default:
 1047                 /* Reuse last frequency. */
 1048                 break;
 1049         }
 1050 
 1051         /* Set bus speed and enable controller. */
 1052         bus_write_2(sc->smb_res, GLXIIC_SMB_CTRL2,
 1053             GLXIIC_SCLFRQ(sc->sclfrq) | GLXIIC_SMB_CTRL2_EN_BIT);
 1054 
 1055         if (addr != 0) {
 1056                 /* Enable new match and global call match interrupts. */
 1057                 ctrl1 |= GLXIIC_SMB_CTRL1_NMINTE_BIT |
 1058                         GLXIIC_SMB_CTRL1_GCMEN_BIT;
 1059                 bus_write_1(sc->smb_res, GLXIIC_SMB_ADDR,
 1060                     GLXIIC_SMB_ADDR_SAEN_BIT | GLXIIC_SMBADDR(addr));
 1061         } else {
 1062                 bus_write_1(sc->smb_res, GLXIIC_SMB_ADDR, 0);
 1063         }
 1064 
 1065         /* Enable stall after start and interrupt. */
 1066         bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1,
 1067             ctrl1 | GLXIIC_SMB_CTRL1_STASTRE_BIT | GLXIIC_SMB_CTRL1_INTEN_BIT);
 1068 }
 1069 
 1070 static void
 1071 glxiic_smb_disable(struct glxiic_softc *sc)
 1072 {
 1073         uint16_t sclfrq;
 1074 
 1075         sclfrq = bus_read_2(sc->smb_res, GLXIIC_SMB_CTRL2);
 1076         bus_write_2(sc->smb_res, GLXIIC_SMB_CTRL2,
 1077             sclfrq & ~GLXIIC_SMB_CTRL2_EN_BIT);
 1078 }

Cache object: 7209dd7cb0b45d905d6af19aa2557c2d


[ 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.