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/iicoc_fdt.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) 2019 Axiado Corporation.
    5  * All rights reserved.
    6  *
    7  * This software was developed in part by Philip Paeps under contract for
    8  * Axiado Corporation.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions are met:
   12  *
   13  * 1. Redistributions of source code must retain the above copyright notice,
   14  *    this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright notice,
   16  *    this list of conditions and the following disclaimer in the documentation
   17  *    and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
   29  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD$");
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/kernel.h>
   38 #include <sys/limits.h>
   39 #include <sys/module.h>
   40 #include <sys/bus.h>
   41 #include <sys/lock.h>
   42 #include <sys/mutex.h>
   43 #include <sys/rman.h>
   44 
   45 #include <dev/extres/clk/clk.h>
   46 
   47 #include <dev/iicbus/iicbus.h>
   48 #include <dev/iicbus/iiconf.h>
   49 
   50 #include <dev/ofw/ofw_bus.h>
   51 #include <dev/ofw/ofw_bus_subr.h>
   52 
   53 #include "iicbus_if.h"
   54 #include "iicoc.h"
   55 
   56 static struct ofw_compat_data compat_data[] = {
   57         { "opencores,i2c-ocores",       1 },
   58         { "sifive,fu740-c000-i2c",      1 },
   59         { "sifive,fu540-c000-i2c",      1 },
   60         { "sifive,i2c0",                1 },
   61         { NULL,                         0 }
   62 };
   63 
   64 static struct resource_spec iicoc_spec[] = {
   65         { SYS_RES_MEMORY, 0, RF_ACTIVE },
   66         RESOURCE_SPEC_END
   67 };
   68 
   69 static phandle_t
   70 iicoc_get_node(device_t bus, device_t dev)
   71 {
   72 
   73         /* Share controller node with iicbus device. */
   74         return (ofw_bus_get_node(bus));
   75 }
   76 
   77 static int
   78 iicoc_attach(device_t dev)
   79 {
   80         struct iicoc_softc *sc;
   81         phandle_t node;
   82         clk_t clock;
   83         uint64_t clockfreq;
   84         int error;
   85 
   86         sc = device_get_softc(dev);
   87         sc->dev = dev;
   88 
   89         mtx_init(&sc->sc_mtx, "iicoc", "iicoc", MTX_DEF);
   90 
   91         error = bus_alloc_resources(dev, iicoc_spec, &sc->mem_res);
   92         if (error) {
   93                 device_printf(dev, "Could not allocate bus resource.\n");
   94                 goto fail;
   95         }
   96 
   97         node = ofw_bus_get_node(dev);
   98         sc->reg_shift = 0;
   99         OF_getencprop(node, "reg-shift", &sc->reg_shift,
  100             sizeof(sc->reg_shift));
  101 
  102         error = clk_get_by_ofw_index(dev, 0, 0, &clock);
  103         if (error) {
  104                 device_printf(dev, "Couldn't get clock\n");
  105                 goto fail;
  106         }
  107         error = clk_enable(clock);
  108         if (error) {
  109                 device_printf(dev, "Couldn't enable clock\n");
  110                 goto fail1;
  111         }
  112         error = clk_get_freq(clock, &clockfreq);
  113         if (error) {
  114                 device_printf(dev, "Couldn't get clock frequency\n");
  115                 goto fail1;
  116         }
  117         if (clockfreq > UINT_MAX) {
  118                 device_printf(dev, "Unsupported clock frequency\n");
  119                 goto fail1;
  120         }
  121         sc->clockfreq = (u_int)clockfreq;
  122         sc->i2cfreq = XLP_I2C_FREQ;
  123         iicoc_init(dev);
  124 
  125         sc->iicbus = device_add_child(dev, "iicbus", -1);
  126         if (sc->iicbus == NULL) {
  127                 device_printf(dev, "Could not allocate iicbus instance.\n");
  128                 error = ENXIO;
  129                 goto fail1;
  130         }
  131 
  132         /* Probe and attach the iicbus when interrupts are available. */
  133         config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev);
  134 
  135         return (0);
  136 
  137 fail1:
  138         clk_disable(clock);
  139 
  140 fail:
  141         bus_release_resources(dev, iicoc_spec, &sc->mem_res);
  142         mtx_destroy(&sc->sc_mtx);
  143         return (error);
  144 }
  145 
  146 static int
  147 iicoc_probe(device_t dev)
  148 {
  149 
  150         if (!ofw_bus_status_okay(dev))
  151                 return (ENXIO);
  152 
  153         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
  154                 return (ENXIO);
  155 
  156         device_set_desc(dev, "OpenCores I2C master controller");
  157 
  158         return (BUS_PROBE_DEFAULT);
  159 }
  160 
  161 static device_method_t iicoc_methods[] = {
  162         /* device interface */
  163         DEVMETHOD(device_probe, iicoc_probe),
  164         DEVMETHOD(device_attach, iicoc_attach),
  165 
  166         /* ofw interface */
  167         DEVMETHOD(ofw_bus_get_node, iicoc_get_node),
  168 
  169         /* iicbus interface */
  170         DEVMETHOD(iicbus_callback, iicbus_null_callback),
  171         DEVMETHOD(iicbus_repeated_start, iicoc_iicbus_repeated_start),
  172         DEVMETHOD(iicbus_start, iicoc_iicbus_start),
  173         DEVMETHOD(iicbus_stop, iicoc_iicbus_stop),
  174         DEVMETHOD(iicbus_reset, iicoc_iicbus_reset),
  175         DEVMETHOD(iicbus_write, iicoc_iicbus_write),
  176         DEVMETHOD(iicbus_read, iicoc_iicbus_read),
  177         DEVMETHOD(iicbus_transfer, iicbus_transfer_gen),
  178 
  179         DEVMETHOD_END
  180 };
  181 
  182 static driver_t iicoc_driver = {
  183         "iicoc",
  184         iicoc_methods,
  185         sizeof(struct iicoc_softc),
  186 };
  187 
  188 SIMPLEBUS_PNP_INFO(compat_data);
  189 DRIVER_MODULE(iicoc, simplebus, iicoc_driver, 0, 0);
  190 DRIVER_MODULE(ofw_iicbus, iicoc, ofw_iicbus_driver, 0, 0);
  191 MODULE_DEPEND(iicoc, iicbus, 1, 1, 1);
  192 MODULE_DEPEND(iicoc, ofw_iicbus, 1, 1, 1);

Cache object: 643ab034cd3e3063576953a27c4fbc6c


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