Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Aug 2022 07:56:20 GMT
From:      Ganbold Tsagaankhuu <ganbold@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 66a3e513412a - main - Add RockChip rk809/rk817 pmic support to existing RockChip pmic drivers.
Message-ID:  <202208160756.27G7uK0L041111@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by ganbold:

URL: https://cgit.FreeBSD.org/src/commit/?id=66a3e513412a818ea802f994c08c2d307f439d81

commit 66a3e513412a818ea802f994c08c2d307f439d81
Author:     Søren Schmidt <sos@FreeBSD.org>
AuthorDate: 2022-08-16 07:55:18 +0000
Commit:     Ganbold Tsagaankhuu <ganbold@FreeBSD.org>
CommitDate: 2022-08-16 07:55:18 +0000

    Add RockChip rk809/rk817 pmic support to existing
    RockChip pmic drivers.
    
    Reviewed by:    manu
    Differential Revision:  https://reviews.freebsd.org/D36149
---
 sys/dev/iicbus/pmic/rockchip/rk817.c            | 532 ++++++++++++++++++++++++
 sys/dev/iicbus/pmic/rockchip/rk817reg.h         | 121 ++++++
 sys/dev/iicbus/pmic/rockchip/rk8xx.c            |  15 +-
 sys/dev/iicbus/pmic/rockchip/rk8xx.h            |   6 +
 sys/dev/iicbus/pmic/rockchip/rk8xx_regulators.c |  58 ++-
 sys/dev/iicbus/pmic/rockchip/rk8xx_rtc.c        |  14 +
 6 files changed, 738 insertions(+), 8 deletions(-)

diff --git a/sys/dev/iicbus/pmic/rockchip/rk817.c b/sys/dev/iicbus/pmic/rockchip/rk817.c
new file mode 100644
index 000000000000..54431aaa4735
--- /dev/null
+++ b/sys/dev/iicbus/pmic/rockchip/rk817.c
@@ -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);
diff --git a/sys/dev/iicbus/pmic/rockchip/rk817reg.h b/sys/dev/iicbus/pmic/rockchip/rk817reg.h
new file mode 100644
index 000000000000..607243826d04
--- /dev/null
+++ b/sys/dev/iicbus/pmic/rockchip/rk817reg.h
@@ -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_ */
diff --git a/sys/dev/iicbus/pmic/rockchip/rk8xx.c b/sys/dev/iicbus/pmic/rockchip/rk8xx.c
index 0e6839ff0152..bf6e5833665a 100644
--- a/sys/dev/iicbus/pmic/rockchip/rk8xx.c
+++ b/sys/dev/iicbus/pmic/rockchip/rk8xx.c
@@ -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);
 
diff --git a/sys/dev/iicbus/pmic/rockchip/rk8xx.h b/sys/dev/iicbus/pmic/rockchip/rk8xx.h
index 739b57c5f0bb..0edd0fd7fe24 100644
--- a/sys/dev/iicbus/pmic/rockchip/rk8xx.h
+++ b/sys/dev/iicbus/pmic/rockchip/rk8xx.h
@@ -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 {
diff --git a/sys/dev/iicbus/pmic/rockchip/rk8xx_regulators.c b/sys/dev/iicbus/pmic/rockchip/rk8xx_regulators.c
index 74bf2ab6ff73..be214228e817 100644
--- a/sys/dev/iicbus/pmic/rockchip/rk8xx_regulators.c
+++ b/sys/dev/iicbus/pmic/rockchip/rk8xx_regulators.c
@@ -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);
diff --git a/sys/dev/iicbus/pmic/rockchip/rk8xx_rtc.c b/sys/dev/iicbus/pmic/rockchip/rk8xx_rtc.c
index 2f755d16b164..91991b4f41be 100644
--- a/sys/dev/iicbus/pmic/rockchip/rk8xx_rtc.c
+++ b/sys/dev/iicbus/pmic/rockchip/rk8xx_rtc.c
@@ -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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202208160756.27G7uK0L041111>