mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/7] rockchip: add RK808 support
@ 2024-10-15 11:10 Sascha Hauer
  2024-10-15 11:10 ` [PATCH 1/7] spi: add rockchip spi controller support Sascha Hauer
                   ` (7 more replies)
  0 siblings, 8 replies; 19+ messages in thread
From: Sascha Hauer @ 2024-10-15 11:10 UTC (permalink / raw)
  To: open list:BAREBOX

This series adds support for the RK808 PMIC found on several Rockchip
boards. Unlike the earlier versions of this PMIC this one comes with
SPI support. As we do not have a Rockchip SPI driver yet, this is added
in this series as well.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Sascha Hauer (7):
      spi: add rockchip spi controller support
      mfd: mx13xxx: drop unnecessary ifdefs
      mfd: rk808: factor out common probe function
      mfd: rk808: update header file from kernel
      mfd: rk808: add support for RK806
      regulator: add regulator_register()
      regulator: rk808: update from kernel

 drivers/mfd/Kconfig                 |    4 +-
 drivers/mfd/mc13xxx.c               |    4 -
 drivers/mfd/rk808.c                 |  217 +++++--
 drivers/regulator/core.c            |   37 ++
 drivers/regulator/rk808-regulator.c | 1085 ++++++++++++++++++++++-------------
 drivers/spi/Makefile                |    1 +
 drivers/spi/spi-rockchip.c          |  584 +++++++++++++++++++
 include/linux/mfd/rk808.h           |  661 ++++++++++++++++++++-
 include/regulator.h                 |   36 ++
 include/spi/spi.h                   |    7 +
 10 files changed, 2165 insertions(+), 471 deletions(-)
---
base-commit: 7b76ca36ccbe4ee992d44ea5c5c5203a93bb672f
change-id: 20241015-rockchip-spi-rk808-da8326d12ba8

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 1/7] spi: add rockchip spi controller support
  2024-10-15 11:10 [PATCH 0/7] rockchip: add RK808 support Sascha Hauer
@ 2024-10-15 11:10 ` Sascha Hauer
  2024-10-15 11:10 ` [PATCH 2/7] mfd: mx13xxx: drop unnecessary ifdefs Sascha Hauer
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2024-10-15 11:10 UTC (permalink / raw)
  To: open list:BAREBOX

This adds support for the SPI controller found on many Rockchip SoCs.
The driver is based on the corresponding Linux driver as of
Linux-6.12-rc1.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/spi/Makefile       |   1 +
 drivers/spi/spi-rockchip.c | 584 +++++++++++++++++++++++++++++++++++++++++++++
 include/spi/spi.h          |   7 +
 3 files changed, 592 insertions(+)

diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 68a8c4e675..f9aefdfe45 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_SPI_ZYNQ_QSPI) += zynq_qspi.o
 obj-$(CONFIG_SPI_NXP_FLEXSPI) += spi-nxp-fspi.o
 obj-$(CONFIG_DRIVER_SPI_STM32) += stm32_spi.o
 obj-$(CONFIG_SPI_SIFIVE) += spi-sifive.o
+obj-y += spi-rockchip.o
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
new file mode 100644
index 0000000000..1e81e9393f
--- /dev/null
+++ b/drivers/spi/spi-rockchip.c
@@ -0,0 +1,584 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Addy Ke <addy.ke@rock-chips.com>
+ */
+
+#include <common.h>
+#include <linux/clk.h>
+#include <driver.h>
+#include <errno.h>
+#include <spi/spi.h>
+#include <linux/spi/spi-mem.h>
+#include <linux/bitops.h>
+#include <clock.h>
+#include <gpio.h>
+#include <of_gpio.h>
+#include <linux/bitfield.h>
+#include <linux/iopoll.h>
+
+#define DRIVER_NAME "rockchip-spi"
+
+#define ROCKCHIP_SPI_CLR_BITS(reg, bits) \
+		writel_relaxed(readl_relaxed(reg) & ~(bits), reg)
+#define ROCKCHIP_SPI_SET_BITS(reg, bits) \
+		writel_relaxed(readl_relaxed(reg) | (bits), reg)
+
+/* SPI register offsets */
+#define ROCKCHIP_SPI_CTRLR0			0x0000
+#define ROCKCHIP_SPI_CTRLR1			0x0004
+#define ROCKCHIP_SPI_SSIENR			0x0008
+#define ROCKCHIP_SPI_SER			0x000c
+#define ROCKCHIP_SPI_BAUDR			0x0010
+#define ROCKCHIP_SPI_TXFTLR			0x0014
+#define ROCKCHIP_SPI_RXFTLR			0x0018
+#define ROCKCHIP_SPI_TXFLR			0x001c
+#define ROCKCHIP_SPI_RXFLR			0x0020
+#define ROCKCHIP_SPI_SR				0x0024
+#define ROCKCHIP_SPI_IPR			0x0028
+#define ROCKCHIP_SPI_IMR			0x002c
+#define ROCKCHIP_SPI_ISR			0x0030
+#define ROCKCHIP_SPI_RISR			0x0034
+#define ROCKCHIP_SPI_ICR			0x0038
+#define ROCKCHIP_SPI_DMACR			0x003c
+#define ROCKCHIP_SPI_DMATDLR			0x0040
+#define ROCKCHIP_SPI_DMARDLR			0x0044
+#define ROCKCHIP_SPI_VERSION			0x0048
+#define ROCKCHIP_SPI_TXDR			0x0400
+#define ROCKCHIP_SPI_RXDR			0x0800
+
+/* Bit fields in CTRLR0 */
+#define CR0_DFS_OFFSET				0
+#define CR0_DFS_4BIT				0x0
+#define CR0_DFS_8BIT				0x1
+#define CR0_DFS_16BIT				0x2
+
+#define CR0_CFS_OFFSET				2
+
+#define CR0_SCPH_OFFSET				6
+
+#define CR0_SCPOL_OFFSET			7
+
+#define CR0_CSM_OFFSET				8
+#define CR0_CSM_KEEP				0x0
+/* ss_n be high for half sclk_out cycles */
+#define CR0_CSM_HALF				0X1
+/* ss_n be high for one sclk_out cycle */
+#define CR0_CSM_ONE					0x2
+
+/* ss_n to sclk_out delay */
+#define CR0_SSD_OFFSET				10
+/*
+ * The period between ss_n active and
+ * sclk_out active is half sclk_out cycles
+ */
+#define CR0_SSD_HALF				0x0
+/*
+ * The period between ss_n active and
+ * sclk_out active is one sclk_out cycle
+ */
+#define CR0_SSD_ONE					0x1
+
+#define CR0_EM_OFFSET				11
+#define CR0_EM_LITTLE				0x0
+#define CR0_EM_BIG					0x1
+
+#define CR0_FBM_OFFSET				12
+#define CR0_FBM_MSB					0x0
+#define CR0_FBM_LSB					0x1
+
+#define CR0_BHT_OFFSET				13
+#define CR0_BHT_16BIT				0x0
+#define CR0_BHT_8BIT				0x1
+
+#define CR0_RSD_OFFSET				14
+#define CR0_RSD_MAX				0x3
+
+#define CR0_FRF_OFFSET				16
+#define CR0_FRF_SPI					0x0
+#define CR0_FRF_SSP					0x1
+#define CR0_FRF_MICROWIRE			0x2
+
+#define CR0_XFM_OFFSET				18
+#define CR0_XFM_MASK				(0x03 << SPI_XFM_OFFSET)
+#define CR0_XFM_TR					0x0
+#define CR0_XFM_TO					0x1
+#define CR0_XFM_RO					0x2
+
+#define CR0_OPM_OFFSET				20
+#define CR0_OPM_HOST				0x0
+#define CR0_OPM_TARGET				0x1
+
+#define CR0_SOI_OFFSET				23
+
+#define CR0_MTM_OFFSET				0x21
+
+/* Bit fields in SER, 2bit */
+#define SER_MASK					0x3
+
+/* Bit fields in BAUDR */
+#define BAUDR_SCKDV_MIN				2
+#define BAUDR_SCKDV_MAX				65534
+
+/* Bit fields in SR, 6bit */
+#define SR_MASK						0x3f
+#define SR_BUSY						(1 << 0)
+#define SR_TF_FULL					(1 << 1)
+#define SR_TF_EMPTY					(1 << 2)
+#define SR_RF_EMPTY					(1 << 3)
+#define SR_RF_FULL					(1 << 4)
+#define SR_TARGET_TX_BUSY				(1 << 5)
+
+/* Bit fields in ISR, IMR, ISR, RISR, 5bit */
+#define INT_MASK					0x1f
+#define INT_TF_EMPTY				(1 << 0)
+#define INT_TF_OVERFLOW				(1 << 1)
+#define INT_RF_UNDERFLOW			(1 << 2)
+#define INT_RF_OVERFLOW				(1 << 3)
+#define INT_RF_FULL				(1 << 4)
+#define INT_CS_INACTIVE				(1 << 6)
+
+/* Bit fields in ICR, 4bit */
+#define ICR_MASK					0x0f
+#define ICR_ALL						(1 << 0)
+#define ICR_RF_UNDERFLOW			(1 << 1)
+#define ICR_RF_OVERFLOW				(1 << 2)
+#define ICR_TF_OVERFLOW				(1 << 3)
+
+/* Bit fields in DMACR */
+#define RF_DMA_EN					(1 << 0)
+#define TF_DMA_EN					(1 << 1)
+
+/* Driver state flags */
+#define RXDMA					(1 << 0)
+#define TXDMA					(1 << 1)
+
+/* sclk_out: spi host internal logic in rk3x can support 50Mhz */
+#define MAX_SCLK_OUT				50000000U
+
+/*
+ * SPI_CTRLR1 is 16-bits, so we should support lengths of 0xffff + 1. However,
+ * the controller seems to hang when given 0x10000, so stick with this for now.
+ */
+#define ROCKCHIP_SPI_MAX_TRANLEN		0xffff
+
+#define ROCKCHIP_SPI_MAX_NATIVE_CS_NUM		2
+#define ROCKCHIP_SPI_VER2_TYPE1			0x05EC0002
+#define ROCKCHIP_SPI_VER2_TYPE2			0x00110002
+
+#define ROCKCHIP_AUTOSUSPEND_TIMEOUT		2000
+
+struct rockchip_spi {
+	struct spi_controller ctlr;
+	struct device *dev;
+
+	struct clk *spiclk;
+	struct clk *apb_pclk;
+
+	void __iomem *regs;
+
+	/*depth of the FIFO buffer */
+	u32 fifo_len;
+	/* frequency of spiclk */
+	u32 freq;
+
+	u8 rsd;
+
+	bool cs_high_supported; /* native CS supports active-high polarity */
+
+	struct spi_transfer *xfer; /* Store xfer temporarily */
+};
+
+static inline void spi_enable_chip(struct rockchip_spi *rs, bool enable)
+{
+	writel_relaxed((enable ? 1U : 0U), rs->regs + ROCKCHIP_SPI_SSIENR);
+}
+
+static inline void wait_for_tx_idle(struct rockchip_spi *rs, bool target_mode)
+{
+	u64 start = get_time_ns();
+
+	do {
+		if (target_mode) {
+			if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_TARGET_TX_BUSY) &&
+			    !((readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY)))
+				return;
+		} else {
+			if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY))
+				return;
+		}
+	} while (!is_timeout(start, 5 * MSECOND));
+
+	dev_warn(rs->dev, "spi controller is in busy state!\n");
+}
+
+static u32 get_fifo_len(struct rockchip_spi *rs)
+{
+	u32 ver;
+
+	ver = readl_relaxed(rs->regs + ROCKCHIP_SPI_VERSION);
+
+	switch (ver) {
+	case ROCKCHIP_SPI_VER2_TYPE1:
+	case ROCKCHIP_SPI_VER2_TYPE2:
+		return 64;
+	default:
+		return 32;
+	}
+}
+
+static inline struct gpio_desc *spi_get_csgpiod(const struct spi_device *spi, u8 idx)
+{
+	return NULL;
+}
+
+static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
+{
+	struct spi_controller *ctlr = spi->controller;
+	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
+	bool cs_asserted = spi->mode & SPI_CS_HIGH ? !enable : enable;
+
+	if (cs_asserted) {
+		if (spi_get_csgpiod(spi, 0))
+			ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER, 1);
+		else
+			ROCKCHIP_SPI_SET_BITS(rs->regs + ROCKCHIP_SPI_SER,
+					      BIT(spi_get_chipselect(spi, 0)));
+	} else {
+		if (spi_get_csgpiod(spi, 0))
+			ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER, 1);
+		else
+			ROCKCHIP_SPI_CLR_BITS(rs->regs + ROCKCHIP_SPI_SER,
+					      BIT(spi_get_chipselect(spi, 0)));
+	}
+}
+
+static int rockchip_spi_pio(struct rockchip_spi *rs, struct spi_transfer *xfer)
+{
+	int bytes_per_word = xfer->bits_per_word <= 8 ? 1 : 2;
+	const void *txbuf = xfer->tx_buf;
+	void *rxbuf = xfer->rx_buf;
+	int rxwords, txwords;
+
+	txwords = rxwords = xfer->len / bytes_per_word;
+
+	while (1) {
+		unsigned int fifowords = readl_relaxed(rs->regs + ROCKCHIP_SPI_TXFLR);
+		unsigned int tx_free = rs->fifo_len - fifowords;
+
+		if (tx_free && txwords) {
+			u32 txw;
+
+			if (!txbuf)
+				txw = 0;
+			else if (bytes_per_word == 1)
+				txw = *(u8 *)txbuf;
+			else
+				txw = *(u16 *)txbuf;
+
+			writel_relaxed(txw, rs->regs + ROCKCHIP_SPI_TXDR);
+
+			if (txbuf)
+				txbuf += bytes_per_word;
+
+			txwords--;
+		}
+
+		fifowords = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR);
+
+		if (fifowords) {
+			u32 rxw = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR);
+
+			if (rxbuf) {
+				if (bytes_per_word == 1)
+					*(u8 *)rxbuf = (u8)rxw;
+				else
+					*(u16 *)rxbuf = (u16)rxw;
+				rxbuf += bytes_per_word;
+			}
+			
+			rxwords--;
+		}
+
+		if (!rxwords)
+			return 0;
+	}
+}
+
+static int rockchip_spi_config(struct rockchip_spi *rs,
+		struct spi_device *spi, struct spi_transfer *xfer)
+{
+	u32 cr0 = CR0_FRF_SPI  << CR0_FRF_OFFSET
+		| CR0_BHT_8BIT << CR0_BHT_OFFSET
+		| CR0_SSD_ONE  << CR0_SSD_OFFSET
+		| CR0_EM_BIG   << CR0_EM_OFFSET;
+
+	cr0 |= rs->rsd << CR0_RSD_OFFSET;
+	cr0 |= (spi->mode & 0x3U) << CR0_SCPH_OFFSET;
+	if (spi->mode & SPI_LSB_FIRST)
+		cr0 |= CR0_FBM_LSB << CR0_FBM_OFFSET;
+	if (spi->mode & SPI_CS_HIGH)
+		cr0 |= BIT(spi_get_chipselect(spi, 0)) << CR0_SOI_OFFSET;
+
+	if (xfer->rx_buf && xfer->tx_buf)
+		cr0 |= CR0_XFM_TR << CR0_XFM_OFFSET;
+	else if (xfer->rx_buf)
+		cr0 |= CR0_XFM_RO << CR0_XFM_OFFSET;
+
+	cr0 |= CR0_XFM_TR << CR0_XFM_OFFSET;
+
+	switch (xfer->bits_per_word) {
+	case 4:
+		cr0 |= CR0_DFS_4BIT << CR0_DFS_OFFSET;
+		break;
+	case 8:
+		cr0 |= CR0_DFS_8BIT << CR0_DFS_OFFSET;
+		break;
+	case 16:
+		cr0 |= CR0_DFS_16BIT << CR0_DFS_OFFSET;
+		break;
+	default:
+		/* we only whitelist 4, 8 and 16 bit words in
+		 * ctlr->bits_per_word_mask, so this shouldn't
+		 * happen
+		 */
+		dev_err(rs->dev, "unknown bits per word: %d\n",
+			xfer->bits_per_word);
+		return -EINVAL;
+	}
+
+	writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
+
+	/* the hardware only supports an even clock divisor, so
+	 * round divisor = spiclk / speed up to nearest even number
+	 * so that the resulting speed is <= the requested speed
+	 */
+	writel_relaxed(2 * DIV_ROUND_UP(rs->freq, 2 * xfer->speed_hz),
+			rs->regs + ROCKCHIP_SPI_BAUDR);
+
+	return 0;
+}
+
+static size_t rockchip_spi_max_transfer_size(struct spi_device *spi)
+{
+	return ROCKCHIP_SPI_MAX_TRANLEN;
+}
+
+static int rockchip_spi_transfer_one(
+		struct rockchip_spi *rs,
+		struct spi_device *spi,
+		struct spi_transfer *xfer)
+{
+	int ret;
+
+	/* Zero length transfers won't trigger an interrupt on completion */
+	if (!xfer->len)
+		return 1;
+
+	if (!xfer->tx_buf && !xfer->rx_buf) {
+		dev_err(rs->dev, "No buffer for transfer\n");
+		return -EINVAL;
+	}
+
+	if (xfer->len > ROCKCHIP_SPI_MAX_TRANLEN) {
+		dev_err(rs->dev, "Transfer is too long (%d)\n", xfer->len);
+		return -EINVAL;
+	}
+
+	ret = rockchip_spi_config(rs, spi, xfer);
+	if (ret)
+		return ret;
+
+	spi_enable_chip(rs, true);
+	rockchip_spi_pio(rs, xfer);
+	spi_enable_chip(rs, false);
+
+	return 0;
+}
+
+static int rockchip_spi_transfer(struct spi_device *spi_dev, struct spi_message *msg)
+{
+	struct rockchip_spi *rs = spi_controller_get_devdata(spi_dev->controller);
+	struct spi_transfer *t;
+	int ret = 0;
+
+	if (list_empty(&msg->transfers))
+		return 0;
+
+	rockchip_spi_set_cs(spi_dev, true);
+
+	msg->actual_length = 0;
+
+	list_for_each_entry(t, &msg->transfers, transfer_list) {
+		dev_dbg(rs->dev, "  xfer %p: len %u tx %p rx %p\n",
+			t, t->len, t->tx_buf, t->rx_buf);
+
+		ret = rockchip_spi_transfer_one(rs, spi_dev, t);
+		if (ret < 0)
+			goto out;
+		msg->actual_length += t->len;
+	}
+
+out:
+	rockchip_spi_set_cs(spi_dev, false);
+	return ret;
+}
+
+static int rockchip_spi_setup(struct spi_device *spi)
+{
+	struct rockchip_spi *rs = spi_controller_get_devdata(spi->controller);
+	u32 cr0;
+
+	if (!spi_get_csgpiod(spi, 0) && (spi->mode & SPI_CS_HIGH) && !rs->cs_high_supported) {
+		dev_warn(&spi->dev, "setup: non GPIO CS can't be active-high\n");
+		return -EINVAL;
+	}
+
+	cr0 = readl_relaxed(rs->regs + ROCKCHIP_SPI_CTRLR0);
+
+	cr0 &= ~(0x3 << CR0_SCPH_OFFSET);
+	cr0 |= ((spi->mode & 0x3) << CR0_SCPH_OFFSET);
+	if (spi->mode & SPI_CS_HIGH && spi_get_chipselect(spi, 0) <= 1)
+		cr0 |= BIT(spi_get_chipselect(spi, 0)) << CR0_SOI_OFFSET;
+	else if (spi_get_chipselect(spi, 0) <= 1)
+		cr0 &= ~(BIT(spi_get_chipselect(spi, 0)) << CR0_SOI_OFFSET);
+
+	writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
+
+	return 0;
+}
+
+static int rockchip_spi_probe(struct device *dev)
+{
+	int ret;
+	struct rockchip_spi *rs;
+	struct spi_controller *ctlr;
+	struct device_node *np = dev->of_node;
+	u32 rsd_nsecs, num_cs;
+	bool target_mode;
+	struct resource *iores;
+
+	target_mode = of_property_read_bool(np, "spi-slave");
+	if (target_mode)
+		return 0;
+
+	rs = xzalloc(sizeof(*rs));
+	ctlr = &rs->ctlr;
+
+	/* Get basic io resource and map it */
+	iores = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(iores))
+		return PTR_ERR(iores);
+	rs->regs = IOMEM(iores->start);
+
+	rs->apb_pclk = clk_get_enabled(dev, "apb_pclk");
+	if (IS_ERR(rs->apb_pclk)) {
+		dev_err(dev, "Failed to get apb_pclk\n");
+		ret = PTR_ERR(rs->apb_pclk);
+		goto err_put_ctlr;
+	}
+
+	rs->spiclk = clk_get_enabled(dev, "spiclk");
+	if (IS_ERR(rs->spiclk)) {
+		dev_err(dev, "Failed to get spi_pclk\n");
+		ret = PTR_ERR(rs->spiclk);
+		goto err_put_ctlr;
+	}
+
+	spi_enable_chip(rs, false);
+
+	rs->dev = dev;
+	rs->freq = clk_get_rate(rs->spiclk);
+
+	if (!of_property_read_u32(np, "rx-sample-delay-ns",
+				  &rsd_nsecs)) {
+		/* rx sample delay is expressed in parent clock cycles (max 3) */
+		u32 rsd = DIV_ROUND_CLOSEST(rsd_nsecs * (rs->freq >> 8),
+				1000000000 >> 8);
+		if (!rsd) {
+			dev_warn(rs->dev, "%u Hz are too slow to express %u ns delay\n",
+					rs->freq, rsd_nsecs);
+		} else if (rsd > CR0_RSD_MAX) {
+			rsd = CR0_RSD_MAX;
+			dev_warn(rs->dev, "%u Hz are too fast to express %u ns delay, clamping at %u ns\n",
+					rs->freq, rsd_nsecs,
+					CR0_RSD_MAX * 1000000000U / rs->freq);
+		}
+		rs->rsd = rsd;
+	}
+
+	rs->fifo_len = get_fifo_len(rs);
+	if (!rs->fifo_len) {
+		dev_err(dev, "Failed to get fifo length\n");
+		ret = -EINVAL;
+		goto err_put_ctlr;
+	}
+
+//	ctlr->bus_num = pdev->id;
+//	ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP | SPI_LSB_FIRST;
+
+	/*
+	 * rk spi0 has two native cs, spi1..5 one cs only
+	 * if num-cs is missing in the dts, default to 1
+	 */
+	num_cs = 1;
+	of_property_read_u32(np, "num-cs", &num_cs);
+	ctlr->num_chipselect = num_cs;
+
+	ctlr->dev = dev;
+	ctlr->bits_per_word_mask = SPI_BPW_MASK(16) | SPI_BPW_MASK(8) | SPI_BPW_MASK(4);
+	ctlr->max_speed_hz = min(rs->freq / BAUDR_SCKDV_MIN, MAX_SCLK_OUT);
+
+	ctlr->setup = rockchip_spi_setup;
+	ctlr->transfer = rockchip_spi_transfer;
+	ctlr->max_transfer_size = rockchip_spi_max_transfer_size;
+
+	switch (readl_relaxed(rs->regs + ROCKCHIP_SPI_VERSION)) {
+	case ROCKCHIP_SPI_VER2_TYPE2:
+		rs->cs_high_supported = true;
+		break;
+	}
+
+	spi_controller_set_devdata(ctlr, rs);
+
+	ret = spi_register_controller(ctlr);
+	if (ret < 0) {
+		dev_err(dev, "Failed to register controller\n");
+		goto err_free_dma_rx;
+	}
+
+	return 0;
+
+err_free_dma_rx:
+err_put_ctlr:
+
+	return ret;
+}
+
+static const struct of_device_id rockchip_spi_dt_match[] = {
+	{ .compatible = "rockchip,px30-spi", },
+	{ .compatible = "rockchip,rk3036-spi", },
+	{ .compatible = "rockchip,rk3066-spi", },
+	{ .compatible = "rockchip,rk3188-spi", },
+	{ .compatible = "rockchip,rk3228-spi", },
+	{ .compatible = "rockchip,rk3288-spi", },
+	{ .compatible = "rockchip,rk3308-spi", },
+	{ .compatible = "rockchip,rk3328-spi", },
+	{ .compatible = "rockchip,rk3368-spi", },
+	{ .compatible = "rockchip,rk3399-spi", },
+	{ .compatible = "rockchip,rv1108-spi", },
+	{ .compatible = "rockchip,rv1126-spi", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match);
+
+static struct driver rockchip_spi_driver = {
+        .name  = DRIVER_NAME,
+        .probe = rockchip_spi_probe,
+        .of_compatible = rockchip_spi_dt_match,
+};
+coredevice_platform_driver(rockchip_spi_driver);
+
+MODULE_AUTHOR("Addy Ke <addy.ke@rock-chips.com>");
+MODULE_DESCRIPTION("ROCKCHIP SPI Controller Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/spi/spi.h b/include/spi/spi.h
index 45d6f5931c..0c60e99868 100644
--- a/include/spi/spi.h
+++ b/include/spi/spi.h
@@ -115,6 +115,13 @@ static inline struct spi_device *to_spi_device(struct device *dev)
         return dev ? container_of(dev, struct spi_device, dev) : NULL;
 }
 
+static inline u8 spi_get_chipselect(const struct spi_device *spi, u8 idx)
+{
+	BUG_ON(idx != 0);
+
+	return spi->chip_select;
+}
+
 struct spi_message;
 
 /**

-- 
2.39.5




^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 2/7] mfd: mx13xxx: drop unnecessary ifdefs
  2024-10-15 11:10 [PATCH 0/7] rockchip: add RK808 support Sascha Hauer
  2024-10-15 11:10 ` [PATCH 1/7] spi: add rockchip spi controller support Sascha Hauer
@ 2024-10-15 11:10 ` Sascha Hauer
  2024-10-15 11:11 ` [PATCH 3/7] mfd: rk808: factor out common probe function Sascha Hauer
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2024-10-15 11:10 UTC (permalink / raw)
  To: open list:BAREBOX

No need to #ifdef coredevice_i2c_driver and coredevice_spi_driver. These
are noops anyway when the corresponding subsystem is disabled.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mfd/mc13xxx.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/mfd/mc13xxx.c b/drivers/mfd/mc13xxx.c
index 1e06a24b45..5dabfe3f61 100644
--- a/drivers/mfd/mc13xxx.c
+++ b/drivers/mfd/mc13xxx.c
@@ -396,9 +396,7 @@ static __maybe_unused struct driver mc13xxx_i2c_driver = {
 	.of_compatible	= DRV_OF_COMPAT(mc13xxx_dt_ids),
 };
 
-#if IS_ENABLED(CONFIG_I2C)
 coredevice_i2c_driver(mc13xxx_i2c_driver);
-#endif
 
 static __maybe_unused struct driver mc13xxx_spi_driver = {
 	.name		= "mc13xxx-spi",
@@ -407,6 +405,4 @@ static __maybe_unused struct driver mc13xxx_spi_driver = {
 	.of_compatible	= DRV_OF_COMPAT(mc13xxx_dt_ids),
 };
 
-#if IS_ENABLED(CONFIG_SPI)
 coredevice_spi_driver(mc13xxx_spi_driver);
-#endif

-- 
2.39.5




^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 3/7] mfd: rk808: factor out common probe function
  2024-10-15 11:10 [PATCH 0/7] rockchip: add RK808 support Sascha Hauer
  2024-10-15 11:10 ` [PATCH 1/7] spi: add rockchip spi controller support Sascha Hauer
  2024-10-15 11:10 ` [PATCH 2/7] mfd: mx13xxx: drop unnecessary ifdefs Sascha Hauer
@ 2024-10-15 11:11 ` Sascha Hauer
  2024-10-15 11:11 ` [PATCH 4/7] mfd: rk808: update header file from kernel Sascha Hauer
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2024-10-15 11:11 UTC (permalink / raw)
  To: open list:BAREBOX

The RK806 comes with SPI support. Factor out a common probe function to
be used with both I2C and SPI.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mfd/rk808.c | 114 ++++++++++++++++++++++++++++++++--------------------
 1 file changed, 70 insertions(+), 44 deletions(-)

diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 565215f26c..788e463c20 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -247,17 +247,14 @@ static void rk808_poweroff(struct poweroff_handler *handler)
 	hang();
 }
 
-static int rk808_probe(struct device *dev)
+static int rk8xx_probe(struct device *dev, int variant, struct regmap *regmap)
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct device_node *np = dev->of_node;
 	struct rk808 *rk808;
 	const struct rk808_reg_data *pre_init_reg;
 	const struct mfd_cell *cells;
 	int nr_pre_init_regs;
 	int nr_cells;
-	int msb, lsb;
-	unsigned char pmic_id_msb, pmic_id_lsb;
 	int ret;
 	int i;
 
@@ -266,51 +263,24 @@ static int rk808_probe(struct device *dev)
 		return -ENOMEM;
 
 	dev->priv = rk808;
-
-	if (of_device_is_compatible(np, "rockchip,rk817") ||
-	    of_device_is_compatible(np, "rockchip,rk809")) {
-		pmic_id_msb = RK817_ID_MSB;
-		pmic_id_lsb = RK817_ID_LSB;
-	} else {
-		pmic_id_msb = RK808_ID_MSB;
-		pmic_id_lsb = RK808_ID_LSB;
-	}
-
-	/* Read chip variant */
-	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
-	if (msb < 0) {
-		dev_err(dev, "failed to read the chip id at 0x%x\n",
-			RK808_ID_MSB);
-		return msb;
-	}
-
-	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
-	if (lsb < 0) {
-		dev_err(dev, "failed to read the chip id at 0x%x\n",
-			RK808_ID_LSB);
-		return lsb;
-	}
-
-	rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
-	dev_info(dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
+	rk808->regmap = regmap;
+	rk808->dev = dev;
+	rk808->variant = variant;
 
 	switch (rk808->variant) {
 	case RK805_ID:
-		rk808->regmap_cfg = &rk805_regmap_config;
 		pre_init_reg = rk805_pre_init_reg;
 		nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
 		cells = rk805s;
 		nr_cells = ARRAY_SIZE(rk805s);
 		break;
 	case RK808_ID:
-		rk808->regmap_cfg = &rk808_regmap_config;
 		pre_init_reg = rk808_pre_init_reg;
 		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
 		cells = rk808s;
 		nr_cells = ARRAY_SIZE(rk808s);
 		break;
 	case RK818_ID:
-		rk808->regmap_cfg = &rk818_regmap_config;
 		pre_init_reg = rk818_pre_init_reg;
 		nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
 		cells = rk818s;
@@ -318,7 +288,6 @@ static int rk808_probe(struct device *dev)
 		break;
 	case RK809_ID:
 	case RK817_ID:
-		rk808->regmap_cfg = &rk817_regmap_config;
 		pre_init_reg = rk817_pre_init_reg;
 		nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
 		cells = rk817s;
@@ -330,15 +299,6 @@ static int rk808_probe(struct device *dev)
 		return -EINVAL;
 	}
 
-	rk808->dev = &client->dev;
-	i2c_set_clientdata(client, rk808);
-
-	rk808->regmap = regmap_init_i2c_smbus(client, rk808->regmap_cfg);
-	if (IS_ERR(rk808->regmap)) {
-		dev_err(dev, "regmap initialization failed\n");
-		return PTR_ERR(rk808->regmap);
-	}
-
 	ret = regmap_register_cdev(rk808->regmap, NULL);
 	if (ret)
 		return ret;
@@ -370,9 +330,75 @@ static int rk808_probe(struct device *dev)
 		rk808->poweroff.priority += 100;
 
 	poweroff_handler_register(&rk808->poweroff);
+
 	return 0;
 }
 
+static int rk808_probe(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct i2c_client *client = to_i2c_client(dev);
+	int msb, lsb;
+	unsigned char pmic_id_msb, pmic_id_lsb;
+	struct regmap *regmap;
+	int variant;
+	const struct regmap_config *regmap_cfg;
+
+	if (of_device_is_compatible(np, "rockchip,rk817") ||
+	    of_device_is_compatible(np, "rockchip,rk809")) {
+		pmic_id_msb = RK817_ID_MSB;
+		pmic_id_lsb = RK817_ID_LSB;
+	} else {
+		pmic_id_msb = RK808_ID_MSB;
+		pmic_id_lsb = RK808_ID_LSB;
+	}
+
+	/* Read chip variant */
+	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
+	if (msb < 0) {
+		dev_err(dev, "failed to read the chip id at 0x%x\n",
+			RK808_ID_MSB);
+		return msb;
+	}
+
+	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
+	if (lsb < 0) {
+		dev_err(dev, "failed to read the chip id at 0x%x\n",
+			RK808_ID_LSB);
+		return lsb;
+	}
+
+	variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
+	dev_info(dev, "chip id: 0x%x\n", (unsigned int)variant);
+
+	switch (variant) {
+	case RK805_ID:
+		regmap_cfg = &rk805_regmap_config;
+		break;
+	case RK808_ID:
+		regmap_cfg = &rk808_regmap_config;
+		break;
+	case RK818_ID:
+		regmap_cfg = &rk818_regmap_config;
+		break;
+	case RK809_ID:
+	case RK817_ID:
+		regmap_cfg = &rk817_regmap_config;
+		break;
+	default:
+		dev_err(dev, "Unsupported RK8XX ID %u\n", variant);
+		return -EINVAL;
+	}
+
+	regmap = regmap_init_i2c_smbus(client, regmap_cfg);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "regmap initialization failed\n");
+		return PTR_ERR(regmap);
+	}
+
+	return rk8xx_probe(dev, variant, regmap);
+}
+
 static const struct of_device_id rk808_of_match[] = {
 	{ .compatible = "rockchip,rk805" },
 	{ .compatible = "rockchip,rk808" },

-- 
2.39.5




^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 4/7] mfd: rk808: update header file from kernel
  2024-10-15 11:10 [PATCH 0/7] rockchip: add RK808 support Sascha Hauer
                   ` (2 preceding siblings ...)
  2024-10-15 11:11 ` [PATCH 3/7] mfd: rk808: factor out common probe function Sascha Hauer
