mirror of
https://github.com/opnsense/src.git
synced 2026-06-04 22:32:43 -04:00
Add RockChip rk809/rk817 pmic support to existing
RockChip pmic drivers. Reviewed by: manu Differential Revision: https://reviews.freebsd.org/D36149
This commit is contained in:
parent
b80572fe3b
commit
66a3e51341
6 changed files with 738 additions and 8 deletions
532
sys/dev/iicbus/pmic/rockchip/rk817.c
Normal file
532
sys/dev/iicbus/pmic/rockchip/rk817.c
Normal file
|
|
@ -0,0 +1,532 @@
|
|||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSS
|
||||
*
|
||||
* Copyright (c) 2021, 2022 Soren Schmidt <sos@deepcore.dk>
|
||||
*
|
||||
* 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/rk817reg.h>
|
||||
#include <dev/iicbus/pmic/rockchip/rk8xx.h>
|
||||
|
||||
|
||||
static struct ofw_compat_data compat_data[] = {
|
||||
{"rockchip,rk809", RK809},
|
||||
{"rockchip,rk817", RK817},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
static struct rk8xx_regdef rk809_regdefs[] = {
|
||||
{
|
||||
.id = RK809_DCDC1,
|
||||
.name = "DCDC_REG1",
|
||||
.enable_reg = RK817_DCDC_EN,
|
||||
.enable_mask = 0x11,
|
||||
.voltage_reg = RK817_DCDC1_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 500000,
|
||||
.voltage_max = 1487500,
|
||||
.voltage_min2 = 1500000,
|
||||
.voltage_max2 = 2400000,
|
||||
.voltage_step = 12500,
|
||||
.voltage_step2 = 100000,
|
||||
.voltage_nstep = 177,
|
||||
},
|
||||
{
|
||||
.id = RK809_DCDC2,
|
||||
.name = "DCDC_REG2",
|
||||
.enable_reg = RK817_DCDC_EN,
|
||||
.enable_mask = 0x22,
|
||||
.voltage_reg = RK817_DCDC2_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 500000,
|
||||
.voltage_max = 1487500,
|
||||
.voltage_min2 = 1500000,
|
||||
.voltage_max2 = 2400000,
|
||||
.voltage_step = 12500,
|
||||
.voltage_step2 = 100000,
|
||||
.voltage_nstep = 177,
|
||||
},
|
||||
{
|
||||
.id = RK809_DCDC3,
|
||||
.name = "DCDC_REG3",
|
||||
.enable_reg = RK817_DCDC_EN,
|
||||
.enable_mask = 0x44,
|
||||
.voltage_reg = RK817_DCDC3_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 500000,
|
||||
.voltage_max = 1487500,
|
||||
.voltage_min2 = 1500000,
|
||||
.voltage_max2 = 2400000,
|
||||
.voltage_step = 12500,
|
||||
.voltage_step2 = 100000,
|
||||
.voltage_nstep = 177,
|
||||
},
|
||||
{
|
||||
.id = RK809_DCDC4,
|
||||
.name = "DCDC_REG4",
|
||||
.enable_reg = RK817_DCDC_EN,
|
||||
.enable_mask = 0x88,
|
||||
.voltage_reg = RK817_DCDC4_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 500000,
|
||||
.voltage_max = 1487500,
|
||||
.voltage_min2 = 1500000,
|
||||
.voltage_max2 = 3400000,
|
||||
.voltage_step = 12500,
|
||||
.voltage_step2 = 100000,
|
||||
.voltage_nstep = 195,
|
||||
},
|
||||
{
|
||||
.id = RK809_DCDC5,
|
||||
.name = "DCDC_REG5",
|
||||
.enable_reg = RK817_LDO_EN3,
|
||||
.enable_mask = 0x22,
|
||||
.voltage_reg = RK817_BOOST_ON_VSEL,
|
||||
.voltage_mask = 0x07,
|
||||
.voltage_min = 1600000, /* cheat is 1.5V */
|
||||
.voltage_max = 3400000,
|
||||
.voltage_min2 = 3500000,
|
||||
.voltage_max2 = 3600000,
|
||||
.voltage_step = 200000,
|
||||
.voltage_step2 = 300000,
|
||||
.voltage_nstep = 8,
|
||||
},
|
||||
{
|
||||
.id = RK809_LDO1,
|
||||
.name = "LDO_REG1",
|
||||
.enable_reg = RK817_LDO_EN1,
|
||||
.enable_mask = 0x11,
|
||||
.voltage_reg = RK817_LDO1_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK809_LDO2,
|
||||
.name = "LDO_REG2",
|
||||
.enable_reg = RK817_LDO_EN1,
|
||||
.enable_mask = 0x22,
|
||||
.voltage_reg = RK817_LDO2_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK809_LDO3,
|
||||
.name = "LDO_REG3",
|
||||
.enable_reg = RK817_LDO_EN1,
|
||||
.enable_mask = 0x44,
|
||||
.voltage_reg = RK817_LDO3_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK809_LDO4,
|
||||
.name = "LDO_REG4",
|
||||
.enable_reg = RK817_LDO_EN1,
|
||||
.enable_mask = 0x88,
|
||||
.voltage_reg = RK817_LDO4_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK809_LDO5,
|
||||
.name = "LDO_REG5",
|
||||
.enable_reg = RK817_LDO_EN2,
|
||||
.enable_mask = 0x11,
|
||||
.voltage_reg = RK817_LDO5_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK809_LDO6,
|
||||
.name = "LDO_REG6",
|
||||
.enable_reg = RK817_LDO_EN2,
|
||||
.enable_mask = 0x22,
|
||||
.voltage_reg = RK817_LDO6_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK809_LDO7,
|
||||
.name = "LDO_REG7",
|
||||
.enable_reg = RK817_LDO_EN2,
|
||||
.enable_mask = 0x44,
|
||||
.voltage_reg = RK817_LDO7_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK809_LDO8,
|
||||
.name = "LDO_REG8",
|
||||
.enable_reg = RK817_LDO_EN2,
|
||||
.enable_mask = 0x88,
|
||||
.voltage_reg = RK817_LDO8_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK809_LDO9,
|
||||
.name = "LDO_REG9",
|
||||
.enable_reg = RK817_LDO_EN3,
|
||||
.enable_mask = 0x11,
|
||||
.voltage_reg = RK817_LDO9_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK809_SWITCH1,
|
||||
.name = "SWITCH_REG1",
|
||||
.enable_reg = RK817_LDO_EN3,
|
||||
.enable_mask = 0x44,
|
||||
.voltage_min = 3300000,
|
||||
.voltage_max = 3300000,
|
||||
.voltage_nstep = 0,
|
||||
},
|
||||
{
|
||||
.id = RK809_SWITCH2,
|
||||
.name = "SWITCH_REG2",
|
||||
.enable_reg = RK817_LDO_EN3,
|
||||
.enable_mask = 0x88,
|
||||
.voltage_min = 3300000,
|
||||
.voltage_max = 3300000,
|
||||
.voltage_nstep = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct rk8xx_regdef rk817_regdefs[] = {
|
||||
{
|
||||
.id = RK817_DCDC1,
|
||||
.name = "DCDC_REG1",
|
||||
.enable_reg = RK817_DCDC_EN,
|
||||
.enable_mask = 0x11,
|
||||
.voltage_reg = RK817_DCDC1_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 500000,
|
||||
.voltage_max = 1487500,
|
||||
.voltage_min2 = 1500000,
|
||||
.voltage_max2 = 2400000,
|
||||
.voltage_step = 12500,
|
||||
.voltage_step2 = 100000,
|
||||
.voltage_nstep = 177,
|
||||
},
|
||||
{
|
||||
.id = RK817_DCDC2,
|
||||
.name = "DCDC_REG2",
|
||||
.enable_reg = RK817_DCDC_EN,
|
||||
.enable_mask = 0x22,
|
||||
.voltage_reg = RK817_DCDC2_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 500000,
|
||||
.voltage_max = 1487500,
|
||||
.voltage_min2 = 1500000,
|
||||
.voltage_max2 = 2400000,
|
||||
.voltage_step = 12500,
|
||||
.voltage_step2 = 100000,
|
||||
.voltage_nstep = 177,
|
||||
},
|
||||
{
|
||||
.id = RK817_DCDC3,
|
||||
.name = "DCDC_REG3",
|
||||
.enable_reg = RK817_DCDC_EN,
|
||||
.enable_mask = 0x44,
|
||||
.voltage_reg = RK817_DCDC3_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 500000,
|
||||
.voltage_max = 1487500,
|
||||
.voltage_min2 = 1500000,
|
||||
.voltage_max2 = 2400000,
|
||||
.voltage_step = 12500,
|
||||
.voltage_step2 = 100000,
|
||||
.voltage_nstep = 177,
|
||||
},
|
||||
{
|
||||
.id = RK817_DCDC4,
|
||||
.name = "DCDC_REG4",
|
||||
.enable_reg = RK817_DCDC_EN,
|
||||
.enable_mask = 0x88,
|
||||
.voltage_reg = RK817_DCDC4_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 500000,
|
||||
.voltage_max = 1487500,
|
||||
.voltage_min2 = 1500000,
|
||||
.voltage_max2 = 3400000,
|
||||
.voltage_step = 12500,
|
||||
.voltage_step2 = 100000,
|
||||
.voltage_nstep = 195,
|
||||
},
|
||||
{
|
||||
.id = RK817_LDO1,
|
||||
.name = "LDO_REG1",
|
||||
.enable_reg = RK817_LDO_EN1,
|
||||
.enable_mask = 0x11,
|
||||
.voltage_reg = RK817_LDO1_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK817_LDO2,
|
||||
.name = "LDO_REG2",
|
||||
.enable_reg = RK817_LDO_EN1,
|
||||
.enable_mask = 0x22,
|
||||
.voltage_reg = RK817_LDO2_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK817_LDO3,
|
||||
.name = "LDO_REG3",
|
||||
.enable_reg = RK817_LDO_EN1,
|
||||
.enable_mask = 0x44,
|
||||
.voltage_reg = RK817_LDO3_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK817_LDO4,
|
||||
.name = "LDO_REG4",
|
||||
.enable_reg = RK817_LDO_EN1,
|
||||
.enable_mask = 0x88,
|
||||
.voltage_reg = RK817_LDO4_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK817_LDO5,
|
||||
.name = "LDO_REG5",
|
||||
.enable_reg = RK817_LDO_EN2,
|
||||
.enable_mask = 0x11,
|
||||
.voltage_reg = RK817_LDO5_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK817_LDO6,
|
||||
.name = "LDO_REG6",
|
||||
.enable_reg = RK817_LDO_EN2,
|
||||
.enable_mask = 0x22,
|
||||
.voltage_reg = RK817_LDO6_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK817_LDO7,
|
||||
.name = "LDO_REG7",
|
||||
.enable_reg = RK817_LDO_EN2,
|
||||
.enable_mask = 0x44,
|
||||
.voltage_reg = RK817_LDO7_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK817_LDO8,
|
||||
.name = "LDO_REG8",
|
||||
.enable_reg = RK817_LDO_EN2,
|
||||
.enable_mask = 0x88,
|
||||
.voltage_reg = RK817_LDO8_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK817_LDO9,
|
||||
.name = "LDO_REG9",
|
||||
.enable_reg = RK817_LDO_EN3,
|
||||
.enable_mask = 0x11,
|
||||
.voltage_reg = RK817_LDO9_ON_VSEL,
|
||||
.voltage_mask = 0x7f,
|
||||
.voltage_min = 600000,
|
||||
.voltage_max = 3400000,
|
||||
.voltage_step = 25000,
|
||||
.voltage_nstep = 112,
|
||||
},
|
||||
{
|
||||
.id = RK817_BOOST,
|
||||
.name = "BOOST",
|
||||
.enable_reg = RK817_LDO_EN3,
|
||||
.enable_mask = 0x22,
|
||||
.voltage_reg = RK817_BOOST_ON_VSEL,
|
||||
.voltage_mask = 0x07,
|
||||
.voltage_min = 4700000,
|
||||
.voltage_max = 5400000,
|
||||
.voltage_step = 100000,
|
||||
.voltage_nstep = 8,
|
||||
},
|
||||
{
|
||||
.id = RK817_OTG_SWITCH,
|
||||
.name = "OTG_SWITCH",
|
||||
.enable_reg = RK817_LDO_EN3,
|
||||
.enable_mask = 0x44,
|
||||
.voltage_nstep = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
rk817_probe(device_t dev)
|
||||
{
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
|
||||
case RK809:
|
||||
device_set_desc(dev, "RockChip RK809 PMIC");
|
||||
break;
|
||||
case RK817:
|
||||
device_set_desc(dev, "RockChip RK817 PMIC");
|
||||
break;
|
||||
default:
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
rk817_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;
|
||||
switch (sc->type) {
|
||||
case RK809:
|
||||
sc->regdefs = rk809_regdefs;
|
||||
sc->nregs = nitems(rk809_regdefs);
|
||||
break;
|
||||
case RK817:
|
||||
sc->regdefs = rk817_regdefs;
|
||||
sc->nregs = nitems(rk817_regdefs);
|
||||
break;
|
||||
default:
|
||||
device_printf(dev, "Unknown type %d\n", sc->type);
|
||||
return (ENXIO);
|
||||
}
|
||||
sc->rtc_regs.secs = RK817_RTC_SECONDS;
|
||||
sc->rtc_regs.secs_mask = RK817_RTC_SECONDS_MASK;
|
||||
sc->rtc_regs.minutes = RK817_RTC_MINUTES;
|
||||
sc->rtc_regs.minutes_mask = RK817_RTC_MINUTES_MASK;
|
||||
sc->rtc_regs.hours = RK817_RTC_HOURS;
|
||||
sc->rtc_regs.hours_mask = RK817_RTC_HOURS_MASK;
|
||||
sc->rtc_regs.days = RK817_RTC_DAYS;
|
||||
sc->rtc_regs.days_mask = RK817_RTC_DAYS_MASK;
|
||||
sc->rtc_regs.months = RK817_RTC_MONTHS;
|
||||
sc->rtc_regs.months_mask = RK817_RTC_MONTHS_MASK;
|
||||
sc->rtc_regs.years = RK817_RTC_YEARS;
|
||||
sc->rtc_regs.weeks = RK817_RTC_WEEKS_MASK;
|
||||
sc->rtc_regs.ctrl = RK817_RTC_CTRL;
|
||||
sc->rtc_regs.ctrl_stop_mask = RK817_RTC_CTRL_STOP;
|
||||
sc->rtc_regs.ctrl_ampm_mask = RK817_RTC_AMPM_MODE;
|
||||
sc->rtc_regs.ctrl_gettime_mask = RK817_RTC_GET_TIME;
|
||||
sc->rtc_regs.ctrl_readsel_mask = RK817_RTC_READSEL;
|
||||
sc->dev_ctrl.dev_ctrl_reg = RK817_SYS_CFG3;
|
||||
sc->dev_ctrl.pwr_off_mask = RK817_SYS_CFG3_OFF;
|
||||
sc->dev_ctrl.pwr_rst_mask = RK817_SYS_CFG3_RST;
|
||||
|
||||
return (rk8xx_attach(sc));
|
||||
}
|
||||
|
||||
static device_method_t rk817_methods[] = {
|
||||
DEVMETHOD(device_probe, rk817_probe),
|
||||
DEVMETHOD(device_attach, rk817_attach),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS_1(rk817_pmu, rk817_driver, rk817_methods,
|
||||
sizeof(struct rk8xx_softc), rk8xx_driver);
|
||||
|
||||
EARLY_DRIVER_MODULE(rk817_pmu, iicbus, rk817_driver, 0, 0,
|
||||
BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST);
|
||||
EARLY_DRIVER_MODULE(iicbus, rk817_pmu, iicbus_driver, 0, 0,
|
||||
BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST);
|
||||
MODULE_DEPEND(rk817_pmu, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
|
||||
MODULE_VERSION(rk817_pmu, 1);
|
||||
121
sys/dev/iicbus/pmic/rockchip/rk817reg.h
Normal file
121
sys/dev/iicbus/pmic/rockchip/rk817reg.h
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBS
|
||||
*
|
||||
* Copyright (c) 2021, 2022 Soren Schmidt <sos@deepcore.dk>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _RK817REG_H_
|
||||
#define _RK817REG_H_
|
||||
|
||||
#define RK817_RTC_SECONDS 0x00
|
||||
#define RK817_RTC_SECONDS_MASK 0x7f
|
||||
#define RK817_RTC_MINUTES 0x01
|
||||
#define RK817_RTC_MINUTES_MASK 0x7f
|
||||
#define RK817_RTC_HOURS 0x02
|
||||
#define RK817_RTC_HOURS_MASK 0x3f
|
||||
#define RK817_RTC_DAYS 0x03
|
||||
#define RK817_RTC_DAYS_MASK 0x3f
|
||||
#define RK817_RTC_MONTHS 0x04
|
||||
#define RK817_RTC_MONTHS_MASK 0x1f
|
||||
#define RK817_RTC_YEARS 0x05
|
||||
#define RK817_RTC_WEEKS 0x06
|
||||
#define RK817_RTC_WEEKS_MASK 0x07
|
||||
#define RK817_ALARM_SECONDS 0x7
|
||||
#define RK817_ALARM_MINUTES 0x8
|
||||
#define RK817_ALARM_HOURS 0x9
|
||||
#define RK817_ALARM_DAYS 0xA
|
||||
#define RK817_ALARM_MONTHS 0xB
|
||||
#define RK817_ALARM_YEARS 0xC
|
||||
#define RK817_RTC_CTRL 0x0d
|
||||
#define RK817_RTC_CTRL_STOP (1 << 0)
|
||||
#define RK817_RTC_AMPM_MODE (1 << 3)
|
||||
#define RK817_RTC_GET_TIME (1 << 6)
|
||||
#define RK817_RTC_READSEL (1 << 7)
|
||||
#define RK817_RTC_STATUS 0x0e
|
||||
#define RK817_RTC_INT 0x0f
|
||||
#define RK817_RTC_COMP_LSB 0x10
|
||||
#define RK817_RTC_COMP_MSB 0x11
|
||||
|
||||
#define RK817_DCDC_EN 0xb1
|
||||
#define RK817_LDO_EN1 0xb2
|
||||
#define RK817_LDO_EN2 0xb3
|
||||
#define RK817_LDO_EN3 0xb4
|
||||
#define RK817_DCDC1_ON_VSEL 0xbb
|
||||
#define RK817_DCDC2_ON_VSEL 0xbe
|
||||
#define RK817_DCDC3_ON_VSEL 0xc1
|
||||
#define RK817_DCDC4_ON_VSEL 0xc4
|
||||
#define RK817_LDO1_ON_VSEL 0xcc
|
||||
#define RK817_LDO2_ON_VSEL 0xce
|
||||
#define RK817_LDO3_ON_VSEL 0xd0
|
||||
#define RK817_LDO4_ON_VSEL 0xd2
|
||||
#define RK817_LDO5_ON_VSEL 0xd4
|
||||
#define RK817_LDO6_ON_VSEL 0xd6
|
||||
#define RK817_LDO7_ON_VSEL 0xd8
|
||||
#define RK817_LDO8_ON_VSEL 0xda
|
||||
#define RK817_LDO9_ON_VSEL 0xdc
|
||||
#define RK817_BOOST_ON_VSEL 0xde
|
||||
#define RK817_SYS_CFG3 0xf4
|
||||
#define RK817_SYS_CFG3_OFF (1 << 0)
|
||||
#define RK817_SYS_CFG3_SLP (1 << 1)
|
||||
#define RK817_SYS_CFG3_RST (1 << 2)
|
||||
|
||||
enum rk809_regulator {
|
||||
RK809_DCDC1 = 0,
|
||||
RK809_DCDC2,
|
||||
RK809_DCDC3,
|
||||
RK809_DCDC4,
|
||||
RK809_DCDC5,
|
||||
RK809_LDO1,
|
||||
RK809_LDO2,
|
||||
RK809_LDO3,
|
||||
RK809_LDO4,
|
||||
RK809_LDO5,
|
||||
RK809_LDO6,
|
||||
RK809_LDO7,
|
||||
RK809_LDO8,
|
||||
RK809_LDO9,
|
||||
RK809_SWITCH1,
|
||||
RK809_SWITCH2,
|
||||
};
|
||||
|
||||
enum rk817_regulator {
|
||||
RK817_DCDC1 = 0,
|
||||
RK817_DCDC2,
|
||||
RK817_DCDC3,
|
||||
RK817_DCDC4,
|
||||
RK817_LDO1,
|
||||
RK817_LDO2,
|
||||
RK817_LDO3,
|
||||
RK817_LDO4,
|
||||
RK817_LDO5,
|
||||
RK817_LDO6,
|
||||
RK817_LDO7,
|
||||
RK817_LDO8,
|
||||
RK817_LDO9,
|
||||
RK817_BOOST,
|
||||
RK817_OTG_SWITCH,
|
||||
};
|
||||
#endif /* _RK817REG_H_ */
|
||||
|
|
@ -115,7 +115,20 @@ rk8xx_poweroff(void *arg, int howto)
|
|||
device_printf(sc->dev, "Powering off...\n");
|
||||
error = rk8xx_read(sc->dev, sc->dev_ctrl.dev_ctrl_reg, &val, 1);
|
||||
if (error == 0) {
|
||||
val |= sc->dev_ctrl.pwr_off_mask;
|
||||
if (howto & RB_POWEROFF)
|
||||
val |= sc->dev_ctrl.pwr_off_mask;
|
||||
else if (howto & RB_POWERCYCLE) {
|
||||
if (sc->type == RK809 || sc->type == RK817) {
|
||||
if (bootverbose) {
|
||||
device_printf(sc->dev,
|
||||
"Powercycle PMIC\n");
|
||||
}
|
||||
val |= sc->dev_ctrl.pwr_rst_mask;;
|
||||
} else {
|
||||
/* Poweroff PMIC that can't powercycle */
|
||||
val |= sc->dev_ctrl.pwr_off_mask;
|
||||
}
|
||||
}
|
||||
error = rk8xx_write(sc->dev, sc->dev_ctrl.dev_ctrl_reg,
|
||||
&val, 1);
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
enum rk_pmic_type {
|
||||
RK805 = 1,
|
||||
RK808,
|
||||
RK809,
|
||||
RK817,
|
||||
};
|
||||
|
||||
struct rk8xx_regdef {
|
||||
|
|
@ -47,7 +49,10 @@ struct rk8xx_regdef {
|
|||
uint8_t voltage_mask;
|
||||
int voltage_min;
|
||||
int voltage_max;
|
||||
int voltage_min2;
|
||||
int voltage_max2;
|
||||
int voltage_step;
|
||||
int voltage_step2;
|
||||
int voltage_nstep;
|
||||
};
|
||||
|
||||
|
|
@ -88,6 +93,7 @@ struct rk8xx_rtc_reg {
|
|||
struct rk8xx_dev_ctrl {
|
||||
uint8_t dev_ctrl_reg;
|
||||
uint8_t pwr_off_mask;
|
||||
uint8_t pwr_rst_mask;
|
||||
};
|
||||
|
||||
struct rk8xx_softc {
|
||||
|
|
|
|||
|
|
@ -113,11 +113,38 @@ rk8xx_regnode_enable(struct regnode *regnode, bool enable, int *udelay)
|
|||
static void
|
||||
rk8xx_regnode_reg_to_voltage(struct rk8xx_reg_sc *sc, uint8_t val, int *uv)
|
||||
{
|
||||
if (val < sc->def->voltage_nstep)
|
||||
*uv = sc->def->voltage_min + val * sc->def->voltage_step;
|
||||
else
|
||||
*uv = sc->def->voltage_min +
|
||||
(sc->def->voltage_nstep * sc->def->voltage_step);
|
||||
struct rk8xx_softc *sc1;
|
||||
|
||||
sc1 = device_get_softc(sc->base_dev);
|
||||
if (sc1->type == RK809 || sc1->type == RK817) {
|
||||
if (sc->def->voltage_step2) {
|
||||
int change;
|
||||
|
||||
change =
|
||||
((sc->def->voltage_min2 - sc->def->voltage_min) /
|
||||
sc->def->voltage_step);
|
||||
if (val > change) {
|
||||
if (val < sc->def->voltage_nstep) {
|
||||
*uv = sc->def->voltage_min2 +
|
||||
(val - change) *
|
||||
sc->def->voltage_step2;
|
||||
} else
|
||||
*uv = sc->def->voltage_max2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (val < sc->def->voltage_nstep)
|
||||
*uv = sc->def->voltage_min + val * sc->def->voltage_step;
|
||||
else
|
||||
*uv = sc->def->voltage_max;
|
||||
|
||||
} else {
|
||||
if (val < sc->def->voltage_nstep)
|
||||
*uv = sc->def->voltage_min + val * sc->def->voltage_step;
|
||||
else
|
||||
*uv = sc->def->voltage_min +
|
||||
(sc->def->voltage_nstep * sc->def->voltage_step);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -126,14 +153,25 @@ rk8xx_regnode_voltage_to_reg(struct rk8xx_reg_sc *sc, int min_uvolt,
|
|||
{
|
||||
uint8_t nval;
|
||||
int nstep, uvolt;
|
||||
struct rk8xx_softc *sc1;
|
||||
|
||||
sc1 = device_get_softc(sc->base_dev);
|
||||
nval = 0;
|
||||
uvolt = sc->def->voltage_min;
|
||||
|
||||
for (nstep = 0; nstep < sc->def->voltage_nstep && uvolt < min_uvolt;
|
||||
nstep++) {
|
||||
++nval;
|
||||
uvolt += sc->def->voltage_step;
|
||||
if (sc1->type == RK809 || sc1->type == RK817) {
|
||||
if (sc->def->voltage_step2) {
|
||||
if (uvolt < sc->def->voltage_min2)
|
||||
uvolt += sc->def->voltage_step;
|
||||
else
|
||||
uvolt += sc->def->voltage_step2;
|
||||
} else
|
||||
uvolt += sc->def->voltage_step;
|
||||
} else
|
||||
uvolt += sc->def->voltage_step;
|
||||
}
|
||||
if (uvolt > max_uvolt)
|
||||
return (EINVAL);
|
||||
|
|
@ -163,10 +201,12 @@ rk8xx_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
|
|||
int max_uvolt, int *udelay)
|
||||
{
|
||||
struct rk8xx_reg_sc *sc;
|
||||
uint8_t val;
|
||||
uint8_t val, old;
|
||||
int uvolt;
|
||||
struct rk8xx_softc *sc1;
|
||||
|
||||
sc = regnode_get_softc(regnode);
|
||||
sc1 = device_get_softc(sc->base_dev);
|
||||
|
||||
if (!sc->def->voltage_step)
|
||||
return (ENXIO);
|
||||
|
|
@ -176,9 +216,13 @@ rk8xx_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
|
|||
min_uvolt,
|
||||
max_uvolt);
|
||||
rk8xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
|
||||
old = val;
|
||||
if (rk8xx_regnode_voltage_to_reg(sc, min_uvolt, max_uvolt, &val) != 0)
|
||||
return (ERANGE);
|
||||
|
||||
if (sc1->type == RK809 || sc1->type == RK817)
|
||||
val |= (old &= ~sc->def->voltage_mask);
|
||||
|
||||
rk8xx_write(sc->base_dev, sc->def->voltage_reg, &val, 1);
|
||||
|
||||
rk8xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
|
||||
|
|
|
|||
|
|
@ -61,6 +61,10 @@ rk8xx_gettime(device_t dev, struct timespec *ts)
|
|||
error = rk8xx_write(dev, sc->rtc_regs.ctrl, &ctrl, 1);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (sc->type == RK809 || sc->type == RK817) {
|
||||
/* wait one 32khz cycle for clock shadow registers to latch */
|
||||
DELAY(1000000 / 32000);
|
||||
}
|
||||
ctrl &= ~sc->rtc_regs.ctrl_gettime_mask;
|
||||
error = rk8xx_write(dev, sc->rtc_regs.ctrl, &ctrl, 1);
|
||||
if (error != 0)
|
||||
|
|
@ -91,6 +95,8 @@ rk8xx_gettime(device_t dev, struct timespec *ts)
|
|||
if (bct.dow == 7)
|
||||
bct.dow = 0;
|
||||
bct.ispm = 0;
|
||||
if (sc->type == RK809 || sc->type == RK817)
|
||||
bct.year += 0x2000; /* valid for 2000-2099 only */
|
||||
|
||||
if (bootverbose)
|
||||
device_printf(dev, "Read RTC: %02x-%02x-%02x %02x:%02x:%02x\n",
|
||||
|
|
@ -113,6 +119,14 @@ rk8xx_settime(device_t dev, struct timespec *ts)
|
|||
clock_ts_to_bcd(ts, &bct, false);
|
||||
|
||||
/* This works as long as RK805_RTC_SECS = 0 */
|
||||
if (sc->type == RK809 || sc->type == RK817) {
|
||||
/* valid for 2000-2099 only */
|
||||
if ((bct.year & 0xff00) != 0x2000) {
|
||||
device_printf(dev, "year out of range\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
bct.year &= 0x00ff;
|
||||
}
|
||||
data[sc->rtc_regs.years] = bct.year;
|
||||
data[sc->rtc_regs.months] = bct.mon;
|
||||
data[sc->rtc_regs.days] = bct.day;
|
||||
|
|
|
|||
Loading…
Reference in a new issue