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

Cache object: 4b07c58a11f3304a1c75774fb6f029be


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