@ 2024-10-15 11:11 ` Sascha Hauer
  2024-10-15 11:11 ` [PATCH 5/7] mfd: rk808: add support for RK806 Sascha Hauer
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2024-10-15 11:11 UTC (permalink / raw)
  To: open list:BAREBOX

This updates rk808.h from Linux as of Linux-6.12-rc1. We currently do
not need all register defines from this file, but maintenance will be
easier when we just verbatim copy it from Linux.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/linux/mfd/rk808.h | 646 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 646 insertions(+)

diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index 7804ea80f6..8cd152625b 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -113,6 +113,148 @@ enum rk808_reg {
 #define RK808_INT_STS_MSK_REG2	0x4f
 #define RK808_IO_POL_REG	0x50
 
+/* RK816 */
+enum rk816_reg {
+	RK816_ID_DCDC1,
+	RK816_ID_DCDC2,
+	RK816_ID_DCDC3,
+	RK816_ID_DCDC4,
+	RK816_ID_LDO1,
+	RK816_ID_LDO2,
+	RK816_ID_LDO3,
+	RK816_ID_LDO4,
+	RK816_ID_LDO5,
+	RK816_ID_LDO6,
+	RK816_ID_BOOST,
+	RK816_ID_OTG_SW,
+};
+
+enum rk816_irqs {
+	/* INT_STS_REG1 */
+	RK816_IRQ_PWRON_FALL,
+	RK816_IRQ_PWRON_RISE,
+
+	/* INT_STS_REG2 */
+	RK816_IRQ_VB_LOW,
+	RK816_IRQ_PWRON,
+	RK816_IRQ_PWRON_LP,
+	RK816_IRQ_HOTDIE,
+	RK816_IRQ_RTC_ALARM,
+	RK816_IRQ_RTC_PERIOD,
+	RK816_IRQ_USB_OV,
+
+	/* INT_STS_REG3 */
+	RK816_IRQ_PLUG_IN,
+	RK816_IRQ_PLUG_OUT,
+	RK816_IRQ_CHG_OK,
+	RK816_IRQ_CHG_TE,
+	RK816_IRQ_CHG_TS,
+	RK816_IRQ_CHG_CVTLIM,
+	RK816_IRQ_DISCHG_ILIM,
+};
+
+/* power channel registers */
+#define RK816_DCDC_EN_REG1		0x23
+
+#define RK816_DCDC_EN_REG2		0x24
+#define	RK816_BOOST_EN			BIT(1)
+#define RK816_OTG_EN			BIT(2)
+#define	RK816_BOOST_EN_MSK		BIT(5)
+#define RK816_OTG_EN_MSK		BIT(6)
+#define RK816_BUCK_DVS_CONFIRM		BIT(7)
+
+#define RK816_LDO_EN_REG1		0x27
+
+#define RK816_LDO_EN_REG2		0x28
+
+/* interrupt registers and irq definitions */
+#define RK816_INT_STS_REG1		0x49
+#define RK816_INT_STS_MSK_REG1		0x4a
+#define RK816_INT_STS_PWRON_FALL	BIT(5)
+#define RK816_INT_STS_PWRON_RISE	BIT(6)
+
+#define RK816_INT_STS_REG2		0x4c
+#define RK816_INT_STS_MSK_REG2		0x4d
+#define RK816_INT_STS_VB_LOW		BIT(1)
+#define RK816_INT_STS_PWRON		BIT(2)
+#define RK816_INT_STS_PWRON_LP		BIT(3)
+#define RK816_INT_STS_HOTDIE		BIT(4)
+#define RK816_INT_STS_RTC_ALARM		BIT(5)
+#define RK816_INT_STS_RTC_PERIOD	BIT(6)
+#define RK816_INT_STS_USB_OV		BIT(7)
+
+#define RK816_INT_STS_REG3		0x4e
+#define RK816_INT_STS_MSK_REG3		0x4f
+#define RK816_INT_STS_PLUG_IN		BIT(0)
+#define RK816_INT_STS_PLUG_OUT		BIT(1)
+#define RK816_INT_STS_CHG_OK		BIT(2)
+#define RK816_INT_STS_CHG_TE		BIT(3)
+#define RK816_INT_STS_CHG_TS		BIT(4)
+#define RK816_INT_STS_CHG_CVTLIM	BIT(6)
+#define RK816_INT_STS_DISCHG_ILIM	BIT(7)
+
+#define RK816_IRQ_STS_OFFSET(x)		((x) - RK816_INT_STS_REG1)
+#define RK816_IRQ_MSK_OFFSET(x)		((x) - RK816_INT_STS_MSK_REG1)
+
+/* charger, boost and OTG registers */
+#define RK816_OTG_BUCK_LDO_CONFIG_REG	0x2a
+#define RK816_CHRG_CONFIG_REG		0x2b
+#define RK816_BOOST_ON_VESL_REG		0x54
+#define RK816_BOOST_SLP_VSEL_REG	0x55
+#define RK816_CHRG_BOOST_CONFIG_REG	0x9a
+#define RK816_SUP_STS_REG		0xa0
+#define RK816_USB_CTRL_REG		0xa1
+#define RK816_CHRG_CTRL(x)		(0xa3 + (x))
+#define RK816_BAT_CTRL_REG		0xa6
+#define RK816_BAT_HTS_TS_REG		0xa8
+#define RK816_BAT_LTS_TS_REG		0xa9
+
+/* adc and fuel gauge registers */
+#define RK816_TS_CTRL_REG		0xac
+#define RK816_ADC_CTRL_REG		0xad
+#define RK816_GGCON_REG			0xb0
+#define RK816_GGSTS_REG			0xb1
+#define RK816_ZERO_CUR_ADC_REGH		0xb2
+#define RK816_ZERO_CUR_ADC_REGL		0xb3
+#define RK816_GASCNT_CAL_REG(x)		(0xb7 - (x))
+#define RK816_GASCNT_REG(x)		(0xbb - (x))
+#define RK816_BAT_CUR_AVG_REGH		0xbc
+#define RK816_BAT_CUR_AVG_REGL		0xbd
+#define RK816_TS_ADC_REGH		0xbe
+#define RK816_TS_ADC_REGL		0xbf
+#define RK816_USB_ADC_REGH		0xc0
+#define RK816_USB_ADC_REGL		0xc1
+#define RK816_BAT_OCV_REGH		0xc2
+#define RK816_BAT_OCV_REGL		0xc3
+#define RK816_BAT_VOL_REGH		0xc4
+#define RK816_BAT_VOL_REGL		0xc5
+#define RK816_RELAX_ENTRY_THRES_REGH	0xc6
+#define RK816_RELAX_ENTRY_THRES_REGL	0xc7
+#define RK816_RELAX_EXIT_THRES_REGH	0xc8
+#define RK816_RELAX_EXIT_THRES_REGL	0xc9
+#define RK816_RELAX_VOL1_REGH		0xca
+#define RK816_RELAX_VOL1_REGL		0xcb
+#define RK816_RELAX_VOL2_REGH		0xcc
+#define RK816_RELAX_VOL2_REGL		0xcd
+#define RK816_RELAX_CUR1_REGH		0xce
+#define RK816_RELAX_CUR1_REGL		0xcf
+#define RK816_RELAX_CUR2_REGH		0xd0
+#define RK816_RELAX_CUR2_REGL		0xd1
+#define RK816_CAL_OFFSET_REGH		0xd2
+#define RK816_CAL_OFFSET_REGL		0xd3
+#define RK816_NON_ACT_TIMER_CNT_REG	0xd4
+#define RK816_VCALIB0_REGH		0xd5
+#define RK816_VCALIB0_REGL		0xd6
+#define RK816_VCALIB1_REGH		0xd7
+#define RK816_VCALIB1_REGL		0xd8
+#define RK816_FCC_GASCNT_REG(x)		(0xdc - (x))
+#define RK816_IOFFSET_REGH		0xdd
+#define RK816_IOFFSET_REGL		0xde
+#define RK816_SLEEP_CON_SAMP_CUR_REG	0xdf
+
+/* general purpose data registers 0xe0 ~ 0xf2 */
+#define RK816_DATA_REG(x)		(0xe0 + (x))
+
 /* RK818 */
 #define RK818_DCDC1			0
 #define RK818_LDO1			4
@@ -289,6 +431,414 @@ enum rk805_reg {
 #define RK805_INT_ALARM_EN		(1 << 3)
 #define RK805_INT_TIMER_EN		(1 << 2)
 
+/* RK806 */
+#define RK806_POWER_EN0			0x0
+#define RK806_POWER_EN1			0x1
+#define RK806_POWER_EN2			0x2
+#define RK806_POWER_EN3			0x3
+#define RK806_POWER_EN4			0x4
+#define RK806_POWER_EN5			0x5
+#define RK806_POWER_SLP_EN0		0x6
+#define RK806_POWER_SLP_EN1		0x7
+#define RK806_POWER_SLP_EN2		0x8
+#define RK806_POWER_DISCHRG_EN0		0x9
+#define RK806_POWER_DISCHRG_EN1		0xA
+#define RK806_POWER_DISCHRG_EN2		0xB
+#define RK806_BUCK_FB_CONFIG		0xC
+#define RK806_SLP_LP_CONFIG		0xD
+#define RK806_POWER_FPWM_EN0		0xE
+#define RK806_POWER_FPWM_EN1		0xF
+#define RK806_BUCK1_CONFIG		0x10
+#define RK806_BUCK2_CONFIG		0x11
+#define RK806_BUCK3_CONFIG		0x12
+#define RK806_BUCK4_CONFIG		0x13
+#define RK806_BUCK5_CONFIG		0x14
+#define RK806_BUCK6_CONFIG		0x15
+#define RK806_BUCK7_CONFIG		0x16
+#define RK806_BUCK8_CONFIG		0x17
+#define RK806_BUCK9_CONFIG		0x18
+#define RK806_BUCK10_CONFIG		0x19
+#define RK806_BUCK1_ON_VSEL		0x1A
+#define RK806_BUCK2_ON_VSEL		0x1B
+#define RK806_BUCK3_ON_VSEL		0x1C
+#define RK806_BUCK4_ON_VSEL		0x1D
+#define RK806_BUCK5_ON_VSEL		0x1E
+#define RK806_BUCK6_ON_VSEL		0x1F
+#define RK806_BUCK7_ON_VSEL		0x20
+#define RK806_BUCK8_ON_VSEL		0x21
+#define RK806_BUCK9_ON_VSEL		0x22
+#define RK806_BUCK10_ON_VSEL		0x23
+#define RK806_BUCK1_SLP_VSEL		0x24
+#define RK806_BUCK2_SLP_VSEL		0x25
+#define RK806_BUCK3_SLP_VSEL		0x26
+#define RK806_BUCK4_SLP_VSEL		0x27
+#define RK806_BUCK5_SLP_VSEL		0x28
+#define RK806_BUCK6_SLP_VSEL		0x29
+#define RK806_BUCK7_SLP_VSEL		0x2A
+#define RK806_BUCK8_SLP_VSEL		0x2B
+#define RK806_BUCK9_SLP_VSEL		0x2D
+#define RK806_BUCK10_SLP_VSEL		0x2E
+#define RK806_BUCK_DEBUG1		0x30
+#define RK806_BUCK_DEBUG2		0x31
+#define RK806_BUCK_DEBUG3		0x32
+#define RK806_BUCK_DEBUG4		0x33
+#define RK806_BUCK_DEBUG5		0x34
+#define RK806_BUCK_DEBUG6		0x35
+#define RK806_BUCK_DEBUG7		0x36
+#define RK806_BUCK_DEBUG8		0x37
+#define RK806_BUCK_DEBUG9		0x38
+#define RK806_BUCK_DEBUG10		0x39
+#define RK806_BUCK_DEBUG11		0x3A
+#define RK806_BUCK_DEBUG12		0x3B
+#define RK806_BUCK_DEBUG13		0x3C
+#define RK806_BUCK_DEBUG14		0x3D
+#define RK806_BUCK_DEBUG15		0x3E
+#define RK806_BUCK_DEBUG16		0x3F
+#define RK806_BUCK_DEBUG17		0x40
+#define RK806_BUCK_DEBUG18		0x41
+#define RK806_NLDO_IMAX			0x42
+#define RK806_NLDO1_ON_VSEL		0x43
+#define RK806_NLDO2_ON_VSEL		0x44
+#define RK806_NLDO3_ON_VSEL		0x45
+#define RK806_NLDO4_ON_VSEL		0x46
+#define RK806_NLDO5_ON_VSEL		0x47
+#define RK806_NLDO1_SLP_VSEL		0x48
+#define RK806_NLDO2_SLP_VSEL		0x49
+#define RK806_NLDO3_SLP_VSEL		0x4A
+#define RK806_NLDO4_SLP_VSEL		0x4B
+#define RK806_NLDO5_SLP_VSEL		0x4C
+#define RK806_PLDO_IMAX			0x4D
+#define RK806_PLDO1_ON_VSEL		0x4E
+#define RK806_PLDO2_ON_VSEL		0x4F
+#define RK806_PLDO3_ON_VSEL		0x50
+#define RK806_PLDO4_ON_VSEL		0x51
+#define RK806_PLDO5_ON_VSEL		0x52
+#define RK806_PLDO6_ON_VSEL		0x53
+#define RK806_PLDO1_SLP_VSEL		0x54
+#define RK806_PLDO2_SLP_VSEL		0x55
+#define RK806_PLDO3_SLP_VSEL		0x56
+#define RK806_PLDO4_SLP_VSEL		0x57
+#define RK806_PLDO5_SLP_VSEL		0x58
+#define RK806_PLDO6_SLP_VSEL		0x59
+#define RK806_CHIP_NAME			0x5A
+#define RK806_CHIP_VER			0x5B
+#define RK806_OTP_VER			0x5C
+#define RK806_SYS_STS			0x5D
+#define RK806_SYS_CFG0			0x5E
+#define RK806_SYS_CFG1			0x5F
+#define RK806_SYS_OPTION		0x61
+#define RK806_SLEEP_CONFIG0		0x62
+#define RK806_SLEEP_CONFIG1		0x63
+#define RK806_SLEEP_CTR_SEL0		0x64
+#define RK806_SLEEP_CTR_SEL1		0x65
+#define RK806_SLEEP_CTR_SEL2		0x66
+#define RK806_SLEEP_CTR_SEL3		0x67
+#define RK806_SLEEP_CTR_SEL4		0x68
+#define RK806_SLEEP_CTR_SEL5		0x69
+#define RK806_DVS_CTRL_SEL0		0x6A
+#define RK806_DVS_CTRL_SEL1		0x6B
+#define RK806_DVS_CTRL_SEL2		0x6C
+#define RK806_DVS_CTRL_SEL3		0x6D
+#define RK806_DVS_CTRL_SEL4		0x6E
+#define RK806_DVS_CTRL_SEL5		0x6F
+#define RK806_DVS_START_CTRL		0x70
+#define RK806_SLEEP_GPIO		0x71
+#define RK806_SYS_CFG3			0x72
+#define RK806_ON_SOURCE			0x74
+#define RK806_OFF_SOURCE		0x75
+#define RK806_PWRON_KEY			0x76
+#define RK806_INT_STS0			0x77
+#define RK806_INT_MSK0			0x78
+#define RK806_INT_STS1			0x79
+#define RK806_INT_MSK1			0x7A
+#define RK806_GPIO_INT_CONFIG		0x7B
+#define RK806_DATA_REG0			0x7C
+#define RK806_DATA_REG1			0x7D
+#define RK806_DATA_REG2			0x7E
+#define RK806_DATA_REG3			0x7F
+#define RK806_DATA_REG4			0x80
+#define RK806_DATA_REG5			0x81
+#define RK806_DATA_REG6			0x82
+#define RK806_DATA_REG7			0x83
+#define RK806_DATA_REG8			0x84
+#define RK806_DATA_REG9			0x85
+#define RK806_DATA_REG10		0x86
+#define RK806_DATA_REG11		0x87
+#define RK806_DATA_REG12		0x88
+#define RK806_DATA_REG13		0x89
+#define RK806_DATA_REG14		0x8A
+#define RK806_DATA_REG15		0x8B
+#define RK806_TM_REG			0x8C
+#define RK806_OTP_EN_REG		0x8D
+#define RK806_FUNC_OTP_EN_REG		0x8E
+#define RK806_TEST_REG1			0x8F
+#define RK806_TEST_REG2			0x90
+#define RK806_TEST_REG3			0x91
+#define RK806_TEST_REG4			0x92
+#define RK806_TEST_REG5			0x93
+#define RK806_BUCK_VSEL_OTP_REG0	0x94
+#define RK806_BUCK_VSEL_OTP_REG1	0x95
+#define RK806_BUCK_VSEL_OTP_REG2	0x96
+#define RK806_BUCK_VSEL_OTP_REG3	0x97
+#define RK806_BUCK_VSEL_OTP_REG4	0x98
+#define RK806_BUCK_VSEL_OTP_REG5	0x99
+#define RK806_BUCK_VSEL_OTP_REG6	0x9A
+#define RK806_BUCK_VSEL_OTP_REG7	0x9B
+#define RK806_BUCK_VSEL_OTP_REG8	0x9C
+#define RK806_BUCK_VSEL_OTP_REG9	0x9D
+#define RK806_NLDO1_VSEL_OTP_REG0	0x9E
+#define RK806_NLDO1_VSEL_OTP_REG1	0x9F
+#define RK806_NLDO1_VSEL_OTP_REG2	0xA0
+#define RK806_NLDO1_VSEL_OTP_REG3	0xA1
+#define RK806_NLDO1_VSEL_OTP_REG4	0xA2
+#define RK806_PLDO_VSEL_OTP_REG0	0xA3
+#define RK806_PLDO_VSEL_OTP_REG1	0xA4
+#define RK806_PLDO_VSEL_OTP_REG2	0xA5
+#define RK806_PLDO_VSEL_OTP_REG3	0xA6
+#define RK806_PLDO_VSEL_OTP_REG4	0xA7
+#define RK806_PLDO_VSEL_OTP_REG5	0xA8
+#define RK806_BUCK_EN_OTP_REG1		0xA9
+#define RK806_NLDO_EN_OTP_REG1		0xAA
+#define RK806_PLDO_EN_OTP_REG1		0xAB
+#define RK806_BUCK_FB_RES_OTP_REG1	0xAC
+#define RK806_OTP_RESEV_REG0		0xAD
+#define RK806_OTP_RESEV_REG1		0xAE
+#define RK806_OTP_RESEV_REG2		0xAF
+#define RK806_OTP_RESEV_REG3		0xB0
+#define RK806_OTP_RESEV_REG4		0xB1
+#define RK806_BUCK_SEQ_REG0		0xB2
+#define RK806_BUCK_SEQ_REG1		0xB3
+#define RK806_BUCK_SEQ_REG2		0xB4
+#define RK806_BUCK_SEQ_REG3		0xB5
+#define RK806_BUCK_SEQ_REG4		0xB6
+#define RK806_BUCK_SEQ_REG5		0xB7
+#define RK806_BUCK_SEQ_REG6		0xB8
+#define RK806_BUCK_SEQ_REG7		0xB9
+#define RK806_BUCK_SEQ_REG8		0xBA
+#define RK806_BUCK_SEQ_REG9		0xBB
+#define RK806_BUCK_SEQ_REG10		0xBC
+#define RK806_BUCK_SEQ_REG11		0xBD
+#define RK806_BUCK_SEQ_REG12		0xBE
+#define RK806_BUCK_SEQ_REG13		0xBF
+#define RK806_BUCK_SEQ_REG14		0xC0
+#define RK806_BUCK_SEQ_REG15		0xC1
+#define RK806_BUCK_SEQ_REG16		0xC2
+#define RK806_BUCK_SEQ_REG17		0xC3
+#define RK806_HK_TRIM_REG1		0xC4
+#define RK806_HK_TRIM_REG2		0xC5
+#define RK806_BUCK_REF_TRIM_REG1	0xC6
+#define RK806_BUCK_REF_TRIM_REG2	0xC7
+#define RK806_BUCK_REF_TRIM_REG3	0xC8
+#define RK806_BUCK_REF_TRIM_REG4	0xC9
+#define RK806_BUCK_REF_TRIM_REG5	0xCA
+#define RK806_BUCK_OSC_TRIM_REG1	0xCB
+#define RK806_BUCK_OSC_TRIM_REG2	0xCC
+#define RK806_BUCK_OSC_TRIM_REG3	0xCD
+#define RK806_BUCK_OSC_TRIM_REG4	0xCE
+#define RK806_BUCK_OSC_TRIM_REG5	0xCF
+#define RK806_BUCK_TRIM_ZCDIOS_REG1	0xD0
+#define RK806_BUCK_TRIM_ZCDIOS_REG2	0xD1
+#define RK806_NLDO_TRIM_REG1		0xD2
+#define RK806_NLDO_TRIM_REG2		0xD3
+#define RK806_NLDO_TRIM_REG3		0xD4
+#define RK806_PLDO_TRIM_REG1		0xD5
+#define RK806_PLDO_TRIM_REG2		0xD6
+#define RK806_PLDO_TRIM_REG3		0xD7
+#define RK806_TRIM_ICOMP_REG1		0xD8
+#define RK806_TRIM_ICOMP_REG2		0xD9
+#define RK806_EFUSE_CONTROL_REGH	0xDA
+#define RK806_FUSE_PROG_REG		0xDB
+#define RK806_MAIN_FSM_STS_REG		0xDD
+#define RK806_FSM_REG			0xDE
+#define RK806_TOP_RESEV_OFFR		0xEC
+#define RK806_TOP_RESEV_POR		0xED
+#define RK806_BUCK_VRSN_REG1		0xEE
+#define RK806_BUCK_VRSN_REG2		0xEF
+#define RK806_NLDO_RLOAD_SEL_REG1	0xF0
+#define RK806_PLDO_RLOAD_SEL_REG1	0xF1
+#define RK806_PLDO_RLOAD_SEL_REG2	0xF2
+#define RK806_BUCK_CMIN_MX_REG1		0xF3
+#define RK806_BUCK_CMIN_MX_REG2		0xF4
+#define RK806_BUCK_FREQ_SET_REG1	0xF5
+#define RK806_BUCK_FREQ_SET_REG2	0xF6
+#define RK806_BUCK_RS_MEABS_REG1	0xF7
+#define RK806_BUCK_RS_MEABS_REG2	0xF8
+#define RK806_BUCK_RS_ZDLEB_REG1	0xF9
+#define RK806_BUCK_RS_ZDLEB_REG2	0xFA
+#define RK806_BUCK_RSERVE_REG1		0xFB
+#define RK806_BUCK_RSERVE_REG2		0xFC
+#define RK806_BUCK_RSERVE_REG3		0xFD
+#define RK806_BUCK_RSERVE_REG4		0xFE
+#define RK806_BUCK_RSERVE_REG5		0xFF
+
+/* INT_STS Register field definitions */
+#define RK806_INT_STS_PWRON_FALL	BIT(0)
+#define RK806_INT_STS_PWRON_RISE	BIT(1)
+#define RK806_INT_STS_PWRON		BIT(2)
+#define RK806_INT_STS_PWRON_LP		BIT(3)
+#define RK806_INT_STS_HOTDIE		BIT(4)
+#define RK806_INT_STS_VDC_RISE		BIT(5)
+#define RK806_INT_STS_VDC_FALL		BIT(6)
+#define RK806_INT_STS_VB_LO		BIT(7)
+#define RK806_INT_STS_REV0		BIT(0)
+#define RK806_INT_STS_REV1		BIT(1)
+#define RK806_INT_STS_REV2		BIT(2)
+#define RK806_INT_STS_CRC_ERROR		BIT(3)
+#define RK806_INT_STS_SLP3_GPIO		BIT(4)
+#define RK806_INT_STS_SLP2_GPIO		BIT(5)
+#define RK806_INT_STS_SLP1_GPIO		BIT(6)
+#define RK806_INT_STS_WDT		BIT(7)
+
+/* SPI command */
+#define RK806_CMD_READ			0
+#define RK806_CMD_WRITE			BIT(7)
+#define RK806_CMD_CRC_EN		BIT(6)
+#define RK806_CMD_CRC_DIS		0
+#define RK806_CMD_LEN_MSK		0x0f
+#define RK806_REG_H			0x00
+
+#define VERSION_AB		0x01
+
+enum rk806_reg_id {
+	RK806_ID_DCDC1 = 0,
+	RK806_ID_DCDC2,
+	RK806_ID_DCDC3,
+	RK806_ID_DCDC4,
+	RK806_ID_DCDC5,
+	RK806_ID_DCDC6,
+	RK806_ID_DCDC7,
+	RK806_ID_DCDC8,
+	RK806_ID_DCDC9,
+	RK806_ID_DCDC10,
+
+	RK806_ID_NLDO1,
+	RK806_ID_NLDO2,
+	RK806_ID_NLDO3,
+	RK806_ID_NLDO4,
+	RK806_ID_NLDO5,
+
+	RK806_ID_PLDO1,
+	RK806_ID_PLDO2,
+	RK806_ID_PLDO3,
+	RK806_ID_PLDO4,
+	RK806_ID_PLDO5,
+	RK806_ID_PLDO6,
+	RK806_ID_END,
+};
+
+/* Define the RK806 IRQ numbers */
+enum rk806_irqs {
+	/* INT_STS0 registers */
+	RK806_IRQ_PWRON_FALL,
+	RK806_IRQ_PWRON_RISE,
+	RK806_IRQ_PWRON,
+	RK806_IRQ_PWRON_LP,
+	RK806_IRQ_HOTDIE,
+	RK806_IRQ_VDC_RISE,
+	RK806_IRQ_VDC_FALL,
+	RK806_IRQ_VB_LO,
+
+	/* INT_STS0 registers */
+	RK806_IRQ_REV0,
+	RK806_IRQ_REV1,
+	RK806_IRQ_REV2,
+	RK806_IRQ_CRC_ERROR,
+	RK806_IRQ_SLP3_GPIO,
+	RK806_IRQ_SLP2_GPIO,
+	RK806_IRQ_SLP1_GPIO,
+	RK806_IRQ_WDT,
+};
+
+/* VCC1 Low Voltage Threshold */
+enum rk806_lv_sel {
+	VB_LO_SEL_2800,
+	VB_LO_SEL_2900,
+	VB_LO_SEL_3000,
+	VB_LO_SEL_3100,
+	VB_LO_SEL_3200,
+	VB_LO_SEL_3300,
+	VB_LO_SEL_3400,
+	VB_LO_SEL_3500,
+};
+
+/* System Shutdown Voltage Select */
+enum rk806_uv_sel {
+	VB_UV_SEL_2700,
+	VB_UV_SEL_2800,
+	VB_UV_SEL_2900,
+	VB_UV_SEL_3000,
+	VB_UV_SEL_3100,
+	VB_UV_SEL_3200,
+	VB_UV_SEL_3300,
+	VB_UV_SEL_3400,
+};
+
+/* Pin Function */
+enum rk806_pwrctrl_fun {
+	PWRCTRL_NULL_FUN,
+	PWRCTRL_SLP_FUN,
+	PWRCTRL_POWOFF_FUN,
+	PWRCTRL_RST_FUN,
+	PWRCTRL_DVS_FUN,
+	PWRCTRL_GPIO_FUN,
+};
+
+/* Pin Polarity */
+enum rk806_pin_level {
+	POL_LOW,
+	POL_HIGH,
+};
+
+enum rk806_vsel_ctr_sel {
+	CTR_BY_NO_EFFECT,
+	CTR_BY_PWRCTRL1,
+	CTR_BY_PWRCTRL2,
+	CTR_BY_PWRCTRL3,
+};
+
+enum rk806_dvs_ctr_sel {
+	CTR_SEL_NO_EFFECT,
+	CTR_SEL_DVS_START1,
+	CTR_SEL_DVS_START2,
+	CTR_SEL_DVS_START3,
+};
+
+enum rk806_pin_dr_sel {
+	RK806_PIN_INPUT,
+	RK806_PIN_OUTPUT,
+};
+
+#define RK806_INT_POL_MSK		BIT(1)
+#define RK806_INT_POL_H			BIT(1)
+#define RK806_INT_POL_L			0
+
+#define RK806_SLAVE_RESTART_FUN_MSK	BIT(1)
+#define RK806_SLAVE_RESTART_FUN_EN	BIT(1)
+#define RK806_SLAVE_RESTART_FUN_OFF	0
+
+#define RK806_SYS_ENB2_2M_MSK		BIT(1)
+#define RK806_SYS_ENB2_2M_EN		BIT(1)
+#define RK806_SYS_ENB2_2M_OFF		0
+
+enum rk806_int_fun {
+	RK806_INT_ONLY,
+	RK806_INT_ADN_WKUP,
+};
+
+enum rk806_dvs_mode {
+	RK806_DVS_NOT_SUPPORT,
+	RK806_DVS_START1,
+	RK806_DVS_START2,
+	RK806_DVS_START3,
+	RK806_DVS_PWRCTRL1,
+	RK806_DVS_PWRCTRL2,
+	RK806_DVS_PWRCTRL3,
+	RK806_DVS_START_PWRCTR1,
+	RK806_DVS_START_PWRCTR2,
+	RK806_DVS_START_PWRCTR3,
+	RK806_DVS_END,
+};
+
 /* RK808 IRQ Definitions */
 #define RK808_IRQ_VOUT_LO	0
 #define RK808_IRQ_VB_LO		1
@@ -373,6 +923,7 @@ enum rk805_reg {
 #define SWITCH2_EN	BIT(6)
 #define SWITCH1_EN	BIT(5)
 #define DEV_OFF_RST	BIT(3)
+#define DEV_RST		BIT(2)
 #define DEV_OFF		BIT(0)
 #define RTC_STOP	BIT(0)
 
@@ -382,6 +933,7 @@ enum rk805_reg {
 #define VOUT_LO_INT	BIT(0)
 #define CLK32KOUT2_EN	BIT(0)
 
+#define TEMP105C			0x08
 #define TEMP115C			0x0c
 #define TEMP_HOTDIE_MSK			0x0c
 #define SLP_SD_MSK			(0x3 << 2)
@@ -531,6 +1083,77 @@ enum rk809_reg_id {
 #define MIC_DIFF_DIS			(0x0 << 7)
 #define MIC_DIFF_EN			(0x1 << 7)
 
+/* RK817 Battery Registers */
+#define RK817_GAS_GAUGE_ADC_CONFIG0	0x50
+#define RK817_GG_EN			(0x1 << 7)
+#define RK817_SYS_VOL_ADC_EN		(0x1 << 6)
+#define RK817_TS_ADC_EN			(0x1 << 5)
+#define RK817_USB_VOL_ADC_EN		(0x1 << 4)
+#define RK817_BAT_VOL_ADC_EN		(0x1 << 3)
+#define RK817_BAT_CUR_ADC_EN		(0x1 << 2)
+
+#define RK817_GAS_GAUGE_ADC_CONFIG1	0x55
+
+#define RK817_VOL_CUR_CALIB_UPD		BIT(7)
+
+#define RK817_GAS_GAUGE_GG_CON		0x56
+#define RK817_GAS_GAUGE_GG_STS		0x57
+
+#define RK817_BAT_CON			(0x1 << 4)
+#define RK817_RELAX_VOL_UPD		(0x3 << 2)
+#define RK817_RELAX_STS			(0x1 << 1)
+
+#define RK817_GAS_GAUGE_RELAX_THRE_H	0x58
+#define RK817_GAS_GAUGE_RELAX_THRE_L	0x59
+#define RK817_GAS_GAUGE_OCV_THRE_VOL	0x62
+#define RK817_GAS_GAUGE_OCV_VOL_H	0x63
+#define RK817_GAS_GAUGE_OCV_VOL_L	0x64
+#define RK817_GAS_GAUGE_PWRON_VOL_H	0x6b
+#define RK817_GAS_GAUGE_PWRON_VOL_L	0x6c
+#define RK817_GAS_GAUGE_PWRON_CUR_H	0x6d
+#define RK817_GAS_GAUGE_PWRON_CUR_L	0x6e
+#define RK817_GAS_GAUGE_OFF_CNT		0x6f
+#define RK817_GAS_GAUGE_Q_INIT_H3	0x70
+#define RK817_GAS_GAUGE_Q_INIT_H2	0x71
+#define RK817_GAS_GAUGE_Q_INIT_L1	0x72
+#define RK817_GAS_GAUGE_Q_INIT_L0	0x73
+#define RK817_GAS_GAUGE_Q_PRES_H3	0x74
+#define RK817_GAS_GAUGE_Q_PRES_H2	0x75
+#define RK817_GAS_GAUGE_Q_PRES_L1	0x76
+#define RK817_GAS_GAUGE_Q_PRES_L0	0x77
+#define RK817_GAS_GAUGE_BAT_VOL_H	0x78
+#define RK817_GAS_GAUGE_BAT_VOL_L	0x79
+#define RK817_GAS_GAUGE_BAT_CUR_H	0x7a
+#define RK817_GAS_GAUGE_BAT_CUR_L	0x7b
+#define RK817_GAS_GAUGE_USB_VOL_H	0x7e
+#define RK817_GAS_GAUGE_USB_VOL_L	0x7f
+#define RK817_GAS_GAUGE_SYS_VOL_H	0x80
+#define RK817_GAS_GAUGE_SYS_VOL_L	0x81
+#define RK817_GAS_GAUGE_Q_MAX_H3	0x82
+#define RK817_GAS_GAUGE_Q_MAX_H2	0x83
+#define RK817_GAS_GAUGE_Q_MAX_L1	0x84
+#define RK817_GAS_GAUGE_Q_MAX_L0	0x85
+#define RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_H	0x8f
+#define RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_L	0x90
+#define RK817_GAS_GAUGE_CAL_OFFSET_H	0x91
+#define RK817_GAS_GAUGE_CAL_OFFSET_L	0x92
+#define RK817_GAS_GAUGE_VCALIB0_H	0x93
+#define RK817_GAS_GAUGE_VCALIB0_L	0x94
+#define RK817_GAS_GAUGE_VCALIB1_H	0x95
+#define RK817_GAS_GAUGE_VCALIB1_L	0x96
+#define RK817_GAS_GAUGE_IOFFSET_H	0x97
+#define RK817_GAS_GAUGE_IOFFSET_L	0x98
+#define RK817_GAS_GAUGE_BAT_R1		0x9a
+#define RK817_GAS_GAUGE_BAT_R2		0x9b
+#define RK817_GAS_GAUGE_BAT_R3		0x9c
+#define RK817_GAS_GAUGE_DATA0		0x9d
+#define RK817_GAS_GAUGE_DATA1		0x9e
+#define RK817_GAS_GAUGE_DATA2		0x9f
+#define RK817_GAS_GAUGE_DATA3		0xa0
+#define RK817_GAS_GAUGE_DATA4		0xa1
+#define RK817_GAS_GAUGE_DATA5		0xa2
+#define RK817_GAS_GAUGE_CUR_ADC_K0	0xb0
+
 #define RK817_POWER_EN_REG(i)		(0xb1 + (i))
 #define RK817_POWER_SLP_EN_REG(i)	(0xb5 + (i))
 
@@ -556,10 +1179,30 @@ enum rk809_reg_id {
 #define RK817_LDO_ON_VSEL_REG(idx)	(0xcc + (idx) * 2)
 #define RK817_BOOST_OTG_CFG		(0xde)
 
+#define RK817_PMIC_CHRG_OUT		0xe4
+#define RK817_CHRG_VOL_SEL		(0x07 << 4)
+#define RK817_CHRG_CUR_SEL		(0x07 << 0)
+
+#define RK817_PMIC_CHRG_IN		0xe5
+#define RK817_USB_VLIM_EN		(0x01 << 7)
+#define RK817_USB_VLIM_SEL		(0x07 << 4)
+#define RK817_USB_ILIM_EN		(0x01 << 3)
+#define RK817_USB_ILIM_SEL		(0x07 << 0)
+#define RK817_PMIC_CHRG_TERM		0xe6
+#define RK817_CHRG_TERM_ANA_DIG		(0x01 << 2)
+#define RK817_CHRG_TERM_ANA_SEL		(0x03 << 0)
+#define RK817_CHRG_EN			(0x01 << 6)
+
+#define RK817_PMIC_CHRG_STS		0xeb
+#define RK817_BAT_EXS			BIT(7)
+#define RK817_CHG_STS			(0x07 << 4)
+
 #define RK817_ID_MSB			0xed
 #define RK817_ID_LSB			0xee
 
 #define RK817_SYS_STS			0xf0
+#define RK817_PLUG_IN_STS		(0x1 << 6)
+
 #define RK817_SYS_CFG(i)		(0xf1 + (i))
 
 #define RK817_ON_SOURCE_REG		0xf5
@@ -701,8 +1344,10 @@ enum {
 
 enum {
 	RK805_ID = 0x8050,
+	RK806_ID = 0x8060,
 	RK808_ID = 0x0000,
 	RK809_ID = 0x8090,
+	RK816_ID = 0x8160,
 	RK817_ID = 0x8170,
 	RK818_ID = 0x8180,
 };
@@ -717,4 +1362,5 @@ struct rk808 {
 	const struct regmap_config	*regmap_cfg;
 	struct poweroff_handler		poweroff;
 };
+
 #endif /* __LINUX_REGULATOR_RK808_H */

-- 
2.39.5




^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 5/7] mfd: rk808: add support for RK806
  2024-10-15 11:10 [PATCH 0/7] rockchip: add RK808 support Sascha Hauer
                   ` (3 preceding siblings ...)
  2024-10-15 11:11 ` [PATCH 4/7] mfd: rk808: update header file from kernel Sascha Hauer
@ 2024-10-15 11:11 ` Sascha Hauer
  2024-10-15 14:46   ` Alexander Shiyan
  2024-10-15 11:11 ` [PATCH 6/7] regulator: add regulator_register() Sascha Hauer
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Sascha Hauer @ 2024-10-15 11:11 UTC (permalink / raw)
  To: open list:BAREBOX

This adds support for the RK806 to the rk808 driver. Additionally to
I2C this variant comes with SPI support, so add SPI probe support to the
driver.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mfd/Kconfig |   4 +-
 drivers/mfd/rk808.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 104 insertions(+), 3 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 5189364c2c..dabe71dbdc 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -119,8 +119,8 @@ config MFD_ATMEL_FLEXCOM
 
 config MFD_RK808
 	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip"
-	depends on I2C && OFDEVICE
-	select REGMAP_I2C
+	depends on (I2C || SPI) && OFDEVICE
+	select REGMAP_I2C if I2C
 	help
 	  If you say yes here you get support for the RK805, RK808, RK809,
 	  RK817 and RK818 Power Management chips.
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 788e463c20..5b010e09ef 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -22,6 +22,7 @@
 #include <poweroff.h>
 #include <of.h>
 #include <linux/regmap.h>
+#include <spi/spi.h>
 
 struct rk808_reg_data {
 	int addr;
@@ -61,6 +62,12 @@ static const struct mfd_cell rk805s[] = {
 	{ .name = "rk805-pwrkey", },
 };
 
+static const struct mfd_cell rk806s[] = {
+	{ .name = "rk805-pinctrl", },
+	{ .name = "rk808-regulator", },
+	{ .name = "rk805-pwrkey", },
+};
+
 static const struct mfd_cell rk808s[] = {
 	{ .name = "rk808-clkout", },
 	{ .name = "rk808-regulator", },
@@ -94,6 +101,12 @@ static const struct rk808_reg_data rk805_pre_init_reg[] = {
 	{RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
 };
 
+static const struct rk808_reg_data rk806_pre_init_reg[] = {
+	{ RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
+	{ RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
+	{ RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
+};
+
 static const struct rk808_reg_data rk808_pre_init_reg[] = {
 	{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_150MA },
 	{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_200MA },
@@ -274,6 +287,12 @@ static int rk8xx_probe(struct device *dev, int variant, struct regmap *regmap)
 		cells = rk805s;
 		nr_cells = ARRAY_SIZE(rk805s);
 		break;
+	case RK806_ID:
+		pre_init_reg = rk806_pre_init_reg;
+		nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
+		cells = rk806s;
+		nr_cells = ARRAY_SIZE(rk806s);
+		break;
 	case RK808_ID:
 		pre_init_reg = rk808_pre_init_reg;
 		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
@@ -399,6 +418,75 @@ static int rk808_probe(struct device *dev)
 	return rk8xx_probe(dev, variant, regmap);
 }
 
+#define RK806_ADDR_SIZE 2
+#define RK806_CMD_WITH_SIZE(CMD, VALUE_BYTES) \
+        (RK806_CMD_##CMD | RK806_CMD_CRC_DIS | (VALUE_BYTES - 1))
+
+static const struct regmap_config rk806_regmap_config_spi = {
+	.reg_bits = 16,
+	.val_bits = 8,
+	.max_register = RK806_BUCK_RSERVE_REG5,
+};
+
+static int rk806_spi_bus_write(void *context, const void *vdata, size_t count)
+{
+	struct device *dev = context;
+	struct spi_device *spi = to_spi_device(dev);
+	struct spi_transfer xfer[2] = { 0 };
+	/* data and thus count includes the register address */
+	size_t val_size = count - RK806_ADDR_SIZE;
+	char cmd;
+
+	if (val_size < 1 || val_size > (RK806_CMD_LEN_MSK + 1))
+		return -EINVAL;
+
+	cmd = RK806_CMD_WITH_SIZE(WRITE, val_size);
+
+	xfer[0].tx_buf = &cmd;
+	xfer[0].len = sizeof(cmd);
+	xfer[1].tx_buf = vdata;
+	xfer[1].len = count;
+
+	return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
+}
+
+static int rk806_spi_bus_read(void *context, const void *vreg, size_t reg_size,
+			      void *val, size_t val_size)
+{
+	struct device *dev = context;
+	struct spi_device *spi = to_spi_device(dev);
+	char txbuf[3] = { 0 };
+
+	if (reg_size != RK806_ADDR_SIZE ||
+	    val_size < 1 || val_size > (RK806_CMD_LEN_MSK + 1))
+		return -EINVAL;
+
+	/* TX buffer contains command byte followed by two address bytes */
+	txbuf[0] = RK806_CMD_WITH_SIZE(READ, val_size);
+	memcpy(txbuf+1, vreg, reg_size);
+
+	return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size);
+}
+
+static const struct regmap_bus rk806_regmap_bus_spi = {
+	.write = rk806_spi_bus_write,
+	.read = rk806_spi_bus_read,
+	.reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
+};
+
+static int rk808_probe_spi(struct device *dev)
+{
+	struct regmap *regmap;
+
+	regmap = regmap_init(dev, &rk806_regmap_bus_spi,
+				  dev, &rk806_regmap_config_spi);
+	if (IS_ERR(regmap))
+		return dev_err_probe(dev, PTR_ERR(regmap),
+				     "Failed to init regmap\n");
+
+	return rk8xx_probe(dev, RK806_ID, regmap);
+}
+
 static const struct of_device_id rk808_of_match[] = {
 	{ .compatible = "rockchip,rk805" },
 	{ .compatible = "rockchip,rk808" },
@@ -409,13 +497,26 @@ static const struct of_device_id rk808_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, rk808_of_match);
 
-static struct driver rk808_i2c_driver = {
+static __maybe_unused struct driver rk808_i2c_driver = {
 	.name = "rk808",
 	.of_compatible = rk808_of_match,
 	.probe    = rk808_probe,
 };
 coredevice_i2c_driver(rk808_i2c_driver);
 
+static const struct of_device_id rk808_spi_of_match[] = {
+	{ .compatible = "rockchip,rk806" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, rk808_of_match);
+
+static __maybe_unused struct driver rk808_spi_driver = {
+	.name = "rk808",
+	.of_compatible = rk808_spi_of_match,
+	.probe    = rk808_probe_spi,
+};
+coredevice_spi_driver(rk808_spi_driver);
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");

-- 
2.39.5




^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 6/7] regulator: add regulator_register()
  2024-10-15 11:10 [PATCH 0/7] rockchip: add RK808 support Sascha Hauer
                   ` (4 preceding siblings ...)
  2024-10-15 11:11 ` [PATCH 5/7] mfd: rk808: add support for RK806 Sascha Hauer
@ 2024-10-15 11:11 ` Sascha Hauer
  2024-10-15 11:11 ` [PATCH 7/7] regulator: rk808: update from kernel Sascha Hauer
  2024-10-18  8:39 ` [PATCH 0/7] rockchip: add RK808 support Sascha Hauer
  7 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2024-10-15 11:11 UTC (permalink / raw)
  To: open list:BAREBOX

This adds a regulator_register() with a prototype compatible to Linux.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/regulator/core.c | 37 +++++++++++++++++++++++++++++++++++++
 include/regulator.h      | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index bbba3b0b57..30ae270b51 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -425,6 +425,43 @@ int dev_regulator_register(struct regulator_dev *rdev, const char *name)
 	return 0;
 }
 
+struct regulator_dev *
+regulator_register(struct device *dev,
+		   const struct regulator_desc *desc,
+		   const struct regulator_config *config)
+{
+	struct regulator_dev *rdev;
+	struct device_node *search, *child;
+	int ret;
+
+	rdev = xzalloc(sizeof(*rdev));
+
+	rdev->name = desc->name;
+	rdev->desc = desc;
+	rdev->regmap = config->regmap;
+	rdev->dev = dev;
+
+	if (desc->regulators_node)
+		search = of_get_child_by_name(dev->of_node,
+					      desc->regulators_node);
+	else
+		search = dev->of_node;
+
+	if (!search) {
+		dev_err(dev, "Failed to find regulator container node\n");
+		return NULL;
+	}
+
+	for_each_child_of_node(search, child) {
+		if (strcmp(desc->of_match, child->name))
+			continue;
+		ret = of_regulator_register(rdev, child);
+		break;
+	}
+
+	return rdev;
+}
+
 static struct regulator_dev *dev_regulator_get(struct device *dev,
 					       const char *supply)
 {
diff --git a/include/regulator.h b/include/regulator.h
index 305da0d774..9785b8ac07 100644
--- a/include/regulator.h
+++ b/include/regulator.h
@@ -35,7 +35,12 @@ struct regulator_bulk_data {
  * structure contains the non-varying parts of the regulator
  * description.
  *
+ * @name: Identifying name for the regulator.
+ * @supply_name: Identifying the regulator supply
  * @supply_name: Identifying the supply of this regulator
+ * @of_match: Name used to identify regulator in DT.
+ * @regulators_node: Name of node containing regulator definitions in DT.
+ * @id: Numerical identifier for the regulator.
  *
  * @n_voltages: Number of selectors available for ops.list_voltage().
  * @ops: Regulator operations table.
@@ -62,7 +67,11 @@ struct regulator_bulk_data {
  */
 
 struct regulator_desc {
+	const char *name;
 	const char *supply_name;
+	const char *of_match;
+	const char *regulators_node;
+	int id;
 	unsigned n_voltages;
 	const struct regulator_ops *ops;
 
@@ -87,6 +96,28 @@ struct regulator_desc {
 	unsigned int off_on_delay;
 };
 
+/**
+ * struct regulator_config - Dynamic regulator descriptor
+ *
+ * Each regulator registered with the core is described with a
+ * structure of this type and a struct regulator_desc.  This structure
+ * contains the runtime variable parts of the regulator description.
+ *
+ * @dev: struct device for the regulator
+ * @init_data: platform provided init data, passed through by driver
+ * @driver_data: private regulator data
+ * @of_node: OpenFirmware node to parse for device tree bindings (may be
+ *           NULL).
+ * @regmap: regmap to use for core regmap helpers if dev_get_regmap() is
+ *          insufficient.
+ * @ena_gpiod: GPIO controlling regulator enable.
+ */
+struct regulator_config {
+	struct device *dev;
+	void *driver_data;
+	struct regmap *regmap;
+};
+
 struct regulator_dev {
 	const char *name;
 	struct list_head list;
@@ -158,6 +189,11 @@ static inline int of_regulator_register(struct regulator_dev *rd,
 #endif
 int dev_regulator_register(struct regulator_dev *rd, const char *name);
 
+struct regulator_dev *
+regulator_register(struct device *dev,
+		   const struct regulator_desc *regulator_desc,
+		   const struct regulator_config *config);
+
 #define REGULATOR_PRINT_DEVS	BIT(0)
 void regulators_print(unsigned flags);
 

-- 
2.39.5




^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 7/7] regulator: rk808: update from kernel
  2024-10-15 11:10 [PATCH 0/7] rockchip: add RK808 support Sascha Hauer
                   ` (5 preceding siblings ...)
  2024-10-15 11:11 ` [PATCH 6/7] regulator: add regulator_register() Sascha Hauer
@ 2024-10-15 11:11 ` Sascha Hauer
  2024-10-18  8:39 ` [PATCH 0/7] rockchip: add RK808 support Sascha Hauer
  7 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2024-10-15 11:11 UTC (permalink / raw)
  To: open list:BAREBOX

This syncs the rk808 regulator driver with Linux-6.12-rc1. A lot has
changed in the Kernel driver which makes an incremental update hard to
do.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/regulator/rk808-regulator.c | 1085 ++++++++++++++++++++++-------------
 include/linux/mfd/rk808.h           |   15 +-
 2 files changed, 680 insertions(+), 420 deletions(-)

diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index b361dae8cf..0a28f84fc1 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -17,6 +17,7 @@
 #include <linux/regulator/of_regulator.h>
 #include <regulator.h>
 #include <linux/mfd/rk808.h>
+#include <linux/gpio/consumer.h>
 
 /* Field Definitions */
 #define RK808_BUCK_VSEL_MASK	0x3f
@@ -35,13 +36,47 @@
 #define RK818_LDO3_ON_VSEL_MASK		0xf
 #define RK818_BOOST_ON_VSEL_MASK	0xe0
 
+#define RK806_DCDC_SLP_REG_OFFSET	0x0A
+#define RK806_NLDO_SLP_REG_OFFSET	0x05
+#define RK806_PLDO_SLP_REG_OFFSET	0x06
+
+#define RK806_BUCK_SEL_CNT		0xff
+#define RK806_LDO_SEL_CNT		0xff
+
+/* Ramp rate definitions for buck1 / buck2 only */
+#define RK808_RAMP_RATE_OFFSET		3
+#define RK808_RAMP_RATE_MASK		(3 << RK808_RAMP_RATE_OFFSET)
+#define RK808_RAMP_RATE_2MV_PER_US	(0 << RK808_RAMP_RATE_OFFSET)
+#define RK808_RAMP_RATE_4MV_PER_US	(1 << RK808_RAMP_RATE_OFFSET)
+#define RK808_RAMP_RATE_6MV_PER_US	(2 << RK808_RAMP_RATE_OFFSET)
+#define RK808_RAMP_RATE_10MV_PER_US	(3 << RK808_RAMP_RATE_OFFSET)
+
+#define RK808_DVS2_POL		BIT(2)
+#define RK808_DVS1_POL		BIT(1)
+
+/* Offset from XXX_ON_VSEL to XXX_SLP_VSEL */
+#define RK808_SLP_REG_OFFSET 1
+
+/* Offset from XXX_ON_VSEL to XXX_DVS_VSEL */
+#define RK808_DVS_REG_OFFSET 2
+
+/* Offset from XXX_EN_REG to SLEEP_SET_OFF_XXX */
+#define RK808_SLP_SET_OFF_REG_OFFSET 2
+
+/* max steps for increase voltage of Buck1/2, equal 100mv*/
+#define MAX_STEPS_ONE_TIME 8
+
 #define ENABLE_MASK(id)			(BIT(id) | BIT(4 + (id)))
 #define DISABLE_VAL(id)			(BIT(4 + (id)))
 
-#define RK817_BOOST_DESC(_supply_name, _min, _max, _step, _vreg,\
-	_vmask, _ereg, _emask, _enval, _disval, _etime)		\
-	{{							\
-		.supply_name	= (_supply_name),			\
+#define RK817_BOOST_DESC(_id, _match, _supply, _min, _max, _step, _vreg,\
+	_vmask, _ereg, _emask, _enval, _disval, _etime, m_drop)		\
+	{							\
+		.name		= (_match),				\
+		.supply_name	= (_supply),				\
+		.of_match	= of_match_ptr(_match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.id		= (_id),				\
 		.n_voltages	= (((_max) - (_min)) / (_step) + 1),	\
 		.min_uV		= (_min) * 1000,			\
 		.uV_step	= (_step) * 1000,			\
@@ -51,14 +86,17 @@
 		.enable_mask	= (_emask),				\
 		.enable_val     = (_enval),				\
 		.disable_val     = (_disval),				\
-		.off_on_delay	= (_etime),				\
 		.ops		= &rk817_boost_ops,			\
-	}}
+	}
 
-#define RK8XX_DESC_COM(_supply_name, _min, _max, _step, _vreg,	\
+#define RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, _enval, _disval, _etime, _ops)		\
-	{{								\
-		.supply_name	= (_supply_name),			\
+	{								\
+		.name		= (_match),				\
+		.supply_name	= (_supply),				\
+		.of_match	= of_match_ptr(_match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.id		= (_id),				\
 		.n_voltages	= (((_max) - (_min)) / (_step) + 1),	\
 		.min_uV		= (_min) * 1000,			\
 		.uV_step	= (_step) * 1000,			\
@@ -68,45 +106,89 @@
 		.enable_mask	= (_emask),				\
 		.enable_val     = (_enval),				\
 		.disable_val     = (_disval),				\
-		.off_on_delay	= (_etime),				\
 		.ops		= _ops,			\
-	}}
+	}
 
-#define RK805_DESC(_supply_name, _min, _max, _step, _vreg,	\
+#define RK805_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, _etime)					\
-	RK8XX_DESC_COM(_supply_name, _min, _max, _step, _vreg,	\
-	_vmask, _ereg, _emask, 0, 0, _etime, &rk808_reg_ops)
+	RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg,	\
+	_vmask, _ereg, _emask, 0, 0, _etime, &rk805_reg_ops)
+
+#define RK806_REGULATOR(_name, _supply_name, _id, _ops,\
+			_n_voltages, _vr, _er, _lr, ctrl_bit,\
+			_rr, _rm, _rt)\
+[_id] = {\
+		.name = _name,\
+		.supply_name = _supply_name,\
+		.of_match = of_match_ptr(_name),\
+		.regulators_node = of_match_ptr("regulators"),\
+		.id = _id,\
+		.ops = &_ops,\
+		.n_voltages = _n_voltages,\
+		.linear_ranges = _lr,\
+		.n_linear_ranges = ARRAY_SIZE(_lr),\
+		.vsel_reg = _vr,\
+		.vsel_mask = 0xff,\
+		.enable_reg = _er,\
+		.enable_mask = ENABLE_MASK(ctrl_bit),\
+		.enable_val = ENABLE_MASK(ctrl_bit),\
+		.disable_val = DISABLE_VAL(ctrl_bit),\
+	}
 
-#define RK8XX_DESC(_supply_name, _min, _max, _step, _vreg,	\
+#define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, _etime)					\
-	RK8XX_DESC_COM(_supply_name, _min, _max, _step, _vreg,	\
+	RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, 0, 0, _etime, &rk808_reg_ops)
 
-#define RK817_DESC(_supply_name, _min, _max, _step, _vreg,	\
+#define RK816_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\
+	_vmask, _ereg, _emask, _disval, _etime)				\
+	RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg,	\
+	_vmask, _ereg, _emask, _emask, _disval, _etime, &rk816_reg_ops)
+
+#define RK817_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, _disval, _etime)				\
-	RK8XX_DESC_COM(_supply_name, _min, _max, _step, _vreg,	\
+	RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, _emask, _disval, _etime, &rk817_reg_ops)
 
-#define RKXX_DESC_SWITCH_COM(_supply_name,_ereg, _emask,	\
+#define RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask,	\
 	_enval, _disval, _ops)						\
-	{{								\
-		.supply_name	= (_supply_name),			\
+	{								\
+		.name		= (_match),				\
+		.supply_name	= (_supply),				\
+		.of_match	= of_match_ptr(_match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.id		= (_id),				\
 		.enable_reg	= (_ereg),				\
 		.enable_mask	= (_emask),				\
 		.enable_val     = (_enval),				\
 		.disable_val     = (_disval),				\
 		.ops		= _ops					\
-	}}
+	}
 
-#define RK817_DESC_SWITCH(_supply_name, _ereg, _emask,		\
+#define RK817_DESC_SWITCH(_id, _match, _supply, _ereg, _emask,		\
 	_disval)							\
-	RKXX_DESC_SWITCH_COM(_supply_name, _ereg, _emask,	\
+	RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask,	\
 	_emask, _disval, &rk817_switch_ops)
 
-#define RK8XX_DESC_SWITCH(_supply_name, _ereg, _emask)		\
-	RKXX_DESC_SWITCH_COM(_supply_name, _ereg, _emask,	\
+#define RK8XX_DESC_SWITCH(_id, _match, _supply, _ereg, _emask)		\
+	RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask,	\
 	0, 0, &rk808_switch_ops)
 
+struct rk8xx_register_bit {
+	u8 reg;
+	u8 bit;
+};
+
+#define RK8XX_REG_BIT(_reg, _bit)					\
+	{								\
+		.reg = _reg,						\
+		.bit = BIT(_bit),						\
+	}
+
+struct rk808_regulator_data {
+	struct gpio_desc *dvs_gpio[2];
+};
+
 static const struct regulator_linear_range rk808_ldo3_voltage_ranges[] = {
 	REGULATOR_LINEAR_RANGE(800000, 0, 13, 100000),
 	REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0),
@@ -157,11 +239,72 @@ static const struct regulator_linear_range rk817_buck3_voltage_ranges[] = {
 			       RK817_BUCK3_SEL_CNT, RK817_BUCK1_STP1),
 };
 
-struct rk_regulator_cfg {
-	struct regulator_desc desc;
-	struct regulator_dev rdev;
+static const __maybe_unused unsigned int rk808_buck1_2_ramp_table[] = {
+	2000, 4000, 6000, 10000
+};
+
+/* RK817/RK809/RK816 (buck 1/2 only) */
+static const __maybe_unused unsigned int rk817_buck1_4_ramp_table[] = {
+	3000, 6300, 12500, 25000
 };
 
+static const __maybe_unused unsigned int rk806_ramp_delay_table_dcdc[] = {
+	50000, 25000, 12500, 6250, 3125, 1560, 961, 390
+};
+
+static const __maybe_unused unsigned int rk806_ramp_delay_table_ldo[] = {
+	100000, 50000, 25000, 12500, 6280, 3120, 1900, 780
+};
+
+static int rk808_buck1_2_set_voltage_sel(struct regulator_dev *rdev,
+					 unsigned sel)
+{
+	int ret, delta_sel;
+	unsigned int old_sel, tmp, val, mask = rdev->desc->vsel_mask;
+
+	ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
+	if (ret != 0)
+		return ret;
+
+	tmp = val & ~mask;
+	old_sel = val & mask;
+	old_sel >>= ffs(mask) - 1;
+	delta_sel = sel - old_sel;
+
+	/*
+	 * If directly modify the register to change the voltage, we will face
+	 * the risk of overshoot. Put it into a multi-step, can effectively
+	 * avoid this problem, a step is 100mv here.
+	 */
+	while (delta_sel > MAX_STEPS_ONE_TIME) {
+		old_sel += MAX_STEPS_ONE_TIME;
+		val = old_sel << (ffs(mask) - 1);
+		val |= tmp;
+
+		/*
+		 * i2c is 400kHz (2.5us per bit) and we must transmit _at least_
+		 * 3 bytes (24 bits) plus start and stop so 26 bits.  So we've
+		 * got more than 65 us between each voltage change and thus
+		 * won't ramp faster than ~1500 uV / us.
+		 */
+		ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, val);
+		delta_sel = sel - old_sel;
+	}
+
+	sel <<= ffs(mask) - 1;
+	val = tmp | sel;
+	ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, val);
+
+	/*
+	 * When we change the voltage register directly, the ramp rate is about
+	 * 100000uv/us, wait 1us to make sure the target voltage to be stable,
+	 * so we needn't wait extra time after that.
+	 */
+	udelay(1);
+
+	return ret;
+}
+
 static int rk8xx_is_enabled_wmsk_regmap(struct regulator_dev *rdev)
 {
 	unsigned int val;
@@ -185,15 +328,67 @@ static int rk8xx_is_enabled_wmsk_regmap(struct regulator_dev *rdev)
 	return val != 0;
 }
 
-static struct regulator_ops rk808_buck1_2_ops = {
+static const struct regulator_ops rk805_reg_ops = {
+	.list_voltage           = regulator_list_voltage_linear,
+	.map_voltage            = regulator_map_voltage_linear,
+	.get_voltage_sel        = regulator_get_voltage_sel_regmap,
+	.set_voltage_sel        = regulator_set_voltage_sel_regmap,
+	.enable                 = regulator_enable_regmap,
+	.disable                = regulator_disable_regmap,
+	.is_enabled             = regulator_is_enabled_regmap,
+};
+
+static const struct regulator_ops rk805_switch_ops = {
+	.enable                 = regulator_enable_regmap,
+	.disable                = regulator_disable_regmap,
+	.is_enabled             = regulator_is_enabled_regmap,
+};
+
+static const struct regulator_ops rk806_ops_dcdc = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel        = regulator_set_voltage_sel_regmap,
+
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= rk8xx_is_enabled_wmsk_regmap,
+};
+
+static const struct regulator_ops rk806_ops_nldo = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel        = regulator_set_voltage_sel_regmap,
+
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+};
+
+static const struct regulator_ops rk806_ops_pldo = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel        = regulator_set_voltage_sel_regmap,
+
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+};
+
+static const struct regulator_ops rk808_buck1_2_ops = {
 	.list_voltage		= regulator_list_voltage_linear,
 	.map_voltage		= regulator_map_voltage_linear,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= rk808_buck1_2_set_voltage_sel,
 	.enable			= regulator_enable_regmap,
 	.disable		= regulator_disable_regmap,
 	.is_enabled		= regulator_is_enabled_regmap,
 };
 
-static struct regulator_ops rk808_reg_ops = {
+static const struct regulator_ops rk808_reg_ops = {
 	.list_voltage		= regulator_list_voltage_linear,
 	.map_voltage		= regulator_map_voltage_linear,
 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
@@ -203,7 +398,7 @@ static struct regulator_ops rk808_reg_ops = {
 	.is_enabled		= regulator_is_enabled_regmap,
 };
 
-static struct regulator_ops rk808_reg_ops_ranges = {
+static const struct regulator_ops rk808_reg_ops_ranges = {
 	.list_voltage		= regulator_list_voltage_linear_range,
 	.map_voltage		= regulator_map_voltage_linear_range,
 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
@@ -213,7 +408,7 @@ static struct regulator_ops rk808_reg_ops_ranges = {
 	.is_enabled		= regulator_is_enabled_regmap,
 };
 
-static struct regulator_ops rk808_switch_ops = {
+static const struct regulator_ops rk808_switch_ops = {
 	.enable			= regulator_enable_regmap,
 	.disable		= regulator_disable_regmap,
 	.is_enabled		= regulator_is_enabled_regmap,
@@ -235,6 +430,36 @@ static const struct regulator_ops rk809_buck5_ops_range = {
 	.is_enabled		= rk8xx_is_enabled_wmsk_regmap,
 };
 
+static const struct regulator_ops rk816_buck1_2_ops_ranges = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+};
+
+static const struct regulator_ops rk816_buck4_ops_ranges = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+};
+
+static const struct regulator_ops rk816_reg_ops = {
+	.list_voltage		= regulator_list_voltage_linear,
+	.map_voltage		= regulator_map_voltage_linear,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= rk8xx_is_enabled_wmsk_regmap,
+};
+
 static const struct regulator_ops rk817_reg_ops = {
 	.list_voltage		= regulator_list_voltage_linear,
 	.map_voltage		= regulator_map_voltage_linear,
@@ -271,10 +496,13 @@ static const struct regulator_ops rk817_switch_ops = {
 	.is_enabled		= rk8xx_is_enabled_wmsk_regmap,
 };
 
-static struct rk_regulator_cfg rk805_reg[] = {
-	{{
-		/* .name = "DCDC_REG1", */
+static const struct regulator_desc rk805_reg[] = {
+	{
+		.name = "DCDC_REG1",
 		.supply_name = "vcc1",
+		.of_match = of_match_ptr("DCDC_REG1"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK805_ID_DCDC1,
 		.ops = &rk808_reg_ops_ranges,
 		.n_voltages = 64,
 		.linear_ranges = rk805_buck_1_2_voltage_ranges,
@@ -283,9 +511,12 @@ static struct rk_regulator_cfg rk805_reg[] = {
 		.vsel_mask = RK818_BUCK_VSEL_MASK,
 		.enable_reg = RK805_DCDC_EN_REG,
 		.enable_mask = BIT(0),
-	}}, {{
-		/* .name = "DCDC_REG2", */
+	}, {
+		.name = "DCDC_REG2",
 		.supply_name = "vcc2",
+		.of_match = of_match_ptr("DCDC_REG2"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK805_ID_DCDC2,
 		.ops = &rk808_reg_ops_ranges,
 		.n_voltages = 64,
 		.linear_ranges = rk805_buck_1_2_voltage_ranges,
@@ -294,35 +525,146 @@ static struct rk_regulator_cfg rk805_reg[] = {
 		.vsel_mask = RK818_BUCK_VSEL_MASK,
 		.enable_reg = RK805_DCDC_EN_REG,
 		.enable_mask = BIT(1),
-	}}, {{
-		/* .name = "DCDC_REG3", */
+	}, {
+		.name = "DCDC_REG3",
 		.supply_name = "vcc3",
-		.ops = &rk808_switch_ops,
+		.of_match = of_match_ptr("DCDC_REG3"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK805_ID_DCDC3,
+		.ops = &rk805_switch_ops,
 		.n_voltages = 1,
 		.enable_reg = RK805_DCDC_EN_REG,
 		.enable_mask = BIT(2),
-	}},
+	},
 
-	RK805_DESC(/* "DCDC_REG4", */ "vcc4", 800, 3400, 100,
+	RK805_DESC(RK805_ID_DCDC4, "DCDC_REG4", "vcc4", 800, 3400, 100,
 		RK805_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK,
 		RK805_DCDC_EN_REG, BIT(3), 0),
 
-	RK805_DESC(/* "LDO_REG1", */ "vcc5", 800, 3400, 100,
+	RK805_DESC(RK805_ID_LDO1, "LDO_REG1", "vcc5", 800, 3400, 100,
 		RK805_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK805_LDO_EN_REG,
 		BIT(0), 400),
-	RK805_DESC(/* "LDO_REG2", */ "vcc5", 800, 3400, 100,
+	RK805_DESC(RK805_ID_LDO2, "LDO_REG2", "vcc5", 800, 3400, 100,
 		RK805_LDO2_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK805_LDO_EN_REG,
 		BIT(1), 400),
-	RK805_DESC(/* "LDO_REG3", */ "vcc6", 800, 3400, 100,
+	RK805_DESC(RK805_ID_LDO3, "LDO_REG3", "vcc6", 800, 3400, 100,
 		RK805_LDO3_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK805_LDO_EN_REG,
 		BIT(2), 400),
 };
-static_assert(ARRAY_SIZE(rk805_reg) == RK805_NUM_REGULATORS);
 
-static struct rk_regulator_cfg rk808_reg[] = {
-	{{
-		/* .name = "DCDC_REG1", */
+static const struct regulator_linear_range rk806_buck_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0, 159, 6250), /* 500mV ~ 1500mV */
+	REGULATOR_LINEAR_RANGE(1500000, 160, 235, 25000), /* 1500mV ~ 3400mV */
+	REGULATOR_LINEAR_RANGE(3400000, 236, 255, 0),
+};
+
+static const struct regulator_linear_range rk806_ldo_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0, 231, 12500), /* 500mV ~ 3400mV */
+	REGULATOR_LINEAR_RANGE(3400000, 232, 255, 0),
+};
+
+static const struct regulator_desc rk806_reg[] = {
+	RK806_REGULATOR("dcdc-reg1", "vcc1", RK806_ID_DCDC1, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK1_ON_VSEL,
+			RK806_POWER_EN0, rk806_buck_voltage_ranges, 0,
+			RK806_BUCK1_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg2", "vcc2", RK806_ID_DCDC2, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK2_ON_VSEL,
+			RK806_POWER_EN0, rk806_buck_voltage_ranges, 1,
+			RK806_BUCK2_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg3", "vcc3", RK806_ID_DCDC3, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK3_ON_VSEL,
+			RK806_POWER_EN0, rk806_buck_voltage_ranges, 2,
+			RK806_BUCK3_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg4", "vcc4", RK806_ID_DCDC4, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK4_ON_VSEL,
+			RK806_POWER_EN0, rk806_buck_voltage_ranges, 3,
+			RK806_BUCK4_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+
+	RK806_REGULATOR("dcdc-reg5", "vcc5", RK806_ID_DCDC5, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK5_ON_VSEL,
+			RK806_POWER_EN1, rk806_buck_voltage_ranges, 0,
+			RK806_BUCK5_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg6", "vcc6", RK806_ID_DCDC6, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK6_ON_VSEL,
+			RK806_POWER_EN1, rk806_buck_voltage_ranges, 1,
+			RK806_BUCK6_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg7", "vcc7", RK806_ID_DCDC7, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK7_ON_VSEL,
+			RK806_POWER_EN1, rk806_buck_voltage_ranges, 2,
+			RK806_BUCK7_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg8", "vcc8", RK806_ID_DCDC8, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK8_ON_VSEL,
+			RK806_POWER_EN1, rk806_buck_voltage_ranges, 3,
+			RK806_BUCK8_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+
+	RK806_REGULATOR("dcdc-reg9", "vcc9", RK806_ID_DCDC9, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK9_ON_VSEL,
+			RK806_POWER_EN2, rk806_buck_voltage_ranges, 0,
+			RK806_BUCK9_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg10", "vcc10", RK806_ID_DCDC10, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK10_ON_VSEL,
+			RK806_POWER_EN2, rk806_buck_voltage_ranges, 1,
+			RK806_BUCK10_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+
+	RK806_REGULATOR("nldo-reg1", "vcc13", RK806_ID_NLDO1, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO1_ON_VSEL,
+			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 0,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("nldo-reg2", "vcc13", RK806_ID_NLDO2, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO2_ON_VSEL,
+			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 1,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("nldo-reg3", "vcc13", RK806_ID_NLDO3, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO3_ON_VSEL,
+			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 2,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("nldo-reg4", "vcc14", RK806_ID_NLDO4, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO4_ON_VSEL,
+			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 3,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+	RK806_REGULATOR("nldo-reg5", "vcc14", RK806_ID_NLDO5, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO5_ON_VSEL,
+			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 2,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+	RK806_REGULATOR("pldo-reg1", "vcc11", RK806_ID_PLDO1, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO1_ON_VSEL,
+			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 1,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("pldo-reg2", "vcc11", RK806_ID_PLDO2, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO2_ON_VSEL,
+			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 2,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("pldo-reg3", "vcc11", RK806_ID_PLDO3, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO3_ON_VSEL,
+			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 3,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+	RK806_REGULATOR("pldo-reg4", "vcc12", RK806_ID_PLDO4, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO4_ON_VSEL,
+			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 0,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("pldo-reg5", "vcc12", RK806_ID_PLDO5, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO5_ON_VSEL,
+			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 1,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+	RK806_REGULATOR("pldo-reg6", "vcca", RK806_ID_PLDO6, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO6_ON_VSEL,
+			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 0,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+};
+
+
+static const struct regulator_desc rk808_reg[] = {
+	{
+		.name = "DCDC_REG1",
 		.supply_name = "vcc1",
+		.of_match = of_match_ptr("DCDC_REG1"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK808_ID_DCDC1,
 		.ops = &rk808_buck1_2_ops,
 		.min_uV = 712500,
 		.uV_step = 12500,
@@ -331,9 +673,12 @@ static struct rk_regulator_cfg rk808_reg[] = {
 		.vsel_mask = RK808_BUCK_VSEL_MASK,
 		.enable_reg = RK808_DCDC_EN_REG,
 		.enable_mask = BIT(0),
-	}}, {{
-		/* .name = "DCDC_REG2", */
+	}, {
+		.name = "DCDC_REG2",
 		.supply_name = "vcc2",
+		.of_match = of_match_ptr("DCDC_REG2"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK808_ID_DCDC2,
 		.ops = &rk808_buck1_2_ops,
 		.min_uV = 712500,
 		.uV_step = 12500,
@@ -342,51 +687,32 @@ static struct rk_regulator_cfg rk808_reg[] = {
 		.vsel_mask = RK808_BUCK_VSEL_MASK,
 		.enable_reg = RK808_DCDC_EN_REG,
 		.enable_mask = BIT(1),
-	}}, {{
-		/* .name = "DCDC_REG3", */
+	}, {
+		.name = "DCDC_REG3",
 		.supply_name = "vcc3",
+		.of_match = of_match_ptr("DCDC_REG3"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK808_ID_DCDC3,
 		.ops = &rk808_switch_ops,
 		.n_voltages = 1,
 		.enable_reg = RK808_DCDC_EN_REG,
 		.enable_mask = BIT(2),
-	}}, {{
-		/* .name = "DCDC_REG4", */
-		.supply_name = "vcc4",
-		.ops = &rk808_reg_ops,
-		.min_uV = 1800000,
-		.uV_step = 100000,
-		.n_voltages = 16,
-		.vsel_reg = RK808_BUCK4_ON_VSEL_REG,
-		.vsel_mask = RK808_BUCK4_VSEL_MASK,
-		.enable_reg = RK808_DCDC_EN_REG,
-		.enable_mask = BIT(3),
-	}}, {{
-		/* .name = "LDO_REG1", */
-		.supply_name = "vcc6",
-		.ops = &rk808_reg_ops,
-		.min_uV = 1800000,
-		.uV_step = 100000,
-		.n_voltages = 17,
-		.vsel_reg = RK808_LDO1_ON_VSEL_REG,
-		.vsel_mask = RK808_LDO_VSEL_MASK,
-		.enable_reg = RK808_LDO_EN_REG,
-		.enable_mask = BIT(0),
-		.off_on_delay = 400,
-	}}, {{
-		/* .name = "LDO_REG2", */
-		.supply_name = "vcc6",
-		.ops = &rk808_reg_ops,
-		.min_uV = 1800000,
-		.uV_step = 100000,
-		.n_voltages = 17,
-		.vsel_reg = RK808_LDO2_ON_VSEL_REG,
-		.vsel_mask = RK808_LDO_VSEL_MASK,
-		.enable_reg = RK808_LDO_EN_REG,
-		.enable_mask = BIT(1),
-		.off_on_delay = 400,
-	}}, {{
-		/* .name = "LDO_REG3", */
+	},
+	RK8XX_DESC(RK808_ID_DCDC4, "DCDC_REG4", "vcc4", 1800, 3300, 100,
+		RK808_BUCK4_ON_VSEL_REG, RK808_BUCK4_VSEL_MASK,
+		RK808_DCDC_EN_REG, BIT(3), 0),
+	RK8XX_DESC(RK808_ID_LDO1, "LDO_REG1", "vcc6", 1800, 3400, 100,
+		RK808_LDO1_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+		BIT(0), 400),
+	RK8XX_DESC(RK808_ID_LDO2, "LDO_REG2", "vcc6", 1800, 3400, 100,
+		RK808_LDO2_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+		BIT(1), 400),
+	{
+		.name = "LDO_REG3",
 		.supply_name = "vcc7",
+		.of_match = of_match_ptr("LDO_REG3"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK808_ID_LDO3,
 		.ops = &rk808_reg_ops_ranges,
 		.n_voltages = 16,
 		.linear_ranges = rk808_ldo3_voltage_ranges,
@@ -395,87 +721,35 @@ static struct rk_regulator_cfg rk808_reg[] = {
 		.vsel_mask = RK808_BUCK4_VSEL_MASK,
 		.enable_reg = RK808_LDO_EN_REG,
 		.enable_mask = BIT(2),
-		.off_on_delay = 400,
-	}}, {{
-		/* .name = "LDO_REG4", */
-		.supply_name = "vcc9",
-		.ops = &rk808_reg_ops,
-		.min_uV = 1800000,
-		.uV_step = 100000,
-		.n_voltages = 17,
-		.vsel_reg = RK808_LDO4_ON_VSEL_REG,
-		.vsel_mask = RK808_LDO_VSEL_MASK,
-		.enable_reg = RK808_LDO_EN_REG,
-		.enable_mask = BIT(3),
-		.off_on_delay = 400,
-	}}, {{
-		/* .name = "LDO_REG5", */
-		.supply_name = "vcc9",
-		.ops = &rk808_reg_ops,
-		.min_uV = 1800000,
-		.uV_step = 100000,
-		.n_voltages = 17,
-		.vsel_reg = RK808_LDO5_ON_VSEL_REG,
-		.vsel_mask = RK808_LDO_VSEL_MASK,
-		.enable_reg = RK808_LDO_EN_REG,
-		.enable_mask = BIT(4),
-		.off_on_delay = 400,
-	}}, {{
-		/* .name = "LDO_REG6", */
-		.supply_name = "vcc10",
-		.ops = &rk808_reg_ops,
-		.min_uV = 800000,
-		.uV_step = 100000,
-		.n_voltages = 18,
-		.vsel_reg = RK808_LDO6_ON_VSEL_REG,
-		.vsel_mask = RK808_LDO_VSEL_MASK,
-		.enable_reg = RK808_LDO_EN_REG,
-		.enable_mask = BIT(5),
-		.off_on_delay = 400,
-	}}, {{
-		/* .name = "LDO_REG7", */
-		.supply_name = "vcc7",
-		.ops = &rk808_reg_ops,
-		.min_uV = 800000,
-		.uV_step = 100000,
-		.n_voltages = 18,
-		.vsel_reg = RK808_LDO7_ON_VSEL_REG,
-		.vsel_mask = RK808_LDO_VSEL_MASK,
-		.enable_reg = RK808_LDO_EN_REG,
-		.enable_mask = BIT(6),
-		.off_on_delay = 400,
-	}}, {{
-		/* .name = "LDO_REG8", */
-		.supply_name = "vcc11",
-		.ops = &rk808_reg_ops,
-		.min_uV = 1800000,
-		.uV_step = 100000,
-		.n_voltages = 17,
-		.vsel_reg = RK808_LDO8_ON_VSEL_REG,
-		.vsel_mask = RK808_LDO_VSEL_MASK,
-		.enable_reg = RK808_LDO_EN_REG,
-		.enable_mask = BIT(7),
-		.off_on_delay = 400,
-	}}, {{
-		/* .name = "SWITCH_REG1", */
-		.supply_name = "vcc8",
-		.ops = &rk808_switch_ops,
-		.enable_reg = RK808_DCDC_EN_REG,
-		.enable_mask = BIT(5),
-	}}, {{
-		/* .name = "SWITCH_REG2", */
-		.supply_name = "vcc12",
-		.ops = &rk808_switch_ops,
-		.enable_reg = RK808_DCDC_EN_REG,
-		.enable_mask = BIT(6),
-	}},
+	},
+	RK8XX_DESC(RK808_ID_LDO4, "LDO_REG4", "vcc9", 1800, 3400, 100,
+		RK808_LDO4_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+		BIT(3), 400),
+	RK8XX_DESC(RK808_ID_LDO5, "LDO_REG5", "vcc9", 1800, 3400, 100,
+		RK808_LDO5_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+		BIT(4), 400),
+	RK8XX_DESC(RK808_ID_LDO6, "LDO_REG6", "vcc10", 800, 2500, 100,
+		RK808_LDO6_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+		BIT(5), 400),
+	RK8XX_DESC(RK808_ID_LDO7, "LDO_REG7", "vcc7", 800, 2500, 100,
+		RK808_LDO7_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+		BIT(6), 400),
+	RK8XX_DESC(RK808_ID_LDO8, "LDO_REG8", "vcc11", 1800, 3400, 100,
+		RK808_LDO8_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG,
+		BIT(7), 400),
+	RK8XX_DESC_SWITCH(RK808_ID_SWITCH1, "SWITCH_REG1", "vcc8",
+		RK808_DCDC_EN_REG, BIT(5)),
+	RK8XX_DESC_SWITCH(RK808_ID_SWITCH2, "SWITCH_REG2", "vcc12",
+		RK808_DCDC_EN_REG, BIT(6)),
 };
-static_assert(ARRAY_SIZE(rk808_reg) == RK808_NUM_REGULATORS);
 
-static struct rk_regulator_cfg rk809_reg[] = {
-	{{
-		/* .name = "DCDC_REG1", */
+static const struct regulator_desc rk809_reg[] = {
+	{
+		.name = "DCDC_REG1",
 		.supply_name = "vcc1",
+		.of_match = of_match_ptr("DCDC_REG1"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK817_ID_DCDC1,
 		.ops = &rk817_buck_ops_range,
 		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
 		.linear_ranges = rk817_buck1_voltage_ranges,
@@ -486,9 +760,12 @@ static struct rk_regulator_cfg rk809_reg[] = {
 		.enable_mask = ENABLE_MASK(RK817_ID_DCDC1),
 		.enable_val = ENABLE_MASK(RK817_ID_DCDC1),
 		.disable_val = DISABLE_VAL(RK817_ID_DCDC1),
-	}}, {{
-		/* .name = "DCDC_REG2", */
+	}, {
+		.name = "DCDC_REG2",
 		.supply_name = "vcc2",
+		.of_match = of_match_ptr("DCDC_REG2"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK817_ID_DCDC2,
 		.ops = &rk817_buck_ops_range,
 		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
 		.linear_ranges = rk817_buck1_voltage_ranges,
@@ -499,9 +776,12 @@ static struct rk_regulator_cfg rk809_reg[] = {
 		.enable_mask = ENABLE_MASK(RK817_ID_DCDC2),
 		.enable_val = ENABLE_MASK(RK817_ID_DCDC2),
 		.disable_val = DISABLE_VAL(RK817_ID_DCDC2),
-	}}, {{
-		/* .name = "DCDC_REG3", */
+	}, {
+		.name = "DCDC_REG3",
 		.supply_name = "vcc3",
+		.of_match = of_match_ptr("DCDC_REG3"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK817_ID_DCDC3,
 		.ops = &rk817_buck_ops_range,
 		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
 		.linear_ranges = rk817_buck1_voltage_ranges,
@@ -512,9 +792,12 @@ static struct rk_regulator_cfg rk809_reg[] = {
 		.enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
 		.enable_val = ENABLE_MASK(RK817_ID_DCDC3),
 		.disable_val = DISABLE_VAL(RK817_ID_DCDC3),
-	}}, {{
-		/* .name = "DCDC_REG4", */
+	}, {
+		.name = "DCDC_REG4",
 		.supply_name = "vcc4",
+		.of_match = of_match_ptr("DCDC_REG4"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK817_ID_DCDC4,
 		.ops = &rk817_buck_ops_range,
 		.n_voltages = RK817_BUCK3_SEL_CNT + 1,
 		.linear_ranges = rk817_buck3_voltage_ranges,
@@ -525,68 +808,166 @@ static struct rk_regulator_cfg rk809_reg[] = {
 		.enable_mask = ENABLE_MASK(RK817_ID_DCDC4),
 		.enable_val = ENABLE_MASK(RK817_ID_DCDC4),
 		.disable_val = DISABLE_VAL(RK817_ID_DCDC4),
-	}},
-	RK817_DESC(/* "LDO_REG1", */ "vcc5", 600, 3400, 25,
+	},
+	{
+		.name = "DCDC_REG5",
+		.supply_name = "vcc9",
+		.of_match = of_match_ptr("DCDC_REG5"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK809_ID_DCDC5,
+		.ops = &rk809_buck5_ops_range,
+		.n_voltages = RK809_BUCK5_SEL_CNT,
+		.linear_ranges = rk809_buck5_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk809_buck5_voltage_ranges),
+		.vsel_reg = RK809_BUCK5_CONFIG(0),
+		.vsel_mask = RK809_BUCK5_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(3),
+		.enable_mask = ENABLE_MASK(1),
+		.enable_val = ENABLE_MASK(1),
+		.disable_val = DISABLE_VAL(1),
+	},
+	RK817_DESC(RK817_ID_LDO1, "LDO_REG1", "vcc5", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(0), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(1), ENABLE_MASK(0),
 		   DISABLE_VAL(0), 400),
-	RK817_DESC(/* "LDO_REG2", */ "vcc5", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO2, "LDO_REG2", "vcc5", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(1), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(1), ENABLE_MASK(1),
 		   DISABLE_VAL(1), 400),
-	RK817_DESC(/* "LDO_REG3", */ "vcc5", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO3, "LDO_REG3", "vcc5", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(2), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(1), ENABLE_MASK(2),
 		   DISABLE_VAL(2), 400),
-	RK817_DESC(/* "LDO_REG4", */ "vcc6", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO4, "LDO_REG4", "vcc6", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(3), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(1), ENABLE_MASK(3),
 		   DISABLE_VAL(3), 400),
-	RK817_DESC(/* "LDO_REG5", */ "vcc6", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO5, "LDO_REG5", "vcc6", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(4), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(2), ENABLE_MASK(0),
 		   DISABLE_VAL(0), 400),
-	RK817_DESC(/* "LDO_REG6", */ "vcc6", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO6, "LDO_REG6", "vcc6", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(5), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(2), ENABLE_MASK(1),
 		   DISABLE_VAL(1), 400),
-	RK817_DESC(/* "LDO_REG7", */ "vcc7", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO7, "LDO_REG7", "vcc7", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(6), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(2), ENABLE_MASK(2),
 		   DISABLE_VAL(2), 400),
-	RK817_DESC(/* "LDO_REG8", */ "vcc7", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO8, "LDO_REG8", "vcc7", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(7), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(2), ENABLE_MASK(3),
 		   DISABLE_VAL(3), 400),
-	RK817_DESC(/* "LDO_REG9", */ "vcc7", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO9, "LDO_REG9", "vcc7", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(8), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(3), ENABLE_MASK(0),
 		   DISABLE_VAL(0), 400),
-	{{
-		/* .name = "DCDC_REG5", */
-		.supply_name = "vcc9",
-		.ops = &rk809_buck5_ops_range,
-		.n_voltages = RK809_BUCK5_SEL_CNT,
-		.linear_ranges = rk809_buck5_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(rk809_buck5_voltage_ranges),
-		.vsel_reg = RK809_BUCK5_CONFIG(0),
-		.vsel_mask = RK809_BUCK5_VSEL_MASK,
-		.enable_reg = RK817_POWER_EN_REG(3),
-		.enable_mask = ENABLE_MASK(1),
-		.enable_val = ENABLE_MASK(1),
-		.disable_val = DISABLE_VAL(1),
-	}},
-	RK817_DESC_SWITCH(/* "SWITCH_REG1", */ "vcc9",
-			  RK817_POWER_EN_REG(3), ENABLE_MASK(2), DISABLE_VAL(2)),
-	RK817_DESC_SWITCH(/* "SWITCH_REG2", */ "vcc8",
-			  RK817_POWER_EN_REG(3), ENABLE_MASK(3), DISABLE_VAL(3)),
+	RK817_DESC_SWITCH(RK809_ID_SW1, "SWITCH_REG1", "vcc9",
+			  RK817_POWER_EN_REG(3), ENABLE_MASK(2),
+			  DISABLE_VAL(2)),
+	RK817_DESC_SWITCH(RK809_ID_SW2, "SWITCH_REG2", "vcc8",
+			  RK817_POWER_EN_REG(3), ENABLE_MASK(3),
+			  DISABLE_VAL(3)),
 };
-static_assert(ARRAY_SIZE(rk809_reg) == RK809_NUM_REGULATORS);
 
-static struct rk_regulator_cfg rk817_reg[] = {
-	{{
-		/* .name = "DCDC_REG1", */
+static const struct regulator_linear_range rk816_buck_4_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(800000, 0, 26, 100000),
+	REGULATOR_LINEAR_RANGE(3500000, 27, 31, 0),
+};
+
+static const struct regulator_desc rk816_reg[] = {
+	{
+		.name = "dcdc1",
 		.supply_name = "vcc1",
+		.of_match = of_match_ptr("dcdc1"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK816_ID_DCDC1,
+		.ops = &rk816_buck1_2_ops_ranges,
+		.n_voltages = 64,
+		.linear_ranges = rk805_buck_1_2_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk805_buck_1_2_voltage_ranges),
+		.vsel_reg = RK818_BUCK1_ON_VSEL_REG,
+		.vsel_mask = RK818_BUCK_VSEL_MASK,
+		.apply_reg = RK816_DCDC_EN_REG2,
+		.apply_bit = RK816_BUCK_DVS_CONFIRM,
+		.enable_reg = RK816_DCDC_EN_REG1,
+		.enable_mask = BIT(4) | BIT(0),
+		.enable_val = BIT(4) | BIT(0),
+		.disable_val = BIT(4),
+	}, {
+		.name = "dcdc2",
+		.supply_name = "vcc2",
+		.of_match = of_match_ptr("dcdc2"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK816_ID_DCDC2,
+		.ops = &rk816_buck1_2_ops_ranges,
+		.n_voltages = 64,
+		.linear_ranges = rk805_buck_1_2_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk805_buck_1_2_voltage_ranges),
+		.vsel_reg = RK818_BUCK2_ON_VSEL_REG,
+		.vsel_mask = RK818_BUCK_VSEL_MASK,
+		.apply_reg = RK816_DCDC_EN_REG2,
+		.apply_bit = RK816_BUCK_DVS_CONFIRM,
+		.enable_reg = RK816_DCDC_EN_REG1,
+		.enable_mask = BIT(5) | BIT(1),
+		.enable_val = BIT(5) | BIT(1),
+		.disable_val = BIT(5),
+	}, {
+		.name = "dcdc3",
+		.supply_name = "vcc3",
+		.of_match = of_match_ptr("dcdc3"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK816_ID_DCDC3,
+		.ops = &rk808_switch_ops,
+		.n_voltages = 1,
+		.enable_reg = RK816_DCDC_EN_REG1,
+		.enable_mask = BIT(6) | BIT(2),
+		.enable_val =  BIT(6) | BIT(2),
+		.disable_val = BIT(6),
+	}, {
+		.name = "dcdc4",
+		.supply_name = "vcc4",
+		.of_match = of_match_ptr("dcdc4"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK816_ID_DCDC4,
+		.ops = &rk816_buck4_ops_ranges,
+		.n_voltages = 32,
+		.linear_ranges = rk816_buck_4_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk816_buck_4_voltage_ranges),
+		.vsel_reg = RK818_BUCK4_ON_VSEL_REG,
+		.vsel_mask = RK818_BUCK4_VSEL_MASK,
+		.enable_reg = RK816_DCDC_EN_REG1,
+		.enable_mask = BIT(7) | BIT(3),
+		.enable_val = BIT(7) | BIT(3),
+		.disable_val = BIT(7),
+	},
+	RK816_DESC(RK816_ID_LDO1, "ldo1", "vcc5", 800, 3400, 100,
+		   RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+		   RK816_LDO_EN_REG1, ENABLE_MASK(0), DISABLE_VAL(0), 400),
+	RK816_DESC(RK816_ID_LDO2, "ldo2", "vcc5", 800, 3400, 100,
+		   RK818_LDO2_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+		   RK816_LDO_EN_REG1, ENABLE_MASK(1), DISABLE_VAL(1), 400),
+	RK816_DESC(RK816_ID_LDO3, "ldo3", "vcc5", 800, 3400, 100,
+		   RK818_LDO3_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+		   RK816_LDO_EN_REG1, ENABLE_MASK(2), DISABLE_VAL(2), 400),
+	RK816_DESC(RK816_ID_LDO4, "ldo4", "vcc6", 800, 3400, 100,
+		   RK818_LDO4_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+		   RK816_LDO_EN_REG1, ENABLE_MASK(3), DISABLE_VAL(3), 400),
+	RK816_DESC(RK816_ID_LDO5, "ldo5", "vcc6", 800, 3400, 100,
+		   RK818_LDO5_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+		   RK816_LDO_EN_REG2, ENABLE_MASK(0), DISABLE_VAL(0), 400),
+	RK816_DESC(RK816_ID_LDO6, "ldo6", "vcc6", 800, 3400, 100,
+		   RK818_LDO6_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+		   RK816_LDO_EN_REG2, ENABLE_MASK(1), DISABLE_VAL(1), 400),
+};
+
+static const struct regulator_desc rk817_reg[] = {
+	{
+		.name = "DCDC_REG1",
+		.supply_name = "vcc1",
+		.of_match = of_match_ptr("DCDC_REG1"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK817_ID_DCDC1,
 		.ops = &rk817_buck_ops_range,
 		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
 		.linear_ranges = rk817_buck1_voltage_ranges,
@@ -597,9 +978,12 @@ static struct rk_regulator_cfg rk817_reg[] = {
 		.enable_mask = ENABLE_MASK(RK817_ID_DCDC1),
 		.enable_val = ENABLE_MASK(RK817_ID_DCDC1),
 		.disable_val = DISABLE_VAL(RK817_ID_DCDC1),
-	 }}, {{
-		/* .name = "DCDC_REG2", */
+	}, {
+		.name = "DCDC_REG2",
 		.supply_name = "vcc2",
+		.of_match = of_match_ptr("DCDC_REG2"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK817_ID_DCDC2,
 		.ops = &rk817_buck_ops_range,
 		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
 		.linear_ranges = rk817_buck1_voltage_ranges,
@@ -610,9 +994,12 @@ static struct rk_regulator_cfg rk817_reg[] = {
 		.enable_mask = ENABLE_MASK(RK817_ID_DCDC2),
 		.enable_val = ENABLE_MASK(RK817_ID_DCDC2),
 		.disable_val = DISABLE_VAL(RK817_ID_DCDC2),
-	 }}, {{
-		/* .name = "DCDC_REG3", */
+	}, {
+		.name = "DCDC_REG3",
 		.supply_name = "vcc3",
+		.of_match = of_match_ptr("DCDC_REG3"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK817_ID_DCDC3,
 		.ops = &rk817_buck_ops_range,
 		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
 		.linear_ranges = rk817_buck1_voltage_ranges,
@@ -623,9 +1010,12 @@ static struct rk_regulator_cfg rk817_reg[] = {
 		.enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
 		.enable_val = ENABLE_MASK(RK817_ID_DCDC3),
 		.disable_val = DISABLE_VAL(RK817_ID_DCDC3),
-	 }}, {{
-		/* .name = "DCDC_REG4", */
+	}, {
+		.name = "DCDC_REG4",
 		.supply_name = "vcc4",
+		.of_match = of_match_ptr("DCDC_REG4"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK817_ID_DCDC4,
 		.ops = &rk817_buck_ops_range,
 		.n_voltages = RK817_BUCK3_SEL_CNT + 1,
 		.linear_ranges = rk817_buck3_voltage_ranges,
@@ -636,56 +1026,59 @@ static struct rk_regulator_cfg rk817_reg[] = {
 		.enable_mask = ENABLE_MASK(RK817_ID_DCDC4),
 		.enable_val = ENABLE_MASK(RK817_ID_DCDC4),
 		.disable_val = DISABLE_VAL(RK817_ID_DCDC4),
-	}},
-	RK817_DESC(/* "LDO_REG1", */ "vcc5", 600, 3400, 25,
+	},
+	RK817_DESC(RK817_ID_LDO1, "LDO_REG1", "vcc5", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(0), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(1), ENABLE_MASK(0),
 		   DISABLE_VAL(0), 400),
-	RK817_DESC(/* "LDO_REG2", */ "vcc5", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO2, "LDO_REG2", "vcc5", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(1), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(1), ENABLE_MASK(1),
 		   DISABLE_VAL(1), 400),
-	RK817_DESC(/* "LDO_REG3", */ "vcc5", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO3, "LDO_REG3", "vcc5", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(2), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(1), ENABLE_MASK(2),
 		   DISABLE_VAL(2), 400),
-	RK817_DESC(/* "LDO_REG4", */ "vcc6", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO4, "LDO_REG4", "vcc6", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(3), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(1), ENABLE_MASK(3),
 		   DISABLE_VAL(3), 400),
-	RK817_DESC(/* "LDO_REG5", */ "vcc6", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO5, "LDO_REG5", "vcc6", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(4), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(2), ENABLE_MASK(0),
 		   DISABLE_VAL(0), 400),
-	RK817_DESC(/* "LDO_REG6", */ "vcc6", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO6, "LDO_REG6", "vcc6", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(5), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(2), ENABLE_MASK(1),
 		   DISABLE_VAL(1), 400),
-	RK817_DESC(/* "LDO_REG7", */ "vcc7", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO7, "LDO_REG7", "vcc7", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(6), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(2), ENABLE_MASK(2),
 		   DISABLE_VAL(2), 400),
-	RK817_DESC(/* "LDO_REG8", */ "vcc7", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO8, "LDO_REG8", "vcc7", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(7), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(2), ENABLE_MASK(3),
 		   DISABLE_VAL(3), 400),
-	RK817_DESC(/* "LDO_REG9", */ "vcc7", 600, 3400, 25,
+	RK817_DESC(RK817_ID_LDO9, "LDO_REG9", "vcc7", 600, 3400, 25,
 		   RK817_LDO_ON_VSEL_REG(8), RK817_LDO_VSEL_MASK,
 		   RK817_POWER_EN_REG(3), ENABLE_MASK(0),
 		   DISABLE_VAL(0), 400),
-	RK817_BOOST_DESC(/* "BOOST", */ "vcc8", 4700, 5400, 100,
+	RK817_BOOST_DESC(RK817_ID_BOOST, "BOOST", "vcc8", 4700, 5400, 100,
 			 RK817_BOOST_OTG_CFG, RK817_BOOST_VSEL_MASK,
 			 RK817_POWER_EN_REG(3), ENABLE_MASK(1), ENABLE_MASK(1),
-		   DISABLE_VAL(1), 400),
-	RK817_DESC_SWITCH(/* "OTG_SWITCH", */ "vcc9",
-			 RK817_POWER_EN_REG(3), ENABLE_MASK(2), DISABLE_VAL(2)),
+		   DISABLE_VAL(1), 400, 3500 - 5400),
+	RK817_DESC_SWITCH(RK817_ID_BOOST_OTG_SW, "OTG_SWITCH", "vcc9",
+			  RK817_POWER_EN_REG(3), ENABLE_MASK(2),
+			  DISABLE_VAL(2)),
 };
-static_assert(ARRAY_SIZE(rk817_reg) == RK817_NUM_REGULATORS);
 
-static struct rk_regulator_cfg rk818_reg[] = {
-	{{
-		/* .name = "DCDC_REG1", */
+static const struct regulator_desc rk818_reg[] = {
+	{
+		.name = "DCDC_REG1",
 		.supply_name = "vcc1",
+		.of_match = of_match_ptr("DCDC_REG1"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK818_ID_DCDC1,
 		.ops = &rk808_reg_ops,
 		.min_uV = 712500,
 		.uV_step = 12500,
@@ -694,9 +1087,12 @@ static struct rk_regulator_cfg rk818_reg[] = {
 		.vsel_mask = RK818_BUCK_VSEL_MASK,
 		.enable_reg = RK818_DCDC_EN_REG,
 		.enable_mask = BIT(0),
-	 }}, {{
-		/* .name = "DCDC_REG2", */
+	}, {
+		.name = "DCDC_REG2",
 		.supply_name = "vcc2",
+		.of_match = of_match_ptr("DCDC_REG2"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK818_ID_DCDC2,
 		.ops = &rk808_reg_ops,
 		.min_uV = 712500,
 		.uV_step = 12500,
@@ -705,29 +1101,35 @@ static struct rk_regulator_cfg rk818_reg[] = {
 		.vsel_mask = RK818_BUCK_VSEL_MASK,
 		.enable_reg = RK818_DCDC_EN_REG,
 		.enable_mask = BIT(1),
-	 }}, {{
-		/* .name = "DCDC_REG3", */
+	}, {
+		.name = "DCDC_REG3",
 		.supply_name = "vcc3",
+		.of_match = of_match_ptr("DCDC_REG3"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK818_ID_DCDC3,
 		.ops = &rk808_switch_ops,
 		.n_voltages = 1,
 		.enable_reg = RK818_DCDC_EN_REG,
 		.enable_mask = BIT(2),
-	}},
-	RK8XX_DESC(/* "DCDC_REG4", */ "vcc4", 1800, 3600, 100,
+	},
+	RK8XX_DESC(RK818_ID_DCDC4, "DCDC_REG4", "vcc4", 1800, 3600, 100,
 		RK818_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK,
 		RK818_DCDC_EN_REG, BIT(3), 0),
-	RK8XX_DESC(/* "DCDC_BOOST", */ "boost", 4700, 5400, 100,
+	RK8XX_DESC(RK818_ID_BOOST, "DCDC_BOOST", "boost", 4700, 5400, 100,
 		RK818_BOOST_LDO9_ON_VSEL_REG, RK818_BOOST_ON_VSEL_MASK,
 		RK818_DCDC_EN_REG, BIT(4), 0),
-	RK8XX_DESC(/* "LDO_REG1", */ "vcc6", 1800, 3400, 100,
+	RK8XX_DESC(RK818_ID_LDO1, "LDO_REG1", "vcc6", 1800, 3400, 100,
 		RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
 		BIT(0), 400),
-	RK8XX_DESC(/* "LDO_REG2", */ "vcc6", 1800, 3400, 100,
+	RK8XX_DESC(RK818_ID_LDO2, "LDO_REG2", "vcc6", 1800, 3400, 100,
 		RK818_LDO2_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
 		BIT(1), 400),
-	{{
-		/* .name = "LDO_REG3", */
+	{
+		.name = "LDO_REG3",
 		.supply_name = "vcc7",
+		.of_match = of_match_ptr("LDO_REG3"),
+		.regulators_node = of_match_ptr("regulators"),
+		.id = RK818_ID_LDO3,
 		.ops = &rk808_reg_ops_ranges,
 		.n_voltages = 16,
 		.linear_ranges = rk808_ldo3_voltage_ranges,
@@ -736,214 +1138,85 @@ static struct rk_regulator_cfg rk818_reg[] = {
 		.vsel_mask = RK818_LDO3_ON_VSEL_MASK,
 		.enable_reg = RK818_LDO_EN_REG,
 		.enable_mask = BIT(2),
-		.off_on_delay = 400,
-	}},
-	RK8XX_DESC(/* "LDO_REG4", */ "vcc8", 1800, 3400, 100,
+	},
+	RK8XX_DESC(RK818_ID_LDO4, "LDO_REG4", "vcc8", 1800, 3400, 100,
 		RK818_LDO4_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
 		BIT(3), 400),
-	RK8XX_DESC(/* "LDO_REG5", */ "vcc7", 1800, 3400, 100,
+	RK8XX_DESC(RK818_ID_LDO5, "LDO_REG5", "vcc7", 1800, 3400, 100,
 		RK818_LDO5_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
 		BIT(4), 400),
-	RK8XX_DESC(/* "LDO_REG6", */ "vcc8", 800, 2500, 100,
+	RK8XX_DESC(RK818_ID_LDO6, "LDO_REG6", "vcc8", 800, 2500, 100,
 		RK818_LDO6_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
 		BIT(5), 400),
-	RK8XX_DESC(/* "LDO_REG7", */ "vcc7", 800, 2500, 100,
+	RK8XX_DESC(RK818_ID_LDO7, "LDO_REG7", "vcc7", 800, 2500, 100,
 		RK818_LDO7_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
 		BIT(6), 400),
-	RK8XX_DESC(/* "LDO_REG8", */ "vcc8", 1800, 3400, 100,
+	RK8XX_DESC(RK818_ID_LDO8, "LDO_REG8", "vcc8", 1800, 3400, 100,
 		RK818_LDO8_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
 		BIT(7), 400),
-	RK8XX_DESC(/* "LDO_REG9", */ "vcc9", 1800, 3400, 100,
+	RK8XX_DESC(RK818_ID_LDO9, "LDO_REG9", "vcc9", 1800, 3400, 100,
 		RK818_BOOST_LDO9_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
 		RK818_DCDC_EN_REG, BIT(5), 400),
-	RK8XX_DESC_SWITCH(/* "SWITCH_REG", */ "vcc9",
-			  RK818_DCDC_EN_REG, BIT(6)),
-	RK8XX_DESC_SWITCH(/* "HDMI_SWITCH", */ "h_5v",
-			  RK818_H5V_EN_REG, BIT(0)),
-	RK8XX_DESC_SWITCH(/* "OTG_SWITCH", */ "usb",
-			  RK818_DCDC_EN_REG, BIT(7)),
-};
-static_assert(ARRAY_SIZE(rk818_reg) == RK818_NUM_REGULATORS);
-
-static int rk808_regulator_register(struct rk808 *rk808, int id,
-				    struct of_regulator_match *match,
-				    struct rk_regulator_cfg *cfg)
-{
-	struct device *dev = rk808->dev;
-	int ret;
-
-	if (!match->of_node) {
-		dev_dbg(dev, "Skip missing DTB regulator %s", match->name);
-		return 0;
-	}
-
-	cfg->rdev.desc = &cfg->desc;
-	cfg->rdev.dev = dev;
-	cfg->rdev.regmap = rk808->regmap;
-
-	ret = of_regulator_register(&cfg->rdev, match->of_node);
-	if (ret)
-		return dev_err_probe(dev, ret, "failed to register %s regulator\n",
-				     match->name);
-
-	dev_dbg(dev, "registered %s\n", match->name);
-
-	return 0;
-}
-
-#define MATCH(variant, _name, _id) [RK##variant##_ID_##_id] = \
-	{ .name = #_name, .desc = &rk##variant##_reg[RK##variant##_ID_##_id].desc }
-
-static struct of_regulator_match rk805_reg_matches[] = {
-	MATCH(805, DCDC_REG1, DCDC1),
-	MATCH(805, DCDC_REG2, DCDC2),
-	MATCH(805, DCDC_REG3, DCDC3),
-	MATCH(805, DCDC_REG4, DCDC4),
-	MATCH(805, LDO_REG1, LDO1),
-	MATCH(805, LDO_REG2, LDO2),
-	MATCH(805, LDO_REG3, LDO3),
-};
-static_assert(ARRAY_SIZE(rk805_reg_matches) == RK805_NUM_REGULATORS);
-
-static struct of_regulator_match rk808_reg_matches[] = {
-	MATCH(808, DCDC_REG1, DCDC1),
-	MATCH(808, DCDC_REG2, DCDC2),
-	MATCH(808, DCDC_REG3, DCDC3),
-	MATCH(808, DCDC_REG4, DCDC4),
-	MATCH(808, LDO_REG1, LDO1),
-	MATCH(808, LDO_REG2, LDO2),
-	MATCH(808, LDO_REG3, LDO3),
-	MATCH(808, LDO_REG4, LDO4),
-	MATCH(808, LDO_REG5, LDO5),
-	MATCH(808, LDO_REG6, LDO6),
-	MATCH(808, LDO_REG7, LDO7),
-	MATCH(808, LDO_REG8, LDO8),
-	MATCH(808, SWITCH_REG1, SWITCH1),
-	MATCH(808, SWITCH_REG2, SWITCH2),
-};
-static_assert(ARRAY_SIZE(rk808_reg_matches) == RK808_NUM_REGULATORS);
-
-static struct of_regulator_match rk809_reg_matches[] = {
-	MATCH(809, DCDC_REG1, DCDC1),
-	MATCH(809, DCDC_REG2, DCDC2),
-	MATCH(809, DCDC_REG3, DCDC3),
-	MATCH(809, DCDC_REG4, DCDC4),
-	MATCH(809, LDO_REG1, LDO1),
-	MATCH(809, LDO_REG2, LDO2),
-	MATCH(809, LDO_REG3, LDO3),
-	MATCH(809, LDO_REG4, LDO4),
-	MATCH(809, LDO_REG5, LDO5),
-	MATCH(809, LDO_REG6, LDO6),
-	MATCH(809, LDO_REG7, LDO7),
-	MATCH(809, LDO_REG8, LDO8),
-	MATCH(809, LDO_REG9, LDO9),
-	MATCH(809, DCDC_REG5, DCDC5),
-	MATCH(809, SWITCH_REG1, SW1),
-	MATCH(809, SWITCH_REG2, SW2),
-};
-static_assert(ARRAY_SIZE(rk809_reg_matches) == RK809_NUM_REGULATORS);
-
-static struct of_regulator_match rk817_reg_matches[] = {
-	MATCH(817, DCDC_REG1, DCDC1),
-	MATCH(817, DCDC_REG2, DCDC2),
-	MATCH(817, DCDC_REG3, DCDC3),
-	MATCH(817, DCDC_REG4, DCDC4),
-	MATCH(817, LDO_REG1, LDO1),
-	MATCH(817, LDO_REG2, LDO2),
-	MATCH(817, LDO_REG3, LDO3),
-	MATCH(817, LDO_REG4, LDO4),
-	MATCH(817, LDO_REG5, LDO5),
-	MATCH(817, LDO_REG6, LDO6),
-	MATCH(817, LDO_REG7, LDO7),
-	MATCH(817, LDO_REG8, LDO8),
-	MATCH(817, LDO_REG9, LDO9),
-	MATCH(817, BOOST, BOOST),
-	MATCH(817, OTG_SWITCH, BOOST_OTG_SW),
-};
-static_assert(ARRAY_SIZE(rk817_reg_matches) == RK817_NUM_REGULATORS);
-
-static struct of_regulator_match rk818_reg_matches[] = {
-	MATCH(818, DCDC_REG1, DCDC1),
-	MATCH(818, DCDC_REG2, DCDC2),
-	MATCH(818, DCDC_REG3, DCDC3),
-	MATCH(818, DCDC_REG4, DCDC4),
-	MATCH(818, DCDC_BOOST, BOOST),
-	MATCH(818, LDO_REG1, LDO1),
-	MATCH(818, LDO_REG2, LDO2),
-	MATCH(818, LDO_REG3, LDO3),
-	MATCH(818, LDO_REG4, LDO4),
-	MATCH(818, LDO_REG5, LDO5),
-	MATCH(818, LDO_REG6, LDO6),
-	MATCH(818, LDO_REG7, LDO7),
-	MATCH(818, LDO_REG8, LDO8),
-	MATCH(818, LDO_REG9, LDO9),
-	MATCH(818, SWITCH_REG, SWITCH),
-	MATCH(818, HDMI_SWITCH, HDMI_SWITCH),
-	MATCH(818, OTG_SWITCH, OTG_SWITCH),
-};
-static_assert(ARRAY_SIZE(rk818_reg_matches) == RK818_NUM_REGULATORS);
-
-static int rk808_regulator_dt_parse(struct device *dev,
-				    struct of_regulator_match *matches,
-				    int nregulators)
-{
-	struct device_node *np = dev->of_node;
-
-	np = of_get_child_by_name(np, "regulators");
-	if (!np)
-		return -ENOENT;
-
-	return of_regulator_match(dev, np, matches, nregulators);
-}
+	RK8XX_DESC_SWITCH(RK818_ID_SWITCH, "SWITCH_REG", "vcc9",
+		RK818_DCDC_EN_REG, BIT(6)),
+	RK8XX_DESC_SWITCH(RK818_ID_HDMI_SWITCH, "HDMI_SWITCH", "h_5v",
+		RK818_H5V_EN_REG, BIT(0)),
+	RK8XX_DESC_SWITCH(RK818_ID_OTG_SWITCH, "OTG_SWITCH", "usb",
+		RK818_DCDC_EN_REG, BIT(7)),
+};
 
 static int rk808_regulator_probe(struct device *dev)
 {
 	struct rk808 *rk808 = dev->parent->priv;
-	struct rk_regulator_cfg *regulators;
-	struct of_regulator_match *matches;
-	int ret, i, nregulators;
+	struct regulator_dev *rk808_rdev;
+	const struct regulator_desc *regulators;
+	int i, nregulators;
+	struct regulator_config config;
 
 	switch (rk808->variant) {
 	case RK805_ID:
 		regulators = rk805_reg;
-		matches = rk805_reg_matches;
 		nregulators = RK805_NUM_REGULATORS;
 		break;
+	case RK806_ID:
+		regulators = rk806_reg;
+		nregulators = ARRAY_SIZE(rk806_reg);
+		break;
 	case RK808_ID:
 		regulators = rk808_reg;
-		matches = rk808_reg_matches;
-		nregulators = RK809_NUM_REGULATORS;
+		nregulators = RK808_NUM_REGULATORS;
 		break;
 	case RK809_ID:
 		regulators = rk809_reg;
-		matches = rk809_reg_matches;
 		nregulators = RK809_NUM_REGULATORS;
 		break;
+	case RK816_ID:
+		regulators = rk816_reg;
+		nregulators = ARRAY_SIZE(rk816_reg);
+		break;
 	case RK817_ID:
 		regulators = rk817_reg;
-		matches = rk817_reg_matches;
 		nregulators = RK817_NUM_REGULATORS;
 		break;
 	case RK818_ID:
 		regulators = rk818_reg;
-		matches = rk818_reg_matches;
 		nregulators = RK818_NUM_REGULATORS;
 		break;
 	default:
-		dev_err(dev, "unsupported RK8XX ID %lu\n", rk808->variant);
+		dev_err(dev, "unsupported RK8XX ID %lu\n",
+			rk808->variant);
 		return -EINVAL;
 	}
 
-	ret = rk808_regulator_dt_parse(rk808->dev, matches, nregulators);
-	if (ret < 0)
-		return ret;
+	config.dev = dev;
+	config.regmap = rk808->regmap;
 
 	/* Instantiate the regulators */
 	for (i = 0; i < nregulators; i++) {
-		ret = rk808_regulator_register(rk808, i, &matches[i],
-					       &regulators[i]);
-		if (ret < 0)
-			return ret;
+		rk808_rdev = regulator_register(rk808->dev, &regulators[i], &config);
+		if (IS_ERR(rk808_rdev))
+			return dev_err_probe(dev, PTR_ERR(rk808_rdev),
+					     "failed to register %d regulator\n", i);
 	}
 
 	return 0;
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index 8cd152625b..8f94103c82 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -964,20 +964,7 @@ enum rk817_reg_id {
 };
 
 enum rk809_reg_id {
-	RK809_ID_DCDC1 = 0,
-	RK809_ID_DCDC2,
-	RK809_ID_DCDC3,
-	RK809_ID_DCDC4,
-	RK809_ID_LDO1,
-	RK809_ID_LDO2,
-	RK809_ID_LDO3,
-	RK809_ID_LDO4,
-	RK809_ID_LDO5,
-	RK809_ID_LDO6,
-	RK809_ID_LDO7,
-	RK809_ID_LDO8,
-	RK809_ID_LDO9,
-	RK809_ID_DCDC5,
+	RK809_ID_DCDC5 = RK817_ID_BOOST,
 	RK809_ID_SW1,
 	RK809_ID_SW2,
 	RK809_NUM_REGULATORS

-- 
2.39.5




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 5/7] mfd: rk808: add support for RK806
  2024-10-15 11:11 ` [PATCH 5/7] mfd: rk808: add support for RK806 Sascha Hauer
@ 2024-10-15 14:46   ` Alexander Shiyan
  2024-10-16  7:07     ` Alexander Shiyan
  0 siblings, 1 reply; 19+ messages in thread
From: Alexander Shiyan @ 2024-10-15 14:46 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: open list:BAREBOX

вт, 15 окт. 2024 г. в 14:21, Sascha Hauer <s.hauer@pengutronix.de>:
>
> This adds support for the RK806 to the rk808 driver. Additionally to
> I2C this variant comes with SPI support, so add SPI probe support to the
> driver.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Hello Sascha.

RK806 can also work via I2C. Can you add this compatibility together?

Thanks!



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 5/7] mfd: rk808: add support for RK806
  2024-10-15 14:46   ` Alexander Shiyan
@ 2024-10-16  7:07     ` Alexander Shiyan
  2024-10-16  9:01       ` Sascha Hauer
  0 siblings, 1 reply; 19+ messages in thread
From: Alexander Shiyan @ 2024-10-16  7:07 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: open list:BAREBOX

Oh, I see that in [4/7]. Sorry for the noise.

вт, 15 окт. 2024 г. в 17:46, Alexander Shiyan <eagle.alexander923@gmail.com>:
>
> вт, 15 окт. 2024 г. в 14:21, Sascha Hauer <s.hauer@pengutronix.de>:
> >
> > This adds support for the RK806 to the rk808 driver. Additionally to
> > I2C this variant comes with SPI support, so add SPI probe support to the
> > driver.
> >
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>
> Hello Sascha.
>
> RK806 can also work via I2C. Can you add this compatibility together?
>
> Thanks!



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 5/7] mfd: rk808: add support for RK806
  2024-10-16  7:07     ` Alexander Shiyan
@ 2024-10-16  9:01       ` Sascha Hauer
  2024-10-16  9:11         ` Alexander Shiyan
  2024-10-16  9:13         ` Alexander Shiyan
  0 siblings, 2 replies; 19+ messages in thread
From: Sascha Hauer @ 2024-10-16  9:01 UTC (permalink / raw)
  To: Alexander Shiyan; +Cc: open list:BAREBOX

On Wed, Oct 16, 2024 at 10:07:57AM +0300, Alexander Shiyan wrote:
> Oh, I see that in [4/7]. Sorry for the noise.

I think you are misreading the patch. Indeed the RK806 can work in I2C
mode and my patch series currently doesn't support this. I have two
different of_device_id tables, one used for I2C and the other for SPI.
RK806 currently only is in the SPI table, not in the I2C table.

I2C support for RK806 is likely only a matter of adding the compatible
entry. I can add it, but I cannot test it. Do you have a hardware to
test this on?

Sascha


> 
> вт, 15 окт. 2024 г. в 17:46, Alexander Shiyan <eagle.alexander923@gmail.com>:
> >
> > вт, 15 окт. 2024 г. в 14:21, Sascha Hauer <s.hauer@pengutronix.de>:
> > >
> > > This adds support for the RK806 to the rk808 driver. Additionally to
> > > I2C this variant comes with SPI support, so add SPI probe support to the
> > > driver.
> > >
> > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> >
> > Hello Sascha.
> >
> > RK806 can also work via I2C. Can you add this compatibility together?
> >
> > Thanks!
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 5/7] mfd: rk808: add support for RK806
  2024-10-16  9:01       ` Sascha Hauer
@ 2024-10-16  9:11         ` Alexander Shiyan
  2024-10-16  9:13         ` Alexander Shiyan
  1 sibling, 0 replies; 19+ messages in thread
From: Alexander Shiyan @ 2024-10-16  9:11 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: open list:BAREBOX

Hello.

Yes, we have developed a scheme and soon I will have a sample in my hands.

ср, 16 окт. 2024 г. в 12:01, Sascha Hauer <s.hauer@pengutronix.de>:
>
> On Wed, Oct 16, 2024 at 10:07:57AM +0300, Alexander Shiyan wrote:
> > Oh, I see that in [4/7]. Sorry for the noise.
>
> I think you are misreading the patch. Indeed the RK806 can work in I2C
> mode and my patch series currently doesn't support this. I have two
> different of_device_id tables, one used for I2C and the other for SPI.
> RK806 currently only is in the SPI table, not in the I2C table.
>
> I2C support for RK806 is likely only a matter of adding the compatible
> entry. I can add it, but I cannot test it. Do you have a hardware to
> test this on?
>
> Sascha
>
>
> >
> > вт, 15 окт. 2024 г. в 17:46, Alexander Shiyan <eagle.alexander923@gmail.com>:
> > >
> > > вт, 15 окт. 2024 г. в 14:21, Sascha Hauer <s.hauer@pengutronix.de>:
> > > >
> > > > This adds support for the RK806 to the rk808 driver. Additionally to
> > > > I2C this variant comes with SPI support, so add SPI probe support to the
> > > > driver.
> > > >
> > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > >
> > > Hello Sascha.
> > >
> > > RK806 can also work via I2C. Can you add this compatibility together?
> > >
> > > Thanks!
> >
>
> --
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 5/7] mfd: rk808: add support for RK806
  2024-10-16  9:01       ` Sascha Hauer
  2024-10-16  9:11         ` Alexander Shiyan
@ 2024-10-16  9:13         ` Alexander Shiyan
  2024-10-16 10:48           ` Sascha Hauer
  1 sibling, 1 reply; 19+ messages in thread
From: Alexander Shiyan @ 2024-10-16  9:13 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: open list:BAREBOX

As an example, this can be tested with i2c-gpio driver, is'nt it?

ср, 16 окт. 2024 г. в 12:01, Sascha Hauer <s.hauer@pengutronix.de>:
>
> On Wed, Oct 16, 2024 at 10:07:57AM +0300, Alexander Shiyan wrote:
> > Oh, I see that in [4/7]. Sorry for the noise.
>
> I think you are misreading the patch. Indeed the RK806 can work in I2C
> mode and my patch series currently doesn't support this. I have two
> different of_device_id tables, one used for I2C and the other for SPI.
> RK806 currently only is in the SPI table, not in the I2C table.
>
> I2C support for RK806 is likely only a matter of adding the compatible
> entry. I can add it, but I cannot test it. Do you have a hardware to
> test this on?
>
> Sascha
>
>
> >
> > вт, 15 окт. 2024 г. в 17:46, Alexander Shiyan <eagle.alexander923@gmail.com>:
> > >
> > > вт, 15 окт. 2024 г. в 14:21, Sascha Hauer <s.hauer@pengutronix.de>:
> > > >
> > > > This adds support for the RK806 to the rk808 driver. Additionally to
> > > > I2C this variant comes with SPI support, so add SPI probe support to the
> > > > driver.
> > > >
> > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > >
> > > Hello Sascha.
> > >
> > > RK806 can also work via I2C. Can you add this compatibility together?
> > >
> > > Thanks!
> >
>
> --
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 5/7] mfd: rk808: add support for RK806
  2024-10-16  9:13         ` Alexander Shiyan
@ 2024-10-16 10:48           ` Sascha Hauer
  2024-10-16 16:08             ` Alexander Shiyan
  0 siblings, 1 reply; 19+ messages in thread
From: Sascha Hauer @ 2024-10-16 10:48 UTC (permalink / raw)
  To: Alexander Shiyan; +Cc: open list:BAREBOX

On Wed, Oct 16, 2024 at 12:13:28PM +0300, Alexander Shiyan wrote:
> As an example, this can be tested with i2c-gpio driver, is'nt it?

We have a rockchip i2c driver in barebox. I just don't have a board
where the RK806 is connected via I2C.

Sascha

> 
> ср, 16 окт. 2024 г. в 12:01, Sascha Hauer <s.hauer@pengutronix.de>:
> >
> > On Wed, Oct 16, 2024 at 10:07:57AM +0300, Alexander Shiyan wrote:
> > > Oh, I see that in [4/7]. Sorry for the noise.
> >
> > I think you are misreading the patch. Indeed the RK806 can work in I2C
> > mode and my patch series currently doesn't support this. I have two
> > different of_device_id tables, one used for I2C and the other for SPI.
> > RK806 currently only is in the SPI table, not in the I2C table.
> >
> > I2C support for RK806 is likely only a matter of adding the compatible
> > entry. I can add it, but I cannot test it. Do you have a hardware to
> > test this on?
> >
> > Sascha
> >
> >
> > >
> > > вт, 15 окт. 2024 г. в 17:46, Alexander Shiyan <eagle.alexander923@gmail.com>:
> > > >
> > > > вт, 15 окт. 2024 г. в 14:21, Sascha Hauer <s.hauer@pengutronix.de>:
> > > > >
> > > > > This adds support for the RK806 to the rk808 driver. Additionally to
> > > > > I2C this variant comes with SPI support, so add SPI probe support to the
> > > > > driver.
> > > > >
> > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > >
> > > > Hello Sascha.
> > > >
> > > > RK806 can also work via I2C. Can you add this compatibility together?
> > > >
> > > > Thanks!
> > >
> >
> > --
> > Pengutronix e.K.                           |                             |
> > Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> > 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 5/7] mfd: rk808: add support for RK806
  2024-10-16 10:48           ` Sascha Hauer
@ 2024-10-16 16:08             ` Alexander Shiyan
  2024-10-17 11:05               ` Sascha Hauer
  0 siblings, 1 reply; 19+ messages in thread
From: Alexander Shiyan @ 2024-10-16 16:08 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: open list:BAREBOX

I'm just saying that we can use i2c-gpio driver on SPI pins since in
rk806 pins are common for i2c/spi :)

ср, 16 окт. 2024 г. в 13:48, Sascha Hauer <s.hauer@pengutronix.de>:
>
> On Wed, Oct 16, 2024 at 12:13:28PM +0300, Alexander Shiyan wrote:
> > As an example, this can be tested with i2c-gpio driver, is'nt it?
>
> We have a rockchip i2c driver in barebox. I just don't have a board
> where the RK806 is connected via I2C.
>
> Sascha
>
> >
> > ср, 16 окт. 2024 г. в 12:01, Sascha Hauer <s.hauer@pengutronix.de>:
> > >
> > > On Wed, Oct 16, 2024 at 10:07:57AM +0300, Alexander Shiyan wrote:
> > > > Oh, I see that in [4/7]. Sorry for the noise.
> > >
> > > I think you are misreading the patch. Indeed the RK806 can work in I2C
> > > mode and my patch series currently doesn't support this. I have two
> > > different of_device_id tables, one used for I2C and the other for SPI.
> > > RK806 currently only is in the SPI table, not in the I2C table.
> > >
> > > I2C support for RK806 is likely only a matter of adding the compatible
> > > entry. I can add it, but I cannot test it. Do you have a hardware to
> > > test this on?
> > >
> > > Sascha
> > >
> > >
> > > >
> > > > вт, 15 окт. 2024 г. в 17:46, Alexander Shiyan <eagle.alexander923@gmail.com>:
> > > > >
> > > > > вт, 15 окт. 2024 г. в 14:21, Sascha Hauer <s.hauer@pengutronix.de>:
> > > > > >
> > > > > > This adds support for the RK806 to the rk808 driver. Additionally to
> > > > > > I2C this variant comes with SPI support, so add SPI probe support to the
> > > > > > driver.
> > > > > >
> > > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > > >
> > > > > Hello Sascha.
> > > > >
> > > > > RK806 can also work via I2C. Can you add this compatibility together?
> > > > >
> > > > > Thanks!
> > > >
> > >
> > > --
> > > Pengutronix e.K.                           |                             |
> > > Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> > > 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> >
>
> --
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 5/7] mfd: rk808: add support for RK806
  2024-10-16 16:08             ` Alexander Shiyan
@ 2024-10-17 11:05               ` Sascha Hauer
  2024-10-18  5:12                 ` Alexander Shiyan
  0 siblings, 1 reply; 19+ messages in thread
From: Sascha Hauer @ 2024-10-17 11:05 UTC (permalink / raw)
  To: Alexander Shiyan; +Cc: open list:BAREBOX

On Wed, Oct 16, 2024 at 07:08:24PM +0300, Alexander Shiyan wrote:
> I'm just saying that we can use i2c-gpio driver on SPI pins since in
> rk806 pins are common for i2c/spi :)

Ok, that could work. We would still bootstrap the RK806 for I2C mode
instead of SPI mode. Anyway, I am not keen on doing that.

Sascha

> 
> ср, 16 окт. 2024 г. в 13:48, Sascha Hauer <s.hauer@pengutronix.de>:
> >
> > On Wed, Oct 16, 2024 at 12:13:28PM +0300, Alexander Shiyan wrote:
> > > As an example, this can be tested with i2c-gpio driver, is'nt it?
> >
> > We have a rockchip i2c driver in barebox. I just don't have a board
> > where the RK806 is connected via I2C.
> >
> > Sascha
> >
> > >
> > > ср, 16 окт. 2024 г. в 12:01, Sascha Hauer <s.hauer@pengutronix.de>:
> > > >
> > > > On Wed, Oct 16, 2024 at 10:07:57AM +0300, Alexander Shiyan wrote:
> > > > > Oh, I see that in [4/7]. Sorry for the noise.
> > > >
> > > > I think you are misreading the patch. Indeed the RK806 can work in I2C
> > > > mode and my patch series currently doesn't support this. I have two
> > > > different of_device_id tables, one used for I2C and the other for SPI.
> > > > RK806 currently only is in the SPI table, not in the I2C table.
> > > >
> > > > I2C support for RK806 is likely only a matter of adding the compatible
> > > > entry. I can add it, but I cannot test it. Do you have a hardware to
> > > > test this on?
> > > >
> > > > Sascha
> > > >
> > > >
> > > > >
> > > > > вт, 15 окт. 2024 г. в 17:46, Alexander Shiyan <eagle.alexander923@gmail.com>:
> > > > > >
> > > > > > вт, 15 окт. 2024 г. в 14:21, Sascha Hauer <s.hauer@pengutronix.de>:
> > > > > > >
> > > > > > > This adds support for the RK806 to the rk808 driver. Additionally to
> > > > > > > I2C this variant comes with SPI support, so add SPI probe support to the
> > > > > > > driver.
> > > > > > >
> > > > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > > > >
> > > > > > Hello Sascha.
> > > > > >
> > > > > > RK806 can also work via I2C. Can you add this compatibility together?
> > > > > >
> > > > > > Thanks!
> > > > >
> > > >
> > > > --
> > > > Pengutronix e.K.                           |                             |
> > > > Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> > > > 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > >
> >
> > --
> > Pengutronix e.K.                           |                             |
> > Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> > 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 5/7] mfd: rk808: add support for RK806
  2024-10-17 11:05               ` Sascha Hauer
@ 2024-10-18  5:12                 ` Alexander Shiyan
  2024-10-18  8:42                   ` Sascha Hauer
  0 siblings, 1 reply; 19+ messages in thread
From: Alexander Shiyan @ 2024-10-18  5:12 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: open list:BAREBOX

Hello Sascha.

Since you're here, I've found another new patch for the driver:
https://patchwork.kernel.org/project/linux-rockchip/patch/20241017-rk809-dcdc3-v1-1-e3c3de92f39c@gmail.com/

чт, 17 окт. 2024 г. в 14:05, Sascha Hauer <s.hauer@pengutronix.de>:
>
> On Wed, Oct 16, 2024 at 07:08:24PM +0300, Alexander Shiyan wrote:
> > I'm just saying that we can use i2c-gpio driver on SPI pins since in
> > rk806 pins are common for i2c/spi :)
>
> Ok, that could work. We would still bootstrap the RK806 for I2C mode
> instead of SPI mode. Anyway, I am not keen on doing that.
>
> Sascha
>
> >
> > ср, 16 окт. 2024 г. в 13:48, Sascha Hauer <s.hauer@pengutronix.de>:
> > >
> > > On Wed, Oct 16, 2024 at 12:13:28PM +0300, Alexander Shiyan wrote:
> > > > As an example, this can be tested with i2c-gpio driver, is'nt it?
> > >
> > > We have a rockchip i2c driver in barebox. I just don't have a board
> > > where the RK806 is connected via I2C.
> > >
> > > Sascha
> > >
> > > >
> > > > ср, 16 окт. 2024 г. в 12:01, Sascha Hauer <s.hauer@pengutronix.de>:
> > > > >
> > > > > On Wed, Oct 16, 2024 at 10:07:57AM +0300, Alexander Shiyan wrote:
> > > > > > Oh, I see that in [4/7]. Sorry for the noise.
> > > > >
> > > > > I think you are misreading the patch. Indeed the RK806 can work in I2C
> > > > > mode and my patch series currently doesn't support this. I have two
> > > > > different of_device_id tables, one used for I2C and the other for SPI.
> > > > > RK806 currently only is in the SPI table, not in the I2C table.
> > > > >
> > > > > I2C support for RK806 is likely only a matter of adding the compatible
> > > > > entry. I can add it, but I cannot test it. Do you have a hardware to
> > > > > test this on?
> > > > >
> > > > > Sascha
> > > > >
> > > > >
> > > > > >
> > > > > > вт, 15 окт. 2024 г. в 17:46, Alexander Shiyan <eagle.alexander923@gmail.com>:
> > > > > > >
> > > > > > > вт, 15 окт. 2024 г. в 14:21, Sascha Hauer <s.hauer@pengutronix.de>:
> > > > > > > >
> > > > > > > > This adds support for the RK806 to the rk808 driver. Additionally to
> > > > > > > > I2C this variant comes with SPI support, so add SPI probe support to the
> > > > > > > > driver.
> > > > > > > >
> > > > > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > > > > >
> > > > > > > Hello Sascha.
> > > > > > >
> > > > > > > RK806 can also work via I2C. Can you add this compatibility together?
> > > > > > >
> > > > > > > Thanks!
> > > > > >
> > > > >
> > > > > --
> > > > > Pengutronix e.K.                           |                             |
> > > > > Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> > > > > 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> > > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > > >
> > >
> > > --
> > > Pengutronix e.K.                           |                             |
> > > Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> > > 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> >
>
> --
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 0/7] rockchip: add RK808 support
  2024-10-15 11:10 [PATCH 0/7] rockchip: add RK808 support Sascha Hauer
                   ` (6 preceding siblings ...)
  2024-10-15 11:11 ` [PATCH 7/7] regulator: rk808: update from kernel Sascha Hauer
@ 2024-10-18  8:39 ` Sascha Hauer
  7 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2024-10-18  8:39 UTC (permalink / raw)
  To: open list:BAREBOX, Sascha Hauer


On Tue, 15 Oct 2024 13:10:57 +0200, Sascha Hauer wrote:
> This series adds support for the RK808 PMIC found on several Rockchip
> boards. Unlike the earlier versions of this PMIC this one comes with
> SPI support. As we do not have a Rockchip SPI driver yet, this is added
> in this series as well.
> 
> 

Applied, thanks!

[1/7] spi: add rockchip spi controller support
      https://git.pengutronix.de/cgit/barebox/commit/?id=c4598e66e92f (link may not be stable)
[2/7] mfd: mx13xxx: drop unnecessary ifdefs
      https://git.pengutronix.de/cgit/barebox/commit/?id=512cfb4b3805 (link may not be stable)
[3/7] mfd: rk808: factor out common probe function
      https://git.pengutronix.de/cgit/barebox/commit/?id=87a9ec846b0a (link may not be stable)
[4/7] mfd: rk808: update header file from kernel
      https://git.pengutronix.de/cgit/barebox/commit/?id=f72a75d550a0 (link may not be stable)
[5/7] mfd: rk808: add support for RK806
      https://git.pengutronix.de/cgit/barebox/commit/?id=e26649b90703 (link may not be stable)
[6/7] regulator: add regulator_register()
      https://git.pengutronix.de/cgit/barebox/commit/?id=2d724387bc68 (link may not be stable)
[7/7] regulator: rk808: update from kernel
      https://git.pengutronix.de/cgit/barebox/commit/?id=50d47557efb9 (link may not be stable)

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 5/7] mfd: rk808: add support for RK806
  2024-10-18  5:12                 ` Alexander Shiyan
@ 2024-10-18  8:42                   ` Sascha Hauer
  0 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2024-10-18  8:42 UTC (permalink / raw)
  To: Alexander Shiyan; +Cc: open list:BAREBOX

On Fri, Oct 18, 2024 at 08:12:40AM +0300, Alexander Shiyan wrote:
> Hello Sascha.
> 
> Since you're here, I've found another new patch for the driver:
> https://patchwork.kernel.org/project/linux-rockchip/patch/20241017-rk809-dcdc3-v1-1-e3c3de92f39c@gmail.com/

Applied this as an extra commit.

Sascha

> 
> чт, 17 окт. 2024 г. в 14:05, Sascha Hauer <s.hauer@pengutronix.de>:
> >
> > On Wed, Oct 16, 2024 at 07:08:24PM +0300, Alexander Shiyan wrote:
> > > I'm just saying that we can use i2c-gpio driver on SPI pins since in
> > > rk806 pins are common for i2c/spi :)
> >
> > Ok, that could work. We would still bootstrap the RK806 for I2C mode
> > instead of SPI mode. Anyway, I am not keen on doing that.
> >
> > Sascha
> >
> > >
> > > ср, 16 окт. 2024 г. в 13:48, Sascha Hauer <s.hauer@pengutronix.de>:
> > > >
> > > > On Wed, Oct 16, 2024 at 12:13:28PM +0300, Alexander Shiyan wrote:
> > > > > As an example, this can be tested with i2c-gpio driver, is'nt it?
> > > >
> > > > We have a rockchip i2c driver in barebox. I just don't have a board
> > > > where the RK806 is connected via I2C.
> > > >
> > > > Sascha
> > > >
> > > > >
> > > > > ср, 16 окт. 2024 г. в 12:01, Sascha Hauer <s.hauer@pengutronix.de>:
> > > > > >
> > > > > > On Wed, Oct 16, 2024 at 10:07:57AM +0300, Alexander Shiyan wrote:
> > > > > > > Oh, I see that in [4/7]. Sorry for the noise.
> > > > > >
> > > > > > I think you are misreading the patch. Indeed the RK806 can work in I2C
> > > > > > mode and my patch series currently doesn't support this. I have two
> > > > > > different of_device_id tables, one used for I2C and the other for SPI.
> > > > > > RK806 currently only is in the SPI table, not in the I2C table.
> > > > > >
> > > > > > I2C support for RK806 is likely only a matter of adding the compatible
> > > > > > entry. I can add it, but I cannot test it. Do you have a hardware to
> > > > > > test this on?
> > > > > >
> > > > > > Sascha
> > > > > >
> > > > > >
> > > > > > >
> > > > > > > вт, 15 окт. 2024 г. в 17:46, Alexander Shiyan <eagle.alexander923@gmail.com>:
> > > > > > > >
> > > > > > > > вт, 15 окт. 2024 г. в 14:21, Sascha Hauer <s.hauer@pengutronix.de>:
> > > > > > > > >
> > > > > > > > > This adds support for the RK806 to the rk808 driver. Additionally to
> > > > > > > > > I2C this variant comes with SPI support, so add SPI probe support to the
> > > > > > > > > driver.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > > > > > >
> > > > > > > > Hello Sascha.
> > > > > > > >
> > > > > > > > RK806 can also work via I2C. Can you add this compatibility together?
> > > > > > > >
> > > > > > > > Thanks!
> > > > > > >
> > > > > >
> > > > > > --
> > > > > > Pengutronix e.K.                           |                             |
> > > > > > Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> > > > > > 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> > > > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > > > >
> > > >
> > > > --
> > > > Pengutronix e.K.                           |                             |
> > > > Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> > > > 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > >
> >
> > --
> > Pengutronix e.K.                           |                             |
> > Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> > 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2024-10-18  8:52 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-15 11:10 [PATCH 0/7] rockchip: add RK808 support Sascha Hauer
2024-10-15 11:10 ` [PATCH 1/7] spi: add rockchip spi controller support Sascha Hauer
2024-10-15 11:10 ` [PATCH 2/7] mfd: mx13xxx: drop unnecessary ifdefs Sascha Hauer
2024-10-15 11:11 ` [PATCH 3/7] mfd: rk808: factor out common probe function Sascha Hauer
2024-10-15 11:11 ` [PATCH 4/7] mfd: rk808: update header file from kernel Sascha Hauer
2024-10-15 11:11 ` [PATCH 5/7] mfd: rk808: add support for RK806 Sascha Hauer
2024-10-15 14:46   ` Alexander Shiyan
2024-10-16  7:07     ` Alexander Shiyan
2024-10-16  9:01       ` Sascha Hauer
2024-10-16  9:11         ` Alexander Shiyan
2024-10-16  9:13         ` Alexander Shiyan
2024-10-16 10:48           ` Sascha Hauer
2024-10-16 16:08             ` Alexander Shiyan
2024-10-17 11:05               ` Sascha Hauer
2024-10-18  5:12                 ` Alexander Shiyan
2024-10-18  8:42                   ` Sascha Hauer
2024-10-15 11:11 ` [PATCH 6/7] regulator: add regulator_register() Sascha Hauer
2024-10-15 11:11 ` [PATCH 7/7] regulator: rk808: update from kernel Sascha Hauer
2024-10-18  8:39 ` [PATCH 0/7] rockchip: add RK808 support Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox