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 DRIVER_MODULE(glxiic, isab, glxiic_driver, 0, 0);
  280 DRIVER_MODULE(iicbus, glxiic, iicbus_driver, 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 
  318         sc = device_get_softc(dev);
  319         sc->dev = dev;
  320         sc->state = GLXIIC_STATE_IDLE;
  321         error = 0;
  322 
  323         GLXIIC_LOCK_INIT(sc);
  324         callout_init_mtx(&sc->callout, &sc->mtx, 0);
  325 
  326         sc->smb_rid = PCIR_BAR(0);
  327         sc->smb_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->smb_rid,
  328             RF_ACTIVE);
  329         if (sc->smb_res == NULL) {
  330                 device_printf(dev, "Could not allocate SMBus I/O port\n");
  331                 error = ENXIO;
  332                 goto out;
  333         }
  334 
  335         sc->gpio_rid = PCIR_BAR(1);
  336         sc->gpio_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
  337             &sc->gpio_rid, RF_SHAREABLE | RF_ACTIVE);
  338         if (sc->gpio_res == NULL) {
  339                 device_printf(dev, "Could not allocate GPIO I/O port\n");
  340                 error = ENXIO;
  341                 goto out;
  342         }
  343 
  344         /* Ensure the controller is not enabled by firmware. */
  345         glxiic_smb_disable(sc);
  346 
  347         /* Read the existing IRQ map. */
  348         irq_map = rdmsr(GLXIIC_MSR_PIC_YSEL_HIGH);
  349         sc->old_irq = GLXIIC_MAP_TO_SMB_IRQ(irq_map);
  350 
  351         unit = device_get_unit(dev);
  352         if (resource_int_value("glxiic", unit, "irq", &irq) == 0) {
  353                 if (irq < 1 || irq > 15) {
  354                         device_printf(dev, "Bad value %d for glxiic.%d.irq\n",
  355                             irq, unit);
  356                         error = ENXIO;
  357                         goto out;
  358                 }
  359 
  360                 if (bootverbose)
  361                         device_printf(dev, "Using irq %d set by hint\n", irq);
  362         } else if (sc->old_irq != 0) {
  363                 if (bootverbose)
  364                         device_printf(dev, "Using irq %d set by firmware\n",
  365                             irq);
  366                 irq = sc->old_irq;
  367         } else {
  368                 device_printf(dev, "No irq mapped by firmware");
  369                 printf(" and no glxiic.%d.irq hint provided\n", unit);
  370                 error = ENXIO;
  371                 goto out;
  372         }
  373 
  374         /* Map the SMBus interrupt to the requested legacy IRQ. */
  375         glxiic_smb_map_interrupt(irq);
  376 
  377         sc->irq_rid = 0;
  378         sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
  379             irq, irq, 1, RF_SHAREABLE | RF_ACTIVE);
  380         if (sc->irq_res == NULL) {
  381                 device_printf(dev, "Could not allocate IRQ %d\n", irq);
  382                 error = ENXIO;
  383                 goto out;
  384         }
  385 
  386         error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
  387             NULL, glxiic_intr, sc, &(sc->irq_handler));
  388         if (error != 0) {
  389                 device_printf(dev, "Could not setup IRQ handler\n");
  390                 error = ENXIO;
  391                 goto out;
  392         }
  393 
  394         if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) {
  395                 device_printf(dev, "Could not allocate iicbus instance\n");
  396                 error = ENXIO;
  397                 goto out;
  398         }
  399 
  400         ctx = device_get_sysctl_ctx(dev);
  401         tree = device_get_sysctl_tree(dev);
  402 
  403         sc->timeout = GLXIIC_DEFAULT_TIMEOUT;
  404         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
  405             "timeout", CTLFLAG_RWTUN, &sc->timeout, 0,
  406             "activity timeout in ms");
  407 
  408         glxiic_gpio_enable(sc);
  409         glxiic_smb_enable(sc, IIC_FASTEST, 0);
  410 
  411         /* Probe and attach the iicbus when interrupts are available. */
  412         error = bus_delayed_attach_children(dev);
  413 
  414 out:
  415         if (error != 0) {
  416                 callout_drain(&sc->callout);
  417 
  418                 if (sc->iicbus != NULL)
  419                         device_delete_child(dev, sc->iicbus);
  420                 if (sc->smb_res != NULL) {
  421                         glxiic_smb_disable(sc);
  422                         bus_release_resource(dev, SYS_RES_IOPORT, sc->smb_rid,
  423                             sc->smb_res);
  424                 }
  425                 if (sc->gpio_res != NULL) {
  426                         glxiic_gpio_disable(sc);
  427                         bus_release_resource(dev, SYS_RES_IOPORT, sc->gpio_rid,
  428                             sc->gpio_res);
  429                 }
  430                 if (sc->irq_handler != NULL)
  431                         bus_teardown_intr(dev, sc->irq_res, sc->irq_handler);
  432                 if (sc->irq_res != NULL)
  433                         bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
  434                             sc->irq_res);
  435 
  436                 /* Restore the old SMBus interrupt mapping. */
  437                 glxiic_smb_map_interrupt(sc->old_irq);
  438 
  439                 GLXIIC_LOCK_DESTROY(sc);
  440         }
  441 
  442         return (error);
  443 }
  444 
  445 static int
  446 glxiic_detach(device_t dev)
  447 {
  448         struct glxiic_softc *sc;
  449         int error;
  450 
  451         sc = device_get_softc(dev);
  452 
  453         error = bus_generic_detach(dev);
  454         if (error != 0)
  455                 goto out;
  456         if (sc->iicbus != NULL)
  457                 error = device_delete_child(dev, sc->iicbus);
  458 
  459 out:
  460         callout_drain(&sc->callout);
  461 
  462         if (sc->smb_res != NULL) {
  463                 glxiic_smb_disable(sc);
  464                 bus_release_resource(dev, SYS_RES_IOPORT, sc->smb_rid,
  465                     sc->smb_res);
  466         }
  467         if (sc->gpio_res != NULL) {
  468                 glxiic_gpio_disable(sc);
  469                 bus_release_resource(dev, SYS_RES_IOPORT, sc->gpio_rid,
  470                     sc->gpio_res);
  471         }
  472         if (sc->irq_handler != NULL)
  473                 bus_teardown_intr(dev, sc->irq_res, sc->irq_handler);
  474         if (sc->irq_res != NULL)
  475                 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
  476                     sc->irq_res);
  477 
  478         /* Restore the old SMBus interrupt mapping. */
  479         glxiic_smb_map_interrupt(sc->old_irq);
  480 
  481         GLXIIC_LOCK_DESTROY(sc);
  482 
  483         return (error);
  484 }
  485 
  486 static uint8_t
  487 glxiic_read_status_locked(struct glxiic_softc *sc)
  488 {
  489         uint8_t status;
  490 
  491         GLXIIC_ASSERT_LOCKED(sc);
  492 
  493         status = bus_read_1(sc->smb_res, GLXIIC_SMB_STS);
  494 
  495         /* Clear all status flags except SDAST and STASTR after reading. */
  496         bus_write_1(sc->smb_res, GLXIIC_SMB_STS, (GLXIIC_SMB_STS_SLVSTP_BIT |
  497                 GLXIIC_SMB_STS_BER_BIT | GLXIIC_SMB_STS_NEGACK_BIT |
  498                 GLXIIC_SMB_STS_NMATCH_BIT));
  499 
  500         return (status);
  501 }
  502 
  503 static void
  504 glxiic_stop_locked(struct glxiic_softc *sc)
  505 {
  506         uint8_t status, ctrl1;
  507 
  508         GLXIIC_ASSERT_LOCKED(sc);
  509 
  510         status = glxiic_read_status_locked(sc);
  511 
  512         ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1);
  513         bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1,
  514             ctrl1 | GLXIIC_SMB_CTRL1_STOP_BIT);
  515 
  516         /*
  517          * Perform a dummy read of SDA in master receive mode to clear
  518          * SDAST if set.
  519          */
  520         if ((status & GLXIIC_SMB_STS_XMIT_BIT) == 0 &&
  521             (status & GLXIIC_SMB_STS_SDAST_BIT) != 0)
  522                 bus_read_1(sc->smb_res, GLXIIC_SMB_SDA);
  523 
  524         /* Check stall after start bit and clear if needed */
  525         if ((status & GLXIIC_SMB_STS_STASTR_BIT) != 0) {
  526                 bus_write_1(sc->smb_res, GLXIIC_SMB_STS,
  527                     GLXIIC_SMB_STS_STASTR_BIT);
  528         }
  529 }
  530 
  531 static void
  532 glxiic_timeout(void *arg)
  533 {
  534         struct glxiic_softc *sc;
  535         uint8_t error;
  536 
  537         sc = (struct glxiic_softc *)arg;
  538 
  539         GLXIIC_DEBUG_LOG("timeout in state %d", sc->state);
  540 
  541         if (glxiic_state_table[sc->state].master) {
  542                 sc->error = IIC_ETIMEOUT;
  543                 GLXIIC_WAKEUP(sc);
  544         } else {
  545                 error = IIC_ETIMEOUT;
  546                 iicbus_intr(sc->iicbus, INTR_ERROR, &error);
  547         }
  548 
  549         glxiic_smb_disable(sc);
  550         glxiic_smb_enable(sc, IIC_UNKNOWN, sc->addr);
  551         glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  552 }
  553 
  554 static void
  555 glxiic_start_timeout_locked(struct glxiic_softc *sc)
  556 {
  557 
  558         GLXIIC_ASSERT_LOCKED(sc);
  559 
  560         callout_reset_sbt(&sc->callout, SBT_1MS * sc->timeout, 0,
  561             glxiic_timeout, sc, 0);
  562 }
  563 
  564 static void
  565 glxiic_set_state_locked(struct glxiic_softc *sc, glxiic_state_t state)
  566 {
  567 
  568         GLXIIC_ASSERT_LOCKED(sc);
  569 
  570         if (state == GLXIIC_STATE_IDLE)
  571                 callout_stop(&sc->callout);
  572         else if (sc->timeout > 0)
  573                 glxiic_start_timeout_locked(sc);
  574 
  575         sc->state = state;
  576 }
  577 
  578 static int
  579 glxiic_handle_slave_match_locked(struct glxiic_softc *sc, uint8_t status)
  580 {
  581         uint8_t ctrl_sts, addr;
  582 
  583         GLXIIC_ASSERT_LOCKED(sc);
  584 
  585         ctrl_sts = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL_STS);
  586 
  587         if ((ctrl_sts & GLXIIC_SMB_CTRL_STS_MATCH_BIT) != 0) {
  588                 if ((status & GLXIIC_SMB_STS_XMIT_BIT) != 0) {
  589                         addr = sc->addr | LSB;
  590                         glxiic_set_state_locked(sc,
  591                             GLXIIC_STATE_SLAVE_TX);
  592                 } else {
  593                         addr = sc->addr & ~LSB;
  594                         glxiic_set_state_locked(sc,
  595                             GLXIIC_STATE_SLAVE_RX);
  596                 }
  597                 iicbus_intr(sc->iicbus, INTR_START, &addr);
  598         } else if ((ctrl_sts & GLXIIC_SMB_CTRL_STS_GCMTCH_BIT) != 0) {
  599                 addr = 0;
  600                 glxiic_set_state_locked(sc, GLXIIC_STATE_SLAVE_RX);
  601                 iicbus_intr(sc->iicbus, INTR_GENERAL, &addr);
  602         } else {
  603                 GLXIIC_DEBUG_LOG("unknown slave match");
  604                 return (IIC_ESTATUS);
  605         }
  606 
  607         return (IIC_NOERR);
  608 }
  609 
  610 static int
  611 glxiic_state_idle_callback(struct glxiic_softc *sc, uint8_t status)
  612 {
  613 
  614         GLXIIC_ASSERT_LOCKED(sc);
  615 
  616         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  617                 GLXIIC_DEBUG_LOG("bus error in idle");
  618                 return (IIC_EBUSERR);
  619         }
  620 
  621         if ((status & GLXIIC_SMB_STS_NMATCH_BIT) != 0) {
  622                 return (glxiic_handle_slave_match_locked(sc, status));
  623         }
  624 
  625         return (IIC_NOERR);
  626 }
  627 
  628 static int
  629 glxiic_state_slave_tx_callback(struct glxiic_softc *sc, uint8_t status)
  630 {
  631         uint8_t data;
  632 
  633         GLXIIC_ASSERT_LOCKED(sc);
  634 
  635         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  636                 GLXIIC_DEBUG_LOG("bus error in slave tx");
  637                 return (IIC_EBUSERR);
  638         }
  639 
  640         if ((status & GLXIIC_SMB_STS_SLVSTP_BIT) != 0) {
  641                 iicbus_intr(sc->iicbus, INTR_STOP, NULL);
  642                 glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  643                 return (IIC_NOERR);
  644         }
  645 
  646         if ((status & GLXIIC_SMB_STS_NEGACK_BIT) != 0) {
  647                 iicbus_intr(sc->iicbus, INTR_NOACK, NULL);
  648                 return (IIC_NOERR);
  649         }
  650 
  651         if ((status & GLXIIC_SMB_STS_NMATCH_BIT) != 0) {
  652                 /* Handle repeated start in slave mode. */
  653                 return (glxiic_handle_slave_match_locked(sc, status));
  654         }
  655 
  656         if ((status & GLXIIC_SMB_STS_SDAST_BIT) == 0) {
  657                 GLXIIC_DEBUG_LOG("not awaiting data in slave tx");
  658                 return (IIC_ESTATUS);
  659         }
  660 
  661         iicbus_intr(sc->iicbus, INTR_TRANSMIT, &data);
  662         bus_write_1(sc->smb_res, GLXIIC_SMB_SDA, data);
  663 
  664         glxiic_start_timeout_locked(sc);
  665 
  666         return (IIC_NOERR);
  667 }
  668 
  669 static int
  670 glxiic_state_slave_rx_callback(struct glxiic_softc *sc, uint8_t status)
  671 {
  672         uint8_t data;
  673 
  674         GLXIIC_ASSERT_LOCKED(sc);
  675 
  676         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  677                 GLXIIC_DEBUG_LOG("bus error in slave rx");
  678                 return (IIC_EBUSERR);
  679         }
  680 
  681         if ((status & GLXIIC_SMB_STS_SLVSTP_BIT) != 0) {
  682                 iicbus_intr(sc->iicbus, INTR_STOP, NULL);
  683                 glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  684                 return (IIC_NOERR);
  685         }
  686 
  687         if ((status & GLXIIC_SMB_STS_NMATCH_BIT) != 0) {
  688                 /* Handle repeated start in slave mode. */
  689                 return (glxiic_handle_slave_match_locked(sc, status));
  690         }
  691 
  692         if ((status & GLXIIC_SMB_STS_SDAST_BIT) == 0) {
  693                 GLXIIC_DEBUG_LOG("no pending data in slave rx");
  694                 return (IIC_ESTATUS);
  695         }
  696 
  697         data = bus_read_1(sc->smb_res, GLXIIC_SMB_SDA);
  698         iicbus_intr(sc->iicbus, INTR_RECEIVE, &data);
  699 
  700         glxiic_start_timeout_locked(sc);
  701 
  702         return (IIC_NOERR);
  703 }
  704 
  705 static int
  706 glxiic_state_master_addr_callback(struct glxiic_softc *sc, uint8_t status)
  707 {
  708         uint8_t slave;
  709         uint8_t ctrl1;
  710 
  711         GLXIIC_ASSERT_LOCKED(sc);
  712 
  713         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  714                 GLXIIC_DEBUG_LOG("bus error after master start");
  715                 return (IIC_EBUSERR);
  716         }
  717 
  718         if ((status & GLXIIC_SMB_STS_MASTER_BIT) == 0) {
  719                 GLXIIC_DEBUG_LOG("not bus master after master start");
  720                 return (IIC_ESTATUS);
  721         }
  722 
  723         if ((status & GLXIIC_SMB_STS_SDAST_BIT) == 0) {
  724                 GLXIIC_DEBUG_LOG("not awaiting address in master addr");
  725                 return (IIC_ESTATUS);
  726         }
  727 
  728         if ((sc->msg->flags & IIC_M_RD) != 0) {
  729                 slave = sc->msg->slave | LSB;
  730                 glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_RX);
  731         } else {
  732                 slave = sc->msg->slave & ~LSB;
  733                 glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_TX);
  734         }
  735 
  736         sc->data = sc->msg->buf;
  737         sc->ndata = sc->msg->len;
  738 
  739         /* Handle address-only transfer. */
  740         if (sc->ndata == 0)
  741                 glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_STOP);
  742 
  743         bus_write_1(sc->smb_res, GLXIIC_SMB_SDA, slave);
  744 
  745         if ((sc->msg->flags & IIC_M_RD) != 0 && sc->ndata == 1) {
  746                 /* Last byte from slave, set NACK. */
  747                 ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1);
  748                 bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1,
  749                     ctrl1 | GLXIIC_SMB_CTRL1_ACK_BIT);
  750         }
  751 
  752         return (IIC_NOERR);
  753 }
  754 
  755 static int
  756 glxiic_state_master_tx_callback(struct glxiic_softc *sc, uint8_t status)
  757 {
  758 
  759         GLXIIC_ASSERT_LOCKED(sc);
  760 
  761         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  762                 GLXIIC_DEBUG_LOG("bus error in master tx");
  763                 return (IIC_EBUSERR);
  764         }
  765 
  766         if ((status & GLXIIC_SMB_STS_MASTER_BIT) == 0) {
  767                 GLXIIC_DEBUG_LOG("not bus master in master tx");
  768                 return (IIC_ESTATUS);
  769         }
  770 
  771         if ((status & GLXIIC_SMB_STS_NEGACK_BIT) != 0) {
  772                 GLXIIC_DEBUG_LOG("slave nack in master tx");
  773                 return (IIC_ENOACK);
  774         }
  775 
  776         if ((status & GLXIIC_SMB_STS_STASTR_BIT) != 0) {
  777                 bus_write_1(sc->smb_res, GLXIIC_SMB_STS,
  778                     GLXIIC_SMB_STS_STASTR_BIT);
  779         }
  780 
  781         if ((status & GLXIIC_SMB_STS_SDAST_BIT) == 0) {
  782                 GLXIIC_DEBUG_LOG("not awaiting data in master tx");
  783                 return (IIC_ESTATUS);
  784         }
  785 
  786         bus_write_1(sc->smb_res, GLXIIC_SMB_SDA, *sc->data++);
  787         if (--sc->ndata == 0)
  788                 glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_STOP);
  789         else
  790                 glxiic_start_timeout_locked(sc);
  791 
  792         return (IIC_NOERR);
  793 }
  794 
  795 static int
  796 glxiic_state_master_rx_callback(struct glxiic_softc *sc, uint8_t status)
  797 {
  798         uint8_t ctrl1;
  799 
  800         GLXIIC_ASSERT_LOCKED(sc);
  801 
  802         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  803                 GLXIIC_DEBUG_LOG("bus error in master rx");
  804                 return (IIC_EBUSERR);
  805         }
  806 
  807         if ((status & GLXIIC_SMB_STS_MASTER_BIT) == 0) {
  808                 GLXIIC_DEBUG_LOG("not bus master in master rx");
  809                 return (IIC_ESTATUS);
  810         }
  811 
  812         if ((status & GLXIIC_SMB_STS_NEGACK_BIT) != 0) {
  813                 GLXIIC_DEBUG_LOG("slave nack in rx");
  814                 return (IIC_ENOACK);
  815         }
  816 
  817         if ((status & GLXIIC_SMB_STS_STASTR_BIT) != 0) {
  818                 /* Bus is stalled, clear and wait for data. */
  819                 bus_write_1(sc->smb_res, GLXIIC_SMB_STS,
  820                     GLXIIC_SMB_STS_STASTR_BIT);
  821                 return (IIC_NOERR);
  822         }
  823 
  824         if ((status & GLXIIC_SMB_STS_SDAST_BIT) == 0) {
  825                 GLXIIC_DEBUG_LOG("no pending data in master rx");
  826                 return (IIC_ESTATUS);
  827         }
  828 
  829         *sc->data++ = bus_read_1(sc->smb_res, GLXIIC_SMB_SDA);
  830         if (--sc->ndata == 0) {
  831                 /* Proceed with stop on reading last byte. */
  832                 glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_STOP);
  833                 return (glxiic_state_table[sc->state].callback(sc, status));
  834         }
  835 
  836         if (sc->ndata == 1) {
  837                 /* Last byte from slave, set NACK. */
  838                 ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1);
  839                 bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1,
  840                     ctrl1 | GLXIIC_SMB_CTRL1_ACK_BIT);
  841         }
  842 
  843         glxiic_start_timeout_locked(sc);
  844 
  845         return (IIC_NOERR);
  846 }
  847 
  848 static int
  849 glxiic_state_master_stop_callback(struct glxiic_softc *sc, uint8_t status)
  850 {
  851         uint8_t ctrl1;
  852 
  853         GLXIIC_ASSERT_LOCKED(sc);
  854 
  855         if ((status & GLXIIC_SMB_STS_BER_BIT) != 0) {
  856                 GLXIIC_DEBUG_LOG("bus error in master stop");
  857                 return (IIC_EBUSERR);
  858         }
  859 
  860         if ((status & GLXIIC_SMB_STS_MASTER_BIT) == 0) {
  861                 GLXIIC_DEBUG_LOG("not bus master in master stop");
  862                 return (IIC_ESTATUS);
  863         }
  864 
  865         if ((status & GLXIIC_SMB_STS_NEGACK_BIT) != 0) {
  866                 GLXIIC_DEBUG_LOG("slave nack in master stop");
  867                 return (IIC_ENOACK);
  868         }
  869 
  870         if (--sc->nmsgs > 0) {
  871                 /* Start transfer of next message. */
  872                 if ((sc->msg->flags & IIC_M_NOSTOP) == 0) {
  873                         glxiic_stop_locked(sc);
  874                 }
  875 
  876                 ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1);
  877                 bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1,
  878                     ctrl1 | GLXIIC_SMB_CTRL1_START_BIT);
  879 
  880                 glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_ADDR);
  881                 sc->msg++;
  882         } else {
  883                 /* Last message. */
  884                 glxiic_stop_locked(sc);
  885                 glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  886                 sc->error = IIC_NOERR;
  887                 GLXIIC_WAKEUP(sc);
  888         }
  889 
  890         return (IIC_NOERR);
  891 }
  892 
  893 static void
  894 glxiic_intr(void *arg)
  895 {
  896         struct glxiic_softc *sc;
  897         int error;
  898         uint8_t status, data;
  899 
  900         sc = (struct glxiic_softc *)arg;
  901 
  902         GLXIIC_LOCK(sc);
  903 
  904         status = glxiic_read_status_locked(sc);
  905 
  906         /* Check if this interrupt originated from the SMBus. */
  907         if ((status &
  908                 ~(GLXIIC_SMB_STS_MASTER_BIT | GLXIIC_SMB_STS_XMIT_BIT)) != 0) {
  909 
  910                 error = glxiic_state_table[sc->state].callback(sc, status);
  911 
  912                 if (error != IIC_NOERR) {
  913                         if (glxiic_state_table[sc->state].master) {
  914                                 glxiic_stop_locked(sc);
  915                                 glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  916                                 sc->error = error;
  917                                 GLXIIC_WAKEUP(sc);
  918                         } else {
  919                                 data = error & 0xff;
  920                                 iicbus_intr(sc->iicbus, INTR_ERROR, &data);
  921                                 glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  922                         }
  923                 }
  924         }
  925 
  926         GLXIIC_UNLOCK(sc);
  927 }
  928 
  929 static int
  930 glxiic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
  931 {
  932         struct glxiic_softc *sc;
  933 
  934         sc = device_get_softc(dev);
  935 
  936         GLXIIC_LOCK(sc);
  937 
  938         if (oldaddr != NULL)
  939                 *oldaddr = sc->addr;
  940         sc->addr = addr;
  941 
  942         /* A disable/enable cycle resets the controller. */
  943         glxiic_smb_disable(sc);
  944         glxiic_smb_enable(sc, speed, addr);
  945 
  946         if (glxiic_state_table[sc->state].master) {
  947                 sc->error = IIC_ESTATUS;
  948                 GLXIIC_WAKEUP(sc);
  949         }
  950         glxiic_set_state_locked(sc, GLXIIC_STATE_IDLE);
  951 
  952         GLXIIC_UNLOCK(sc);
  953 
  954         return (IIC_NOERR);
  955 }
  956 
  957 static int
  958 glxiic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
  959 {
  960         struct glxiic_softc *sc;
  961         int error;
  962         uint8_t ctrl1;
  963 
  964         sc = device_get_softc(dev);
  965 
  966         GLXIIC_LOCK(sc);
  967 
  968         if (sc->state != GLXIIC_STATE_IDLE) {
  969                 error = IIC_EBUSBSY;
  970                 goto out;
  971         }
  972 
  973         sc->msg = msgs;
  974         sc->nmsgs = nmsgs;
  975         glxiic_set_state_locked(sc, GLXIIC_STATE_MASTER_ADDR);
  976 
  977         /* Set start bit and let glxiic_intr() handle the transfer. */
  978         ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1);
  979         bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1,
  980             ctrl1 | GLXIIC_SMB_CTRL1_START_BIT);
  981 
  982         GLXIIC_SLEEP(sc);
  983         error = sc->error;
  984 out:
  985         GLXIIC_UNLOCK(sc);
  986 
  987         return (error);
  988 }
  989 
  990 static void
  991 glxiic_smb_map_interrupt(int irq)
  992 {
  993         uint32_t irq_map;
  994         int old_irq;
  995 
  996         /* Protect the read-modify-write operation. */
  997         critical_enter();
  998 
  999         irq_map = rdmsr(GLXIIC_MSR_PIC_YSEL_HIGH);
 1000         old_irq = GLXIIC_MAP_TO_SMB_IRQ(irq_map);
 1001 
 1002         if (irq != old_irq) {
 1003                 irq_map &= ~GLXIIC_SMB_IRQ_TO_MAP(old_irq);
 1004                 irq_map |= GLXIIC_SMB_IRQ_TO_MAP(irq);
 1005                 wrmsr(GLXIIC_MSR_PIC_YSEL_HIGH, irq_map);
 1006         }
 1007 
 1008         critical_exit();
 1009 }
 1010 
 1011 static void
 1012 glxiic_gpio_enable(struct glxiic_softc *sc)
 1013 {
 1014 
 1015         bus_write_4(sc->gpio_res, GLXIIC_GPIOL_IN_AUX1_SEL,
 1016             GLXIIC_GPIO_14_15_ENABLE);
 1017         bus_write_4(sc->gpio_res, GLXIIC_GPIOL_OUT_AUX1_SEL,
 1018             GLXIIC_GPIO_14_15_ENABLE);
 1019 }
 1020 
 1021 static void
 1022 glxiic_gpio_disable(struct glxiic_softc *sc)
 1023 {
 1024 
 1025         bus_write_4(sc->gpio_res, GLXIIC_GPIOL_OUT_AUX1_SEL,
 1026             GLXIIC_GPIO_14_15_DISABLE);
 1027         bus_write_4(sc->gpio_res, GLXIIC_GPIOL_IN_AUX1_SEL,
 1028             GLXIIC_GPIO_14_15_DISABLE);
 1029 }
 1030 
 1031 static void
 1032 glxiic_smb_enable(struct glxiic_softc *sc, uint8_t speed, uint8_t addr)
 1033 {
 1034         uint8_t ctrl1;
 1035 
 1036         ctrl1 = 0;
 1037 
 1038         switch (speed) {
 1039         case IIC_SLOW:
 1040                 sc->sclfrq = GLXIIC_SLOW;
 1041                 break;
 1042         case IIC_FAST:
 1043                 sc->sclfrq = GLXIIC_FAST;
 1044                 break;
 1045         case IIC_FASTEST:
 1046                 sc->sclfrq = GLXIIC_FASTEST;
 1047                 break;
 1048         case IIC_UNKNOWN:
 1049         default:
 1050                 /* Reuse last frequency. */
 1051                 break;
 1052         }
 1053 
 1054         /* Set bus speed and enable controller. */
 1055         bus_write_2(sc->smb_res, GLXIIC_SMB_CTRL2,
 1056             GLXIIC_SCLFRQ(sc->sclfrq) | GLXIIC_SMB_CTRL2_EN_BIT);
 1057 
 1058         if (addr != 0) {
 1059                 /* Enable new match and global call match interrupts. */
 1060                 ctrl1 |= GLXIIC_SMB_CTRL1_NMINTE_BIT |
 1061                         GLXIIC_SMB_CTRL1_GCMEN_BIT;
 1062                 bus_write_1(sc->smb_res, GLXIIC_SMB_ADDR,
 1063                     GLXIIC_SMB_ADDR_SAEN_BIT | GLXIIC_SMBADDR(addr));
 1064         } else {
 1065                 bus_write_1(sc->smb_res, GLXIIC_SMB_ADDR, 0);
 1066         }
 1067 
 1068         /* Enable stall after start and interrupt. */
 1069         bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1,
 1070             ctrl1 | GLXIIC_SMB_CTRL1_STASTRE_BIT | GLXIIC_SMB_CTRL1_INTEN_BIT);
 1071 }
 1072 
 1073 static void
 1074 glxiic_smb_disable(struct glxiic_softc *sc)
 1075 {
 1076         uint16_t sclfrq;
 1077 
 1078         sclfrq = bus_read_2(sc->smb_res, GLXIIC_SMB_CTRL2);
 1079         bus_write_2(sc->smb_res, GLXIIC_SMB_CTRL2,
 1080             sclfrq & ~GLXIIC_SMB_CTRL2_EN_BIT);
 1081 }

Cache object: a1cb72f8aac565fa3827a08b559047ea


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