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/ichiic/ig4_iic.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) 2014 The DragonFly Project.  All rights reserved.
    3  *
    4  * This code is derived from software contributed to The DragonFly Project
    5  * by Matthew Dillon <dillon@backplane.com> and was subsequently ported
    6  * to FreeBSD by Michael Gmelin <freebsd@grem.de>
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  *
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in
   16  *    the documentation and/or other materials provided with the
   17  *    distribution.
   18  * 3. Neither the name of The DragonFly Project nor the names of its
   19  *    contributors may be used to endorse or promote products derived
   20  *    from this software without specific, prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
   26  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
   28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   32  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD: releng/11.2/sys/dev/ichiic/ig4_iic.c 331834 2018-03-31 00:30:47Z gonzo $");
   38 
   39 /*
   40  * Intel fourth generation mobile cpus integrated I2C device.
   41  *
   42  * See ig4_reg.h for datasheet reference and notes.
   43  * See ig4_var.h for locking semantics.
   44  */
   45 
   46 #include <sys/param.h>
   47 #include <sys/systm.h>
   48 #include <sys/kernel.h>
   49 #include <sys/module.h>
   50 #include <sys/errno.h>
   51 #include <sys/lock.h>
   52 #include <sys/mutex.h>
   53 #include <sys/sx.h>
   54 #include <sys/syslog.h>
   55 #include <sys/bus.h>
   56 #include <sys/sysctl.h>
   57 
   58 #include <machine/bus.h>
   59 #include <sys/rman.h>
   60 
   61 #include <dev/pci/pcivar.h>
   62 #include <dev/pci/pcireg.h>
   63 #include <dev/iicbus/iicbus.h>
   64 #include <dev/iicbus/iiconf.h>
   65 
   66 #include <dev/ichiic/ig4_reg.h>
   67 #include <dev/ichiic/ig4_var.h>
   68 
   69 #define TRANS_NORMAL    1
   70 #define TRANS_PCALL     2
   71 #define TRANS_BLOCK     3
   72 
   73 static void ig4iic_start(void *xdev);
   74 static void ig4iic_intr(void *cookie);
   75 static void ig4iic_dump(ig4iic_softc_t *sc);
   76 
   77 static int ig4_dump;
   78 SYSCTL_INT(_debug, OID_AUTO, ig4_dump, CTLFLAG_RW,
   79            &ig4_dump, 0, "Dump controller registers");
   80 
   81 /*
   82  * Low-level inline support functions
   83  */
   84 static __inline void
   85 reg_write(ig4iic_softc_t *sc, uint32_t reg, uint32_t value)
   86 {
   87         bus_write_4(sc->regs_res, reg, value);
   88         bus_barrier(sc->regs_res, reg, 4, BUS_SPACE_BARRIER_WRITE);
   89 }
   90 
   91 static __inline uint32_t
   92 reg_read(ig4iic_softc_t *sc, uint32_t reg)
   93 {
   94         uint32_t value;
   95 
   96         bus_barrier(sc->regs_res, reg, 4, BUS_SPACE_BARRIER_READ);
   97         value = bus_read_4(sc->regs_res, reg);
   98         return (value);
   99 }
  100 
  101 /*
  102  * Enable or disable the controller and wait for the controller to acknowledge
  103  * the state change.
  104  */
  105 static int
  106 set_controller(ig4iic_softc_t *sc, uint32_t ctl)
  107 {
  108         int retry;
  109         int error;
  110         uint32_t v;
  111 
  112         /*
  113          * When the controller is enabled, interrupt on STOP detect
  114          * or receive character ready and clear pending interrupts.
  115          */
  116         if (ctl & IG4_I2C_ENABLE) {
  117                 reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET |
  118                                                  IG4_INTR_RX_FULL);
  119                 reg_read(sc, IG4_REG_CLR_INTR);
  120         } else
  121                 reg_write(sc, IG4_REG_INTR_MASK, 0);
  122 
  123         reg_write(sc, IG4_REG_I2C_EN, ctl);
  124         error = IIC_ETIMEOUT;
  125 
  126         for (retry = 100; retry > 0; --retry) {
  127                 v = reg_read(sc, IG4_REG_ENABLE_STATUS);
  128                 if (((v ^ ctl) & IG4_I2C_ENABLE) == 0) {
  129                         error = 0;
  130                         break;
  131                 }
  132                 if (cold)
  133                         DELAY(1000);
  134                 else
  135                         mtx_sleep(sc, &sc->io_lock, 0, "i2cslv", 1);
  136         }
  137         return (error);
  138 }
  139 
  140 /*
  141  * Wait up to 25ms for the requested status using a 25uS polling loop.
  142  */
  143 static int
  144 wait_status(ig4iic_softc_t *sc, uint32_t status)
  145 {
  146         uint32_t v;
  147         int error;
  148         int txlvl = -1;
  149         u_int count_us = 0;
  150         u_int limit_us = 25000; /* 25ms */
  151 
  152         error = IIC_ETIMEOUT;
  153 
  154         for (;;) {
  155                 /*
  156                  * Check requested status
  157                  */
  158                 v = reg_read(sc, IG4_REG_I2C_STA);
  159                 if (v & status) {
  160                         error = 0;
  161                         break;
  162                 }
  163 
  164                 /*
  165                  * When waiting for receive data break-out if the interrupt
  166                  * loaded data into the FIFO.
  167                  */
  168                 if (status & IG4_STATUS_RX_NOTEMPTY) {
  169                         if (sc->rpos != sc->rnext) {
  170                                 error = 0;
  171                                 break;
  172                         }
  173                 }
  174 
  175                 /*
  176                  * When waiting for the transmit FIFO to become empty,
  177                  * reset the timeout if we see a change in the transmit
  178                  * FIFO level as progress is being made.
  179                  */
  180                 if (status & IG4_STATUS_TX_EMPTY) {
  181                         v = reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK;
  182                         if (txlvl != v) {
  183                                 txlvl = v;
  184                                 count_us = 0;
  185                         }
  186                 }
  187 
  188                 /*
  189                  * Stop if we've run out of time.
  190                  */
  191                 if (count_us >= limit_us)
  192                         break;
  193 
  194                 /*
  195                  * When waiting for receive data let the interrupt do its
  196                  * work, otherwise poll with the lock held.
  197                  */
  198                 if (status & IG4_STATUS_RX_NOTEMPTY) {
  199                         mtx_sleep(sc, &sc->io_lock, 0, "i2cwait",
  200                                   (hz + 99) / 100); /* sleep up to 10ms */
  201                         count_us += 10000;
  202                 } else {
  203                         DELAY(25);
  204                         count_us += 25;
  205                 }
  206         }
  207 
  208         return (error);
  209 }
  210 
  211 /*
  212  * Read I2C data.  The data might have already been read by
  213  * the interrupt code, otherwise it is sitting in the data
  214  * register.
  215  */
  216 static uint8_t
  217 data_read(ig4iic_softc_t *sc)
  218 {
  219         uint8_t c;
  220 
  221         if (sc->rpos == sc->rnext) {
  222                 c = (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
  223         } else {
  224                 c = sc->rbuf[sc->rpos & IG4_RBUFMASK];
  225                 ++sc->rpos;
  226         }
  227         return (c);
  228 }
  229 
  230 /*
  231  * Set the slave address.  The controller must be disabled when
  232  * changing the address.
  233  *
  234  * This operation does not issue anything to the I2C bus but sets
  235  * the target address for when the controller later issues a START.
  236  */
  237 static void
  238 set_slave_addr(ig4iic_softc_t *sc, uint8_t slave)
  239 {
  240         uint32_t tar;
  241         uint32_t ctl;
  242         int use_10bit;
  243 
  244         use_10bit = 0;
  245         if (sc->slave_valid && sc->last_slave == slave &&
  246             sc->use_10bit == use_10bit) {
  247                 return;
  248         }
  249         sc->use_10bit = use_10bit;
  250 
  251         /*
  252          * Wait for TXFIFO to drain before disabling the controller.
  253          *
  254          * If a write message has not been completed it's really a
  255          * programming error, but for now in that case issue an extra
  256          * byte + STOP.
  257          *
  258          * If a read message has not been completed it's also a programming
  259          * error, for now just ignore it.
  260          */
  261         wait_status(sc, IG4_STATUS_TX_NOTFULL);
  262         if (sc->write_started) {
  263                 reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_STOP);
  264                 sc->write_started = 0;
  265         }
  266         if (sc->read_started)
  267                 sc->read_started = 0;
  268         wait_status(sc, IG4_STATUS_TX_EMPTY);
  269 
  270         set_controller(sc, 0);
  271         ctl = reg_read(sc, IG4_REG_CTL);
  272         ctl &= ~IG4_CTL_10BIT;
  273         ctl |= IG4_CTL_RESTARTEN;
  274 
  275         tar = slave;
  276         if (sc->use_10bit) {
  277                 tar |= IG4_TAR_10BIT;
  278                 ctl |= IG4_CTL_10BIT;
  279         }
  280         reg_write(sc, IG4_REG_CTL, ctl);
  281         reg_write(sc, IG4_REG_TAR_ADD, tar);
  282         set_controller(sc, IG4_I2C_ENABLE);
  283         sc->slave_valid = 1;
  284         sc->last_slave = slave;
  285 }
  286 
  287 /*
  288  *                              IICBUS API FUNCTIONS
  289  */
  290 static int
  291 ig4iic_xfer_start(ig4iic_softc_t *sc, uint16_t slave)
  292 {
  293         set_slave_addr(sc, slave >> 1);
  294         return (0);
  295 }
  296 
  297 static int
  298 ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
  299     bool repeated_start, bool stop)
  300 {
  301         uint32_t cmd;
  302         uint16_t i;
  303         int error;
  304 
  305         if (len == 0)
  306                 return (0);
  307 
  308         cmd = IG4_DATA_COMMAND_RD;
  309         cmd |= repeated_start ? IG4_DATA_RESTART : 0;
  310         cmd |= stop && len == 1 ? IG4_DATA_STOP : 0;
  311 
  312         /* Issue request for the first byte (could be last as well). */
  313         reg_write(sc, IG4_REG_DATA_CMD, cmd);
  314 
  315         for (i = 0; i < len; i++) {
  316                 /*
  317                  * Maintain a pipeline by queueing the allowance for the next
  318                  * read before waiting for the current read.
  319                  */
  320                 cmd = IG4_DATA_COMMAND_RD;
  321                 if (i < len - 1) {
  322                         cmd = IG4_DATA_COMMAND_RD;
  323                         cmd |= stop && i == len - 2 ? IG4_DATA_STOP : 0;
  324                         reg_write(sc, IG4_REG_DATA_CMD, cmd);
  325                 }
  326                 error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY);
  327                 if (error)
  328                         break;
  329                 buf[i] = data_read(sc);
  330         }
  331 
  332         (void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
  333         return (error);
  334 }
  335 
  336 static int
  337 ig4iic_write(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
  338     bool repeated_start, bool stop)
  339 {
  340         uint32_t cmd;
  341         uint16_t i;
  342         int error;
  343 
  344         if (len == 0)
  345                 return (0);
  346 
  347         cmd = repeated_start ? IG4_DATA_RESTART : 0;
  348         for (i = 0; i < len; i++) {
  349                 error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
  350                 if (error)
  351                         break;
  352                 cmd |= buf[i];
  353                 cmd |= stop && i == len - 1 ? IG4_DATA_STOP : 0;
  354                 reg_write(sc, IG4_REG_DATA_CMD, cmd);
  355                 cmd = 0;
  356         }
  357 
  358         (void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
  359         return (error);
  360 }
  361 
  362 int
  363 ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
  364 {
  365         ig4iic_softc_t *sc = device_get_softc(dev);
  366         const char *reason = NULL;
  367         uint32_t i;
  368         int error;
  369         int unit;
  370         bool rpstart;
  371         bool stop;
  372 
  373         /*
  374          * The hardware interface imposes limits on allowed I2C messages.
  375          * It is not possible to explicitly send a start or stop.
  376          * They are automatically sent (or not sent, depending on the
  377          * configuration) when a data byte is transferred.
  378          * For this reason it's impossible to send a message with no data
  379          * at all (like an SMBus quick message).
  380          * The start condition is automatically generated after the stop
  381          * condition, so it's impossible to not have a start after a stop.
  382          * The repeated start condition is automatically sent if a change
  383          * of the transfer direction happens, so it's impossible to have
  384          * a change of direction without a (repeated) start.
  385          * The repeated start can be forced even without the change of
  386          * direction.
  387          * Changing the target slave address requires resetting the hardware
  388          * state, so it's impossible to do that without the stop followed
  389          * by the start.
  390          */
  391         for (i = 0; i < nmsgs; i++) {
  392 #if 0
  393                 if (i == 0 && (msgs[i].flags & IIC_M_NOSTART) != 0) {
  394                         reason = "first message without start";
  395                         break;
  396                 }
  397                 if (i == nmsgs - 1 && (msgs[i].flags & IIC_M_NOSTOP) != 0) {
  398                         reason = "last message without stop";
  399                         break;
  400                 }
  401 #endif
  402                 if (msgs[i].len == 0) {
  403                         reason = "message with no data";
  404                         break;
  405                 }
  406                 if (i > 0) {
  407                         if ((msgs[i].flags & IIC_M_NOSTART) != 0 &&
  408                             (msgs[i - 1].flags & IIC_M_NOSTOP) == 0) {
  409                                 reason = "stop not followed by start";
  410                                 break;
  411                         }
  412                         if ((msgs[i - 1].flags & IIC_M_NOSTOP) != 0 &&
  413                             msgs[i].slave != msgs[i - 1].slave) {
  414                                 reason = "change of slave without stop";
  415                                 break;
  416                         }
  417                         if ((msgs[i].flags & IIC_M_NOSTART) != 0 &&
  418                             (msgs[i].flags & IIC_M_RD) !=
  419                             (msgs[i - 1].flags & IIC_M_RD)) {
  420                                 reason = "change of direction without repeated"
  421                                     " start";
  422                                 break;
  423                         }
  424                 }
  425         }
  426         if (reason != NULL) {
  427                 if (bootverbose)
  428                         device_printf(dev, "%s\n", reason);
  429                 return (IIC_ENOTSUPP);
  430         }
  431 
  432         sx_xlock(&sc->call_lock);
  433         mtx_lock(&sc->io_lock);
  434 
  435         /* Debugging - dump registers. */
  436         if (ig4_dump) {
  437                 unit = device_get_unit(dev);
  438                 if (ig4_dump & (1 << unit)) {
  439                         ig4_dump &= ~(1 << unit);
  440                         ig4iic_dump(sc);
  441                 }
  442         }
  443 
  444         /*
  445          * Clear any previous abort condition that may have been holding
  446          * the txfifo in reset.
  447          */
  448         reg_read(sc, IG4_REG_CLR_TX_ABORT);
  449 
  450         /*
  451          * Clean out any previously received data.
  452          */
  453         if (sc->rpos != sc->rnext && bootverbose) {
  454                 device_printf(sc->dev, "discarding %d bytes of spurious data\n",
  455                     sc->rnext - sc->rpos);
  456         }
  457         sc->rpos = 0;
  458         sc->rnext = 0;
  459 
  460         rpstart = false;
  461         error = 0;
  462         for (i = 0; i < nmsgs; i++) {
  463                 if ((msgs[i].flags & IIC_M_NOSTART) == 0) {
  464                         error = ig4iic_xfer_start(sc, msgs[i].slave);
  465                 } else {
  466                         if (!sc->slave_valid ||
  467                             (msgs[i].slave >> 1) != sc->last_slave) {
  468                                 device_printf(dev, "start condition suppressed"
  469                                     "but slave address is not set up");
  470                                 error = EINVAL;
  471                                 break;
  472                         }
  473                         rpstart = false;
  474                 }
  475                 if (error != 0)
  476                         break;
  477 
  478                 stop = (msgs[i].flags & IIC_M_NOSTOP) == 0;
  479                 if (msgs[i].flags & IIC_M_RD)
  480                         error = ig4iic_read(sc, msgs[i].buf, msgs[i].len,
  481                             rpstart, stop);
  482                 else
  483                         error = ig4iic_write(sc, msgs[i].buf, msgs[i].len,
  484                             rpstart, stop);
  485                 if (error != 0)
  486                         break;
  487 
  488                 rpstart = !stop;
  489         }
  490 
  491         mtx_unlock(&sc->io_lock);
  492         sx_unlock(&sc->call_lock);
  493         return (error);
  494 }
  495 
  496 int
  497 ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
  498 {
  499         ig4iic_softc_t *sc = device_get_softc(dev);
  500 
  501         sx_xlock(&sc->call_lock);
  502         mtx_lock(&sc->io_lock);
  503 
  504         /* TODO handle speed configuration? */
  505         if (oldaddr != NULL)
  506                 *oldaddr = sc->last_slave << 1;
  507         set_slave_addr(sc, addr >> 1);
  508         if (addr == IIC_UNKNOWN)
  509                 sc->slave_valid = false;
  510 
  511         mtx_unlock(&sc->io_lock);
  512         sx_unlock(&sc->call_lock);
  513         return (0);
  514 }
  515 
  516 /*
  517  * Called from ig4iic_pci_attach/detach()
  518  */
  519 int
  520 ig4iic_attach(ig4iic_softc_t *sc)
  521 {
  522         int error;
  523         uint32_t v;
  524 
  525         mtx_init(&sc->io_lock, "IG4 I/O lock", NULL, MTX_DEF);
  526         sx_init(&sc->call_lock, "IG4 call lock");
  527 
  528         if (sc->version == IG4_ATOM)
  529                 v = reg_read(sc, IG4_REG_COMP_TYPE);
  530         
  531         if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) {
  532                 v = reg_read(sc, IG4_REG_COMP_PARAM1);
  533                 v = reg_read(sc, IG4_REG_GENERAL);
  534                 /*
  535                  * The content of IG4_REG_GENERAL is different for each
  536                  * controller version.
  537                  */
  538                 if (sc->version == IG4_HASWELL &&
  539                     (v & IG4_GENERAL_SWMODE) == 0) {
  540                         v |= IG4_GENERAL_SWMODE;
  541                         reg_write(sc, IG4_REG_GENERAL, v);
  542                         v = reg_read(sc, IG4_REG_GENERAL);
  543                 }
  544         }
  545 
  546         if (sc->version == IG4_HASWELL) {
  547                 v = reg_read(sc, IG4_REG_SW_LTR_VALUE);
  548                 v = reg_read(sc, IG4_REG_AUTO_LTR_VALUE);
  549         } else if (sc->version == IG4_SKYLAKE) {
  550                 v = reg_read(sc, IG4_REG_ACTIVE_LTR_VALUE);
  551                 v = reg_read(sc, IG4_REG_IDLE_LTR_VALUE);
  552         }
  553 
  554         if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) {
  555                 v = reg_read(sc, IG4_REG_COMP_VER);
  556                 if (v != IG4_COMP_VER) {
  557                         error = ENXIO;
  558                         goto done;
  559                 }
  560         }
  561         v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
  562         v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
  563         v = reg_read(sc, IG4_REG_FS_SCL_HCNT);
  564         v = reg_read(sc, IG4_REG_FS_SCL_LCNT);
  565         v = reg_read(sc, IG4_REG_SDA_HOLD);
  566 
  567         v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
  568         reg_write(sc, IG4_REG_FS_SCL_HCNT, v);
  569         v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
  570         reg_write(sc, IG4_REG_FS_SCL_LCNT, v);
  571 
  572         /*
  573          * Program based on a 25000 Hz clock.  This is a bit of a
  574          * hack (obviously).  The defaults are 400 and 470 for standard
  575          * and 60 and 130 for fast.  The defaults for standard fail
  576          * utterly (presumably cause an abort) because the clock time
  577          * is ~18.8ms by default.  This brings it down to ~4ms (for now).
  578          */
  579         reg_write(sc, IG4_REG_SS_SCL_HCNT, 100);
  580         reg_write(sc, IG4_REG_SS_SCL_LCNT, 125);
  581         reg_write(sc, IG4_REG_FS_SCL_HCNT, 100);
  582         reg_write(sc, IG4_REG_FS_SCL_LCNT, 125);
  583 
  584         /*
  585          * Use a threshold of 1 so we get interrupted on each character,
  586          * allowing us to use mtx_sleep() in our poll code.  Not perfect
  587          * but this is better than using DELAY() for receiving data.
  588          *
  589          * See ig4_var.h for details on interrupt handler synchronization.
  590          */
  591         reg_write(sc, IG4_REG_RX_TL, 1);
  592 
  593         reg_write(sc, IG4_REG_CTL,
  594                   IG4_CTL_MASTER |
  595                   IG4_CTL_SLAVE_DISABLE |
  596                   IG4_CTL_RESTARTEN |
  597                   IG4_CTL_SPEED_STD);
  598 
  599         sc->iicbus = device_add_child(sc->dev, "iicbus", -1);
  600         if (sc->iicbus == NULL) {
  601                 device_printf(sc->dev, "iicbus driver not found\n");
  602                 error = ENXIO;
  603                 goto done;
  604         }
  605 
  606 #if 0
  607         /*
  608          * Don't do this, it blows up the PCI config
  609          */
  610         if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) {
  611                 reg_write(sc, IG4_REG_RESETS_HSW, IG4_RESETS_ASSERT_HSW);
  612                 reg_write(sc, IG4_REG_RESETS_HSW, IG4_RESETS_DEASSERT_HSW);
  613         } else if (sc->version = IG4_SKYLAKE) {
  614                 reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_ASSERT_SKL);
  615                 reg_write(sc, IG4_REG_RESETS_SKL, IG4_RESETS_DEASSERT_SKL);
  616         }
  617 #endif
  618 
  619         mtx_lock(&sc->io_lock);
  620         if (set_controller(sc, 0))
  621                 device_printf(sc->dev, "controller error during attach-1\n");
  622         if (set_controller(sc, IG4_I2C_ENABLE))
  623                 device_printf(sc->dev, "controller error during attach-2\n");
  624         mtx_unlock(&sc->io_lock);
  625         error = bus_setup_intr(sc->dev, sc->intr_res, INTR_TYPE_MISC | INTR_MPSAFE,
  626                                NULL, ig4iic_intr, sc, &sc->intr_handle);
  627         if (error) {
  628                 device_printf(sc->dev,
  629                               "Unable to setup irq: error %d\n", error);
  630         }
  631 
  632         sc->enum_hook.ich_func = ig4iic_start;
  633         sc->enum_hook.ich_arg = sc->dev;
  634 
  635         /*
  636          * We have to wait until interrupts are enabled. I2C read and write
  637          * only works if the interrupts are available.
  638          */
  639         if (config_intrhook_establish(&sc->enum_hook) != 0)
  640                 error = ENOMEM;
  641         else
  642                 error = 0;
  643 
  644 done:
  645         return (error);
  646 }
  647 
  648 void
  649 ig4iic_start(void *xdev)
  650 {
  651         int error;
  652         ig4iic_softc_t *sc;
  653         device_t dev = (device_t)xdev;
  654 
  655         sc = device_get_softc(dev);
  656 
  657         config_intrhook_disestablish(&sc->enum_hook);
  658 
  659         error = bus_generic_attach(sc->dev);
  660         if (error) {
  661                 device_printf(sc->dev,
  662                               "failed to attach child: error %d\n", error);
  663         }
  664 }
  665 
  666 int
  667 ig4iic_detach(ig4iic_softc_t *sc)
  668 {
  669         int error;
  670 
  671         if (device_is_attached(sc->dev)) {
  672                 error = bus_generic_detach(sc->dev);
  673                 if (error)
  674                         return (error);
  675         }
  676         if (sc->iicbus)
  677                 device_delete_child(sc->dev, sc->iicbus);
  678         if (sc->intr_handle)
  679                 bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle);
  680 
  681         sx_xlock(&sc->call_lock);
  682         mtx_lock(&sc->io_lock);
  683 
  684         sc->iicbus = NULL;
  685         sc->intr_handle = NULL;
  686         reg_write(sc, IG4_REG_INTR_MASK, 0);
  687         set_controller(sc, 0);
  688 
  689         mtx_unlock(&sc->io_lock);
  690         sx_xunlock(&sc->call_lock);
  691 
  692         mtx_destroy(&sc->io_lock);
  693         sx_destroy(&sc->call_lock);
  694 
  695         return (0);
  696 }
  697 
  698 /*
  699  * Interrupt Operation, see ig4_var.h for locking semantics.
  700  */
  701 static void
  702 ig4iic_intr(void *cookie)
  703 {
  704         ig4iic_softc_t *sc = cookie;
  705         uint32_t status;
  706 
  707         mtx_lock(&sc->io_lock);
  708 /*      reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET);*/
  709         reg_read(sc, IG4_REG_CLR_INTR);
  710         status = reg_read(sc, IG4_REG_I2C_STA);
  711         while (status & IG4_STATUS_RX_NOTEMPTY) {
  712                 sc->rbuf[sc->rnext & IG4_RBUFMASK] =
  713                     (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
  714                 ++sc->rnext;
  715                 status = reg_read(sc, IG4_REG_I2C_STA);
  716         }
  717         wakeup(sc);
  718         mtx_unlock(&sc->io_lock);
  719 }
  720 
  721 #define REGDUMP(sc, reg)        \
  722         device_printf(sc->dev, "  %-23s %08x\n", #reg, reg_read(sc, reg))
  723 
  724 static void
  725 ig4iic_dump(ig4iic_softc_t *sc)
  726 {
  727         device_printf(sc->dev, "ig4iic register dump:\n");
  728         REGDUMP(sc, IG4_REG_CTL);
  729         REGDUMP(sc, IG4_REG_TAR_ADD);
  730         REGDUMP(sc, IG4_REG_SS_SCL_HCNT);
  731         REGDUMP(sc, IG4_REG_SS_SCL_LCNT);
  732         REGDUMP(sc, IG4_REG_FS_SCL_HCNT);
  733         REGDUMP(sc, IG4_REG_FS_SCL_LCNT);
  734         REGDUMP(sc, IG4_REG_INTR_STAT);
  735         REGDUMP(sc, IG4_REG_INTR_MASK);
  736         REGDUMP(sc, IG4_REG_RAW_INTR_STAT);
  737         REGDUMP(sc, IG4_REG_RX_TL);
  738         REGDUMP(sc, IG4_REG_TX_TL);
  739         REGDUMP(sc, IG4_REG_I2C_EN);
  740         REGDUMP(sc, IG4_REG_I2C_STA);
  741         REGDUMP(sc, IG4_REG_TXFLR);
  742         REGDUMP(sc, IG4_REG_RXFLR);
  743         REGDUMP(sc, IG4_REG_SDA_HOLD);
  744         REGDUMP(sc, IG4_REG_TX_ABRT_SOURCE);
  745         REGDUMP(sc, IG4_REG_SLV_DATA_NACK);
  746         REGDUMP(sc, IG4_REG_DMA_CTRL);
  747         REGDUMP(sc, IG4_REG_DMA_TDLR);
  748         REGDUMP(sc, IG4_REG_DMA_RDLR);
  749         REGDUMP(sc, IG4_REG_SDA_SETUP);
  750         REGDUMP(sc, IG4_REG_ENABLE_STATUS);
  751         if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) {
  752                 REGDUMP(sc, IG4_REG_COMP_PARAM1);
  753                 REGDUMP(sc, IG4_REG_COMP_VER);
  754         }
  755         if (sc->version == IG4_ATOM) {
  756                 REGDUMP(sc, IG4_REG_COMP_TYPE);
  757                 REGDUMP(sc, IG4_REG_CLK_PARMS);
  758         }
  759         if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) {
  760                 REGDUMP(sc, IG4_REG_RESETS_HSW);
  761                 REGDUMP(sc, IG4_REG_GENERAL);
  762         } else if (sc->version == IG4_SKYLAKE) {
  763                 REGDUMP(sc, IG4_REG_RESETS_SKL);
  764         }
  765         if (sc->version == IG4_HASWELL) {
  766                 REGDUMP(sc, IG4_REG_SW_LTR_VALUE);
  767                 REGDUMP(sc, IG4_REG_AUTO_LTR_VALUE);
  768         } else if (sc->version == IG4_SKYLAKE) {
  769                 REGDUMP(sc, IG4_REG_ACTIVE_LTR_VALUE);
  770                 REGDUMP(sc, IG4_REG_IDLE_LTR_VALUE);
  771         }
  772 }
  773 #undef REGDUMP
  774 
  775 DRIVER_MODULE(iicbus, ig4iic_acpi, iicbus_driver, iicbus_devclass, NULL, NULL);
  776 DRIVER_MODULE(iicbus, ig4iic_pci, iicbus_driver, iicbus_devclass, NULL, NULL);

Cache object: 3b9c170829c033b44d7e5ac3d6fe0b1f


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