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


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

FreeBSD/Linux Kernel Cross Reference
sys/dev/iicbus/twsi/twsi.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) 2008 MARVELL INTERNATIONAL LTD.
    3  * All rights reserved.
    4  *
    5  * Developed by Semihalf.
    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  * 3. Neither the name of MARVELL nor the names of contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Driver for the TWSI (aka I2C, aka IIC) bus controller found on Marvell
   34  * and Allwinner SoCs. Supports master operation only.
   35  *
   36  * Calls to DELAY() are needed per Application Note AN-179 "TWSI Software
   37  * Guidelines for Discovery(TM), Horizon (TM) and Feroceon(TM) Devices".
   38  */
   39 
   40 #include <sys/cdefs.h>
   41 __FBSDID("$FreeBSD$");
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h>
   45 #include <sys/bus.h>
   46 #include <sys/kernel.h>
   47 #include <sys/lock.h>
   48 #include <sys/mutex.h>
   49 #include <sys/module.h>
   50 #include <sys/resource.h>
   51 #include <sys/rman.h>
   52 #include <sys/sysctl.h>
   53 
   54 #include <machine/_inttypes.h>
   55 #include <machine/bus.h>
   56 #include <machine/resource.h>
   57 
   58 #include <dev/iicbus/iiconf.h>
   59 #include <dev/iicbus/iicbus.h>
   60 
   61 #include <dev/iicbus/twsi/twsi.h>
   62 
   63 #include "iicbus_if.h"
   64 
   65 #define TWSI_CONTROL_ACK        (1 << 2)
   66 #define TWSI_CONTROL_IFLG       (1 << 3)
   67 #define TWSI_CONTROL_STOP       (1 << 4)
   68 #define TWSI_CONTROL_START      (1 << 5)
   69 #define TWSI_CONTROL_TWSIEN     (1 << 6)
   70 #define TWSI_CONTROL_INTEN      (1 << 7)
   71 
   72 #define TWSI_STATUS_BUS_ERROR           0x00
   73 #define TWSI_STATUS_START               0x08
   74 #define TWSI_STATUS_RPTD_START          0x10
   75 #define TWSI_STATUS_ADDR_W_ACK          0x18
   76 #define TWSI_STATUS_ADDR_W_NACK         0x20
   77 #define TWSI_STATUS_DATA_WR_ACK         0x28
   78 #define TWSI_STATUS_DATA_WR_NACK        0x30
   79 #define TWSI_STATUS_ARBITRATION_LOST    0x38
   80 #define TWSI_STATUS_ADDR_R_ACK          0x40
   81 #define TWSI_STATUS_ADDR_R_NACK         0x48
   82 #define TWSI_STATUS_DATA_RD_ACK         0x50
   83 #define TWSI_STATUS_DATA_RD_NOACK       0x58
   84 #define TWSI_STATUS_IDLE                0xf8
   85 
   86 #define TWSI_DEBUG
   87 #undef TWSI_DEBUG
   88 
   89 #define debugf(sc, fmt, args...)        if ((sc)->debug)        \
   90     device_printf((sc)->dev, "%s: " fmt, __func__, ##args)
   91 
   92 static struct resource_spec res_spec[] = {
   93         { SYS_RES_MEMORY, 0, RF_ACTIVE },
   94         { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE},
   95         { -1, 0 }
   96 };
   97 
   98 static __inline uint32_t
   99 TWSI_READ(struct twsi_softc *sc, bus_size_t off)
  100 {
  101         uint32_t val;
  102 
  103         val = bus_read_4(sc->res[0], off);
  104         if (sc->debug > 1)
  105                 debugf(sc, "read %x from %lx\n", val, off);
  106         return (val);
  107 }
  108 
  109 static __inline void
  110 TWSI_WRITE(struct twsi_softc *sc, bus_size_t off, uint32_t val)
  111 {
  112 
  113         if (sc->debug > 1)
  114                 debugf(sc, "Writing %x to %lx\n", val, off);
  115         bus_write_4(sc->res[0], off, val);
  116 }
  117 
  118 static __inline void
  119 twsi_control_clear(struct twsi_softc *sc, uint32_t mask)
  120 {
  121         uint32_t val;
  122 
  123         val = TWSI_READ(sc, sc->reg_control);
  124         debugf(sc, "read val=%x\n", val);
  125         val &= ~(TWSI_CONTROL_STOP | TWSI_CONTROL_START);
  126         val &= ~mask;
  127         debugf(sc, "write val=%x\n", val);
  128         TWSI_WRITE(sc, sc->reg_control, val);
  129 }
  130 
  131 static __inline void
  132 twsi_control_set(struct twsi_softc *sc, uint32_t mask)
  133 {
  134         uint32_t val;
  135 
  136         val = TWSI_READ(sc, sc->reg_control);
  137         debugf(sc, "read val=%x\n", val);
  138         val &= ~(TWSI_CONTROL_STOP | TWSI_CONTROL_START);
  139         val |= mask;
  140         debugf(sc, "write val=%x\n", val);
  141         TWSI_WRITE(sc, sc->reg_control, val);
  142 }
  143 
  144 static __inline void
  145 twsi_clear_iflg(struct twsi_softc *sc)
  146 {
  147 
  148         DELAY(1000);
  149         /* There are two ways of clearing IFLAG. */
  150         if (sc->iflag_w1c)
  151                 twsi_control_set(sc, TWSI_CONTROL_IFLG);
  152         else
  153                 twsi_control_clear(sc, TWSI_CONTROL_IFLG);
  154         DELAY(1000);
  155 }
  156 
  157 
  158 /*
  159  * timeout given in us
  160  * returns
  161  *   0 on successful mask change
  162  *   non-zero on timeout
  163  */
  164 static int
  165 twsi_poll_ctrl(struct twsi_softc *sc, int timeout, uint32_t mask)
  166 {
  167 
  168         timeout /= 10;
  169         debugf(sc, "Waiting for ctrl reg to match mask %x\n", mask);
  170         while (!(TWSI_READ(sc, sc->reg_control) & mask)) {
  171                 DELAY(10);
  172                 if (--timeout < 0)
  173                         return (timeout);
  174         }
  175         debugf(sc, "done\n");
  176         return (0);
  177 }
  178 
  179 
  180 /*
  181  * 'timeout' is given in us. Note also that timeout handling is not exact --
  182  * twsi_locked_start() total wait can be more than 2 x timeout
  183  * (twsi_poll_ctrl() is called twice). 'mask' can be either TWSI_STATUS_START
  184  * or TWSI_STATUS_RPTD_START
  185  */
  186 static int
  187 twsi_locked_start(device_t dev, struct twsi_softc *sc, int32_t mask,
  188     u_char slave, int timeout)
  189 {
  190         int read_access, iflg_set = 0;
  191         uint32_t status;
  192 
  193         mtx_assert(&sc->mutex, MA_OWNED);
  194 
  195         if (mask == TWSI_STATUS_RPTD_START)
  196                 /* read IFLG to know if it should be cleared later; from NBSD */
  197                 iflg_set = TWSI_READ(sc, sc->reg_control) & TWSI_CONTROL_IFLG;
  198 
  199         debugf(sc, "send start\n");
  200         twsi_control_set(sc, TWSI_CONTROL_START);
  201 
  202         if (mask == TWSI_STATUS_RPTD_START && iflg_set) {
  203                 debugf(sc, "IFLG set, clearing (mask=%x)\n", mask);
  204                 twsi_clear_iflg(sc);
  205         }
  206 
  207         /*
  208          * Without this delay we timeout checking IFLG if the timeout is 0.
  209          * NBSD driver always waits here too.
  210          */
  211         DELAY(1000);
  212 
  213         if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
  214                 debugf(sc, "timeout sending %sSTART condition\n",
  215                     mask == TWSI_STATUS_START ? "" : "repeated ");
  216                 return (IIC_ETIMEOUT);
  217         }
  218 
  219         status = TWSI_READ(sc, sc->reg_status);
  220         debugf(sc, "status=%x\n", status);
  221 
  222         if (status != mask) {
  223                 debugf(sc, "wrong status (%02x) after sending %sSTART condition\n",
  224                     status, mask == TWSI_STATUS_START ? "" : "repeated ");
  225                 return (IIC_ESTATUS);
  226         }
  227 
  228         TWSI_WRITE(sc, sc->reg_data, slave);
  229         twsi_clear_iflg(sc);
  230         DELAY(1000);
  231 
  232         if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
  233                 debugf(sc, "timeout sending slave address (timeout=%d)\n", timeout);
  234                 return (IIC_ETIMEOUT);
  235         }
  236 
  237         read_access = (slave & 0x1) ? 1 : 0;
  238         status = TWSI_READ(sc, sc->reg_status);
  239         if (status != (read_access ?
  240             TWSI_STATUS_ADDR_R_ACK : TWSI_STATUS_ADDR_W_ACK)) {
  241                 debugf(sc, "no ACK (status: %02x) after sending slave address\n",
  242                     status);
  243                 return (IIC_ENOACK);
  244         }
  245 
  246         return (IIC_NOERR);
  247 }
  248 
  249 #define TWSI_BAUD_RATE_RAW(C,M,N)       ((C)/((10*(M+1))<<(N)))
  250 #define ABSSUB(a,b)     (((a) > (b)) ? (a) - (b) : (b) - (a))
  251 
  252 static int
  253 twsi_calc_baud_rate(struct twsi_softc *sc, const u_int target,
  254   int *param)
  255 {
  256         uint64_t clk;
  257         uint32_t cur, diff, diff0;
  258         int m, n, m0, n0;
  259 
  260         /* Calculate baud rate. */
  261         diff0 = 0xffffffff;
  262 
  263         if (clk_get_freq(sc->clk_core, &clk) < 0)
  264                 return (-1);
  265 
  266         debugf(sc, "Bus clock is at %ju\n", clk);
  267 
  268         for (n = 0; n < 8; n++) {
  269                 for (m = 0; m < 16; m++) {
  270                         cur = TWSI_BAUD_RATE_RAW(clk,m,n);
  271                         diff = ABSSUB(target, cur);
  272                         if (diff < diff0) {
  273                                 m0 = m;
  274                                 n0 = n;
  275                                 diff0 = diff;
  276                         }
  277                 }
  278         }
  279         *param = TWSI_BAUD_RATE_PARAM(m0, n0);
  280 
  281         return (0);
  282 }
  283 
  284 /*
  285  * Only slave mode supported, disregard [old]addr
  286  */
  287 static int
  288 twsi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
  289 {
  290         struct twsi_softc *sc;
  291         uint32_t param;
  292         u_int busfreq;
  293 
  294         sc = device_get_softc(dev);
  295 
  296         busfreq = IICBUS_GET_FREQUENCY(sc->iicbus, speed);
  297 
  298         if (twsi_calc_baud_rate(sc, busfreq, &param) == -1) {
  299                 switch (speed) {
  300                 case IIC_SLOW:
  301                 case IIC_FAST:
  302                         param = sc->baud_rate[speed].param;
  303                         debugf(sc, "Using IIC_FAST mode with speed param=%x\n", param);
  304                         break;
  305                 case IIC_FASTEST:
  306                 case IIC_UNKNOWN:
  307                 default:
  308                         param = sc->baud_rate[IIC_FAST].param;
  309                         debugf(sc, "Using IIC_FASTEST/UNKNOWN mode with speed param=%x\n", param);
  310                         break;
  311                 }
  312         }
  313 
  314         debugf(sc, "Using clock param=%x\n", param);
  315 
  316         mtx_lock(&sc->mutex);
  317         TWSI_WRITE(sc, sc->reg_soft_reset, 0x1);
  318         TWSI_WRITE(sc, sc->reg_baud_rate, param);
  319         TWSI_WRITE(sc, sc->reg_control, TWSI_CONTROL_TWSIEN);
  320         DELAY(1000);
  321         mtx_unlock(&sc->mutex);
  322 
  323         return (0);
  324 }
  325 
  326 static int
  327 twsi_stop(device_t dev)
  328 {
  329         struct twsi_softc *sc;
  330 
  331         sc = device_get_softc(dev);
  332 
  333         debugf(sc, "%s\n", __func__);
  334         mtx_lock(&sc->mutex);
  335         twsi_control_clear(sc, TWSI_CONTROL_ACK);
  336         twsi_control_set(sc, TWSI_CONTROL_STOP);
  337         twsi_clear_iflg(sc);
  338         DELAY(1000);
  339         mtx_unlock(&sc->mutex);
  340 
  341         return (IIC_NOERR);
  342 }
  343 
  344 /*
  345  * timeout is given in us
  346  */
  347 static int
  348 twsi_repeated_start(device_t dev, u_char slave, int timeout)
  349 {
  350         struct twsi_softc *sc;
  351         int rv;
  352 
  353         sc = device_get_softc(dev);
  354 
  355         debugf(sc, "%s: slave=%x\n", __func__, slave);
  356         mtx_lock(&sc->mutex);
  357         rv = twsi_locked_start(dev, sc, TWSI_STATUS_RPTD_START, slave,
  358             timeout);
  359         mtx_unlock(&sc->mutex);
  360 
  361         if (rv) {
  362                 twsi_stop(dev);
  363                 return (rv);
  364         } else
  365                 return (IIC_NOERR);
  366 }
  367 
  368 /*
  369  * timeout is given in us
  370  */
  371 static int
  372 twsi_start(device_t dev, u_char slave, int timeout)
  373 {
  374         struct twsi_softc *sc;
  375         int rv;
  376 
  377         sc = device_get_softc(dev);
  378 
  379         debugf(sc, "%s: slave=%x\n", __func__, slave);
  380         mtx_lock(&sc->mutex);
  381         rv = twsi_locked_start(dev, sc, TWSI_STATUS_START, slave, timeout);
  382         mtx_unlock(&sc->mutex);
  383 
  384         if (rv) {
  385                 twsi_stop(dev);
  386                 return (rv);
  387         } else
  388                 return (IIC_NOERR);
  389 }
  390 
  391 static int
  392 twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay)
  393 {
  394         struct twsi_softc *sc;
  395         uint32_t status;
  396         int last_byte, rv;
  397 
  398         sc = device_get_softc(dev);
  399 
  400         mtx_lock(&sc->mutex);
  401         *read = 0;
  402         while (*read < len) {
  403                 /*
  404                  * Check if we are reading last byte of the last buffer,
  405                  * do not send ACK then, per I2C specs
  406                  */
  407                 last_byte = ((*read == len - 1) && last) ? 1 : 0;
  408                 if (last_byte)
  409                         twsi_control_clear(sc, TWSI_CONTROL_ACK);
  410                 else
  411                         twsi_control_set(sc, TWSI_CONTROL_ACK);
  412 
  413                 twsi_clear_iflg(sc);
  414                 DELAY(1000);
  415 
  416                 if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) {
  417                         debugf(sc, "timeout reading data (delay=%d)\n", delay);
  418                         rv = IIC_ETIMEOUT;
  419                         goto out;
  420                 }
  421 
  422                 status = TWSI_READ(sc, sc->reg_status);
  423                 if (status != (last_byte ?
  424                     TWSI_STATUS_DATA_RD_NOACK : TWSI_STATUS_DATA_RD_ACK)) {
  425                         debugf(sc, "wrong status (%02x) while reading\n", status);
  426                         rv = IIC_ESTATUS;
  427                         goto out;
  428                 }
  429 
  430                 *buf++ = TWSI_READ(sc, sc->reg_data);
  431                 (*read)++;
  432         }
  433         rv = IIC_NOERR;
  434 out:
  435         mtx_unlock(&sc->mutex);
  436         return (rv);
  437 }
  438 
  439 static int
  440 twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout)
  441 {
  442         struct twsi_softc *sc;
  443         uint32_t status;
  444         int rv;
  445 
  446         sc = device_get_softc(dev);
  447 
  448         mtx_lock(&sc->mutex);
  449         *sent = 0;
  450         while (*sent < len) {
  451                 TWSI_WRITE(sc, sc->reg_data, *buf++);
  452 
  453                 twsi_clear_iflg(sc);
  454                 DELAY(1000);
  455                 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
  456                         debugf(sc, "timeout writing data (timeout=%d)\n", timeout);
  457                         rv = IIC_ETIMEOUT;
  458                         goto out;
  459                 }
  460 
  461                 status = TWSI_READ(sc, sc->reg_status);
  462                 if (status != TWSI_STATUS_DATA_WR_ACK) {
  463                         debugf(sc, "wrong status (%02x) while writing\n", status);
  464                         rv = IIC_ESTATUS;
  465                         goto out;
  466                 }
  467                 (*sent)++;
  468         }
  469         rv = IIC_NOERR;
  470 out:
  471         mtx_unlock(&sc->mutex);
  472         return (rv);
  473 }
  474 
  475 static void
  476 twsi_error(struct twsi_softc *sc, int err)
  477 {
  478         /*
  479          * Must send stop condition to abort the current transfer.
  480          */
  481         debugf(sc, "Sending STOP condition for error %d\n", err);
  482         sc->transfer = 0;
  483         sc->error = err;
  484         sc->control_val = 0;
  485         TWSI_WRITE(sc, sc->reg_control, sc->control_val | TWSI_CONTROL_STOP);
  486 }
  487 
  488 static int
  489 twsi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
  490 {
  491         struct twsi_softc *sc;
  492         uint32_t status;
  493         int error;
  494 
  495         sc = device_get_softc(dev);
  496 
  497         if (!sc->have_intr)
  498                 return (iicbus_transfer_gen(dev, msgs, nmsgs));
  499 
  500         mtx_lock(&sc->mutex);
  501         KASSERT(sc->transfer == 0,
  502             ("starting a transfer while another is active"));
  503 
  504         debugf(sc, "transmitting %d messages\n", nmsgs);
  505         status = TWSI_READ(sc, sc->reg_status);
  506         debugf(sc, "status=0x%x\n", status);
  507         if (status != TWSI_STATUS_IDLE) {
  508                 debugf(sc, "Bad status at start of transfer\n");
  509                 twsi_error(sc, IIC_ESTATUS);
  510                 goto end;
  511         }
  512 
  513         sc->nmsgs = nmsgs;
  514         sc->msgs = msgs;
  515         sc->msg_idx = 0;
  516         sc->transfer = 1;
  517         sc->error = 0;
  518 
  519 #ifdef TWSI_DEBUG
  520         for (int i = 0; i < nmsgs; i++)
  521                 debugf(sc, "msg %d is %d bytes long\n", i, msgs[i].len);
  522 #endif
  523 
  524         /* Send start and re-enable interrupts */
  525         sc->control_val = TWSI_CONTROL_TWSIEN | TWSI_CONTROL_INTEN;
  526         TWSI_WRITE(sc, sc->reg_control, sc->control_val | TWSI_CONTROL_START);
  527         msleep_sbt(sc, &sc->mutex, 0, "twsi", 3000 * SBT_1MS, SBT_1MS, 0);
  528         debugf(sc, "pause finish\n");
  529         if (sc->error == 0 && sc->transfer != 0) {
  530                 device_printf(sc->dev, "transfer timeout\n");
  531                 sc->error = IIC_ETIMEOUT;
  532                 sc->transfer = 0;
  533         }
  534 
  535         if (sc->error != 0)
  536                 debugf(sc, "Error: %d\n", sc->error);
  537 
  538 end:
  539         /* Disable module and interrupts */
  540         debugf(sc, "status=0x%x\n", TWSI_READ(sc, sc->reg_status));
  541         TWSI_WRITE(sc, sc->reg_control, 0);
  542         debugf(sc, "status=0x%x\n", TWSI_READ(sc, sc->reg_status));
  543         error = sc->error;
  544         mtx_unlock(&sc->mutex);
  545 
  546         return (error);
  547 }
  548 
  549 static void
  550 twsi_intr(void *arg)
  551 {
  552         struct twsi_softc *sc;
  553         uint32_t status;
  554         bool message_done;
  555         bool send_start;
  556 
  557         sc = arg;
  558         send_start = false;
  559 
  560         mtx_lock(&sc->mutex);
  561         debugf(sc, "Got interrupt, current msg=%u\n", sc->msg_idx);
  562 
  563         status = TWSI_READ(sc, sc->reg_status);
  564         debugf(sc, "reg control = 0x%x, status = 0x%x\n",
  565             TWSI_READ(sc, sc->reg_control), status);
  566 
  567         if (sc->transfer == 0) {
  568                 device_printf(sc->dev, "interrupt without active transfer, "
  569                     "status = 0x%x\n", status);
  570                 TWSI_WRITE(sc, sc->reg_control, sc->control_val |
  571                     TWSI_CONTROL_STOP);
  572                 goto end;
  573         }
  574 
  575 restart:
  576         message_done = false;
  577 
  578         switch (status) {
  579         case TWSI_STATUS_START:
  580         case TWSI_STATUS_RPTD_START:
  581                 /* Transmit the address */
  582                 debugf(sc, "Send address 0x%x\n",
  583                     sc->msgs[sc->msg_idx].slave);
  584 
  585                 if (sc->msgs[sc->msg_idx].flags & IIC_M_RD)
  586                         TWSI_WRITE(sc, sc->reg_data,
  587                             sc->msgs[sc->msg_idx].slave | LSB);
  588                 else
  589                         TWSI_WRITE(sc, sc->reg_data,
  590                             sc->msgs[sc->msg_idx].slave & ~LSB);
  591                 break;
  592 
  593         case TWSI_STATUS_ADDR_W_ACK:
  594                 debugf(sc, "Address ACK-ed (write)\n");
  595 
  596                 if (sc->msgs[sc->msg_idx].len > 0) {
  597                         /* Directly send the first byte */
  598                         sc->sent_bytes = 1;
  599                         debugf(sc, "Sending byte 0 (of %d) = %x\n",
  600                             sc->msgs[sc->msg_idx].len,
  601                             sc->msgs[sc->msg_idx].buf[0]);
  602                         TWSI_WRITE(sc, sc->reg_data,
  603                             sc->msgs[sc->msg_idx].buf[0]);
  604                 } else {
  605                         debugf(sc, "Zero-length write, sending STOP\n");
  606                         TWSI_WRITE(sc, sc->reg_control,
  607                             sc->control_val | TWSI_CONTROL_STOP);
  608                 }
  609                 break;
  610 
  611         case TWSI_STATUS_ADDR_R_ACK:
  612                 debugf(sc, "Address ACK-ed (read)\n");
  613                 sc->recv_bytes = 0;
  614 
  615                 if (sc->msgs[sc->msg_idx].len == 0) {
  616                         debugf(sc, "Zero-length read, sending STOP\n");
  617                         TWSI_WRITE(sc, sc->reg_control,
  618                             sc->control_val | TWSI_CONTROL_STOP);
  619                 } else if (sc->msgs[sc->msg_idx].len == 1) {
  620                         sc->control_val &= ~TWSI_CONTROL_ACK;
  621                 } else {
  622                         sc->control_val |= TWSI_CONTROL_ACK;
  623                 }
  624                 break;
  625 
  626         case TWSI_STATUS_ADDR_W_NACK:
  627         case TWSI_STATUS_ADDR_R_NACK:
  628                 debugf(sc, "Address NACK-ed\n");
  629                 twsi_error(sc, IIC_ENOACK);
  630                 break;
  631         case TWSI_STATUS_DATA_WR_NACK:
  632                 debugf(sc, "Data byte NACK-ed\n");
  633                 twsi_error(sc, IIC_ENOACK);
  634                 break;
  635         case TWSI_STATUS_DATA_WR_ACK:
  636                 KASSERT(sc->sent_bytes <= sc->msgs[sc->msg_idx].len,
  637                     ("sent_bytes beyond message length"));
  638                 debugf(sc, "ACK received after transmitting data\n");
  639                 if (sc->sent_bytes == sc->msgs[sc->msg_idx].len) {
  640                         debugf(sc, "Done TX data\n");
  641 
  642                         /* Send stop, no interrupts on stop */
  643                         if (!(sc->msgs[sc->msg_idx].flags & IIC_M_NOSTOP)) {
  644                                 TWSI_WRITE(sc, sc->reg_control,
  645                                     sc->control_val | TWSI_CONTROL_STOP);
  646                         } else {
  647                                 debugf(sc, "NOSTOP flag\n");
  648                         }
  649                         message_done = true;
  650                         break;
  651                 }
  652 
  653                 debugf(sc, "Sending byte %d (of %d) = 0x%x\n",
  654                     sc->sent_bytes,
  655                     sc->msgs[sc->msg_idx].len,
  656                     sc->msgs[sc->msg_idx].buf[sc->sent_bytes]);
  657                 TWSI_WRITE(sc, sc->reg_data,
  658                     sc->msgs[sc->msg_idx].buf[sc->sent_bytes]);
  659                 sc->sent_bytes++;
  660                 break;
  661 
  662         case TWSI_STATUS_DATA_RD_ACK:
  663                 debugf(sc, "Received and ACK-ed data\n");
  664                 KASSERT(sc->recv_bytes < sc->msgs[sc->msg_idx].len,
  665                     ("receiving beyond the end of buffer"));
  666 
  667                 sc->msgs[sc->msg_idx].buf[sc->recv_bytes] =
  668                     TWSI_READ(sc, sc->reg_data);
  669                 debugf(sc, "Received byte %d (of %d) = 0x%x\n",
  670                     sc->recv_bytes,
  671                     sc->msgs[sc->msg_idx].len,
  672                     sc->msgs[sc->msg_idx].buf[sc->recv_bytes]);
  673                 sc->recv_bytes++;
  674 
  675                 /* If we only have one byte left, disable ACK */
  676                 if (sc->msgs[sc->msg_idx].len - sc->recv_bytes == 1) {
  677                         sc->control_val &= ~TWSI_CONTROL_ACK;
  678                 } else if (sc->msgs[sc->msg_idx].len == sc->recv_bytes) {
  679                         /*
  680                          * We should not have ACK-ed the last byte.
  681                          * The protocol state machine is in invalid state.
  682                          */
  683                         debugf(sc, "RX all but asked for more?\n");
  684                         twsi_error(sc, IIC_ESTATUS);
  685                 }
  686                 break;
  687 
  688         case TWSI_STATUS_DATA_RD_NOACK:
  689                 debugf(sc, "Received and NACK-ed data\n");
  690                 KASSERT(sc->recv_bytes == sc->msgs[sc->msg_idx].len - 1,
  691                     ("sent NACK before receiving all requested data"));
  692                 sc->msgs[sc->msg_idx].buf[sc->recv_bytes] =
  693                     TWSI_READ(sc, sc->reg_data);
  694                 debugf(sc, "Received byte %d (of %d) = 0x%x\n",
  695                     sc->recv_bytes,
  696                     sc->msgs[sc->msg_idx].len,
  697                     sc->msgs[sc->msg_idx].buf[sc->recv_bytes]);
  698                 sc->recv_bytes++;
  699 
  700                 if (sc->msgs[sc->msg_idx].len == sc->recv_bytes) {
  701                         debugf(sc, "Done RX data\n");
  702                         if (!(sc->msgs[sc->msg_idx].flags & IIC_M_NOSTOP)) {
  703                                 debugf(sc, "Send STOP\n");
  704                                 TWSI_WRITE(sc, sc->reg_control,
  705                                     sc->control_val | TWSI_CONTROL_STOP);
  706                         }
  707                         message_done = true;
  708                 } else {
  709                         /*
  710                          * We should not have NACK-ed yet.
  711                          * The protocol state machine is in invalid state.
  712                          */
  713                         debugf(sc, "NACK-ed before receving all bytes?\n");
  714                         twsi_error(sc, IIC_ESTATUS);
  715                 }
  716                 break;
  717 
  718         case TWSI_STATUS_BUS_ERROR:
  719                 debugf(sc, "Bus error\n");
  720                 twsi_error(sc, IIC_EBUSERR);
  721                 break;
  722         case TWSI_STATUS_ARBITRATION_LOST:
  723                 debugf(sc, "Arbitration lost\n");
  724                 twsi_error(sc, IIC_EBUSBSY);
  725                 break;
  726         default:
  727                 debugf(sc, "unexpected status 0x%x\n", status);
  728                 twsi_error(sc, IIC_ESTATUS);
  729                 break;
  730         }
  731 
  732         if (message_done) {
  733                 sc->msg_idx++;
  734                 if (sc->msg_idx == sc->nmsgs) {
  735                         debugf(sc, "All messages transmitted\n");
  736                         sc->transfer = 0;
  737                         sc->error = 0;
  738                 } else if ((sc->msgs[sc->msg_idx].flags & IIC_M_NOSTART) == 0) {
  739                         debugf(sc, "Send (repeated) start\n");
  740                         send_start = true;
  741                 } else {
  742                         /* Just keep transmitting data. */
  743                         KASSERT((sc->msgs[sc->msg_idx - 1].flags & IIC_M_NOSTOP) != 0,
  744                             ("NOSTART message after STOP"));
  745                         KASSERT((sc->msgs[sc->msg_idx].flags & IIC_M_RD) ==
  746                             (sc->msgs[sc->msg_idx - 1].flags & IIC_M_RD),
  747                             ("change of transfer direction without a START"));
  748                         debugf(sc, "NOSTART message after NOSTOP\n");
  749                         sc->sent_bytes = 0;
  750                         sc->recv_bytes = 0;
  751                         if ((sc->msgs[sc->msg_idx].flags & IIC_M_RD) == 0) {
  752                                 status = TWSI_STATUS_ADDR_W_ACK;
  753                                 goto restart;
  754                         } else {
  755                                 debugf(sc, "Read+NOSTART unsupported\n");
  756                                 twsi_error(sc, IIC_ESTATUS);
  757                         }
  758                 }
  759         }
  760 end:
  761         /*
  762          * Newer Allwinner chips clear IFLG after writing 1 to it.
  763          */
  764         debugf(sc, "Refresh reg_control\n");
  765         TWSI_WRITE(sc, sc->reg_control, sc->control_val |
  766             (sc->iflag_w1c ? TWSI_CONTROL_IFLG : 0) |
  767             (send_start ? TWSI_CONTROL_START : 0));
  768 
  769         debugf(sc, "Done with interrupt, transfer = %d\n", sc->transfer);
  770         if (sc->transfer == 0)
  771                 wakeup(sc);
  772         mtx_unlock(&sc->mutex);
  773 }
  774 
  775 static void
  776 twsi_intr_start(void *pdev)
  777 {
  778         struct twsi_softc *sc;
  779 
  780         sc = device_get_softc(pdev);
  781 
  782         if ((bus_setup_intr(pdev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE,
  783               NULL, twsi_intr, sc, &sc->intrhand)))
  784                 device_printf(pdev, "unable to register interrupt handler\n");
  785 
  786         sc->have_intr = true;
  787 }
  788 
  789 int
  790 twsi_attach(device_t dev)
  791 {
  792         struct twsi_softc *sc;
  793         struct sysctl_ctx_list *ctx;
  794         struct sysctl_oid *tree_node;
  795         struct sysctl_oid_list *tree;
  796 
  797         sc = device_get_softc(dev);
  798         sc->dev = dev;
  799 
  800         mtx_init(&sc->mutex, device_get_nameunit(dev), "twsi", MTX_DEF);
  801 
  802         if (bus_alloc_resources(dev, res_spec, sc->res)) {
  803                 device_printf(dev, "could not allocate resources\n");
  804                 twsi_detach(dev);
  805                 return (ENXIO);
  806         }
  807 
  808 #ifdef TWSI_DEBUG
  809         sc->debug = 1;
  810 #endif
  811         ctx = device_get_sysctl_ctx(dev);
  812         tree_node = device_get_sysctl_tree(dev);
  813         tree = SYSCTL_CHILDREN(tree_node);
  814         SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "debug", CTLFLAG_RWTUN,
  815             &sc->debug, 0, "Set debug level (zero to disable)");
  816 
  817         /* Attach the iicbus. */
  818         if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) {
  819                 device_printf(dev, "could not allocate iicbus instance\n");
  820                 twsi_detach(dev);
  821                 return (ENXIO);
  822         }
  823         bus_generic_attach(dev);
  824 
  825         config_intrhook_oneshot(twsi_intr_start, dev);
  826 
  827         return (0);
  828 }
  829 
  830 int
  831 twsi_detach(device_t dev)
  832 {
  833         struct twsi_softc *sc;
  834         int rv;
  835 
  836         sc = device_get_softc(dev);
  837 
  838         if ((rv = bus_generic_detach(dev)) != 0)
  839                 return (rv);
  840 
  841         if (sc->iicbus != NULL)
  842                 if ((rv = device_delete_child(dev, sc->iicbus)) != 0)
  843                         return (rv);
  844 
  845         if (sc->intrhand != NULL)
  846                 bus_teardown_intr(sc->dev, sc->res[1], sc->intrhand);
  847 
  848         bus_release_resources(dev, res_spec, sc->res);
  849 
  850         mtx_destroy(&sc->mutex);
  851         return (0);
  852 }
  853 
  854 static device_method_t twsi_methods[] = {
  855         /* device interface */
  856         DEVMETHOD(device_detach,        twsi_detach),
  857 
  858         /* Bus interface */
  859         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
  860         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
  861         DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
  862         DEVMETHOD(bus_release_resource, bus_generic_release_resource),
  863         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
  864         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
  865         DEVMETHOD(bus_adjust_resource,  bus_generic_adjust_resource),
  866         DEVMETHOD(bus_set_resource,     bus_generic_rl_set_resource),
  867         DEVMETHOD(bus_get_resource,     bus_generic_rl_get_resource),
  868 
  869         /* iicbus interface */
  870         DEVMETHOD(iicbus_callback, iicbus_null_callback),
  871         DEVMETHOD(iicbus_repeated_start, twsi_repeated_start),
  872         DEVMETHOD(iicbus_start,         twsi_start),
  873         DEVMETHOD(iicbus_stop,          twsi_stop),
  874         DEVMETHOD(iicbus_write,         twsi_write),
  875         DEVMETHOD(iicbus_read,          twsi_read),
  876         DEVMETHOD(iicbus_reset,         twsi_reset),
  877         DEVMETHOD(iicbus_transfer,      twsi_transfer),
  878         { 0, 0 }
  879 };
  880 
  881 DEFINE_CLASS_0(twsi, twsi_driver, twsi_methods,
  882     sizeof(struct twsi_softc));

Cache object: f41c4674fcc09a1cb85a36f329c5336d


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