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/arm/freescale/vybrid/vf_i2c.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) 2014 Ruslan Bukin <br@bsdpad.com>
    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 AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 /*
   30  * Vybrid Family Inter-Integrated Circuit (I2C)
   31  * Chapter 48, Vybrid Reference Manual, Rev. 5, 07/2013
   32  */
   33 
   34 /*
   35  * This driver is based on the I2C driver for i.MX
   36  */
   37 
   38 #include <sys/cdefs.h>
   39 __FBSDID("$FreeBSD$");
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/bus.h>
   44 #include <sys/kernel.h>
   45 #include <sys/module.h>
   46 #include <sys/malloc.h>
   47 #include <sys/rman.h>
   48 #include <sys/timeet.h>
   49 #include <sys/timetc.h>
   50 
   51 #include <dev/iicbus/iiconf.h>
   52 #include <dev/iicbus/iicbus.h>
   53 
   54 #include "iicbus_if.h"
   55 
   56 #include <dev/ofw/openfirm.h>
   57 #include <dev/ofw/ofw_bus.h>
   58 #include <dev/ofw/ofw_bus_subr.h>
   59 
   60 #include <dev/extres/clk/clk.h>
   61 
   62 #include <machine/bus.h>
   63 #include <machine/cpu.h>
   64 #include <machine/intr.h>
   65 
   66 #include <arm/freescale/vybrid/vf_common.h>
   67 
   68 #define I2C_IBAD        0x0     /* I2C Bus Address Register */
   69 #define I2C_IBFD        0x1     /* I2C Bus Frequency Divider Register */
   70 #define I2C_IBCR        0x2     /* I2C Bus Control Register */
   71 #define  IBCR_MDIS              (1 << 7) /* Module disable. */
   72 #define  IBCR_IBIE              (1 << 6) /* I-Bus Interrupt Enable. */
   73 #define  IBCR_MSSL              (1 << 5) /* Master/Slave mode select. */
   74 #define  IBCR_TXRX              (1 << 4) /* Transmit/Receive mode select. */
   75 #define  IBCR_NOACK             (1 << 3) /* Data Acknowledge disable. */
   76 #define  IBCR_RSTA              (1 << 2) /* Repeat Start. */
   77 #define  IBCR_DMAEN             (1 << 1) /* DMA Enable. */
   78 #define I2C_IBSR        0x3     /* I2C Bus Status Register */
   79 #define  IBSR_TCF               (1 << 7) /* Transfer complete. */
   80 #define  IBSR_IAAS              (1 << 6) /* Addressed as a slave. */
   81 #define  IBSR_IBB               (1 << 5) /* Bus busy. */
   82 #define  IBSR_IBAL              (1 << 4) /* Arbitration Lost. */
   83 #define  IBSR_SRW               (1 << 2) /* Slave Read/Write. */
   84 #define  IBSR_IBIF              (1 << 1) /* I-Bus Interrupt Flag. */
   85 #define  IBSR_RXAK              (1 << 0) /* Received Acknowledge. */
   86 #define I2C_IBDR        0x4     /* I2C Bus Data I/O Register */
   87 #define I2C_IBIC        0x5     /* I2C Bus Interrupt Config Register */
   88 #define  IBIC_BIIE              (1 << 7) /* Bus Idle Interrupt Enable bit. */
   89 #define I2C_IBDBG       0x6     /* I2C Bus Debug Register */
   90 
   91 #ifdef DEBUG
   92 #define vf_i2c_dbg(_sc, fmt, args...) \
   93         device_printf((_sc)->dev, fmt, ##args)
   94 #else
   95 #define vf_i2c_dbg(_sc, fmt, args...)
   96 #endif
   97 
   98 #define HW_UNKNOWN      0x00
   99 #define HW_MVF600       0x01
  100 #define HW_VF610        0x02
  101 
  102 static int i2c_repeated_start(device_t, u_char, int);
  103 static int i2c_start(device_t, u_char, int);
  104 static int i2c_stop(device_t);
  105 static int i2c_reset(device_t, u_char, u_char, u_char *);
  106 static int i2c_read(device_t, char *, int, int *, int, int);
  107 static int i2c_write(device_t, const char *, int, int *, int);
  108 static phandle_t i2c_get_node(device_t, device_t);
  109 
  110 struct i2c_div_type {
  111         uint32_t reg_val;
  112         uint32_t div;
  113 };
  114 
  115 struct i2c_softc {
  116         struct resource         *res[2];
  117         bus_space_tag_t         bst;
  118         bus_space_handle_t      bsh;
  119         clk_t                   clock;
  120         uint32_t                freq;
  121         device_t                dev;
  122         device_t                iicbus;
  123         struct mtx              mutex;
  124         uintptr_t               hwtype;
  125 };
  126 
  127 static struct resource_spec i2c_spec[] = {
  128         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
  129         { SYS_RES_IRQ,          0,      RF_ACTIVE },
  130         { -1, 0 }
  131 };
  132 
  133 static struct i2c_div_type vf610_div_table[] = {
  134         { 0x00, 20 }, { 0x01, 22 }, { 0x02, 24 }, { 0x03, 26 },
  135         { 0x04, 28 }, { 0x05, 30 }, { 0x09, 32 }, { 0x06, 34 },
  136         { 0x0A, 36 }, { 0x0B, 40 }, { 0x0C, 44 }, { 0x0D, 48 },
  137         { 0x0E, 56 }, { 0x12, 64 }, { 0x13, 72 }, { 0x14, 80 },
  138         { 0x15, 88 }, { 0x19, 96 }, { 0x16, 104 }, { 0x1A, 112 },
  139         { 0x17, 128 }, { 0x1D, 160 }, { 0x1E, 192 }, { 0x22, 224 },
  140         { 0x1F, 240 }, { 0x23, 256 }, { 0x24, 288 }, { 0x25, 320 },
  141         { 0x26, 384 }, { 0x2A, 448 }, { 0x27, 480 }, { 0x2B, 512 },
  142         { 0x2C, 576 }, { 0x2D, 640 }, { 0x2E, 768 }, { 0x32, 896 },
  143         { 0x2F, 960 }, { 0x33, 1024 }, { 0x34, 1152 }, { 0x35, 1280 },
  144         { 0x36, 1536 }, { 0x3A, 1792 }, { 0x37, 1920 }, { 0x3B, 2048 },
  145         { 0x3C, 2304 }, { 0x3D, 2560 }, { 0x3E, 3072 }, { 0x3F, 3840 },
  146         { 0x3F, 3840 }, { 0x7B, 4096 }, { 0x7D, 5120 }, { 0x7E, 6144 },
  147 };
  148 
  149 static const struct ofw_compat_data i2c_compat_data[] = {
  150         {"fsl,mvf600-i2c",      HW_MVF600},
  151         {"fsl,vf610-i2c",       HW_VF610},
  152         {NULL,                  HW_UNKNOWN}
  153 };
  154 
  155 static int
  156 i2c_probe(device_t dev)
  157 {
  158 
  159         if (!ofw_bus_status_okay(dev))
  160                 return (ENXIO);
  161 
  162         if (!ofw_bus_search_compatible(dev, i2c_compat_data)->ocd_data)
  163                 return (ENXIO);
  164 
  165         device_set_desc(dev, "Vybrid Family Inter-Integrated Circuit (I2C)");
  166         return (BUS_PROBE_DEFAULT);
  167 }
  168 
  169 static int
  170 i2c_attach(device_t dev)
  171 {
  172         struct i2c_softc *sc;
  173         phandle_t node;
  174         int error;
  175 
  176         sc = device_get_softc(dev);
  177         sc->dev = dev;
  178         sc->hwtype = ofw_bus_search_compatible(dev, i2c_compat_data)->ocd_data;
  179         node = ofw_bus_get_node(dev);
  180 
  181         error = clk_get_by_ofw_index(dev, node, 0, &sc->clock);
  182         if (error != 0) {
  183                 sc->freq = 0;
  184                 device_printf(dev, "Parent clock not found.\n");
  185         } else {
  186                 if (OF_hasprop(node, "clock-frequency"))
  187                         OF_getencprop(node, "clock-frequency", &sc->freq,
  188                             sizeof(sc->freq));
  189                 else
  190                         sc->freq = 100000;
  191         }
  192 
  193         mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF);
  194 
  195         error = bus_alloc_resources(dev, i2c_spec, sc->res);
  196         if (error != 0) {
  197                 mtx_destroy(&sc->mutex);
  198                 device_printf(dev, "could not allocate resources\n");
  199                 return (ENXIO);
  200         }
  201 
  202         /* Memory interface */
  203         sc->bst = rman_get_bustag(sc->res[0]);
  204         sc->bsh = rman_get_bushandle(sc->res[0]);
  205 
  206         WRITE1(sc, I2C_IBIC, IBIC_BIIE);
  207 
  208         sc->iicbus = device_add_child(dev, "iicbus", -1);
  209         if (sc->iicbus == NULL) {
  210                 device_printf(dev, "could not add iicbus child");
  211                 mtx_destroy(&sc->mutex);
  212                 bus_release_resources(dev, i2c_spec, sc->res);
  213                 return (ENXIO);
  214         }
  215 
  216         bus_generic_attach(dev);
  217 
  218         return (0);
  219 }
  220 
  221 static int
  222 i2c_detach(device_t dev)
  223 {
  224         struct i2c_softc *sc;
  225         int error = 0;
  226 
  227         sc = device_get_softc(dev);
  228 
  229         error = bus_generic_detach(dev);
  230         if (error != 0) {
  231                 device_printf(dev, "cannot detach child devices.\n");
  232                 return (error);
  233         }
  234 
  235         error = device_delete_child(dev, sc->iicbus);
  236         if (error != 0) {
  237                 device_printf(dev, "could not delete iicbus child.\n");
  238                 return (error);
  239         }
  240 
  241         bus_release_resources(dev, i2c_spec, sc->res);
  242 
  243         mtx_destroy(&sc->mutex);
  244 
  245         return (0);
  246 }
  247 
  248 /* Wait for transfer interrupt flag */
  249 static int
  250 wait_for_iif(struct i2c_softc *sc)
  251 {
  252         int retry;
  253 
  254         retry = 1000;
  255         while (retry --) {
  256                 if (READ1(sc, I2C_IBSR) & IBSR_IBIF) {
  257                         WRITE1(sc, I2C_IBSR, IBSR_IBIF);
  258                         return (IIC_NOERR);
  259                 }
  260                 DELAY(10);
  261         }
  262 
  263         return (IIC_ETIMEOUT);
  264 }
  265 
  266 /* Wait for free bus */
  267 static int
  268 wait_for_nibb(struct i2c_softc *sc)
  269 {
  270         int retry;
  271 
  272         retry = 1000;
  273         while (retry --) {
  274                 if ((READ1(sc, I2C_IBSR) & IBSR_IBB) == 0)
  275                         return (IIC_NOERR);
  276                 DELAY(10);
  277         }
  278 
  279         return (IIC_ETIMEOUT);
  280 }
  281 
  282 /* Wait for transfer complete+interrupt flag */
  283 static int
  284 wait_for_icf(struct i2c_softc *sc)
  285 {
  286         int retry;
  287 
  288         retry = 1000;
  289         while (retry --) {
  290                 if (READ1(sc, I2C_IBSR) & IBSR_TCF) {
  291                         if (READ1(sc, I2C_IBSR) & IBSR_IBIF) {
  292                                 WRITE1(sc, I2C_IBSR, IBSR_IBIF);
  293                                 return (IIC_NOERR);
  294                         }
  295                 }
  296                 DELAY(10);
  297         }
  298 
  299         return (IIC_ETIMEOUT);
  300 }
  301 /* Get ACK bit from last write */
  302 static bool
  303 tx_acked(struct i2c_softc *sc)
  304 {
  305 
  306         return (READ1(sc, I2C_IBSR) & IBSR_RXAK) ? false : true;
  307 
  308 }
  309 
  310 static int
  311 i2c_repeated_start(device_t dev, u_char slave, int timeout)
  312 {
  313         struct i2c_softc *sc;
  314         int error;
  315         int reg;
  316 
  317         sc = device_get_softc(dev);
  318 
  319         vf_i2c_dbg(sc, "i2c repeated start\n");
  320 
  321         mtx_lock(&sc->mutex);
  322 
  323         WRITE1(sc, I2C_IBAD, slave);
  324 
  325         if ((READ1(sc, I2C_IBSR) & IBSR_IBB) == 0) {
  326                 mtx_unlock(&sc->mutex);
  327                 return (IIC_EBUSERR);
  328         }
  329 
  330         /* Set repeated start condition */
  331         DELAY(10);
  332 
  333         reg = READ1(sc, I2C_IBCR);
  334         reg |= (IBCR_RSTA | IBCR_IBIE);
  335         WRITE1(sc, I2C_IBCR, reg);
  336 
  337         DELAY(10);
  338 
  339         /* Write target address - LSB is R/W bit */
  340         WRITE1(sc, I2C_IBDR, slave);
  341 
  342         error = wait_for_iif(sc);
  343 
  344         if (!tx_acked(sc)) {
  345                 vf_i2c_dbg(sc,
  346                     "cant i2c start: missing ACK after slave addres\n");
  347                 return (IIC_ENOACK);
  348         }
  349 
  350         mtx_unlock(&sc->mutex);
  351 
  352         if (error != 0)
  353                 return (error);
  354 
  355         return (IIC_NOERR);
  356 }
  357 
  358 static int
  359 i2c_start(device_t dev, u_char slave, int timeout)
  360 {
  361         struct i2c_softc *sc;
  362         int error;
  363         int reg;
  364 
  365         sc = device_get_softc(dev);
  366 
  367         vf_i2c_dbg(sc, "i2c start\n");
  368 
  369         mtx_lock(&sc->mutex);
  370 
  371         WRITE1(sc, I2C_IBAD, slave);
  372 
  373         if (READ1(sc, I2C_IBSR) & IBSR_IBB) {
  374                 mtx_unlock(&sc->mutex);
  375                 vf_i2c_dbg(sc, "cant i2c start: IIC_EBUSBSY\n");
  376                 return (IIC_EBUSERR);
  377         }
  378 
  379         /* Set start condition */
  380         reg = (IBCR_MSSL | IBCR_NOACK | IBCR_IBIE);
  381         WRITE1(sc, I2C_IBCR, reg);
  382 
  383         DELAY(100);
  384 
  385         reg |= (IBCR_TXRX);
  386         WRITE1(sc, I2C_IBCR, reg);
  387 
  388         /* Write target address - LSB is R/W bit */
  389         WRITE1(sc, I2C_IBDR, slave);
  390 
  391         error = wait_for_iif(sc);
  392         if (error != 0) {
  393                 mtx_unlock(&sc->mutex);
  394                 vf_i2c_dbg(sc, "cant i2c start: iif error\n");
  395                 return (error);
  396         }
  397         mtx_unlock(&sc->mutex);
  398 
  399         if (!tx_acked(sc)) {
  400                 vf_i2c_dbg(sc,
  401                     "cant i2c start: missing QACK after slave addres\n");
  402                 return (IIC_ENOACK);
  403         }
  404 
  405         return (IIC_NOERR);
  406 }
  407 
  408 static int
  409 i2c_stop(device_t dev)
  410 {
  411         struct i2c_softc *sc;
  412 
  413         sc = device_get_softc(dev);
  414 
  415         vf_i2c_dbg(sc, "i2c stop\n");
  416 
  417         mtx_lock(&sc->mutex);
  418 
  419         WRITE1(sc, I2C_IBCR, IBCR_NOACK | IBCR_IBIE);
  420 
  421         DELAY(100);
  422 
  423         /* Reset controller if bus still busy after STOP */
  424         if (wait_for_nibb(sc) == IIC_ETIMEOUT) {
  425                 WRITE1(sc, I2C_IBCR, IBCR_MDIS);
  426                 DELAY(1000);
  427                 WRITE1(sc, I2C_IBCR, IBCR_NOACK);
  428         }
  429         mtx_unlock(&sc->mutex);
  430 
  431         return (IIC_NOERR);
  432 }
  433 
  434 static uint32_t
  435 i2c_get_div_val(device_t dev)
  436 {
  437         struct i2c_softc *sc;
  438         uint64_t clk_freq;
  439         int error, i;
  440 
  441         sc = device_get_softc(dev);
  442 
  443         if (sc->hwtype == HW_MVF600)
  444                 return 20;
  445 
  446         if (sc->freq == 0)
  447                 return vf610_div_table[nitems(vf610_div_table) - 1].reg_val;
  448 
  449         error = clk_get_freq(sc->clock, &clk_freq);
  450         if (error != 0) {
  451                 device_printf(dev, "Could not get parent clock frequency. "
  452                     "Using default divider.\n");
  453                 return vf610_div_table[nitems(vf610_div_table) - 1].reg_val;
  454         }
  455 
  456         for (i = 0; i < nitems(vf610_div_table) - 1; i++)
  457                 if ((clk_freq / vf610_div_table[i].div) <= sc->freq)
  458                         break;
  459 
  460         return vf610_div_table[i].reg_val;
  461 }
  462 
  463 static int
  464 i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
  465 {
  466         struct i2c_softc *sc;
  467         uint32_t div;
  468 
  469         sc = device_get_softc(dev);
  470         div = i2c_get_div_val(dev);
  471         vf_i2c_dbg(sc, "Div val: %02x\n", div);
  472 
  473         vf_i2c_dbg(sc, "i2c reset\n");
  474 
  475         switch (speed) {
  476         case IIC_FAST:
  477         case IIC_SLOW:
  478         case IIC_UNKNOWN:
  479         case IIC_FASTEST:
  480         default:
  481                 break;
  482         }
  483 
  484         mtx_lock(&sc->mutex);
  485         WRITE1(sc, I2C_IBCR, IBCR_MDIS);
  486 
  487         DELAY(1000);
  488 
  489         WRITE1(sc, I2C_IBFD, div);
  490         WRITE1(sc, I2C_IBCR, 0x0); /* Enable i2c */
  491 
  492         DELAY(1000);
  493 
  494         mtx_unlock(&sc->mutex);
  495 
  496         return (IIC_NOERR);
  497 }
  498 
  499 static int
  500 i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay)
  501 {
  502         struct i2c_softc *sc;
  503         int error;
  504 
  505         sc = device_get_softc(dev);
  506 
  507         vf_i2c_dbg(sc, "i2c read\n");
  508 
  509         *read = 0;
  510 
  511         mtx_lock(&sc->mutex);
  512 
  513         if (len) {
  514                 if (len == 1)
  515                         WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL |    \
  516                             IBCR_NOACK);
  517                 else
  518                         WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL);
  519 
  520                 /* dummy read */
  521                 READ1(sc, I2C_IBDR);
  522                 DELAY(1000);
  523         }
  524 
  525         while (*read < len) {
  526                 error = wait_for_icf(sc);
  527                 if (error != 0) {
  528                         mtx_unlock(&sc->mutex);
  529                         return (error);
  530                 }
  531 
  532                 if ((*read == len - 2) && last) {
  533                         /* NO ACK on last byte */
  534                         WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL |    \
  535                             IBCR_NOACK);
  536                 }
  537 
  538                 if ((*read == len - 1) && last) {
  539                         /* Transfer done, remove master bit */
  540                         WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_NOACK);
  541                 }
  542 
  543                 *buf++ = READ1(sc, I2C_IBDR);
  544                 (*read)++;
  545         }
  546         mtx_unlock(&sc->mutex);
  547 
  548         return (IIC_NOERR);
  549 }
  550 
  551 static int
  552 i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout)
  553 {
  554         struct i2c_softc *sc;
  555         int error;
  556 
  557         sc = device_get_softc(dev);
  558 
  559         vf_i2c_dbg(sc, "i2c write\n");
  560 
  561         *sent = 0;
  562 
  563         mtx_lock(&sc->mutex);
  564         while (*sent < len) {
  565                 WRITE1(sc, I2C_IBDR, *buf++);
  566 
  567                 error = wait_for_iif(sc);
  568                 if (error != 0) {
  569                         mtx_unlock(&sc->mutex);
  570                         return (error);
  571                 }
  572 
  573                 if (!tx_acked(sc) && (*sent  = (len - 2)) ){
  574                         mtx_unlock(&sc->mutex);
  575                         vf_i2c_dbg(sc, "no ACK on %d write\n", *sent);
  576                         return (IIC_ENOACK);
  577                 }
  578 
  579                 (*sent)++;
  580         }
  581         mtx_unlock(&sc->mutex);
  582         return (IIC_NOERR);
  583 }
  584 
  585 static phandle_t
  586 i2c_get_node(device_t bus, device_t dev)
  587 {
  588 
  589         return ofw_bus_get_node(bus);
  590 }
  591 
  592 static device_method_t i2c_methods[] = {
  593         DEVMETHOD(device_probe,                 i2c_probe),
  594         DEVMETHOD(device_attach,                i2c_attach),
  595         DEVMETHOD(device_detach,                i2c_detach),
  596 
  597         DEVMETHOD(ofw_bus_get_node,             i2c_get_node),
  598 
  599         DEVMETHOD(iicbus_callback,              iicbus_null_callback),
  600         DEVMETHOD(iicbus_repeated_start,        i2c_repeated_start),
  601         DEVMETHOD(iicbus_start,                 i2c_start),
  602         DEVMETHOD(iicbus_stop,                  i2c_stop),
  603         DEVMETHOD(iicbus_reset,                 i2c_reset),
  604         DEVMETHOD(iicbus_read,                  i2c_read),
  605         DEVMETHOD(iicbus_write,                 i2c_write),
  606         DEVMETHOD(iicbus_transfer,              iicbus_transfer_gen),
  607         { 0, 0 }
  608 };
  609 
  610 static devclass_t i2c_devclass;
  611 static DEFINE_CLASS_0(i2c, i2c_driver, i2c_methods, sizeof(struct i2c_softc));
  612 DRIVER_MODULE(vybrid_i2c, simplebus, i2c_driver, i2c_devclass, 0, 0);
  613 DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0);
  614 DRIVER_MODULE(ofw_iicbus, i2c, ofw_iicbus_driver, ofw_iicbus_devclass, 0, 0);

Cache object: 58c3ea55da4c58f3a89eaa1dacd3197b


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