pmic: rockchip: Split the driver in rk805 and rk808
This make the base driver cleaner and the subclassed driver only have related code. Kernel config wise this is still only handled by rk805. No functional changes intended.
This commit is contained in:
parent
cb3c3e0a42
commit
98c60dc31f
@ -540,7 +540,9 @@ arm64/rockchip/rk3399_emmcphy.c optional fdt rk_emmcphy soc_rockchip_rk3399
|
||||
arm64/rockchip/rk_dwc3.c optional fdt rk_dwc3 soc_rockchip_rk3399
|
||||
arm64/rockchip/rk_i2c.c optional fdt rk_i2c soc_rockchip_rk3328 | fdt rk_i2c soc_rockchip_rk3399
|
||||
arm64/rockchip/rk_i2s.c optional fdt sound soc_rockchip_rk3328 | fdt sound soc_rockchip_rk3399
|
||||
dev/iicbus/pmic/rockchip/rk805.c optional fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399
|
||||
dev/iicbus/pmic/rockchip/rk8xx.c optional fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399
|
||||
dev/iicbus/pmic/rockchip/rk805.c optional fdt rk805 soc_rockchip_rk3328
|
||||
dev/iicbus/pmic/rockchip/rk808.c optional fdt rk805 soc_rockchip_rk3399
|
||||
dev/iicbus/pmic/rockchip/rk8xx_clocks.c optional fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399
|
||||
dev/iicbus/pmic/rockchip/rk8xx_regulators.c optional fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399
|
||||
dev/iicbus/pmic/rockchip/rk8xx_rtc.c optional fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2018 Emmanuel Vadot <manu@FreeBSD.org>
|
||||
* Copyright (c) 2018-2021 Emmanuel Vadot <manu@FreeBSD.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -46,17 +46,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <dev/iicbus/pmic/rockchip/rk805reg.h>
|
||||
#include <dev/iicbus/pmic/rockchip/rk808reg.h>
|
||||
#include <dev/iicbus/pmic/rockchip/rk8xx.h>
|
||||
|
||||
#include "clock_if.h"
|
||||
#include "regdev_if.h"
|
||||
|
||||
MALLOC_DEFINE(M_RK805_REG, "RK805 regulator", "RK805 power regulator");
|
||||
|
||||
static struct ofw_compat_data compat_data[] = {
|
||||
{"rockchip,rk805", RK805},
|
||||
{"rockchip,rk808", RK808},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
@ -141,182 +134,8 @@ static struct rk8xx_regdef rk805_regdefs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct rk8xx_regdef rk808_regdefs[] = {
|
||||
{
|
||||
.id = RK808_BUCK1,
|
||||
.name = "DCDC_REG1",
|
||||
.enable_reg = RK808_DCDC_EN,
|
||||
.enable_mask = 0x1,
|
||||
.voltage_reg = RK808_BUCK1_ON_VSEL,
|
||||
.voltage_mask = 0x3F,
|
||||
.voltage_min = 712500,
|
||||
.voltage_max = 1500000,
|
||||
.voltage_step = 12500,
|
||||
.voltage_nstep = 64,
|
||||
},
|
||||
{
|
||||
.id = RK808_BUCK2,
|
||||
.name = "DCDC_REG2",
|
||||
.enable_reg = RK808_DCDC_EN,
|
||||
.enable_mask = 0x2,
|
||||
.voltage_reg = RK808_BUCK2_ON_VSEL,
|
||||
.voltage_mask = 0x3F,
|
||||
.voltage_min = 712500,
|
||||
.voltage_max = 1500000,
|
||||
.voltage_step = 12500,
|
||||
.voltage_nstep = 64,
|
||||
},
|
||||
{
|
||||
/* BUCK3 voltage is calculated based on external resistor */
|
||||
.id = RK808_BUCK3,
|
||||
.name = "DCDC_REG3",
|
||||
.enable_reg = RK808_DCDC_EN,
|
||||
.enable_mask = 0x4,
|
||||
},
|
||||
{
|
||||
.id = RK808_BUCK4,
|
||||
.name = "DCDC_REG4",
|
||||
.enable_reg = RK808_DCDC_EN,
|
||||
.enable_mask = 0x8,
|
||||
.voltage_reg = RK808_BUCK4_ON_VSEL,
|
||||
.voltage_mask = 0xF,
|
||||
.voltage_min = 1800000,
|
||||
.voltage_max = 3300000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 16,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO1,
|
||||
.name = "LDO_REG1",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x1,
|
||||
.voltage_reg = RK808_LDO1_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 1800000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 17,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO2,
|
||||
.name = "LDO_REG2",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x2,
|
||||
.voltage_reg = RK808_LDO2_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 1800000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 17,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO3,
|
||||
.name = "LDO_REG3",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x4,
|
||||
.voltage_reg = RK808_LDO3_ON_VSEL,
|
||||
.voltage_mask = 0xF,
|
||||
.voltage_min = 800000,
|
||||
.voltage_max = 2500000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 18,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO4,
|
||||
.name = "LDO_REG4",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x8,
|
||||
.voltage_reg = RK808_LDO4_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 1800000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 17,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO5,
|
||||
.name = "LDO_REG5",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x10,
|
||||
.voltage_reg = RK808_LDO5_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 1800000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 17,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO6,
|
||||
.name = "LDO_REG6",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x20,
|
||||
.voltage_reg = RK808_LDO6_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 800000,
|
||||
.voltage_max = 2500000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 18,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO7,
|
||||
.name = "LDO_REG7",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x40,
|
||||
.voltage_reg = RK808_LDO7_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 800000,
|
||||
.voltage_max = 2500000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 18,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO8,
|
||||
.name = "LDO_REG8",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x80,
|
||||
.voltage_reg = RK808_LDO8_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 1800000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 17,
|
||||
},
|
||||
{
|
||||
.id = RK808_SWITCH1,
|
||||
.name = "SWITCH_REG1",
|
||||
.enable_reg = RK808_DCDC_EN,
|
||||
.enable_mask = 0x20,
|
||||
.voltage_min = 3000000,
|
||||
.voltage_max = 3000000,
|
||||
},
|
||||
{
|
||||
.id = RK808_SWITCH2,
|
||||
.name = "SWITCH_REG2",
|
||||
.enable_reg = RK808_DCDC_EN,
|
||||
.enable_mask = 0x40,
|
||||
.voltage_min = 3000000,
|
||||
.voltage_max = 3000000,
|
||||
},
|
||||
};
|
||||
|
||||
int
|
||||
rk8xx_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = iicdev_readfrom(dev, reg, data, size, IIC_INTRWAIT);
|
||||
return (err);
|
||||
}
|
||||
|
||||
int
|
||||
rk8xx_write(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
|
||||
{
|
||||
|
||||
return (iicdev_writeto(dev, reg, data, size, IIC_INTRWAIT));
|
||||
}
|
||||
|
||||
static int
|
||||
rk8xx_probe(device_t dev)
|
||||
rk805_probe(device_t dev)
|
||||
{
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
@ -324,188 +143,56 @@ rk8xx_probe(device_t dev)
|
||||
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "RockChip RK8XX PMIC");
|
||||
device_set_desc(dev, "RockChip RK805 PMIC");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static void
|
||||
rk8xx_start(void *pdev)
|
||||
static int
|
||||
rk805_attach(device_t dev)
|
||||
{
|
||||
struct rk8xx_softc *sc;
|
||||
device_t dev;
|
||||
uint8_t data[2];
|
||||
int err;
|
||||
|
||||
dev = pdev;
|
||||
sc = device_get_softc(dev);
|
||||
sc->dev = dev;
|
||||
|
||||
/* No version register in RK808 */
|
||||
if (bootverbose && sc->type == RK805) {
|
||||
err = rk8xx_read(dev, RK805_CHIP_NAME, data, 1);
|
||||
if (err != 0) {
|
||||
device_printf(dev, "Cannot read chip name reg\n");
|
||||
return;
|
||||
}
|
||||
err = rk8xx_read(dev, RK805_CHIP_VER, data + 1, 1);
|
||||
if (err != 0) {
|
||||
device_printf(dev, "Cannot read chip version reg\n");
|
||||
return;
|
||||
}
|
||||
device_printf(dev, "Chip Name: %x\n",
|
||||
data[0] << 4 | ((data[1] >> 4) & 0xf));
|
||||
device_printf(dev, "Chip Version: %x\n", data[1] & 0xf);
|
||||
}
|
||||
|
||||
/* Register this as a 1Hz clock */
|
||||
clock_register(dev, 1000000);
|
||||
|
||||
config_intrhook_disestablish(&sc->intr_hook);
|
||||
}
|
||||
|
||||
static int
|
||||
rk8xx_attach(device_t dev)
|
||||
{
|
||||
struct rk8xx_softc *sc;
|
||||
struct rk8xx_reg_sc *reg;
|
||||
struct rk8xx_regdef *regdefs;
|
||||
struct reg_list *regp;
|
||||
phandle_t rnode, child;
|
||||
int error, i;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
|
||||
error = rk8xx_export_clocks(dev);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
sc->intr_hook.ich_func = rk8xx_start;
|
||||
sc->intr_hook.ich_arg = dev;
|
||||
if (config_intrhook_establish(&sc->intr_hook) != 0)
|
||||
return (ENOMEM);
|
||||
sc->regdefs = rk805_regdefs;
|
||||
sc->nregs = nitems(rk805_regdefs);
|
||||
sc->rtc_regs.secs = RK805_RTC_SECS;
|
||||
sc->rtc_regs.secs_mask = RK805_RTC_SECS_MASK;
|
||||
sc->rtc_regs.minutes = RK805_RTC_MINUTES;
|
||||
sc->rtc_regs.minutes_mask = RK805_RTC_MINUTES_MASK;
|
||||
sc->rtc_regs.hours = RK805_RTC_HOURS;
|
||||
sc->rtc_regs.hours_mask = RK805_RTC_HOURS_MASK;
|
||||
sc->rtc_regs.days = RK805_RTC_DAYS;
|
||||
sc->rtc_regs.days_mask = RK805_RTC_DAYS_MASK;
|
||||
sc->rtc_regs.months = RK805_RTC_MONTHS;
|
||||
sc->rtc_regs.months_mask = RK805_RTC_MONTHS_MASK;
|
||||
sc->rtc_regs.years = RK805_RTC_YEARS;
|
||||
sc->rtc_regs.weeks = RK805_RTC_WEEKS_MASK;
|
||||
sc->rtc_regs.ctrl = RK805_RTC_CTRL;
|
||||
sc->rtc_regs.ctrl_stop_mask = RK805_RTC_CTRL_STOP;
|
||||
sc->rtc_regs.ctrl_ampm_mask = RK805_RTC_AMPM_MODE;
|
||||
sc->rtc_regs.ctrl_gettime_mask = RK805_RTC_GET_TIME;
|
||||
sc->rtc_regs.ctrl_readsel_mask = RK805_RTC_READSEL;
|
||||
|
||||
switch (sc->type) {
|
||||
case RK805:
|
||||
regdefs = rk805_regdefs;
|
||||
sc->nregs = nitems(rk805_regdefs);
|
||||
sc->rtc_regs.secs = RK805_RTC_SECS;
|
||||
sc->rtc_regs.secs_mask = RK805_RTC_SECS_MASK;
|
||||
sc->rtc_regs.minutes = RK805_RTC_MINUTES;
|
||||
sc->rtc_regs.minutes_mask = RK805_RTC_MINUTES_MASK;
|
||||
sc->rtc_regs.hours = RK805_RTC_HOURS;
|
||||
sc->rtc_regs.hours_mask = RK805_RTC_HOURS_MASK;
|
||||
sc->rtc_regs.days = RK805_RTC_DAYS;
|
||||
sc->rtc_regs.days_mask = RK805_RTC_DAYS_MASK;
|
||||
sc->rtc_regs.months = RK805_RTC_MONTHS;
|
||||
sc->rtc_regs.months_mask = RK805_RTC_MONTHS_MASK;
|
||||
sc->rtc_regs.years = RK805_RTC_YEARS;
|
||||
sc->rtc_regs.weeks = RK805_RTC_WEEKS_MASK;
|
||||
sc->rtc_regs.ctrl = RK805_RTC_CTRL;
|
||||
sc->rtc_regs.ctrl_stop_mask = RK805_RTC_CTRL_STOP;
|
||||
sc->rtc_regs.ctrl_ampm_mask = RK805_RTC_AMPM_MODE;
|
||||
sc->rtc_regs.ctrl_gettime_mask = RK805_RTC_GET_TIME;
|
||||
sc->rtc_regs.ctrl_readsel_mask = RK805_RTC_READSEL;
|
||||
break;
|
||||
case RK808:
|
||||
regdefs = rk808_regdefs;
|
||||
sc->nregs = nitems(rk808_regdefs);
|
||||
sc->rtc_regs.secs = RK808_RTC_SECS;
|
||||
sc->rtc_regs.secs_mask = RK808_RTC_SECS_MASK;
|
||||
sc->rtc_regs.minutes = RK808_RTC_MINUTES;
|
||||
sc->rtc_regs.minutes_mask = RK808_RTC_MINUTES_MASK;
|
||||
sc->rtc_regs.hours = RK808_RTC_HOURS;
|
||||
sc->rtc_regs.hours_mask = RK808_RTC_HOURS_MASK;
|
||||
sc->rtc_regs.days = RK808_RTC_DAYS;
|
||||
sc->rtc_regs.days_mask = RK808_RTC_DAYS_MASK;
|
||||
sc->rtc_regs.months = RK808_RTC_MONTHS;
|
||||
sc->rtc_regs.months_mask = RK808_RTC_MONTHS_MASK;
|
||||
sc->rtc_regs.years = RK808_RTC_YEARS;
|
||||
sc->rtc_regs.weeks = RK808_RTC_WEEKS_MASK;
|
||||
sc->rtc_regs.ctrl = RK808_RTC_CTRL;
|
||||
sc->rtc_regs.ctrl_stop_mask = RK808_RTC_CTRL_STOP;
|
||||
sc->rtc_regs.ctrl_ampm_mask = RK808_RTC_AMPM_MODE;
|
||||
sc->rtc_regs.ctrl_gettime_mask = RK808_RTC_GET_TIME;
|
||||
sc->rtc_regs.ctrl_readsel_mask = RK808_RTC_READSEL;
|
||||
break;
|
||||
default:
|
||||
device_printf(dev, "Unknown type %d\n", sc->type);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
TAILQ_INIT(&sc->regs);
|
||||
|
||||
rnode = ofw_bus_find_child(ofw_bus_get_node(dev), "regulators");
|
||||
if (rnode > 0) {
|
||||
for (i = 0; i < sc->nregs; i++) {
|
||||
child = ofw_bus_find_child(rnode,
|
||||
regdefs[i].name);
|
||||
if (child == 0)
|
||||
continue;
|
||||
if (OF_hasprop(child, "regulator-name") != 1)
|
||||
continue;
|
||||
reg = rk8xx_reg_attach(dev, child, ®defs[i]);
|
||||
if (reg == NULL) {
|
||||
device_printf(dev,
|
||||
"cannot attach regulator %s\n",
|
||||
regdefs[i].name);
|
||||
continue;
|
||||
}
|
||||
regp = malloc(sizeof(*regp), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
regp->reg = reg;
|
||||
TAILQ_INSERT_TAIL(&sc->regs, regp, next);
|
||||
if (bootverbose)
|
||||
device_printf(dev, "Regulator %s attached\n",
|
||||
regdefs[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
if (OF_hasprop(ofw_bus_get_node(dev),
|
||||
"rockchip,system-power-controller")) {
|
||||
/*
|
||||
* The priority is chosen to override PSCI and EFI shutdown
|
||||
* methods as those two just hang without powering off on Rock64
|
||||
* at least.
|
||||
*/
|
||||
EVENTHANDLER_REGISTER(shutdown_final, rk805_poweroff, dev,
|
||||
SHUTDOWN_PRI_LAST - 2);
|
||||
}
|
||||
|
||||
return (0);
|
||||
return (rk8xx_attach(sc));
|
||||
}
|
||||
|
||||
static int
|
||||
rk8xx_detach(device_t dev)
|
||||
{
|
||||
|
||||
/* We cannot detach regulators */
|
||||
return (EBUSY);
|
||||
}
|
||||
|
||||
static device_method_t rk8xx_methods[] = {
|
||||
DEVMETHOD(device_probe, rk8xx_probe),
|
||||
DEVMETHOD(device_attach, rk8xx_attach),
|
||||
DEVMETHOD(device_detach, rk8xx_detach),
|
||||
|
||||
/* regdev interface */
|
||||
DEVMETHOD(regdev_map, rk8xx_map),
|
||||
|
||||
/* Clock interface */
|
||||
DEVMETHOD(clock_gettime, rk8xx_gettime),
|
||||
DEVMETHOD(clock_settime, rk8xx_settime),
|
||||
static device_method_t rk805_methods[] = {
|
||||
DEVMETHOD(device_probe, rk805_probe),
|
||||
DEVMETHOD(device_attach, rk805_attach),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t rk8xx_driver = {
|
||||
"rk8xx_pmu",
|
||||
rk8xx_methods,
|
||||
sizeof(struct rk8xx_softc),
|
||||
};
|
||||
DEFINE_CLASS_1(iichb, rk805_driver, rk805_methods,
|
||||
sizeof(struct rk8xx_softc), rk8xx_driver);
|
||||
|
||||
static devclass_t rk8xx_devclass;
|
||||
static devclass_t rk805_devclass;
|
||||
|
||||
EARLY_DRIVER_MODULE(rk8xx, iicbus, rk8xx_driver, rk8xx_devclass, 0, 0,
|
||||
EARLY_DRIVER_MODULE(rk805, iicbus, rk805_driver, rk805_devclass, 0, 0,
|
||||
BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST);
|
||||
MODULE_DEPEND(rk8xx, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
|
||||
MODULE_VERSION(rk8xx, 1);
|
||||
MODULE_DEPEND(rk805, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
|
||||
MODULE_VERSION(rk805, 1);
|
||||
|
273
sys/dev/iicbus/pmic/rockchip/rk808.c
Normal file
273
sys/dev/iicbus/pmic/rockchip/rk808.c
Normal file
@ -0,0 +1,273 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2018-2021 Emmanuel Vadot <manu@FreeBSD.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/clock.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/rman.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <dev/iicbus/pmic/rockchip/rk808reg.h>
|
||||
#include <dev/iicbus/pmic/rockchip/rk8xx.h>
|
||||
|
||||
static struct ofw_compat_data compat_data[] = {
|
||||
{"rockchip,rk808", RK808},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
static struct rk8xx_regdef rk808_regdefs[] = {
|
||||
{
|
||||
.id = RK808_BUCK1,
|
||||
.name = "DCDC_REG1",
|
||||
.enable_reg = RK808_DCDC_EN,
|
||||
.enable_mask = 0x1,
|
||||
.voltage_reg = RK808_BUCK1_ON_VSEL,
|
||||
.voltage_mask = 0x3F,
|
||||
.voltage_min = 712500,
|
||||
.voltage_max = 1500000,
|
||||
.voltage_step = 12500,
|
||||
.voltage_nstep = 64,
|
||||
},
|
||||
{
|
||||
.id = RK808_BUCK2,
|
||||
.name = "DCDC_REG2",
|
||||
.enable_reg = RK808_DCDC_EN,
|
||||
.enable_mask = 0x2,
|
||||
.voltage_reg = RK808_BUCK2_ON_VSEL,
|
||||
.voltage_mask = 0x3F,
|
||||
.voltage_min = 712500,
|
||||
.voltage_max = 1500000,
|
||||
.voltage_step = 12500,
|
||||
.voltage_nstep = 64,
|
||||
},
|
||||
{
|
||||
/* BUCK3 voltage is calculated based on external resistor */
|
||||
.id = RK808_BUCK3,
|
||||
.name = "DCDC_REG3",
|
||||
.enable_reg = RK808_DCDC_EN,
|
||||
.enable_mask = 0x4,
|
||||
},
|
||||
{
|
||||
.id = RK808_BUCK4,
|
||||
.name = "DCDC_REG4",
|
||||
.enable_reg = RK808_DCDC_EN,
|
||||
.enable_mask = 0x8,
|
||||
.voltage_reg = RK808_BUCK4_ON_VSEL,
|
||||
.voltage_mask = 0xF,
|
||||
.voltage_min = 1800000,
|
||||
.voltage_max = 3300000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 16,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO1,
|
||||
.name = "LDO_REG1",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x1,
|
||||
.voltage_reg = RK808_LDO1_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 1800000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 17,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO2,
|
||||
.name = "LDO_REG2",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x2,
|
||||
.voltage_reg = RK808_LDO2_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 1800000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 17,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO3,
|
||||
.name = "LDO_REG3",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x4,
|
||||
.voltage_reg = RK808_LDO3_ON_VSEL,
|
||||
.voltage_mask = 0xF,
|
||||
.voltage_min = 800000,
|
||||
.voltage_max = 2500000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 18,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO4,
|
||||
.name = "LDO_REG4",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x8,
|
||||
.voltage_reg = RK808_LDO4_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 1800000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 17,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO5,
|
||||
.name = "LDO_REG5",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x10,
|
||||
.voltage_reg = RK808_LDO5_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 1800000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 17,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO6,
|
||||
.name = "LDO_REG6",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x20,
|
||||
.voltage_reg = RK808_LDO6_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 800000,
|
||||
.voltage_max = 2500000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 18,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO7,
|
||||
.name = "LDO_REG7",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x40,
|
||||
.voltage_reg = RK808_LDO7_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 800000,
|
||||
.voltage_max = 2500000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 18,
|
||||
},
|
||||
{
|
||||
.id = RK808_LDO8,
|
||||
.name = "LDO_REG8",
|
||||
.enable_reg = RK808_LDO_EN,
|
||||
.enable_mask = 0x80,
|
||||
.voltage_reg = RK808_LDO8_ON_VSEL,
|
||||
.voltage_mask = 0x1F,
|
||||
.voltage_min = 1800000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 17,
|
||||
},
|
||||
{
|
||||
.id = RK808_SWITCH1,
|
||||
.name = "SWITCH_REG1",
|
||||
.enable_reg = RK808_DCDC_EN,
|
||||
.enable_mask = 0x20,
|
||||
.voltage_min = 3000000,
|
||||
.voltage_max = 3000000,
|
||||
},
|
||||
{
|
||||
.id = RK808_SWITCH2,
|
||||
.name = "SWITCH_REG2",
|
||||
.enable_reg = RK808_DCDC_EN,
|
||||
.enable_mask = 0x40,
|
||||
.voltage_min = 3000000,
|
||||
.voltage_max = 3000000,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
rk808_probe(device_t dev)
|
||||
{
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "RockChip RK808 PMIC");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
rk808_attach(device_t dev)
|
||||
{
|
||||
struct rk8xx_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->dev = dev;
|
||||
|
||||
sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
|
||||
|
||||
sc->regdefs = rk808_regdefs;
|
||||
sc->nregs = nitems(rk808_regdefs);
|
||||
sc->rtc_regs.secs = RK808_RTC_SECS;
|
||||
sc->rtc_regs.secs_mask = RK808_RTC_SECS_MASK;
|
||||
sc->rtc_regs.minutes = RK808_RTC_MINUTES;
|
||||
sc->rtc_regs.minutes_mask = RK808_RTC_MINUTES_MASK;
|
||||
sc->rtc_regs.hours = RK808_RTC_HOURS;
|
||||
sc->rtc_regs.hours_mask = RK808_RTC_HOURS_MASK;
|
||||
sc->rtc_regs.days = RK808_RTC_DAYS;
|
||||
sc->rtc_regs.days_mask = RK808_RTC_DAYS_MASK;
|
||||
sc->rtc_regs.months = RK808_RTC_MONTHS;
|
||||
sc->rtc_regs.months_mask = RK808_RTC_MONTHS_MASK;
|
||||
sc->rtc_regs.years = RK808_RTC_YEARS;
|
||||
sc->rtc_regs.weeks = RK808_RTC_WEEKS_MASK;
|
||||
sc->rtc_regs.ctrl = RK808_RTC_CTRL;
|
||||
sc->rtc_regs.ctrl_stop_mask = RK808_RTC_CTRL_STOP;
|
||||
sc->rtc_regs.ctrl_ampm_mask = RK808_RTC_AMPM_MODE;
|
||||
sc->rtc_regs.ctrl_gettime_mask = RK808_RTC_GET_TIME;
|
||||
sc->rtc_regs.ctrl_readsel_mask = RK808_RTC_READSEL;
|
||||
|
||||
return (rk8xx_attach(sc));
|
||||
}
|
||||
|
||||
static device_method_t rk808_methods[] = {
|
||||
DEVMETHOD(device_probe, rk808_probe),
|
||||
DEVMETHOD(device_attach, rk808_attach),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS_1(iichb, rk808_driver, rk808_methods,
|
||||
sizeof(struct rk8xx_softc), rk8xx_driver);
|
||||
|
||||
static devclass_t rk808_devclass;
|
||||
|
||||
EARLY_DRIVER_MODULE(rk808, iicbus, rk808_driver, rk808_devclass, 0, 0,
|
||||
BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST);
|
||||
MODULE_DEPEND(rk808, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
|
||||
MODULE_VERSION(rk808, 1);
|
145
sys/dev/iicbus/pmic/rockchip/rk8xx.c
Normal file
145
sys/dev/iicbus/pmic/rockchip/rk8xx.c
Normal file
@ -0,0 +1,145 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2018-2021 Emmanuel Vadot <manu@FreeBSD.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/clock.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/rman.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
|
||||
#include <dev/iicbus/pmic/rockchip/rk805reg.h>
|
||||
#include <dev/iicbus/pmic/rockchip/rk808reg.h>
|
||||
#include <dev/iicbus/pmic/rockchip/rk8xx.h>
|
||||
|
||||
#include "clock_if.h"
|
||||
#include "regdev_if.h"
|
||||
|
||||
int
|
||||
rk8xx_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = iicdev_readfrom(dev, reg, data, size, IIC_INTRWAIT);
|
||||
return (err);
|
||||
}
|
||||
|
||||
int
|
||||
rk8xx_write(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
|
||||
{
|
||||
|
||||
return (iicdev_writeto(dev, reg, data, size, IIC_INTRWAIT));
|
||||
}
|
||||
|
||||
static void
|
||||
rk8xx_start(void *pdev)
|
||||
{
|
||||
struct rk8xx_softc *sc;
|
||||
device_t dev;
|
||||
uint8_t data[2];
|
||||
int err;
|
||||
|
||||
dev = pdev;
|
||||
sc = device_get_softc(dev);
|
||||
sc->dev = dev;
|
||||
|
||||
/* No version register in RK808 */
|
||||
if (bootverbose && sc->type == RK805) {
|
||||
err = rk8xx_read(dev, RK805_CHIP_NAME, data, 1);
|
||||
if (err != 0) {
|
||||
device_printf(dev, "Cannot read chip name reg\n");
|
||||
return;
|
||||
}
|
||||
err = rk8xx_read(dev, RK805_CHIP_VER, data + 1, 1);
|
||||
if (err != 0) {
|
||||
device_printf(dev, "Cannot read chip version reg\n");
|
||||
return;
|
||||
}
|
||||
device_printf(dev, "Chip Name: %x\n",
|
||||
data[0] << 4 | ((data[1] >> 4) & 0xf));
|
||||
device_printf(dev, "Chip Version: %x\n", data[1] & 0xf);
|
||||
}
|
||||
|
||||
/* Register this as a 1Hz clock */
|
||||
clock_register(dev, 1000000);
|
||||
|
||||
config_intrhook_disestablish(&sc->intr_hook);
|
||||
}
|
||||
|
||||
int
|
||||
rk8xx_attach(struct rk8xx_softc *sc)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = rk8xx_attach_clocks(sc);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
sc->intr_hook.ich_func = rk8xx_start;
|
||||
sc->intr_hook.ich_arg = sc->dev;
|
||||
if (config_intrhook_establish(&sc->intr_hook) != 0)
|
||||
return (ENOMEM);
|
||||
|
||||
rk8xx_attach_regulators(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
rk8xx_detach(device_t dev)
|
||||
{
|
||||
|
||||
/* We cannot detach regulators */
|
||||
return (EBUSY);
|
||||
}
|
||||
|
||||
static device_method_t rk8xx_methods[] = {
|
||||
DEVMETHOD(device_detach, rk8xx_detach),
|
||||
|
||||
/* regdev interface */
|
||||
DEVMETHOD(regdev_map, rk8xx_map),
|
||||
|
||||
/* Clock interface */
|
||||
DEVMETHOD(clock_gettime, rk8xx_gettime),
|
||||
DEVMETHOD(clock_settime, rk8xx_settime),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS_0(rk8xx, rk8xx_driver, rk8xx_methods,
|
||||
sizeof(struct rk8xx_softc));
|
@ -93,7 +93,8 @@ struct rk8xx_softc {
|
||||
struct intr_config_hook intr_hook;
|
||||
enum rk_pmic_type type;
|
||||
|
||||
TAILQ_HEAD(, reg_list) regs;
|
||||
struct rk8xx_regdef *regdefs;
|
||||
TAILQ_HEAD(, reg_list) regs;
|
||||
int nregs;
|
||||
|
||||
struct rk8xx_rtc_reg rtc_regs;
|
||||
@ -102,12 +103,15 @@ struct rk8xx_softc {
|
||||
int rk8xx_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size);
|
||||
int rk8xx_write(device_t dev, uint8_t reg, uint8_t *data, uint8_t size);
|
||||
|
||||
DECLARE_CLASS(rk8xx_driver);
|
||||
|
||||
int rk8xx_attach(struct rk8xx_softc *sc);
|
||||
|
||||
/* rk8xx_clocks.c */
|
||||
int rk8xx_export_clocks(device_t dev);
|
||||
int rk8xx_attach_clocks(struct rk8xx_softc *sc);
|
||||
|
||||
/* rk8xx_regulators.c */
|
||||
struct rk8xx_reg_sc *rk8xx_reg_attach(device_t dev, phandle_t node,
|
||||
struct rk8xx_regdef *def);
|
||||
void rk8xx_attach_regulators(struct rk8xx_softc *sc);
|
||||
int rk8xx_map(device_t dev, phandle_t xref, int ncells,
|
||||
pcell_t *cells, intptr_t *id);
|
||||
|
||||
|
@ -94,7 +94,7 @@ DEFINE_CLASS_1(rk8xx_clk_clknode_1, rk8xx_clk_clknode_class_1,
|
||||
rk8xx_clk_clknode_class_0);
|
||||
|
||||
int
|
||||
rk8xx_export_clocks(device_t dev)
|
||||
rk8xx_attach_clocks(struct rk8xx_softc *sc)
|
||||
{
|
||||
struct clkdom *clkdom;
|
||||
struct clknode_init_def clkidef;
|
||||
@ -104,24 +104,24 @@ rk8xx_export_clocks(device_t dev)
|
||||
phandle_t node;
|
||||
int nclks, rv;
|
||||
|
||||
node = ofw_bus_get_node(dev);
|
||||
node = ofw_bus_get_node(sc->dev);
|
||||
|
||||
/* clock-output-names are optional. Could use them for clkidef.name. */
|
||||
nclks = ofw_bus_string_list_to_array(node, "clock-output-names",
|
||||
&clknames);
|
||||
|
||||
clkdom = clkdom_create(dev);
|
||||
clkdom = clkdom_create(sc->dev);
|
||||
|
||||
memset(&clkidef, 0, sizeof(clkidef));
|
||||
clkidef.id = 0;
|
||||
clkidef.name = (nclks = 2) ? clknames[0] : "clk32kout1";
|
||||
clk = clknode_create(clkdom, &rk8xx_clk_clknode_class_0, &clkidef);
|
||||
if (clk == NULL) {
|
||||
device_printf(dev, "Cannot create '%s'.\n", clkidef.name);
|
||||
device_printf(sc->dev, "Cannot create '%s'.\n", clkidef.name);
|
||||
return (ENXIO);
|
||||
}
|
||||
clksc = clknode_get_softc(clk);
|
||||
clksc->base_dev = dev;
|
||||
clksc->base_dev = sc->dev;
|
||||
clknode_register(clkdom, clk);
|
||||
|
||||
memset(&clkidef, 0, sizeof(clkidef));
|
||||
@ -129,16 +129,16 @@ rk8xx_export_clocks(device_t dev)
|
||||
clkidef.name = (nclks = 2) ? clknames[1] : "clk32kout2";
|
||||
clk = clknode_create(clkdom, &rk8xx_clk_clknode_class_1, &clkidef);
|
||||
if (clk == NULL) {
|
||||
device_printf(dev, "Cannot create '%s'.\n", clkidef.name);
|
||||
device_printf(sc->dev, "Cannot create '%s'.\n", clkidef.name);
|
||||
return (ENXIO);
|
||||
}
|
||||
clksc = clknode_get_softc(clk);
|
||||
clksc->base_dev = dev;
|
||||
clksc->base_dev = sc->dev;
|
||||
clknode_register(clkdom, clk);
|
||||
|
||||
rv = clkdom_finit(clkdom);
|
||||
if (rv != 0) {
|
||||
device_printf(dev, "Cannot finalize clkdom initialization: "
|
||||
device_printf(sc->dev, "Cannot finalize clkdom initialization: "
|
||||
"%d\n", rv);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ static regnode_method_t rk8xx_regnode_methods[] = {
|
||||
DEFINE_CLASS_1(rk8xx_regnode, rk8xx_regnode_class, rk8xx_regnode_methods,
|
||||
sizeof(struct rk8xx_reg_sc), regnode_class);
|
||||
|
||||
struct rk8xx_reg_sc *
|
||||
static struct rk8xx_reg_sc *
|
||||
rk8xx_reg_attach(device_t dev, phandle_t node,
|
||||
struct rk8xx_regdef *def)
|
||||
{
|
||||
@ -270,6 +270,42 @@ rk8xx_reg_attach(device_t dev, phandle_t node,
|
||||
return (reg_sc);
|
||||
}
|
||||
|
||||
void
|
||||
rk8xx_attach_regulators(struct rk8xx_softc *sc)
|
||||
{
|
||||
struct rk8xx_reg_sc *reg;
|
||||
struct reg_list *regp;
|
||||
phandle_t rnode, child;
|
||||
int i;
|
||||
|
||||
TAILQ_INIT(&sc->regs);
|
||||
|
||||
rnode = ofw_bus_find_child(ofw_bus_get_node(sc->dev), "regulators");
|
||||
if (rnode > 0) {
|
||||
for (i = 0; i < sc->nregs; i++) {
|
||||
child = ofw_bus_find_child(rnode,
|
||||
sc->regdefs[i].name);
|
||||
if (child == 0)
|
||||
continue;
|
||||
if (OF_hasprop(child, "regulator-name") != 1)
|
||||
continue;
|
||||
reg = rk8xx_reg_attach(sc->dev, child, &sc->regdefs[i]);
|
||||
if (reg == NULL) {
|
||||
device_printf(sc->dev,
|
||||
"cannot attach regulator %s\n",
|
||||
sc->regdefs[i].name);
|
||||
continue;
|
||||
}
|
||||
regp = malloc(sizeof(*regp), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
regp->reg = reg;
|
||||
TAILQ_INSERT_TAIL(&sc->regs, regp, next);
|
||||
if (bootverbose)
|
||||
device_printf(sc->dev, "Regulator %s attached\n",
|
||||
sc->regdefs[i].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rk8xx_map(device_t dev, phandle_t xref, int ncells,
|
||||
pcell_t *cells, intptr_t *id)
|
||||
|
Loading…
Reference in New Issue
Block a user