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/powerpc/powermac/kiic.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) 2001 Tsubai Masanari.  All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  * 3. The name of the author may not be used to endorse or promote products
   13  *    derived from this software without specific prior written permission.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  *
   26  * $FreeBSD$
   27  *      NetBSD: ki2c.c,v 1.11 2007/12/06 17:00:33 ad Exp
   28  *      Id: ki2c.c,v 1.7 2002/10/05 09:56:05 tsubai Exp
   29  */
   30 
   31 /*
   32  *      Support routines for the Keywest I2C controller.
   33  */
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/kernel.h>
   38 #include <sys/module.h>
   39 #include <sys/bus.h>
   40 #include <sys/lock.h>
   41 #include <sys/mutex.h>
   42 #include <machine/resource.h>
   43 #include <machine/bus.h>
   44 #include <sys/rman.h>
   45 
   46 #include <dev/iicbus/iicbus.h>
   47 #include <dev/iicbus/iiconf.h>
   48 #include <dev/ofw/ofw_bus.h>
   49 #include "iicbus_if.h"
   50 
   51 /* Keywest I2C Register offsets */
   52 #define MODE    0
   53 #define CONTROL 1
   54 #define STATUS  2
   55 #define ISR     3
   56 #define IER     4
   57 #define ADDR    5
   58 #define SUBADDR 6
   59 #define DATA    7
   60 #define REV     8
   61 
   62 /* MODE */
   63 #define I2C_SPEED       0x03    /* Speed mask */
   64 #define  I2C_100kHz     0x00
   65 #define  I2C_50kHz      0x01
   66 #define  I2C_25kHz      0x02
   67 #define I2C_MODE        0x0c    /* Mode mask */
   68 #define  I2C_DUMBMODE   0x00    /*  Dumb mode */
   69 #define  I2C_STDMODE    0x04    /*  Standard mode */
   70 #define  I2C_STDSUBMODE 0x08    /*  Standard mode + sub address */
   71 #define  I2C_COMBMODE   0x0c    /*  Combined mode */
   72 #define I2C_PORT        0xf0    /* Port mask */
   73 
   74 /* CONTROL */
   75 #define I2C_CT_AAK      0x01    /* Send AAK */
   76 #define I2C_CT_ADDR     0x02    /* Send address(es) */
   77 #define I2C_CT_STOP     0x04    /* Send STOP */
   78 #define I2C_CT_START    0x08    /* Send START */
   79 
   80 /* STATUS */
   81 #define I2C_ST_BUSY     0x01    /* Busy */
   82 #define I2C_ST_LASTAAK  0x02    /* Last AAK */
   83 #define I2C_ST_LASTRW   0x04    /* Last R/W */
   84 #define I2C_ST_SDA      0x08    /* SDA */
   85 #define I2C_ST_SCL      0x10    /* SCL */
   86 
   87 /* ISR/IER */
   88 #define I2C_INT_DATA    0x01    /* Data byte sent/received */
   89 #define I2C_INT_ADDR    0x02    /* Address sent */
   90 #define I2C_INT_STOP    0x04    /* STOP condition sent */
   91 #define I2C_INT_START   0x08    /* START condition sent */
   92 
   93 /* I2C flags */
   94 #define I2C_BUSY        0x01
   95 #define I2C_READING     0x02
   96 #define I2C_ERROR       0x04
   97 #define I2C_SELECTED    0x08
   98 
   99 struct kiic_softc {
  100         device_t                 sc_dev;
  101         phandle_t                sc_node;
  102         struct mtx               sc_mutex;
  103         struct resource         *sc_reg;
  104         int                      sc_irqrid;
  105         struct resource         *sc_irq;
  106         void                    *sc_ih;
  107         u_int                    sc_regstep;
  108         u_int                    sc_flags;
  109         u_char                  *sc_data;
  110         int                      sc_resid;
  111         uint16_t                 sc_i2c_base;
  112         device_t                 sc_iicbus;
  113 };
  114 
  115 static int      kiic_probe(device_t dev);
  116 static int      kiic_attach(device_t dev);
  117 static void     kiic_writereg(struct kiic_softc *sc, u_int, u_int);
  118 static u_int    kiic_readreg(struct kiic_softc *, u_int);
  119 static void     kiic_setport(struct kiic_softc *, u_int);
  120 static void     kiic_setmode(struct kiic_softc *, u_int);
  121 static void     kiic_setspeed(struct kiic_softc *, u_int);
  122 static void     kiic_intr(void *xsc);
  123 static int      kiic_transfer(device_t dev, struct iic_msg *msgs,
  124                     uint32_t nmsgs);
  125 static phandle_t kiic_get_node(device_t bus, device_t dev);
  126 
  127 static device_method_t kiic_methods[] = {
  128         /* device interface */
  129         DEVMETHOD(device_probe,         kiic_probe),
  130         DEVMETHOD(device_attach,        kiic_attach),
  131 
  132         /* iicbus interface */
  133         DEVMETHOD(iicbus_callback,      iicbus_null_callback),
  134         DEVMETHOD(iicbus_transfer,      kiic_transfer),
  135 
  136         /* ofw_bus interface */
  137         DEVMETHOD(ofw_bus_get_node,     kiic_get_node),
  138 
  139         { 0, 0 }
  140 };
  141 
  142 static driver_t kiic_driver = {
  143         "iichb",
  144         kiic_methods,
  145         sizeof(struct kiic_softc)
  146 };
  147 static devclass_t kiic_devclass;
  148 
  149 DRIVER_MODULE(kiic, macio, kiic_driver, kiic_devclass, 0, 0);
  150 DRIVER_MODULE(kiic, unin, kiic_driver, kiic_devclass, 0, 0);
  151 
  152 static int
  153 kiic_probe(device_t self)
  154 {
  155         const char *name;
  156 
  157         name = ofw_bus_get_name(self);
  158         if (name && strcmp(name, "i2c") == 0) {
  159                 device_set_desc(self, "Keywest I2C controller");
  160                 return (0);
  161         }
  162 
  163         return (ENXIO);
  164 }
  165 
  166 static int
  167 kiic_attach(device_t self)
  168 {
  169         struct kiic_softc *sc = device_get_softc(self);
  170         int rid, rate;
  171         phandle_t node;
  172         char name[64];
  173 
  174         bzero(sc, sizeof(*sc));
  175         sc->sc_dev = self;
  176         
  177         node = ofw_bus_get_node(self);
  178         if (node == 0 || node == -1) {
  179                 return (EINVAL);
  180         }
  181 
  182         rid = 0;
  183         sc->sc_reg = bus_alloc_resource_any(self, SYS_RES_MEMORY,
  184                         &rid, RF_ACTIVE);
  185         if (sc->sc_reg == NULL) {
  186                 return (ENOMEM);
  187         }
  188 
  189         if (OF_getprop(node, "AAPL,i2c-rate", &rate, 4) != 4) {
  190                 device_printf(self, "cannot get i2c-rate\n");
  191                 return (ENXIO);
  192         }
  193         if (OF_getprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) {
  194                 device_printf(self, "unable to find i2c address step\n");
  195                 return (ENXIO);
  196         }
  197 
  198         /*
  199          * Some Keywest I2C devices have their children attached directly
  200          * underneath them.  Some have a single 'iicbus' child with the
  201          * devices underneath that.  Sort this out, and make sure that the
  202          * OFW I2C layer has the correct node.
  203          *
  204          * Note: the I2C children of the Uninorth bridges have two ports.
  205          *  In general, the port is designated in the 9th bit of the I2C
  206          *  address. However, for kiic devices with children attached below
  207          *  an i2c-bus node, the port is indicated in the 'reg' property
  208          *  of the i2c-bus node.
  209          */
  210 
  211         sc->sc_node = node;
  212 
  213         node = OF_child(node);
  214         if (OF_getprop(node, "name", name, sizeof(name)) > 0) {
  215                 if (strcmp(name,"i2c-bus") == 0) {
  216                         phandle_t reg;
  217                         if (OF_getprop(node, "reg", &reg, sizeof(reg)) > 0)
  218                                 sc->sc_i2c_base = reg << 8;
  219 
  220                         sc->sc_node = node;
  221                 }
  222         }
  223 
  224         mtx_init(&sc->sc_mutex, "kiic", NULL, MTX_DEF);
  225 
  226         sc->sc_irq = bus_alloc_resource_any(self, SYS_RES_IRQ, &sc->sc_irqrid, 
  227             RF_ACTIVE);
  228         bus_setup_intr(self, sc->sc_irq, INTR_TYPE_MISC | INTR_MPSAFE, NULL,
  229             kiic_intr, sc, &sc->sc_ih);
  230 
  231         kiic_writereg(sc, ISR, kiic_readreg(sc, ISR));
  232         kiic_writereg(sc, STATUS, 0);
  233         kiic_writereg(sc, IER, 0);
  234 
  235         kiic_setmode(sc, I2C_STDMODE);
  236         kiic_setspeed(sc, I2C_100kHz);          /* XXX rate */
  237         
  238         kiic_writereg(sc, IER, I2C_INT_DATA | I2C_INT_ADDR | I2C_INT_STOP);
  239 
  240         if (bootverbose)
  241                 device_printf(self, "Revision: %02X\n", kiic_readreg(sc, REV));
  242 
  243         /* Add the IIC bus layer */
  244         sc->sc_iicbus = device_add_child(self, "iicbus", -1);
  245 
  246         return (bus_generic_attach(self));
  247 }
  248 
  249 static void
  250 kiic_writereg(struct kiic_softc *sc, u_int reg, u_int val)
  251 {
  252         bus_write_4(sc->sc_reg, sc->sc_regstep * reg, val);
  253         DELAY(100); /* register access delay */
  254 }
  255 
  256 static u_int
  257 kiic_readreg(struct kiic_softc *sc, u_int reg)
  258 {
  259         return bus_read_4(sc->sc_reg, sc->sc_regstep * reg) & 0xff;
  260 }
  261 
  262 static void
  263 kiic_setmode(struct kiic_softc *sc, u_int mode)
  264 {
  265         u_int x;
  266 
  267         KASSERT((mode & ~I2C_MODE) == 0, ("bad mode"));
  268         x = kiic_readreg(sc, MODE);
  269         x &= ~I2C_MODE;
  270         x |= mode;
  271         kiic_writereg(sc, MODE, x);
  272 }
  273 
  274 static void
  275 kiic_setport(struct kiic_softc *sc, u_int port)
  276 {
  277         u_int x;
  278 
  279         KASSERT(port == 1 || port == 0, ("bad port"));
  280         x = kiic_readreg(sc, MODE);
  281         x &= ~I2C_PORT;
  282         x |= (port << 4);
  283         kiic_writereg(sc, MODE, x);
  284 }
  285 
  286 static void
  287 kiic_setspeed(struct kiic_softc *sc, u_int speed)
  288 {
  289         u_int x;
  290 
  291         KASSERT((speed & ~I2C_SPEED) == 0, ("bad speed"));
  292         x = kiic_readreg(sc, MODE);
  293         x &= ~I2C_SPEED;
  294         x |= speed;
  295         kiic_writereg(sc, MODE, x);
  296 }
  297 
  298 static void
  299 kiic_intr(void *xsc)
  300 {
  301         struct kiic_softc *sc = xsc;
  302         u_int isr;
  303         uint32_t x;
  304 
  305         mtx_lock(&sc->sc_mutex);
  306         isr = kiic_readreg(sc, ISR);
  307 
  308         if (isr & I2C_INT_ADDR) {
  309                 sc->sc_flags |= I2C_SELECTED;
  310 
  311                 if (sc->sc_flags & I2C_READING) {
  312                         if (sc->sc_resid > 1) {
  313                                 x = kiic_readreg(sc, CONTROL);
  314                                 x |= I2C_CT_AAK;
  315                                 kiic_writereg(sc, CONTROL, x);
  316                         }
  317                 } else {
  318                         kiic_writereg(sc, DATA, *sc->sc_data++);
  319                         sc->sc_resid--;
  320                 }
  321         }
  322 
  323         if (isr & I2C_INT_DATA) {
  324                 if (sc->sc_flags & I2C_READING) {
  325                         if (sc->sc_resid > 0) {
  326                                 *sc->sc_data++ = kiic_readreg(sc, DATA);
  327                                 sc->sc_resid--;
  328                         }
  329                         if (sc->sc_resid == 0)  /* done */
  330                                 kiic_writereg(sc, CONTROL, 0);
  331                 } else {
  332                         if (sc->sc_resid == 0) {
  333                                 x = kiic_readreg(sc, CONTROL);
  334                                 x |= I2C_CT_STOP;
  335                                 kiic_writereg(sc, CONTROL, x);
  336                         } else {
  337                                 kiic_writereg(sc, DATA, *sc->sc_data++);
  338                                 sc->sc_resid--;
  339                         }
  340                 }
  341         }
  342 
  343         if (isr & I2C_INT_STOP) {
  344                 kiic_writereg(sc, CONTROL, 0);
  345                 sc->sc_flags &= ~I2C_SELECTED;
  346                 wakeup(sc->sc_dev);
  347         }
  348 
  349         kiic_writereg(sc, ISR, isr);
  350         mtx_unlock(&sc->sc_mutex);
  351 }
  352 
  353 static int
  354 kiic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
  355 {
  356         struct kiic_softc *sc;
  357         int i, x, timo, err;
  358         uint16_t addr;
  359         uint8_t subaddr;
  360 
  361         sc = device_get_softc(dev);
  362         timo = 100;
  363         subaddr = 0;
  364 
  365         mtx_lock(&sc->sc_mutex);
  366 
  367         if (sc->sc_flags & I2C_BUSY)
  368                 mtx_sleep(dev, &sc->sc_mutex, 0, "kiic", timo);
  369 
  370         if (sc->sc_flags & I2C_BUSY) {
  371                 mtx_unlock(&sc->sc_mutex);
  372                 return (ETIMEDOUT);
  373         }
  374                 
  375         sc->sc_flags = I2C_BUSY;
  376 
  377         /* Clear pending interrupts, and reset controller */
  378         kiic_writereg(sc, ISR, kiic_readreg(sc, ISR));
  379         kiic_writereg(sc, STATUS, 0);
  380 
  381         for (i = 0; i < nmsgs; i++) {
  382                 if (msgs[i].flags & IIC_M_NOSTOP) {
  383                         if (msgs[i+1].flags & IIC_M_RD)
  384                                 kiic_setmode(sc, I2C_COMBMODE);
  385                         else
  386                                 kiic_setmode(sc, I2C_STDSUBMODE);
  387                         KASSERT(msgs[i].len == 1, ("oversize I2C message"));
  388                         subaddr = msgs[i].buf[0];
  389                         i++;
  390                 } else {
  391                         kiic_setmode(sc, I2C_STDMODE);
  392                 }
  393 
  394                 sc->sc_data = msgs[i].buf;
  395                 sc->sc_resid = msgs[i].len;
  396                 sc->sc_flags = I2C_BUSY;
  397                 addr = msgs[i].slave;
  398                 timo = 1000 + sc->sc_resid * 200;
  399                 timo += 100000;
  400 
  401                 if (msgs[i].flags & IIC_M_RD) {
  402                         sc->sc_flags |= I2C_READING;
  403                         addr |= 1;
  404                 }
  405 
  406                 addr |= sc->sc_i2c_base;
  407 
  408                 kiic_setport(sc, (addr & 0x100) >> 8);
  409                 kiic_writereg(sc, ADDR, addr & 0xff);
  410                 kiic_writereg(sc, SUBADDR, subaddr);
  411 
  412                 x = kiic_readreg(sc, CONTROL) | I2C_CT_ADDR;
  413                 kiic_writereg(sc, CONTROL, x);
  414 
  415                 err = mtx_sleep(dev, &sc->sc_mutex, 0, "kiic", timo);
  416                 
  417                 msgs[i].len -= sc->sc_resid;
  418 
  419                 if ((sc->sc_flags & I2C_ERROR) || err == EWOULDBLOCK) {
  420                         device_printf(sc->sc_dev, "I2C error\n");
  421                         sc->sc_flags = 0;
  422                         mtx_unlock(&sc->sc_mutex);
  423                         return (-1);
  424                 }
  425         }
  426 
  427         sc->sc_flags = 0;
  428 
  429         mtx_unlock(&sc->sc_mutex);
  430 
  431         return (0);
  432 }
  433 
  434 static phandle_t
  435 kiic_get_node(device_t bus, device_t dev)
  436 {
  437         struct kiic_softc *sc;
  438 
  439         sc = device_get_softc(bus);
  440         /* We only have one child, the I2C bus, which needs our own node. */
  441                 
  442         return sc->sc_node;
  443 }
  444 

Cache object: ba3113b74da02b25938a2e75554d1dc5


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