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/pmic/rockchip/rk8xx.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) 2018-2021 Emmanuel Vadot <manu@FreeBSD.org>
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  */
   27 
   28 #include "opt_platform.h"
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 #include <sys/param.h>
   34 #include <sys/bus.h>
   35 #include <sys/clock.h>
   36 #include <sys/eventhandler.h>
   37 #include <sys/kernel.h>
   38 #include <sys/module.h>
   39 #include <sys/reboot.h>
   40 #include <sys/mutex.h>
   41 #include <sys/rman.h>
   42 #include <machine/bus.h>
   43 
   44 #include <dev/iicbus/iiconf.h>
   45 #include <dev/iicbus/iicbus.h>
   46 
   47 #include <dev/ofw/ofw_bus.h>
   48 #include <dev/ofw/ofw_bus_subr.h>
   49 
   50 #include <dev/iicbus/pmic/rockchip/rk805reg.h>
   51 #include <dev/iicbus/pmic/rockchip/rk808reg.h>
   52 #include <dev/iicbus/pmic/rockchip/rk8xx.h>
   53 
   54 #include "clock_if.h"
   55 #include "regdev_if.h"
   56 
   57 int
   58 rk8xx_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
   59 {
   60         int err;
   61 
   62         err = iicdev_readfrom(dev, reg, data, size, IIC_INTRWAIT);
   63         return (err);
   64 }
   65 
   66 int
   67 rk8xx_write(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
   68 {
   69 
   70         return (iicdev_writeto(dev, reg, data, size, IIC_INTRWAIT));
   71 }
   72 
   73 static void
   74 rk8xx_start(void *pdev)
   75 {
   76         struct rk8xx_softc *sc;
   77         device_t dev;
   78         uint8_t data[2];
   79         int err;
   80 
   81         dev = pdev;
   82         sc = device_get_softc(dev);
   83 
   84         /* No version register in RK808 */
   85         if (bootverbose && sc->type == RK805) {
   86                 err = rk8xx_read(dev, RK805_CHIP_NAME, data, 1);
   87                 if (err != 0) {
   88                         device_printf(dev, "Cannot read chip name reg\n");
   89                         return;
   90                 }
   91                 err = rk8xx_read(dev, RK805_CHIP_VER, data + 1, 1);
   92                 if (err != 0) {
   93                         device_printf(dev, "Cannot read chip version reg\n");
   94                         return;
   95                 }
   96                 device_printf(dev, "Chip Name: %x\n",
   97                     data[0] << 4 | ((data[1] >> 4) & 0xf));
   98                 device_printf(dev, "Chip Version: %x\n", data[1] & 0xf);
   99         }
  100 
  101         /* Register this as a 1Hz clock */
  102         clock_register(dev, 1000000);
  103 
  104         config_intrhook_disestablish(&sc->intr_hook);
  105 }
  106 
  107 static void
  108 rk8xx_poweroff(void *arg, int howto)
  109 {
  110         struct rk8xx_softc *sc = arg;
  111         int error;
  112         uint8_t val;
  113 
  114         if ((howto & RB_POWEROFF) == 0)
  115                 return;
  116 
  117         device_printf(sc->dev, "Powering off...\n");
  118         error = rk8xx_read(sc->dev, sc->dev_ctrl.dev_ctrl_reg, &val, 1);
  119         if (error == 0) {
  120                 if (howto & RB_POWEROFF)
  121                         val |= sc->dev_ctrl.pwr_off_mask;
  122                 else if (howto & RB_POWERCYCLE) {
  123                         if (sc->type == RK809 || sc->type == RK817) {
  124                                 if (bootverbose) {
  125                                         device_printf(sc->dev,
  126                                             "Powercycle PMIC\n");
  127                                 }
  128                                 val |= sc->dev_ctrl.pwr_rst_mask;;
  129                         } else {
  130                                 /* Poweroff PMIC that can't powercycle */
  131                                 val |= sc->dev_ctrl.pwr_off_mask;
  132                         }
  133                 }
  134                 error = rk8xx_write(sc->dev, sc->dev_ctrl.dev_ctrl_reg,
  135                     &val, 1);
  136 
  137                 /* Wait a bit for the command to take effect. */
  138                 if (error == 0)
  139                         DELAY(100);
  140         }
  141         device_printf(sc->dev, "Power off failed\n");
  142 }
  143 
  144 int
  145 rk8xx_attach(struct rk8xx_softc *sc)
  146 {
  147         int error;
  148 
  149         error = rk8xx_attach_clocks(sc);
  150         if (error != 0)
  151                 return (error);
  152 
  153         sc->intr_hook.ich_func = rk8xx_start;
  154         sc->intr_hook.ich_arg = sc->dev;
  155         if (config_intrhook_establish(&sc->intr_hook) != 0)
  156                 return (ENOMEM);
  157 
  158         rk8xx_attach_regulators(sc);
  159 
  160         if (OF_hasprop(ofw_bus_get_node(sc->dev),
  161             "rockchip,system-power-controller")) {
  162                 /*
  163                  * The priority is chosen to override PSCI and EFI shutdown
  164                  * methods as those two just hang without powering off on Rock64
  165                  * at least.
  166                  */
  167                 EVENTHANDLER_REGISTER(shutdown_final, rk8xx_poweroff, sc,
  168                     SHUTDOWN_PRI_LAST - 2);
  169         }
  170 
  171         return (0);
  172 }
  173 
  174 static int
  175 rk8xx_detach(device_t dev)
  176 {
  177 
  178         /* We cannot detach regulators */
  179         return (EBUSY);
  180 }
  181 
  182 static device_method_t rk8xx_methods[] = {
  183         DEVMETHOD(device_detach,        rk8xx_detach),
  184 
  185         /* regdev interface */
  186         DEVMETHOD(regdev_map,           rk8xx_map),
  187 
  188         /* Clock interface */
  189         DEVMETHOD(clock_gettime,        rk8xx_gettime),
  190         DEVMETHOD(clock_settime,        rk8xx_settime),
  191 
  192         DEVMETHOD_END
  193 };
  194 
  195 DEFINE_CLASS_0(rk8xx, rk8xx_driver, rk8xx_methods,
  196     sizeof(struct rk8xx_softc));

Cache object: 781b0db8ad5b04b5e815a0040fed1748


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