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/iiconf.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) 1998 Nicolas Souchu
    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 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/lock.h>
   35 #include <sys/malloc.h>
   36 #include <sys/module.h>
   37 #include <sys/mutex.h>
   38 #include <sys/bus.h>
   39 
   40 #include <dev/iicbus/iiconf.h>
   41 #include <dev/iicbus/iicbus.h>
   42 #include "iicbus_if.h"
   43 
   44 /*
   45  * Encode a system errno value into the IIC_Exxxxx space by setting the
   46  * IIC_ERRNO marker bit, so that iic2errno() can turn it back into a plain
   47  * system errno value later.  This lets controller- and bus-layer code get
   48  * important system errno values (such as EINTR/ERESTART) back to the caller.
   49  */
   50 int
   51 errno2iic(int errno)
   52 {
   53         return ((errno == 0) ? 0 : errno | IIC_ERRNO);
   54 }
   55 
   56 /*
   57  * Translate IIC_Exxxxx status values to vaguely-equivelent errno values.
   58  */
   59 int
   60 iic2errno(int iic_status)
   61 {
   62         switch (iic_status) {
   63         case IIC_NOERR:         return (0);
   64         case IIC_EBUSERR:       return (EALREADY);
   65         case IIC_ENOACK:        return (EIO);
   66         case IIC_ETIMEOUT:      return (ETIMEDOUT);
   67         case IIC_EBUSBSY:       return (EWOULDBLOCK);
   68         case IIC_ESTATUS:       return (EPROTO);
   69         case IIC_EUNDERFLOW:    return (EIO);
   70         case IIC_EOVERFLOW:     return (EOVERFLOW);
   71         case IIC_ENOTSUPP:      return (EOPNOTSUPP);
   72         case IIC_ENOADDR:       return (EADDRNOTAVAIL);
   73         case IIC_ERESOURCE:     return (ENOMEM);
   74         default:
   75                 /*
   76                  * If the high bit is set, that means it's a system errno value
   77                  * that was encoded into the IIC_Exxxxxx space by setting the
   78                  * IIC_ERRNO marker bit.  If lots of high-order bits are set,
   79                  * then it's one of the negative pseudo-errors such as ERESTART
   80                  * and we return it as-is.  Otherwise it's a plain "small
   81                  * positive integer" errno, so just remove the IIC_ERRNO marker
   82                  * bit.  If it's some unknown number without the high bit set,
   83                  * there isn't much we can do except call it an I/O error.
   84                  */
   85                 if ((iic_status & IIC_ERRNO) == 0)
   86                         return (EIO);
   87                 if ((iic_status & 0xFFFF0000) != 0)
   88                         return (iic_status);
   89                 return (iic_status & ~IIC_ERRNO);
   90         }
   91 }
   92 
   93 /*
   94  * iicbus_intr()
   95  */
   96 void
   97 iicbus_intr(device_t bus, int event, char *buf)
   98 {
   99         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
  100 
  101         /* call owner's intr routine */
  102         if (sc->owner)
  103                 IICBUS_INTR(sc->owner, event, buf);
  104 
  105         return;
  106 }
  107 
  108 static int
  109 iicbus_poll(struct iicbus_softc *sc, int how)
  110 {
  111         int error;
  112 
  113         IICBUS_ASSERT_LOCKED(sc);
  114         switch (how & IIC_INTRWAIT) {
  115         case IIC_WAIT | IIC_INTR:
  116                 error = mtx_sleep(sc, &sc->lock, IICPRI|PCATCH, "iicreq", 0);
  117                 break;
  118 
  119         case IIC_WAIT | IIC_NOINTR:
  120                 error = mtx_sleep(sc, &sc->lock, IICPRI, "iicreq", 0);
  121                 break;
  122 
  123         default:
  124                 return (IIC_EBUSBSY);
  125         }
  126 
  127         return (errno2iic(error));
  128 }
  129 
  130 /*
  131  * iicbus_request_bus()
  132  *
  133  * Allocate the device to perform transfers.
  134  *
  135  * how  : IIC_WAIT or IIC_DONTWAIT
  136  */
  137 int
  138 iicbus_request_bus(device_t bus, device_t dev, int how)
  139 {
  140         struct iic_reqbus_data reqdata;
  141         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
  142         int error = 0;
  143 
  144         IICBUS_LOCK(sc);
  145 
  146         for (;;) {
  147                 if (sc->owner == NULL)
  148                         break;
  149                 if ((how & IIC_RECURSIVE) && sc->owner == dev)
  150                         break;
  151                 if ((error = iicbus_poll(sc, how)) != 0)
  152                         break;
  153         }
  154 
  155         if (error == 0) {
  156                 ++sc->owncount;
  157                 if (sc->owner == NULL) {
  158                         sc->owner = dev;
  159                         /*
  160                          * Mark the device busy while it owns the bus, to
  161                          * prevent detaching the device, bus, or hardware
  162                          * controller, until ownership is relinquished.  If the
  163                          * device is doing IO from its probe method before
  164                          * attaching, it cannot be busied; mark the bus busy.
  165                          */
  166                         if (device_get_state(dev) < DS_ATTACHING)
  167                                 sc->busydev = bus;
  168                         else
  169                                 sc->busydev = dev;
  170                         device_busy(sc->busydev);
  171                         /* 
  172                          * Drop the lock around the call to the bus driver, it
  173                          * should be allowed to sleep in the IIC_WAIT case.
  174                          * Drivers might also need to grab locks that would
  175                          * cause a LOR if our lock is held.
  176                          */
  177                         IICBUS_UNLOCK(sc);
  178                         /* Ask the underlying layers if the request is ok */
  179                         reqdata.dev = dev;
  180                         reqdata.bus = bus;
  181                         reqdata.flags = how | IIC_REQBUS_DEV;
  182                         error = IICBUS_CALLBACK(device_get_parent(bus),
  183                             IIC_REQUEST_BUS, (caddr_t)&reqdata);
  184                         IICBUS_LOCK(sc);
  185         
  186                         if (error != 0) {
  187                                 sc->owner = NULL;
  188                                 sc->owncount = 0;
  189                                 wakeup_one(sc);
  190                                 device_unbusy(sc->busydev);
  191                         }
  192                 }
  193         }
  194 
  195         IICBUS_UNLOCK(sc);
  196 
  197         return (error);
  198 }
  199 
  200 /*
  201  * iicbus_release_bus()
  202  *
  203  * Release the device allocated with iicbus_request_dev()
  204  */
  205 int
  206 iicbus_release_bus(device_t bus, device_t dev)
  207 {
  208         struct iic_reqbus_data reqdata;
  209         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
  210 
  211         IICBUS_LOCK(sc);
  212 
  213         if (sc->owner != dev) {
  214                 IICBUS_UNLOCK(sc);
  215                 return (IIC_EBUSBSY);
  216         }
  217 
  218         if (--sc->owncount == 0) {
  219                 /* Drop the lock while informing the low-level driver. */
  220                 IICBUS_UNLOCK(sc);
  221                 reqdata.dev = dev;
  222                 reqdata.bus = bus;
  223                 reqdata.flags = IIC_REQBUS_DEV;
  224                 IICBUS_CALLBACK(device_get_parent(bus), IIC_RELEASE_BUS,
  225                     (caddr_t)&reqdata);
  226                 IICBUS_LOCK(sc);
  227                 sc->owner = NULL;
  228                 wakeup_one(sc);
  229                 device_unbusy(sc->busydev);
  230         }
  231         IICBUS_UNLOCK(sc);
  232         return (0);
  233 }
  234 
  235 /*
  236  * iicbus_started()
  237  *
  238  * Test if the iicbus is started by the controller
  239  */
  240 int
  241 iicbus_started(device_t bus)
  242 {
  243         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
  244 
  245         return (sc->started);
  246 }
  247 
  248 /*
  249  * iicbus_start()
  250  *
  251  * Send start condition to the slave addressed by 'slave'
  252  */
  253 int
  254 iicbus_start(device_t bus, u_char slave, int timeout)
  255 {
  256         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
  257         int error = 0;
  258 
  259         if (sc->started)
  260                 return (IIC_ESTATUS); /* protocol error, bus already started */
  261 
  262         if (!(error = IICBUS_START(device_get_parent(bus), slave, timeout)))
  263                 sc->started = slave;
  264         else
  265                 sc->started = 0;
  266 
  267         return (error);
  268 }
  269 
  270 /*
  271  * iicbus_repeated_start()
  272  *
  273  * Send start condition to the slave addressed by 'slave'
  274  */
  275 int
  276 iicbus_repeated_start(device_t bus, u_char slave, int timeout)
  277 {
  278         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
  279         int error = 0;
  280 
  281         if (!sc->started)
  282                 return (IIC_ESTATUS); /* protocol error, bus not started */
  283 
  284         if (!(error = IICBUS_REPEATED_START(device_get_parent(bus), slave, timeout)))
  285                 sc->started = slave;
  286         else
  287                 sc->started = 0;
  288 
  289         return (error);
  290 }
  291 
  292 /*
  293  * iicbus_stop()
  294  *
  295  * Send stop condition to the bus
  296  */
  297 int
  298 iicbus_stop(device_t bus)
  299 {
  300         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
  301         int error = 0;
  302 
  303         if (!sc->started)
  304                 return (IIC_ESTATUS); /* protocol error, bus not started */
  305 
  306         error = IICBUS_STOP(device_get_parent(bus));
  307 
  308         /* refuse any further access */
  309         sc->started = 0;
  310 
  311         return (error);
  312 }
  313 
  314 /*
  315  * iicbus_write()
  316  *
  317  * Write a block of data to the slave previously started by
  318  * iicbus_start() call
  319  */
  320 int
  321 iicbus_write(device_t bus, const char *buf, int len, int *sent, int timeout)
  322 {
  323         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
  324         
  325         /* a slave must have been started for writing */
  326         if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) != 0))
  327                 return (IIC_ESTATUS);
  328 
  329         return (IICBUS_WRITE(device_get_parent(bus), buf, len, sent, timeout));
  330 }
  331 
  332 /*
  333  * iicbus_read()
  334  *
  335  * Read a block of data from the slave previously started by
  336  * iicbus_read() call
  337  */
  338 int 
  339 iicbus_read(device_t bus, char *buf, int len, int *read, int last, int delay)
  340 {
  341         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
  342         
  343         /* a slave must have been started for reading */
  344         if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) == 0))
  345                 return (IIC_ESTATUS);
  346 
  347         return (IICBUS_READ(device_get_parent(bus), buf, len, read, last, delay));
  348 }
  349 
  350 /*
  351  * iicbus_write_byte()
  352  *
  353  * Write a byte to the slave previously started by iicbus_start() call
  354  */
  355 int
  356 iicbus_write_byte(device_t bus, char byte, int timeout)
  357 {
  358         struct iicbus_softc *sc = device_get_softc(bus);
  359         char data = byte;
  360         int sent;
  361 
  362         /* a slave must have been started for writing */
  363         if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) != 0))
  364                 return (IIC_ESTATUS);
  365 
  366         return (iicbus_write(bus, &data, 1, &sent, timeout));
  367 }
  368 
  369 /*
  370  * iicbus_read_byte()
  371  *
  372  * Read a byte from the slave previously started by iicbus_start() call
  373  */
  374 int
  375 iicbus_read_byte(device_t bus, char *byte, int timeout)
  376 {
  377         struct iicbus_softc *sc = device_get_softc(bus);
  378         int read;
  379 
  380         /* a slave must have been started for reading */
  381         if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) == 0))
  382                 return (IIC_ESTATUS);
  383 
  384         return (iicbus_read(bus, byte, 1, &read, IIC_LAST_READ, timeout));
  385 }
  386 
  387 /*
  388  * iicbus_block_write()
  389  *
  390  * Write a block of data to slave ; start/stop protocol managed
  391  */
  392 int
  393 iicbus_block_write(device_t bus, u_char slave, char *buf, int len, int *sent)
  394 {
  395         u_char addr = slave & ~LSB;
  396         int error;
  397 
  398         if ((error = iicbus_start(bus, addr, 0)))
  399                 return (error);
  400 
  401         error = iicbus_write(bus, buf, len, sent, 0);
  402 
  403         iicbus_stop(bus);
  404 
  405         return (error);
  406 }
  407 
  408 /*
  409  * iicbus_block_read()
  410  *
  411  * Read a block of data from slave ; start/stop protocol managed
  412  */
  413 int
  414 iicbus_block_read(device_t bus, u_char slave, char *buf, int len, int *read)
  415 {
  416         u_char addr = slave | LSB;
  417         int error;
  418 
  419         if ((error = iicbus_start(bus, addr, 0)))
  420                 return (error);
  421 
  422         error = iicbus_read(bus, buf, len, read, IIC_LAST_READ, 0);
  423 
  424         iicbus_stop(bus);
  425 
  426         return (error);
  427 }
  428 
  429 /*
  430  * iicbus_transfer()
  431  *
  432  * Do an aribtrary number of transfers on the iicbus.  We pass these
  433  * raw requests to the bridge driver.  If the bridge driver supports
  434  * them directly, then it manages all the details.  If not, it can use
  435  * the helper function iicbus_transfer_gen() which will do the
  436  * transfers at a low level.
  437  *
  438  * Pointers passed in as part of iic_msg must be kernel pointers.
  439  * Callers that have user addresses to manage must do so on their own.
  440  */
  441 int
  442 iicbus_transfer(device_t bus, struct iic_msg *msgs, uint32_t nmsgs)
  443 {
  444 
  445         return (IICBUS_TRANSFER(device_get_parent(bus), msgs, nmsgs));
  446 }
  447 
  448 int
  449 iicbus_transfer_excl(device_t dev, struct iic_msg *msgs, uint32_t nmsgs,
  450     int how)
  451 {
  452         device_t bus;
  453         int error;
  454 
  455         bus = device_get_parent(dev);
  456         error = iicbus_request_bus(bus, dev, how);
  457         if (error == 0)
  458                 error = IICBUS_TRANSFER(bus, msgs, nmsgs);
  459         iicbus_release_bus(bus, dev);
  460         return (error);
  461 }
  462 
  463 /*
  464  * Generic version of iicbus_transfer that calls the appropriate
  465  * routines to accomplish this.  See note above about acceptable
  466  * buffer addresses.
  467  */
  468 int
  469 iicbus_transfer_gen(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
  470 {
  471         int i, error, lenread, lenwrote, nkid, rpstart, addr;
  472         device_t *children, bus;
  473         bool started;
  474 
  475         if ((error = device_get_children(dev, &children, &nkid)) != 0)
  476                 return (IIC_ERESOURCE);
  477         if (nkid != 1) {
  478                 free(children, M_TEMP);
  479                 return (IIC_ENOTSUPP);
  480         }
  481         bus = children[0];
  482         rpstart = 0;
  483         free(children, M_TEMP);
  484         started = false;
  485         for (i = 0, error = 0; i < nmsgs && error == 0; i++) {
  486                 addr = msgs[i].slave;
  487                 if (msgs[i].flags & IIC_M_RD)
  488                         addr |= LSB;
  489                 else
  490                         addr &= ~LSB;
  491 
  492                 if (!(msgs[i].flags & IIC_M_NOSTART)) {
  493                         if (rpstart)
  494                                 error = iicbus_repeated_start(bus, addr, 0);
  495                         else
  496                                 error = iicbus_start(bus, addr, 0);
  497                         if (error != 0)
  498                                 break;
  499                         started = true;
  500                 }
  501 
  502                 if (msgs[i].flags & IIC_M_RD)
  503                         error = iicbus_read(bus, msgs[i].buf, msgs[i].len,
  504                             &lenread, IIC_LAST_READ, 0);
  505                 else
  506                         error = iicbus_write(bus, msgs[i].buf, msgs[i].len,
  507                             &lenwrote, 0);
  508                 if (error != 0)
  509                         break;
  510 
  511                 if (!(msgs[i].flags & IIC_M_NOSTOP)) {
  512                         rpstart = 0;
  513                         iicbus_stop(bus);
  514                 } else {
  515                         rpstart = 1;    /* Next message gets repeated start */
  516                 }
  517         }
  518         if (error != 0 && started)
  519                 iicbus_stop(bus);
  520         return (error);
  521 }
  522 
  523 int
  524 iicdev_readfrom(device_t slavedev, uint8_t regaddr, void *buffer,
  525     uint16_t buflen, int waithow)
  526 {
  527         struct iic_msg msgs[2];
  528         uint8_t slaveaddr;
  529 
  530         /*
  531          * Two transfers back to back with a repeat-start between them; first we
  532          * write the address-within-device, then we read from the device.
  533          */
  534         slaveaddr = iicbus_get_addr(slavedev);
  535 
  536         msgs[0].slave = slaveaddr;
  537         msgs[0].flags = IIC_M_WR | IIC_M_NOSTOP;
  538         msgs[0].len   = 1;
  539         msgs[0].buf   = &regaddr;
  540 
  541         msgs[1].slave = slaveaddr;
  542         msgs[1].flags = IIC_M_RD;
  543         msgs[1].len   = buflen;
  544         msgs[1].buf   = buffer;
  545 
  546         return (iicbus_transfer_excl(slavedev, msgs, nitems(msgs), waithow));
  547 }
  548 
  549 int iicdev_writeto(device_t slavedev, uint8_t regaddr, void *buffer,
  550     uint16_t buflen, int waithow)
  551 {
  552         struct iic_msg msg;
  553         uint8_t local_buffer[32];
  554         uint8_t *bufptr;
  555         size_t bufsize;
  556         int error;
  557 
  558         /*
  559          * Ideally, we would do two transfers back to back with no stop or start
  560          * between them using an array of 2 iic_msgs; first we'd write the
  561          * address byte using the IIC_M_NOSTOP flag, then we write the data
  562          * using IIC_M_NOSTART, all in a single transfer.  Unfortunately,
  563          * several i2c hardware drivers don't support that (perhaps because the
  564          * hardware itself can't support it).  So instead we gather the
  565          * scattered bytes into a single buffer here before writing them using a
  566          * single iic_msg.  This function is typically used to write a few bytes
  567          * at a time, so we try to use a small local buffer on the stack, but
  568          * fall back to allocating a temporary buffer when necessary.
  569          */
  570 
  571         bufsize = buflen + 1;
  572         if (bufsize <= sizeof(local_buffer)) {
  573                 bufptr = local_buffer;
  574         } else {
  575                 bufptr = malloc(bufsize, M_DEVBUF,
  576                     (waithow & IIC_WAIT) ? M_WAITOK : M_NOWAIT);
  577                 if (bufptr == NULL)
  578                         return (errno2iic(ENOMEM));
  579         }
  580 
  581         bufptr[0] = regaddr;
  582         memcpy(&bufptr[1], buffer, buflen);
  583 
  584         msg.slave = iicbus_get_addr(slavedev);
  585         msg.flags = IIC_M_WR;
  586         msg.len   = bufsize;
  587         msg.buf   = bufptr;
  588 
  589         error = iicbus_transfer_excl(slavedev, &msg, 1, waithow);
  590 
  591         if (bufptr != local_buffer)
  592                 free(bufptr, M_DEVBUF);
  593 
  594         return (error);
  595 }

Cache object: 2a2814be4848ba0aa7e1cb5ccb3ce260


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