All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] support a new type of PMIC,including two chips(rk817 and rk809)
@ 2018-07-23  3:19 ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: linux-rtc, a.zummo, alexandre.belloni, tony.xie, huangtao,
	devicetree, sboyd, zhangqing, linux-kernel, xsf, linux-rockchip,
	broonie, lee.jones, linux-clk, linux-arm-kernel, chenjh

TW9zdCBvZiBmdW5jdGlvbnMgYW5kIHJlZ2lzdGVycyBvZiB0aGUgcms4MTcgYW5kIHJrODA4IGFy
ZSB0aGUgc2FtZSwKc28gdGhleSBjYW4gc2hhcmUgYWxsbW9zdCBhbGwgY29kZXMuCgpUaGVpciBz
cGVjaWZpY2F0aW9ucyBhcmUgYXMgZm9sbG93c++8mgogIDEpIFRoZSBSSzgwOSBhbmQgUks4MDkg
Y29uc2lzdCBvZiA1IERDRENzLCA5IExET3MgYW5kIGhhdmUgdGhlIHNhbWUgcmVnaXN0ZXJzCiAg
ICAgZm9yIHRoZXNlIGNvbXBvbmVudHMgZXhjZXB0IGRjZGM1LgogIDIpIFRoZSBkY2RjNSBpcyBh
IGJvb3N0IGRjZGMgZm9yIFJLODE3IGFuZCBpcyBhIGJ1Y2sgZm9yIFJLODA5LgogIDMpIFRoZSBS
SzgxNyBoYXMgb25lIHN3aXRjaCBidXQgVGhlIFJrODA5IGhhcyB0d28uCgpUb255IFhpZSAoNSk6
CiAgbWZkOiByazgwODogQWRkIFJLODE3IGFuZCBSSzgwOSBzdXBwb3J0CiAgcmVndWxhdG9yOiBy
azgwODogQWRkIHJlZ3VsYXRvciBkcml2ZXIgZm9yIFJLODA5IGFuZCBSSzgxNy4KICBtZmQ6IGR0
LWJpbmRpbmdzOiBBZGQgUks4MDkgYW5kIFJLODE3IGRldmljZSB0cmVlIGJpbmRpbmdzIGRvY3Vt
ZW50CiAgUlRDOiBSSzgwODogYWRkIFJUQyBkcml2ZXIgZm9yIFJLODA5IGFuZCBSSzgxNy4KICBj
bGs6IFJLODA4OiBhZGQgY2xrb3V0IGRyaXZlciBmb3IgUks4MDkgYW5kIFJLODE3LgoKIERvY3Vt
ZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9tZmQvcms4MDgudHh0IHwgIDU1ICsrCiBkcml2
ZXJzL2Nsay9LY29uZmlnICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgNiArLQogZHJp
dmVycy9jbGsvY2xrLXJrODA4LmMgICAgICAgICAgICAgICAgICAgICAgICAgfCAgNjIgKystCiBk
cml2ZXJzL21mZC9LY29uZmlnICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgNiArLQog
ZHJpdmVycy9tZmQvcms4MDguYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAyMTYgKysr
KysrKy0KIGRyaXZlcnMvcmVndWxhdG9yL0tjb25maWcgICAgICAgICAgICAgICAgICAgICAgIHwg
ICA0ICstCiBkcml2ZXJzL3JlZ3VsYXRvci9yazgwOC1yZWd1bGF0b3IuYyAgICAgICAgICAgICB8
IDYzMyArKysrKysrKysrKysrKysrKysrKysrKy0KIGRyaXZlcnMvcnRjL0tjb25maWcgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgIHwgICA0ICstCiBkcml2ZXJzL3J0Yy9ydGMtcms4MDguYyAg
ICAgICAgICAgICAgICAgICAgICAgICB8ICA2OCArKy0KIGluY2x1ZGUvbGludXgvbWZkL3JrODA4
LmggICAgICAgICAgICAgICAgICAgICAgIHwgMTc1ICsrKysrKysKIDEwIGZpbGVzIGNoYW5nZWQs
IDEyMDEgaW5zZXJ0aW9ucygrKSwgMjggZGVsZXRpb25zKC0pCgotLSAKMS45LjEKCgoKX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5l
bCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6
Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=

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

* [PATCH 0/5] support a new type of PMIC,including two chips(rk817 and rk809)
@ 2018-07-23  3:19 ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: linux-rtc, a.zummo, alexandre.belloni, tony.xie, huangtao,
	devicetree, sboyd, zhangqing, linux-kernel, xsf, linux-rockchip,
	broonie, lee.jones, linux-clk, linux-arm-kernel, chenjh

Most of functions and registers of the rk817 and rk808 are the same,
so they can share allmost all codes.

Their specifications are as follows:
  1) The RK809 and RK809 consist of 5 DCDCs, 9 LDOs and have the same registers
     for these components except dcdc5.
  2) The dcdc5 is a boost dcdc for RK817 and is a buck for RK809.
  3) The RK817 has one switch but The Rk809 has two.

Tony Xie (5):
  mfd: rk808: Add RK817 and RK809 support
  regulator: rk808: Add regulator driver for RK809 and RK817.
  mfd: dt-bindings: Add RK809 and RK817 device tree bindings document
  RTC: RK808: add RTC driver for RK809 and RK817.
  clk: RK808: add clkout driver for RK809 and RK817.

 Documentation/devicetree/bindings/mfd/rk808.txt |  55 ++
 drivers/clk/Kconfig                             |   6 +-
 drivers/clk/clk-rk808.c                         |  62 ++-
 drivers/mfd/Kconfig                             |   6 +-
 drivers/mfd/rk808.c                             | 216 +++++++-
 drivers/regulator/Kconfig                       |   4 +-
 drivers/regulator/rk808-regulator.c             | 633 +++++++++++++++++++++++-
 drivers/rtc/Kconfig                             |   4 +-
 drivers/rtc/rtc-rk808.c                         |  68 ++-
 include/linux/mfd/rk808.h                       | 175 +++++++
 10 files changed, 1201 insertions(+), 28 deletions(-)

-- 
1.9.1



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 0/5] support a new type of PMIC,including two chips(rk817 and rk809)
@ 2018-07-23  3:19 ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: broonie, lee.jones, a.zummo, alexandre.belloni, sboyd, linux-clk,
	linux-rtc, linux-arm-kernel, linux-rockchip, devicetree,
	linux-kernel, chenjh, xsf, zhangqing, huangtao, tony.xie

Most of functions and registers of the rk817 and rk808 are the same,
so they can share allmost all codes.

Their specifications are as follows:
  1) The RK809 and RK809 consist of 5 DCDCs, 9 LDOs and have the same registers
     for these components except dcdc5.
  2) The dcdc5 is a boost dcdc for RK817 and is a buck for RK809.
  3) The RK817 has one switch but The Rk809 has two.

Tony Xie (5):
  mfd: rk808: Add RK817 and RK809 support
  regulator: rk808: Add regulator driver for RK809 and RK817.
  mfd: dt-bindings: Add RK809 and RK817 device tree bindings document
  RTC: RK808: add RTC driver for RK809 and RK817.
  clk: RK808: add clkout driver for RK809 and RK817.

 Documentation/devicetree/bindings/mfd/rk808.txt |  55 ++
 drivers/clk/Kconfig                             |   6 +-
 drivers/clk/clk-rk808.c                         |  62 ++-
 drivers/mfd/Kconfig                             |   6 +-
 drivers/mfd/rk808.c                             | 216 +++++++-
 drivers/regulator/Kconfig                       |   4 +-
 drivers/regulator/rk808-regulator.c             | 633 +++++++++++++++++++++++-
 drivers/rtc/Kconfig                             |   4 +-
 drivers/rtc/rtc-rk808.c                         |  68 ++-
 include/linux/mfd/rk808.h                       | 175 +++++++
 10 files changed, 1201 insertions(+), 28 deletions(-)

-- 
1.9.1

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

* [PATCH 0/5] support a new type of PMIC,including two chips(rk817 and rk809)
@ 2018-07-23  3:19 ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: linux-arm-kernel

Most of functions and registers of the rk817 and rk808 are the same,
so they can share allmost all codes.

Their specifications are as follows?
  1) The RK809 and RK809 consist of 5 DCDCs, 9 LDOs and have the same registers
     for these components except dcdc5.
  2) The dcdc5 is a boost dcdc for RK817 and is a buck for RK809.
  3) The RK817 has one switch but The Rk809 has two.

Tony Xie (5):
  mfd: rk808: Add RK817 and RK809 support
  regulator: rk808: Add regulator driver for RK809 and RK817.
  mfd: dt-bindings: Add RK809 and RK817 device tree bindings document
  RTC: RK808: add RTC driver for RK809 and RK817.
  clk: RK808: add clkout driver for RK809 and RK817.

 Documentation/devicetree/bindings/mfd/rk808.txt |  55 ++
 drivers/clk/Kconfig                             |   6 +-
 drivers/clk/clk-rk808.c                         |  62 ++-
 drivers/mfd/Kconfig                             |   6 +-
 drivers/mfd/rk808.c                             | 216 +++++++-
 drivers/regulator/Kconfig                       |   4 +-
 drivers/regulator/rk808-regulator.c             | 633 +++++++++++++++++++++++-
 drivers/rtc/Kconfig                             |   4 +-
 drivers/rtc/rtc-rk808.c                         |  68 ++-
 include/linux/mfd/rk808.h                       | 175 +++++++
 10 files changed, 1201 insertions(+), 28 deletions(-)

-- 
1.9.1

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

* [PATCH 1/5] mfd: rk808: Add RK817 and RK809 support
  2018-07-23  3:19 ` Tony Xie
  (?)
  (?)
@ 2018-07-23  3:19   ` Tony Xie
  -1 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: linux-rtc, a.zummo, alexandre.belloni, tony.xie, huangtao,
	devicetree, sboyd, zhangqing, linux-kernel, xsf, linux-rockchip,
	broonie, lee.jones, linux-clk, linux-arm-kernel, chenjh

    The rk809 and rk817 are a Power Management IC (PMIC) for multimedia
    and handheld devices. It contains the following components:

        - Regulators
        - RTC
        - Clocking

    Both RK809 and RK817 chips are using a similar register map,
    so we can reuse the RTC and Clocking and regulators functionality.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/mfd/Kconfig       |   6 +-
 drivers/mfd/rk808.c       | 216 +++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/mfd/rk808.h | 172 ++++++++++++++++++++++++++++++++++++
 3 files changed, 389 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b860eb5..84f2f22 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -967,14 +967,14 @@ config MFD_RC5T583
 	  different functionality of the device.
 
 config MFD_RK808
-	tristate "Rockchip RK805/RK808/RK818 Power Management Chip"
+	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip"
 	depends on I2C && OF
 	select MFD_CORE
 	select REGMAP_I2C
 	select REGMAP_IRQ
 	help
-	  If you say yes here you get support for the RK805, RK808 and RK818
-	  Power Management chips.
+	  If you say yes here you get support for the RK805, RK809 and RK817,
+	  RK808 and RK818 Power Management chips.
 	  This driver provides common support for accessing the device
 	  through I2C interface. The device supports multiple sub-devices
 	  including interrupts, RTC, LDO & DCDC regulators, and onkey.
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 216fbf6..bfb5668 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -62,6 +62,29 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	return false;
 }
 
+static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+	/*
+	 * Notes:
+	 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
+	 *   we don't use that feature.  It's better to cache.
+	 * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
+	 *   bits are cleared in case when we shutoff anyway, but better safe.
+	 */
+
+	switch (reg) {
+	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
+	case RK817_RTC_STATUS_REG:
+	case RK817_INT_STS_REG0:
+	case RK817_INT_STS_REG1:
+	case RK817_INT_STS_REG2:
+	case RK817_SYS_STS:
+		return true;
+	}
+
+	return true;
+}
+
 static const struct regmap_config rk818_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
@@ -86,6 +109,14 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	.volatile_reg = rk808_is_volatile_reg,
 };
 
+static const struct regmap_config rk817_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = RK817_GPIO_INT_CFG,
+	.cache_type = REGCACHE_NONE,
+	.volatile_reg = rk817_is_volatile_reg,
+};
+
 static struct resource rtc_resources[] = {
 	{
 		.start  = RK808_IRQ_RTC_ALARM,
@@ -94,6 +125,13 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	}
 };
 
+static struct resource rk817_rtc_resources[] = {
+	{
+		.start  = RK817_IRQ_RTC_ALARM,
+		.end    = RK817_IRQ_RTC_ALARM,
+		.flags  = IORESOURCE_IRQ,
+	}
+};
 static struct resource rk805_key_resources[] = {
 	{
 		.start  = RK805_IRQ_PWRON_FALL,
@@ -107,6 +145,19 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	}
 };
 
+static struct resource rk817_pwrkey_resources[] = {
+	{
+		.start  = RK817_IRQ_PWRON_RISE,
+		.end    = RK817_IRQ_PWRON_RISE,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.start  = RK817_IRQ_PWRON_FALL,
+		.end    = RK817_IRQ_PWRON_FALL,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
 static const struct mfd_cell rk805s[] = {
 	{ .name = "rk808-clkout", },
 	{ .name = "rk808-regulator", },
@@ -132,6 +183,21 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	},
 };
 
+static const struct mfd_cell rk817s[] = {
+	{ .name = "rk808-clkout",},
+	{ .name = "rk808-regulator",},
+	{
+		.name = "rk8xx-pwrkey",
+		.num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
+		.resources = &rk817_pwrkey_resources[0],
+	},
+	{
+		.name = "rk808-rtc",
+		.num_resources = ARRAY_SIZE(rk817_rtc_resources),
+		.resources = &rk817_rtc_resources[0],
+	},
+};
+
 static const struct mfd_cell rk818s[] = {
 	{ .name = "rk808-clkout", },
 	{ .name = "rk808-regulator", },
@@ -167,6 +233,13 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 						    VB_LO_SEL_3500MV },
 };
 
+static const struct rk808_reg_data rk817_pre_init_reg[] = {
+	{RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
+	{RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_H},
+	{RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK,
+					   RK817_HOTDIE_105 | RK817_TSD_140},
+};
+
 static const struct rk808_reg_data rk818_pre_init_reg[] = {
 	/* improve efficiency */
 	{ RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK,  BUCK_ILMIN_250MA },
@@ -332,6 +405,39 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	},
 };
 
+#define REGMAP_IRQ_M(_id) \
+	[_id] = {				\
+		.mask = BIT(((_id) % 8)),	\
+		.reg_offset = ((_id) / 8),	\
+	}
+
+static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
+	REGMAP_IRQ_M(0),
+	REGMAP_IRQ_M(1),
+	REGMAP_IRQ_M(2),
+	REGMAP_IRQ_M(3),
+	REGMAP_IRQ_M(4),
+	REGMAP_IRQ_M(5),
+	REGMAP_IRQ_M(6),
+	REGMAP_IRQ_M(7),
+	REGMAP_IRQ_M(8),
+	REGMAP_IRQ_M(9),
+	REGMAP_IRQ_M(10),
+	REGMAP_IRQ_M(11),
+	REGMAP_IRQ_M(12),
+	REGMAP_IRQ_M(13),
+	REGMAP_IRQ_M(14),
+	REGMAP_IRQ_M(15),
+	REGMAP_IRQ_M(16),
+	REGMAP_IRQ_M(17),
+	REGMAP_IRQ_M(18),
+	REGMAP_IRQ_M(19),
+	REGMAP_IRQ_M(20),
+	REGMAP_IRQ_M(21),
+	REGMAP_IRQ_M(22),
+	REGMAP_IRQ_M(23)
+};
+
 static struct regmap_irq_chip rk805_irq_chip = {
 	.name = "rk805",
 	.irqs = rk805_irqs,
@@ -355,6 +461,18 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	.init_ack_masked = true,
 };
 
+static struct regmap_irq_chip rk817_irq_chip = {
+	.name = "rk817",
+	.irqs = rk817_irqs,
+	.num_irqs = ARRAY_SIZE(rk817_irqs),
+	.num_regs = 3,
+	.irq_reg_stride = 2,
+	.status_base = RK817_INT_STS_REG0,
+	.mask_base = RK817_INT_STS_MSK_REG0,
+	.ack_base = RK817_INT_STS_REG0,
+	.init_ack_masked = true,
+};
+
 static const struct regmap_irq_chip rk818_irq_chip = {
 	.name = "rk818",
 	.irqs = rk818_irqs,
@@ -423,9 +541,39 @@ static void rk818_device_shutdown(void)
 		dev_err(&rk808_i2c_client->dev, "power off error!\n");
 }
 
+static void rk8xx_device_shutdown_prepare(void)
+{
+	int ret;
+	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+	if (!rk808) {
+		dev_warn(&rk808_i2c_client->dev,
+			 "have no rk808, so do nothing here\n");
+		return;
+	}
+
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		ret = regmap_update_bits(rk808->regmap,
+					 RK817_SYS_CFG(3),
+					 RK817_SLPPIN_FUNC_MSK,
+					 SLPPIN_DN_FUN);
+		if (ret) {
+			dev_warn(&rk808_i2c_client->dev,
+				 "switch pin func to power down error!\n");
+		}
+		break;
+	default:
+		break;
+	}
+}
+
 static const struct of_device_id rk808_of_match[] = {
 	{ .compatible = "rockchip,rk805" },
 	{ .compatible = "rockchip,rk808" },
+	{ .compatible = "rockchip,rk809" },
+	{ .compatible = "rockchip,rk817" },
 	{ .compatible = "rockchip,rk818" },
 	{ },
 };
@@ -442,6 +590,7 @@ static int rk808_probe(struct i2c_client *client,
 	int nr_pre_init_regs;
 	int nr_cells;
 	int pm_off = 0, msb, lsb;
+	unsigned char pmic_id_msb = RK808_ID_MSB, pmic_id_lsb = RK808_ID_LSB;
 	int ret;
 	int i;
 
@@ -449,15 +598,20 @@ static int rk808_probe(struct i2c_client *client,
 	if (!rk808)
 		return -ENOMEM;
 
+	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;
+	}
 	/* Read chip variant */
-	msb = i2c_smbus_read_byte_data(client, RK808_ID_MSB);
+	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
 	if (msb < 0) {
 		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
 			RK808_ID_MSB);
 		return msb;
 	}
 
-	lsb = i2c_smbus_read_byte_data(client, RK808_ID_LSB);
+	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
 	if (lsb < 0) {
 		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
 			RK808_ID_LSB);
@@ -495,6 +649,16 @@ static int rk808_probe(struct i2c_client *client,
 		nr_cells = ARRAY_SIZE(rk818s);
 		pm_pwroff_fn = rk818_device_shutdown;
 		break;
+	case RK809_ID:
+	case RK817_ID:
+		rk808->regmap_cfg = &rk817_regmap_config;
+		rk808->regmap_irq_chip = &rk817_irq_chip;
+		pre_init_reg = rk817_pre_init_reg;
+		nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
+		cells = rk817s;
+		nr_cells = ARRAY_SIZE(rk817s);
+		pm_power_off_prepare = rk8xx_device_shutdown_prepare;
+		break;
 	default:
 		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
 			rk808->variant);
@@ -568,9 +732,56 @@ static int rk808_remove(struct i2c_client *client)
 	return 0;
 }
 
+static int rk8xx_suspend(struct device *dev)
+{
+	int ret = 0;
+	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		ret = regmap_update_bits(rk808->regmap,
+					 RK817_SYS_CFG(3),
+					 RK817_SLPPIN_FUNC_MSK,
+					 SLPPIN_SLP_FUN);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int rk8xx_resume(struct device *dev)
+{
+	int ret = 0;
+	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		ret = regmap_update_bits(rk808->regmap,
+					 RK817_SYS_CFG(3),
+					 RK817_SLPPIN_FUNC_MSK,
+					 SLPPIN_NULL_FUN);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static const struct dev_pm_ops rk8xx_pm_ops = {
+	.suspend = rk8xx_suspend,
+	.resume =  rk8xx_resume,
+};
+
 static const struct i2c_device_id rk808_ids[] = {
 	{ "rk805" },
 	{ "rk808" },
+	{ "rk809" },
+	{ "rk817" },
 	{ "rk818" },
 	{ },
 };
@@ -580,6 +791,7 @@ static int rk808_remove(struct i2c_client *client)
 	.driver = {
 		.name = "rk808",
 		.of_match_table = rk808_of_match,
+		.pm = &rk8xx_pm_ops,
 	},
 	.probe    = rk808_probe,
 	.remove   = rk808_remove,
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index d315659..b973b0a 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -382,6 +382,7 @@ enum rk805_reg {
 #define SWITCH1_EN	BIT(5)
 #define DEV_OFF_RST	BIT(3)
 #define DEV_OFF		BIT(0)
+#define RTC_STOP	BIT(0)
 
 #define VB_LO_ACT		BIT(4)
 #define VB_LO_SEL_3500MV	(7 << 0)
@@ -396,6 +397,175 @@ enum rk805_reg {
 #define SLEEP_FUN			(0x1 << 2)
 #define RK8XX_ID_MSK			0xfff0
 #define FPWM_MODE			BIT(7)
+enum rk817_reg_id {
+	RK817_ID_DCDC1 = 0,
+	RK817_ID_DCDC2,
+	RK817_ID_DCDC3,
+	RK817_ID_DCDC4,
+	RK817_ID_LDO1,
+	RK817_ID_LDO2,
+	RK817_ID_LDO3,
+	RK817_ID_LDO4,
+	RK817_ID_LDO5,
+	RK817_ID_LDO6,
+	RK817_ID_LDO7,
+	RK817_ID_LDO8,
+	RK817_ID_LDO9,
+	RK817_ID_BOOST,
+	RK817_ID_BOOST_OTG_SW,
+	RK817_NUM_REGULATORS
+};
+
+enum rk809_reg_id {
+	RK809_ID_DCDC5 = RK817_ID_BOOST,
+	RK809_ID_SW1,
+	RK809_ID_SW2,
+	RK809_NUM_REGULATORS
+};
+
+#define RK817_SECONDS_REG		0x00
+#define RK817_MINUTES_REG		0x01
+#define RK817_HOURS_REG			0x02
+#define RK817_DAYS_REG			0x03
+#define RK817_MONTHS_REG		0x04
+#define RK817_YEARS_REG			0x05
+#define RK817_WEEKS_REG			0x06
+#define RK817_ALARM_SECONDS_REG		0x07
+#define RK817_ALARM_MINUTES_REG		0x08
+#define RK817_ALARM_HOURS_REG		0x09
+#define RK817_ALARM_DAYS_REG		0x0a
+#define RK817_ALARM_MONTHS_REG		0x0b
+#define RK817_ALARM_YEARS_REG		0x0c
+#define RK817_RTC_CTRL_REG		0xd
+#define RK817_RTC_STATUS_REG		0xe
+#define RK817_RTC_INT_REG		0xf
+#define RK817_RTC_COMP_LSB_REG		0x10
+#define RK817_RTC_COMP_MSB_REG		0x11
+
+#define RK817_POWER_EN_REG(i)		(0xb1 + (i))
+#define RK817_POWER_SLP_EN_REG(i)	(0xb5 + (i))
+
+#define RK817_POWER_CONFIG		(0xb9)
+
+#define RK817_BUCK_CONFIG_REG(i)	(0xba + (i) * 3)
+
+#define RK817_BUCK1_ON_VSEL_REG		0xBB
+#define RK817_BUCK1_SLP_VSEL_REG	0xBC
+
+#define RK817_BUCK2_CONFIG_REG		0xBD
+#define RK817_BUCK2_ON_VSEL_REG		0xBE
+#define RK817_BUCK2_SLP_VSEL_REG	0xBF
+
+#define RK817_BUCK3_CONFIG_REG		0xC0
+#define RK817_BUCK3_ON_VSEL_REG		0xC1
+#define RK817_BUCK3_SLP_VSEL_REG	0xC2
+
+#define RK817_BUCK4_CONFIG_REG		0xC3
+#define RK817_BUCK4_ON_VSEL_REG		0xC4
+#define RK817_BUCK4_SLP_VSEL_REG	0xC5
+
+#define RK817_LDO_ON_VSEL_REG(idx)	(0xcc + (idx) * 2)
+#define RK817_BOOST_OTG_CFG		(0xde)
+
+#define RK817_ID_MSB			0xed
+#define RK817_ID_LSB			0xee
+
+#define RK817_SYS_STS			0xf0
+#define RK817_SYS_CFG(i)		(0xf1 + (i))
+
+#define RK817_ON_SOURCE_REG		0xf5
+#define RK817_OFF_SOURCE_REG		0xf6
+
+/* INTERRUPT REGISTER */
+#define RK817_INT_STS_REG0		0xf8
+#define RK817_INT_STS_MSK_REG0		0xf9
+#define RK817_INT_STS_REG1		0xfa
+#define RK817_INT_STS_MSK_REG1		0xfb
+#define RK817_INT_STS_REG2		0xfc
+#define RK817_INT_STS_MSK_REG2		0xfd
+#define RK817_GPIO_INT_CFG		0xfe
+
+/* IRQ Definitions */
+#define RK817_IRQ_PWRON_FALL		0
+#define RK817_IRQ_PWRON_RISE		1
+#define RK817_IRQ_PWRON			2
+#define RK817_IRQ_PWMON_LP		3
+#define RK817_IRQ_HOTDIE		4
+#define RK817_IRQ_RTC_ALARM		5
+#define RK817_IRQ_RTC_PERIOD		6
+#define RK817_IRQ_VB_LO			7
+#define RK817_IRQ_PLUG_IN		(8 + 0)
+#define RK817_IRQ_PLUG_OUT		(8 + 1)
+#define RK817_IRQ_CHRG_TERM		(8 + 2)
+#define RK817_IRQ_CHRG_TIME		(8 + 3)
+#define RK817_IRQ_CHRG_TS		(8 + 4)
+#define RK817_IRQ_USB_OV		(8 + 5)
+#define RK817_IRQ_CHRG_IN_CLMP		(8 + 6)
+#define RK817_IRQ_BAT_DIS_ILIM		(8 + 7)
+#define RK817_IRQ_GATE_GPIO		(16 + 0)
+#define RK817_IRQ_TS_GPIO		(16 + 1)
+#define RK817_IRQ_CODEC_PD		(16 + 2)
+#define RK817_IRQ_CODEC_PO		(16 + 3)
+#define RK817_IRQ_CLASSD_MUTE_DONE	(16 + 4)
+#define RK817_IRQ_CLASSD_OCP		(16 + 5)
+#define RK817_IRQ_BAT_OVP		(16 + 6)
+#define RK817_IRQ_CHRG_BAT_HI		(16 + 7)
+#define RK817_IRQ_END			(RK817_IRQ_CHRG_BAT_HI + 1)
+
+/*
+ * rtc_ctrl 0xd
+ * same as 808, except bit4
+ */
+#define RK817_RTC_CTRL_RSV4		BIT(4)
+
+/* power config 0xb9 */
+#define RK817_BUCK3_FB_RES_MSK		BIT(6)
+#define RK817_BUCK3_FB_RES_INTER	BIT(6)
+#define RK817_BUCK3_FB_RES_EXT		0
+
+/* buck config 0xba */
+#define RK817_RAMP_RATE_OFFSET		6
+#define RK817_RAMP_RATE_MASK		(0x3 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_3MV_PER_US	(0x0 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_6_3MV_PER_US	(0x1 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_12_5MV_PER_US	(0x2 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_25MV_PER_US	(0x3 << RK817_RAMP_RATE_OFFSET)
+
+/* sys_cfg1 0xf2 */
+#define RK817_HOTDIE_TEMP_MSK		(0x3 << 4)
+#define RK817_HOTDIE_85			(0x0 << 4)
+#define RK817_HOTDIE_95			(0x1 << 4)
+#define RK817_HOTDIE_105		(0x2 << 4)
+#define RK817_HOTDIE_115		(0x3 << 4)
+
+#define RK817_TSD_TEMP_MSK		BIT(6)
+#define RK817_TSD_140			0
+#define RK817_TSD_160			BIT(6)
+
+#define RK817_CLK32KOUT2_EN		BIT(7)
+
+/* sys_cfg3 0xf4 */
+#define RK817_SLPPIN_FUNC_MSK		(0x3 << 3)
+#define SLPPIN_NULL_FUN			(0x0 << 3)
+#define SLPPIN_SLP_FUN			(0x1 << 3)
+#define SLPPIN_DN_FUN			(0x2 << 3)
+#define SLPPIN_RST_FUN			(0x3 << 3)
+
+#define RK817_RST_FUNC_MSK		(0x3 << 6)
+#define RK817_RST_FUNC_SFT		(6)
+#define RK817_RST_FUNC_CNT		(3)
+#define RK817_RST_FUNC_DEV		(0) /* reset the dev */
+#define RK817_RST_FUNC_REG		(0x1 << 6) /* reset the reg only */
+
+#define RK817_SLPPOL_MSK		BIT(5)
+#define RK817_SLPPOL_H			BIT(5)
+#define RK817_SLPPOL_L			(0)
+
+/* gpio&int 0xfe */
+#define RK817_INT_POL_MSK		BIT(1)
+#define RK817_INT_POL_H			BIT(1)
+#define RK817_INT_POL_L			0
+#define RK809_BUCK5_CONFIG(i)		(RK817_BOOST_OTG_CFG + (i) * 1)
 
 enum {
 	BUCK_ILMIN_50MA,
@@ -443,6 +613,8 @@ enum {
 enum {
 	RK805_ID = 0x8050,
 	RK808_ID = 0x0000,
+	RK809_ID = 0x8090,
+	RK817_ID = 0x8170,
 	RK818_ID = 0x8181,
 };
 
-- 
1.9.1



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/5] mfd: rk808: Add RK817 and RK809 support
@ 2018-07-23  3:19   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: linux-rtc, a.zummo, alexandre.belloni, tony.xie, huangtao,
	devicetree, sboyd, zhangqing, linux-kernel, xsf, linux-rockchip,
	broonie, lee.jones, linux-clk, linux-arm-kernel, chenjh

    The rk809 and rk817 are a Power Management IC (PMIC) for multimedia
    and handheld devices. It contains the following components:

        - Regulators
        - RTC
        - Clocking

    Both RK809 and RK817 chips are using a similar register map,
    so we can reuse the RTC and Clocking and regulators functionality.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/mfd/Kconfig       |   6 +-
 drivers/mfd/rk808.c       | 216 +++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/mfd/rk808.h | 172 ++++++++++++++++++++++++++++++++++++
 3 files changed, 389 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b860eb5..84f2f22 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -967,14 +967,14 @@ config MFD_RC5T583
 	  different functionality of the device.
 
 config MFD_RK808
-	tristate "Rockchip RK805/RK808/RK818 Power Management Chip"
+	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip"
 	depends on I2C && OF
 	select MFD_CORE
 	select REGMAP_I2C
 	select REGMAP_IRQ
 	help
-	  If you say yes here you get support for the RK805, RK808 and RK818
-	  Power Management chips.
+	  If you say yes here you get support for the RK805, RK809 and RK817,
+	  RK808 and RK818 Power Management chips.
 	  This driver provides common support for accessing the device
 	  through I2C interface. The device supports multiple sub-devices
 	  including interrupts, RTC, LDO & DCDC regulators, and onkey.
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 216fbf6..bfb5668 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -62,6 +62,29 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	return false;
 }
 
+static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+	/*
+	 * Notes:
+	 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
+	 *   we don't use that feature.  It's better to cache.
+	 * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
+	 *   bits are cleared in case when we shutoff anyway, but better safe.
+	 */
+
+	switch (reg) {
+	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
+	case RK817_RTC_STATUS_REG:
+	case RK817_INT_STS_REG0:
+	case RK817_INT_STS_REG1:
+	case RK817_INT_STS_REG2:
+	case RK817_SYS_STS:
+		return true;
+	}
+
+	return true;
+}
+
 static const struct regmap_config rk818_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
@@ -86,6 +109,14 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	.volatile_reg = rk808_is_volatile_reg,
 };
 
+static const struct regmap_config rk817_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = RK817_GPIO_INT_CFG,
+	.cache_type = REGCACHE_NONE,
+	.volatile_reg = rk817_is_volatile_reg,
+};
+
 static struct resource rtc_resources[] = {
 	{
 		.start  = RK808_IRQ_RTC_ALARM,
@@ -94,6 +125,13 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	}
 };
 
+static struct resource rk817_rtc_resources[] = {
+	{
+		.start  = RK817_IRQ_RTC_ALARM,
+		.end    = RK817_IRQ_RTC_ALARM,
+		.flags  = IORESOURCE_IRQ,
+	}
+};
 static struct resource rk805_key_resources[] = {
 	{
 		.start  = RK805_IRQ_PWRON_FALL,
@@ -107,6 +145,19 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	}
 };
 
+static struct resource rk817_pwrkey_resources[] = {
+	{
+		.start  = RK817_IRQ_PWRON_RISE,
+		.end    = RK817_IRQ_PWRON_RISE,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.start  = RK817_IRQ_PWRON_FALL,
+		.end    = RK817_IRQ_PWRON_FALL,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
 static const struct mfd_cell rk805s[] = {
 	{ .name = "rk808-clkout", },
 	{ .name = "rk808-regulator", },
@@ -132,6 +183,21 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	},
 };
 
+static const struct mfd_cell rk817s[] = {
+	{ .name = "rk808-clkout",},
+	{ .name = "rk808-regulator",},
+	{
+		.name = "rk8xx-pwrkey",
+		.num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
+		.resources = &rk817_pwrkey_resources[0],
+	},
+	{
+		.name = "rk808-rtc",
+		.num_resources = ARRAY_SIZE(rk817_rtc_resources),
+		.resources = &rk817_rtc_resources[0],
+	},
+};
+
 static const struct mfd_cell rk818s[] = {
 	{ .name = "rk808-clkout", },
 	{ .name = "rk808-regulator", },
@@ -167,6 +233,13 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 						    VB_LO_SEL_3500MV },
 };
 
+static const struct rk808_reg_data rk817_pre_init_reg[] = {
+	{RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
+	{RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_H},
+	{RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK,
+					   RK817_HOTDIE_105 | RK817_TSD_140},
+};
+
 static const struct rk808_reg_data rk818_pre_init_reg[] = {
 	/* improve efficiency */
 	{ RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK,  BUCK_ILMIN_250MA },
@@ -332,6 +405,39 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	},
 };
 
+#define REGMAP_IRQ_M(_id) \
+	[_id] = {				\
+		.mask = BIT(((_id) % 8)),	\
+		.reg_offset = ((_id) / 8),	\
+	}
+
+static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
+	REGMAP_IRQ_M(0),
+	REGMAP_IRQ_M(1),
+	REGMAP_IRQ_M(2),
+	REGMAP_IRQ_M(3),
+	REGMAP_IRQ_M(4),
+	REGMAP_IRQ_M(5),
+	REGMAP_IRQ_M(6),
+	REGMAP_IRQ_M(7),
+	REGMAP_IRQ_M(8),
+	REGMAP_IRQ_M(9),
+	REGMAP_IRQ_M(10),
+	REGMAP_IRQ_M(11),
+	REGMAP_IRQ_M(12),
+	REGMAP_IRQ_M(13),
+	REGMAP_IRQ_M(14),
+	REGMAP_IRQ_M(15),
+	REGMAP_IRQ_M(16),
+	REGMAP_IRQ_M(17),
+	REGMAP_IRQ_M(18),
+	REGMAP_IRQ_M(19),
+	REGMAP_IRQ_M(20),
+	REGMAP_IRQ_M(21),
+	REGMAP_IRQ_M(22),
+	REGMAP_IRQ_M(23)
+};
+
 static struct regmap_irq_chip rk805_irq_chip = {
 	.name = "rk805",
 	.irqs = rk805_irqs,
@@ -355,6 +461,18 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	.init_ack_masked = true,
 };
 
+static struct regmap_irq_chip rk817_irq_chip = {
+	.name = "rk817",
+	.irqs = rk817_irqs,
+	.num_irqs = ARRAY_SIZE(rk817_irqs),
+	.num_regs = 3,
+	.irq_reg_stride = 2,
+	.status_base = RK817_INT_STS_REG0,
+	.mask_base = RK817_INT_STS_MSK_REG0,
+	.ack_base = RK817_INT_STS_REG0,
+	.init_ack_masked = true,
+};
+
 static const struct regmap_irq_chip rk818_irq_chip = {
 	.name = "rk818",
 	.irqs = rk818_irqs,
@@ -423,9 +541,39 @@ static void rk818_device_shutdown(void)
 		dev_err(&rk808_i2c_client->dev, "power off error!\n");
 }
 
+static void rk8xx_device_shutdown_prepare(void)
+{
+	int ret;
+	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+	if (!rk808) {
+		dev_warn(&rk808_i2c_client->dev,
+			 "have no rk808, so do nothing here\n");
+		return;
+	}
+
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		ret = regmap_update_bits(rk808->regmap,
+					 RK817_SYS_CFG(3),
+					 RK817_SLPPIN_FUNC_MSK,
+					 SLPPIN_DN_FUN);
+		if (ret) {
+			dev_warn(&rk808_i2c_client->dev,
+				 "switch pin func to power down error!\n");
+		}
+		break;
+	default:
+		break;
+	}
+}
+
 static const struct of_device_id rk808_of_match[] = {
 	{ .compatible = "rockchip,rk805" },
 	{ .compatible = "rockchip,rk808" },
+	{ .compatible = "rockchip,rk809" },
+	{ .compatible = "rockchip,rk817" },
 	{ .compatible = "rockchip,rk818" },
 	{ },
 };
@@ -442,6 +590,7 @@ static int rk808_probe(struct i2c_client *client,
 	int nr_pre_init_regs;
 	int nr_cells;
 	int pm_off = 0, msb, lsb;
+	unsigned char pmic_id_msb = RK808_ID_MSB, pmic_id_lsb = RK808_ID_LSB;
 	int ret;
 	int i;
 
@@ -449,15 +598,20 @@ static int rk808_probe(struct i2c_client *client,
 	if (!rk808)
 		return -ENOMEM;
 
+	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;
+	}
 	/* Read chip variant */
-	msb = i2c_smbus_read_byte_data(client, RK808_ID_MSB);
+	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
 	if (msb < 0) {
 		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
 			RK808_ID_MSB);
 		return msb;
 	}
 
-	lsb = i2c_smbus_read_byte_data(client, RK808_ID_LSB);
+	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
 	if (lsb < 0) {
 		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
 			RK808_ID_LSB);
@@ -495,6 +649,16 @@ static int rk808_probe(struct i2c_client *client,
 		nr_cells = ARRAY_SIZE(rk818s);
 		pm_pwroff_fn = rk818_device_shutdown;
 		break;
+	case RK809_ID:
+	case RK817_ID:
+		rk808->regmap_cfg = &rk817_regmap_config;
+		rk808->regmap_irq_chip = &rk817_irq_chip;
+		pre_init_reg = rk817_pre_init_reg;
+		nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
+		cells = rk817s;
+		nr_cells = ARRAY_SIZE(rk817s);
+		pm_power_off_prepare = rk8xx_device_shutdown_prepare;
+		break;
 	default:
 		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
 			rk808->variant);
@@ -568,9 +732,56 @@ static int rk808_remove(struct i2c_client *client)
 	return 0;
 }
 
+static int rk8xx_suspend(struct device *dev)
+{
+	int ret = 0;
+	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		ret = regmap_update_bits(rk808->regmap,
+					 RK817_SYS_CFG(3),
+					 RK817_SLPPIN_FUNC_MSK,
+					 SLPPIN_SLP_FUN);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int rk8xx_resume(struct device *dev)
+{
+	int ret = 0;
+	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		ret = regmap_update_bits(rk808->regmap,
+					 RK817_SYS_CFG(3),
+					 RK817_SLPPIN_FUNC_MSK,
+					 SLPPIN_NULL_FUN);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static const struct dev_pm_ops rk8xx_pm_ops = {
+	.suspend = rk8xx_suspend,
+	.resume =  rk8xx_resume,
+};
+
 static const struct i2c_device_id rk808_ids[] = {
 	{ "rk805" },
 	{ "rk808" },
+	{ "rk809" },
+	{ "rk817" },
 	{ "rk818" },
 	{ },
 };
@@ -580,6 +791,7 @@ static int rk808_remove(struct i2c_client *client)
 	.driver = {
 		.name = "rk808",
 		.of_match_table = rk808_of_match,
+		.pm = &rk8xx_pm_ops,
 	},
 	.probe    = rk808_probe,
 	.remove   = rk808_remove,
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index d315659..b973b0a 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -382,6 +382,7 @@ enum rk805_reg {
 #define SWITCH1_EN	BIT(5)
 #define DEV_OFF_RST	BIT(3)
 #define DEV_OFF		BIT(0)
+#define RTC_STOP	BIT(0)
 
 #define VB_LO_ACT		BIT(4)
 #define VB_LO_SEL_3500MV	(7 << 0)
@@ -396,6 +397,175 @@ enum rk805_reg {
 #define SLEEP_FUN			(0x1 << 2)
 #define RK8XX_ID_MSK			0xfff0
 #define FPWM_MODE			BIT(7)
+enum rk817_reg_id {
+	RK817_ID_DCDC1 = 0,
+	RK817_ID_DCDC2,
+	RK817_ID_DCDC3,
+	RK817_ID_DCDC4,
+	RK817_ID_LDO1,
+	RK817_ID_LDO2,
+	RK817_ID_LDO3,
+	RK817_ID_LDO4,
+	RK817_ID_LDO5,
+	RK817_ID_LDO6,
+	RK817_ID_LDO7,
+	RK817_ID_LDO8,
+	RK817_ID_LDO9,
+	RK817_ID_BOOST,
+	RK817_ID_BOOST_OTG_SW,
+	RK817_NUM_REGULATORS
+};
+
+enum rk809_reg_id {
+	RK809_ID_DCDC5 = RK817_ID_BOOST,
+	RK809_ID_SW1,
+	RK809_ID_SW2,
+	RK809_NUM_REGULATORS
+};
+
+#define RK817_SECONDS_REG		0x00
+#define RK817_MINUTES_REG		0x01
+#define RK817_HOURS_REG			0x02
+#define RK817_DAYS_REG			0x03
+#define RK817_MONTHS_REG		0x04
+#define RK817_YEARS_REG			0x05
+#define RK817_WEEKS_REG			0x06
+#define RK817_ALARM_SECONDS_REG		0x07
+#define RK817_ALARM_MINUTES_REG		0x08
+#define RK817_ALARM_HOURS_REG		0x09
+#define RK817_ALARM_DAYS_REG		0x0a
+#define RK817_ALARM_MONTHS_REG		0x0b
+#define RK817_ALARM_YEARS_REG		0x0c
+#define RK817_RTC_CTRL_REG		0xd
+#define RK817_RTC_STATUS_REG		0xe
+#define RK817_RTC_INT_REG		0xf
+#define RK817_RTC_COMP_LSB_REG		0x10
+#define RK817_RTC_COMP_MSB_REG		0x11
+
+#define RK817_POWER_EN_REG(i)		(0xb1 + (i))
+#define RK817_POWER_SLP_EN_REG(i)	(0xb5 + (i))
+
+#define RK817_POWER_CONFIG		(0xb9)
+
+#define RK817_BUCK_CONFIG_REG(i)	(0xba + (i) * 3)
+
+#define RK817_BUCK1_ON_VSEL_REG		0xBB
+#define RK817_BUCK1_SLP_VSEL_REG	0xBC
+
+#define RK817_BUCK2_CONFIG_REG		0xBD
+#define RK817_BUCK2_ON_VSEL_REG		0xBE
+#define RK817_BUCK2_SLP_VSEL_REG	0xBF
+
+#define RK817_BUCK3_CONFIG_REG		0xC0
+#define RK817_BUCK3_ON_VSEL_REG		0xC1
+#define RK817_BUCK3_SLP_VSEL_REG	0xC2
+
+#define RK817_BUCK4_CONFIG_REG		0xC3
+#define RK817_BUCK4_ON_VSEL_REG		0xC4
+#define RK817_BUCK4_SLP_VSEL_REG	0xC5
+
+#define RK817_LDO_ON_VSEL_REG(idx)	(0xcc + (idx) * 2)
+#define RK817_BOOST_OTG_CFG		(0xde)
+
+#define RK817_ID_MSB			0xed
+#define RK817_ID_LSB			0xee
+
+#define RK817_SYS_STS			0xf0
+#define RK817_SYS_CFG(i)		(0xf1 + (i))
+
+#define RK817_ON_SOURCE_REG		0xf5
+#define RK817_OFF_SOURCE_REG		0xf6
+
+/* INTERRUPT REGISTER */
+#define RK817_INT_STS_REG0		0xf8
+#define RK817_INT_STS_MSK_REG0		0xf9
+#define RK817_INT_STS_REG1		0xfa
+#define RK817_INT_STS_MSK_REG1		0xfb
+#define RK817_INT_STS_REG2		0xfc
+#define RK817_INT_STS_MSK_REG2		0xfd
+#define RK817_GPIO_INT_CFG		0xfe
+
+/* IRQ Definitions */
+#define RK817_IRQ_PWRON_FALL		0
+#define RK817_IRQ_PWRON_RISE		1
+#define RK817_IRQ_PWRON			2
+#define RK817_IRQ_PWMON_LP		3
+#define RK817_IRQ_HOTDIE		4
+#define RK817_IRQ_RTC_ALARM		5
+#define RK817_IRQ_RTC_PERIOD		6
+#define RK817_IRQ_VB_LO			7
+#define RK817_IRQ_PLUG_IN		(8 + 0)
+#define RK817_IRQ_PLUG_OUT		(8 + 1)
+#define RK817_IRQ_CHRG_TERM		(8 + 2)
+#define RK817_IRQ_CHRG_TIME		(8 + 3)
+#define RK817_IRQ_CHRG_TS		(8 + 4)
+#define RK817_IRQ_USB_OV		(8 + 5)
+#define RK817_IRQ_CHRG_IN_CLMP		(8 + 6)
+#define RK817_IRQ_BAT_DIS_ILIM		(8 + 7)
+#define RK817_IRQ_GATE_GPIO		(16 + 0)
+#define RK817_IRQ_TS_GPIO		(16 + 1)
+#define RK817_IRQ_CODEC_PD		(16 + 2)
+#define RK817_IRQ_CODEC_PO		(16 + 3)
+#define RK817_IRQ_CLASSD_MUTE_DONE	(16 + 4)
+#define RK817_IRQ_CLASSD_OCP		(16 + 5)
+#define RK817_IRQ_BAT_OVP		(16 + 6)
+#define RK817_IRQ_CHRG_BAT_HI		(16 + 7)
+#define RK817_IRQ_END			(RK817_IRQ_CHRG_BAT_HI + 1)
+
+/*
+ * rtc_ctrl 0xd
+ * same as 808, except bit4
+ */
+#define RK817_RTC_CTRL_RSV4		BIT(4)
+
+/* power config 0xb9 */
+#define RK817_BUCK3_FB_RES_MSK		BIT(6)
+#define RK817_BUCK3_FB_RES_INTER	BIT(6)
+#define RK817_BUCK3_FB_RES_EXT		0
+
+/* buck config 0xba */
+#define RK817_RAMP_RATE_OFFSET		6
+#define RK817_RAMP_RATE_MASK		(0x3 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_3MV_PER_US	(0x0 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_6_3MV_PER_US	(0x1 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_12_5MV_PER_US	(0x2 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_25MV_PER_US	(0x3 << RK817_RAMP_RATE_OFFSET)
+
+/* sys_cfg1 0xf2 */
+#define RK817_HOTDIE_TEMP_MSK		(0x3 << 4)
+#define RK817_HOTDIE_85			(0x0 << 4)
+#define RK817_HOTDIE_95			(0x1 << 4)
+#define RK817_HOTDIE_105		(0x2 << 4)
+#define RK817_HOTDIE_115		(0x3 << 4)
+
+#define RK817_TSD_TEMP_MSK		BIT(6)
+#define RK817_TSD_140			0
+#define RK817_TSD_160			BIT(6)
+
+#define RK817_CLK32KOUT2_EN		BIT(7)
+
+/* sys_cfg3 0xf4 */
+#define RK817_SLPPIN_FUNC_MSK		(0x3 << 3)
+#define SLPPIN_NULL_FUN			(0x0 << 3)
+#define SLPPIN_SLP_FUN			(0x1 << 3)
+#define SLPPIN_DN_FUN			(0x2 << 3)
+#define SLPPIN_RST_FUN			(0x3 << 3)
+
+#define RK817_RST_FUNC_MSK		(0x3 << 6)
+#define RK817_RST_FUNC_SFT		(6)
+#define RK817_RST_FUNC_CNT		(3)
+#define RK817_RST_FUNC_DEV		(0) /* reset the dev */
+#define RK817_RST_FUNC_REG		(0x1 << 6) /* reset the reg only */
+
+#define RK817_SLPPOL_MSK		BIT(5)
+#define RK817_SLPPOL_H			BIT(5)
+#define RK817_SLPPOL_L			(0)
+
+/* gpio&int 0xfe */
+#define RK817_INT_POL_MSK		BIT(1)
+#define RK817_INT_POL_H			BIT(1)
+#define RK817_INT_POL_L			0
+#define RK809_BUCK5_CONFIG(i)		(RK817_BOOST_OTG_CFG + (i) * 1)
 
 enum {
 	BUCK_ILMIN_50MA,
@@ -443,6 +613,8 @@ enum {
 enum {
 	RK805_ID = 0x8050,
 	RK808_ID = 0x0000,
+	RK809_ID = 0x8090,
+	RK817_ID = 0x8170,
 	RK818_ID = 0x8181,
 };
 
-- 
1.9.1

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

* [PATCH 1/5] mfd: rk808: Add RK817 and RK809 support
@ 2018-07-23  3:19   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: broonie, lee.jones, a.zummo, alexandre.belloni, sboyd, linux-clk,
	linux-rtc, linux-arm-kernel, linux-rockchip, devicetree,
	linux-kernel, chenjh, xsf, zhangqing, huangtao, tony.xie

    The rk809 and rk817 are a Power Management IC (PMIC) for multimedia
    and handheld devices. It contains the following components:

        - Regulators
        - RTC
        - Clocking

    Both RK809 and RK817 chips are using a similar register map,
    so we can reuse the RTC and Clocking and regulators functionality.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/mfd/Kconfig       |   6 +-
 drivers/mfd/rk808.c       | 216 +++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/mfd/rk808.h | 172 ++++++++++++++++++++++++++++++++++++
 3 files changed, 389 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b860eb5..84f2f22 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -967,14 +967,14 @@ config MFD_RC5T583
 	  different functionality of the device.
 
 config MFD_RK808
-	tristate "Rockchip RK805/RK808/RK818 Power Management Chip"
+	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip"
 	depends on I2C && OF
 	select MFD_CORE
 	select REGMAP_I2C
 	select REGMAP_IRQ
 	help
-	  If you say yes here you get support for the RK805, RK808 and RK818
-	  Power Management chips.
+	  If you say yes here you get support for the RK805, RK809 and RK817,
+	  RK808 and RK818 Power Management chips.
 	  This driver provides common support for accessing the device
 	  through I2C interface. The device supports multiple sub-devices
 	  including interrupts, RTC, LDO & DCDC regulators, and onkey.
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 216fbf6..bfb5668 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -62,6 +62,29 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	return false;
 }
 
+static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+	/*
+	 * Notes:
+	 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
+	 *   we don't use that feature.  It's better to cache.
+	 * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
+	 *   bits are cleared in case when we shutoff anyway, but better safe.
+	 */
+
+	switch (reg) {
+	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
+	case RK817_RTC_STATUS_REG:
+	case RK817_INT_STS_REG0:
+	case RK817_INT_STS_REG1:
+	case RK817_INT_STS_REG2:
+	case RK817_SYS_STS:
+		return true;
+	}
+
+	return true;
+}
+
 static const struct regmap_config rk818_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
@@ -86,6 +109,14 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	.volatile_reg = rk808_is_volatile_reg,
 };
 
+static const struct regmap_config rk817_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = RK817_GPIO_INT_CFG,
+	.cache_type = REGCACHE_NONE,
+	.volatile_reg = rk817_is_volatile_reg,
+};
+
 static struct resource rtc_resources[] = {
 	{
 		.start  = RK808_IRQ_RTC_ALARM,
@@ -94,6 +125,13 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	}
 };
 
+static struct resource rk817_rtc_resources[] = {
+	{
+		.start  = RK817_IRQ_RTC_ALARM,
+		.end    = RK817_IRQ_RTC_ALARM,
+		.flags  = IORESOURCE_IRQ,
+	}
+};
 static struct resource rk805_key_resources[] = {
 	{
 		.start  = RK805_IRQ_PWRON_FALL,
@@ -107,6 +145,19 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	}
 };
 
+static struct resource rk817_pwrkey_resources[] = {
+	{
+		.start  = RK817_IRQ_PWRON_RISE,
+		.end    = RK817_IRQ_PWRON_RISE,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.start  = RK817_IRQ_PWRON_FALL,
+		.end    = RK817_IRQ_PWRON_FALL,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
 static const struct mfd_cell rk805s[] = {
 	{ .name = "rk808-clkout", },
 	{ .name = "rk808-regulator", },
@@ -132,6 +183,21 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	},
 };
 
+static const struct mfd_cell rk817s[] = {
+	{ .name = "rk808-clkout",},
+	{ .name = "rk808-regulator",},
+	{
+		.name = "rk8xx-pwrkey",
+		.num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
+		.resources = &rk817_pwrkey_resources[0],
+	},
+	{
+		.name = "rk808-rtc",
+		.num_resources = ARRAY_SIZE(rk817_rtc_resources),
+		.resources = &rk817_rtc_resources[0],
+	},
+};
+
 static const struct mfd_cell rk818s[] = {
 	{ .name = "rk808-clkout", },
 	{ .name = "rk808-regulator", },
@@ -167,6 +233,13 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 						    VB_LO_SEL_3500MV },
 };
 
+static const struct rk808_reg_data rk817_pre_init_reg[] = {
+	{RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
+	{RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_H},
+	{RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK,
+					   RK817_HOTDIE_105 | RK817_TSD_140},
+};
+
 static const struct rk808_reg_data rk818_pre_init_reg[] = {
 	/* improve efficiency */
 	{ RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK,  BUCK_ILMIN_250MA },
@@ -332,6 +405,39 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	},
 };
 
+#define REGMAP_IRQ_M(_id) \
+	[_id] = {				\
+		.mask = BIT(((_id) % 8)),	\
+		.reg_offset = ((_id) / 8),	\
+	}
+
+static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
+	REGMAP_IRQ_M(0),
+	REGMAP_IRQ_M(1),
+	REGMAP_IRQ_M(2),
+	REGMAP_IRQ_M(3),
+	REGMAP_IRQ_M(4),
+	REGMAP_IRQ_M(5),
+	REGMAP_IRQ_M(6),
+	REGMAP_IRQ_M(7),
+	REGMAP_IRQ_M(8),
+	REGMAP_IRQ_M(9),
+	REGMAP_IRQ_M(10),
+	REGMAP_IRQ_M(11),
+	REGMAP_IRQ_M(12),
+	REGMAP_IRQ_M(13),
+	REGMAP_IRQ_M(14),
+	REGMAP_IRQ_M(15),
+	REGMAP_IRQ_M(16),
+	REGMAP_IRQ_M(17),
+	REGMAP_IRQ_M(18),
+	REGMAP_IRQ_M(19),
+	REGMAP_IRQ_M(20),
+	REGMAP_IRQ_M(21),
+	REGMAP_IRQ_M(22),
+	REGMAP_IRQ_M(23)
+};
+
 static struct regmap_irq_chip rk805_irq_chip = {
 	.name = "rk805",
 	.irqs = rk805_irqs,
@@ -355,6 +461,18 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	.init_ack_masked = true,
 };
 
+static struct regmap_irq_chip rk817_irq_chip = {
+	.name = "rk817",
+	.irqs = rk817_irqs,
+	.num_irqs = ARRAY_SIZE(rk817_irqs),
+	.num_regs = 3,
+	.irq_reg_stride = 2,
+	.status_base = RK817_INT_STS_REG0,
+	.mask_base = RK817_INT_STS_MSK_REG0,
+	.ack_base = RK817_INT_STS_REG0,
+	.init_ack_masked = true,
+};
+
 static const struct regmap_irq_chip rk818_irq_chip = {
 	.name = "rk818",
 	.irqs = rk818_irqs,
@@ -423,9 +541,39 @@ static void rk818_device_shutdown(void)
 		dev_err(&rk808_i2c_client->dev, "power off error!\n");
 }
 
+static void rk8xx_device_shutdown_prepare(void)
+{
+	int ret;
+	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+	if (!rk808) {
+		dev_warn(&rk808_i2c_client->dev,
+			 "have no rk808, so do nothing here\n");
+		return;
+	}
+
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		ret = regmap_update_bits(rk808->regmap,
+					 RK817_SYS_CFG(3),
+					 RK817_SLPPIN_FUNC_MSK,
+					 SLPPIN_DN_FUN);
+		if (ret) {
+			dev_warn(&rk808_i2c_client->dev,
+				 "switch pin func to power down error!\n");
+		}
+		break;
+	default:
+		break;
+	}
+}
+
 static const struct of_device_id rk808_of_match[] = {
 	{ .compatible = "rockchip,rk805" },
 	{ .compatible = "rockchip,rk808" },
+	{ .compatible = "rockchip,rk809" },
+	{ .compatible = "rockchip,rk817" },
 	{ .compatible = "rockchip,rk818" },
 	{ },
 };
@@ -442,6 +590,7 @@ static int rk808_probe(struct i2c_client *client,
 	int nr_pre_init_regs;
 	int nr_cells;
 	int pm_off = 0, msb, lsb;
+	unsigned char pmic_id_msb = RK808_ID_MSB, pmic_id_lsb = RK808_ID_LSB;
 	int ret;
 	int i;
 
@@ -449,15 +598,20 @@ static int rk808_probe(struct i2c_client *client,
 	if (!rk808)
 		return -ENOMEM;
 
+	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;
+	}
 	/* Read chip variant */
-	msb = i2c_smbus_read_byte_data(client, RK808_ID_MSB);
+	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
 	if (msb < 0) {
 		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
 			RK808_ID_MSB);
 		return msb;
 	}
 
-	lsb = i2c_smbus_read_byte_data(client, RK808_ID_LSB);
+	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
 	if (lsb < 0) {
 		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
 			RK808_ID_LSB);
@@ -495,6 +649,16 @@ static int rk808_probe(struct i2c_client *client,
 		nr_cells = ARRAY_SIZE(rk818s);
 		pm_pwroff_fn = rk818_device_shutdown;
 		break;
+	case RK809_ID:
+	case RK817_ID:
+		rk808->regmap_cfg = &rk817_regmap_config;
+		rk808->regmap_irq_chip = &rk817_irq_chip;
+		pre_init_reg = rk817_pre_init_reg;
+		nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
+		cells = rk817s;
+		nr_cells = ARRAY_SIZE(rk817s);
+		pm_power_off_prepare = rk8xx_device_shutdown_prepare;
+		break;
 	default:
 		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
 			rk808->variant);
@@ -568,9 +732,56 @@ static int rk808_remove(struct i2c_client *client)
 	return 0;
 }
 
+static int rk8xx_suspend(struct device *dev)
+{
+	int ret = 0;
+	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		ret = regmap_update_bits(rk808->regmap,
+					 RK817_SYS_CFG(3),
+					 RK817_SLPPIN_FUNC_MSK,
+					 SLPPIN_SLP_FUN);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int rk8xx_resume(struct device *dev)
+{
+	int ret = 0;
+	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		ret = regmap_update_bits(rk808->regmap,
+					 RK817_SYS_CFG(3),
+					 RK817_SLPPIN_FUNC_MSK,
+					 SLPPIN_NULL_FUN);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static const struct dev_pm_ops rk8xx_pm_ops = {
+	.suspend = rk8xx_suspend,
+	.resume =  rk8xx_resume,
+};
+
 static const struct i2c_device_id rk808_ids[] = {
 	{ "rk805" },
 	{ "rk808" },
+	{ "rk809" },
+	{ "rk817" },
 	{ "rk818" },
 	{ },
 };
@@ -580,6 +791,7 @@ static int rk808_remove(struct i2c_client *client)
 	.driver = {
 		.name = "rk808",
 		.of_match_table = rk808_of_match,
+		.pm = &rk8xx_pm_ops,
 	},
 	.probe    = rk808_probe,
 	.remove   = rk808_remove,
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index d315659..b973b0a 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -382,6 +382,7 @@ enum rk805_reg {
 #define SWITCH1_EN	BIT(5)
 #define DEV_OFF_RST	BIT(3)
 #define DEV_OFF		BIT(0)
+#define RTC_STOP	BIT(0)
 
 #define VB_LO_ACT		BIT(4)
 #define VB_LO_SEL_3500MV	(7 << 0)
@@ -396,6 +397,175 @@ enum rk805_reg {
 #define SLEEP_FUN			(0x1 << 2)
 #define RK8XX_ID_MSK			0xfff0
 #define FPWM_MODE			BIT(7)
+enum rk817_reg_id {
+	RK817_ID_DCDC1 = 0,
+	RK817_ID_DCDC2,
+	RK817_ID_DCDC3,
+	RK817_ID_DCDC4,
+	RK817_ID_LDO1,
+	RK817_ID_LDO2,
+	RK817_ID_LDO3,
+	RK817_ID_LDO4,
+	RK817_ID_LDO5,
+	RK817_ID_LDO6,
+	RK817_ID_LDO7,
+	RK817_ID_LDO8,
+	RK817_ID_LDO9,
+	RK817_ID_BOOST,
+	RK817_ID_BOOST_OTG_SW,
+	RK817_NUM_REGULATORS
+};
+
+enum rk809_reg_id {
+	RK809_ID_DCDC5 = RK817_ID_BOOST,
+	RK809_ID_SW1,
+	RK809_ID_SW2,
+	RK809_NUM_REGULATORS
+};
+
+#define RK817_SECONDS_REG		0x00
+#define RK817_MINUTES_REG		0x01
+#define RK817_HOURS_REG			0x02
+#define RK817_DAYS_REG			0x03
+#define RK817_MONTHS_REG		0x04
+#define RK817_YEARS_REG			0x05
+#define RK817_WEEKS_REG			0x06
+#define RK817_ALARM_SECONDS_REG		0x07
+#define RK817_ALARM_MINUTES_REG		0x08
+#define RK817_ALARM_HOURS_REG		0x09
+#define RK817_ALARM_DAYS_REG		0x0a
+#define RK817_ALARM_MONTHS_REG		0x0b
+#define RK817_ALARM_YEARS_REG		0x0c
+#define RK817_RTC_CTRL_REG		0xd
+#define RK817_RTC_STATUS_REG		0xe
+#define RK817_RTC_INT_REG		0xf
+#define RK817_RTC_COMP_LSB_REG		0x10
+#define RK817_RTC_COMP_MSB_REG		0x11
+
+#define RK817_POWER_EN_REG(i)		(0xb1 + (i))
+#define RK817_POWER_SLP_EN_REG(i)	(0xb5 + (i))
+
+#define RK817_POWER_CONFIG		(0xb9)
+
+#define RK817_BUCK_CONFIG_REG(i)	(0xba + (i) * 3)
+
+#define RK817_BUCK1_ON_VSEL_REG		0xBB
+#define RK817_BUCK1_SLP_VSEL_REG	0xBC
+
+#define RK817_BUCK2_CONFIG_REG		0xBD
+#define RK817_BUCK2_ON_VSEL_REG		0xBE
+#define RK817_BUCK2_SLP_VSEL_REG	0xBF
+
+#define RK817_BUCK3_CONFIG_REG		0xC0
+#define RK817_BUCK3_ON_VSEL_REG		0xC1
+#define RK817_BUCK3_SLP_VSEL_REG	0xC2
+
+#define RK817_BUCK4_CONFIG_REG		0xC3
+#define RK817_BUCK4_ON_VSEL_REG		0xC4
+#define RK817_BUCK4_SLP_VSEL_REG	0xC5
+
+#define RK817_LDO_ON_VSEL_REG(idx)	(0xcc + (idx) * 2)
+#define RK817_BOOST_OTG_CFG		(0xde)
+
+#define RK817_ID_MSB			0xed
+#define RK817_ID_LSB			0xee
+
+#define RK817_SYS_STS			0xf0
+#define RK817_SYS_CFG(i)		(0xf1 + (i))
+
+#define RK817_ON_SOURCE_REG		0xf5
+#define RK817_OFF_SOURCE_REG		0xf6
+
+/* INTERRUPT REGISTER */
+#define RK817_INT_STS_REG0		0xf8
+#define RK817_INT_STS_MSK_REG0		0xf9
+#define RK817_INT_STS_REG1		0xfa
+#define RK817_INT_STS_MSK_REG1		0xfb
+#define RK817_INT_STS_REG2		0xfc
+#define RK817_INT_STS_MSK_REG2		0xfd
+#define RK817_GPIO_INT_CFG		0xfe
+
+/* IRQ Definitions */
+#define RK817_IRQ_PWRON_FALL		0
+#define RK817_IRQ_PWRON_RISE		1
+#define RK817_IRQ_PWRON			2
+#define RK817_IRQ_PWMON_LP		3
+#define RK817_IRQ_HOTDIE		4
+#define RK817_IRQ_RTC_ALARM		5
+#define RK817_IRQ_RTC_PERIOD		6
+#define RK817_IRQ_VB_LO			7
+#define RK817_IRQ_PLUG_IN		(8 + 0)
+#define RK817_IRQ_PLUG_OUT		(8 + 1)
+#define RK817_IRQ_CHRG_TERM		(8 + 2)
+#define RK817_IRQ_CHRG_TIME		(8 + 3)
+#define RK817_IRQ_CHRG_TS		(8 + 4)
+#define RK817_IRQ_USB_OV		(8 + 5)
+#define RK817_IRQ_CHRG_IN_CLMP		(8 + 6)
+#define RK817_IRQ_BAT_DIS_ILIM		(8 + 7)
+#define RK817_IRQ_GATE_GPIO		(16 + 0)
+#define RK817_IRQ_TS_GPIO		(16 + 1)
+#define RK817_IRQ_CODEC_PD		(16 + 2)
+#define RK817_IRQ_CODEC_PO		(16 + 3)
+#define RK817_IRQ_CLASSD_MUTE_DONE	(16 + 4)
+#define RK817_IRQ_CLASSD_OCP		(16 + 5)
+#define RK817_IRQ_BAT_OVP		(16 + 6)
+#define RK817_IRQ_CHRG_BAT_HI		(16 + 7)
+#define RK817_IRQ_END			(RK817_IRQ_CHRG_BAT_HI + 1)
+
+/*
+ * rtc_ctrl 0xd
+ * same as 808, except bit4
+ */
+#define RK817_RTC_CTRL_RSV4		BIT(4)
+
+/* power config 0xb9 */
+#define RK817_BUCK3_FB_RES_MSK		BIT(6)
+#define RK817_BUCK3_FB_RES_INTER	BIT(6)
+#define RK817_BUCK3_FB_RES_EXT		0
+
+/* buck config 0xba */
+#define RK817_RAMP_RATE_OFFSET		6
+#define RK817_RAMP_RATE_MASK		(0x3 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_3MV_PER_US	(0x0 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_6_3MV_PER_US	(0x1 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_12_5MV_PER_US	(0x2 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_25MV_PER_US	(0x3 << RK817_RAMP_RATE_OFFSET)
+
+/* sys_cfg1 0xf2 */
+#define RK817_HOTDIE_TEMP_MSK		(0x3 << 4)
+#define RK817_HOTDIE_85			(0x0 << 4)
+#define RK817_HOTDIE_95			(0x1 << 4)
+#define RK817_HOTDIE_105		(0x2 << 4)
+#define RK817_HOTDIE_115		(0x3 << 4)
+
+#define RK817_TSD_TEMP_MSK		BIT(6)
+#define RK817_TSD_140			0
+#define RK817_TSD_160			BIT(6)
+
+#define RK817_CLK32KOUT2_EN		BIT(7)
+
+/* sys_cfg3 0xf4 */
+#define RK817_SLPPIN_FUNC_MSK		(0x3 << 3)
+#define SLPPIN_NULL_FUN			(0x0 << 3)
+#define SLPPIN_SLP_FUN			(0x1 << 3)
+#define SLPPIN_DN_FUN			(0x2 << 3)
+#define SLPPIN_RST_FUN			(0x3 << 3)
+
+#define RK817_RST_FUNC_MSK		(0x3 << 6)
+#define RK817_RST_FUNC_SFT		(6)
+#define RK817_RST_FUNC_CNT		(3)
+#define RK817_RST_FUNC_DEV		(0) /* reset the dev */
+#define RK817_RST_FUNC_REG		(0x1 << 6) /* reset the reg only */
+
+#define RK817_SLPPOL_MSK		BIT(5)
+#define RK817_SLPPOL_H			BIT(5)
+#define RK817_SLPPOL_L			(0)
+
+/* gpio&int 0xfe */
+#define RK817_INT_POL_MSK		BIT(1)
+#define RK817_INT_POL_H			BIT(1)
+#define RK817_INT_POL_L			0
+#define RK809_BUCK5_CONFIG(i)		(RK817_BOOST_OTG_CFG + (i) * 1)
 
 enum {
 	BUCK_ILMIN_50MA,
@@ -443,6 +613,8 @@ enum {
 enum {
 	RK805_ID = 0x8050,
 	RK808_ID = 0x0000,
+	RK809_ID = 0x8090,
+	RK817_ID = 0x8170,
 	RK818_ID = 0x8181,
 };
 
-- 
1.9.1

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

* [PATCH 1/5] mfd: rk808: Add RK817 and RK809 support
@ 2018-07-23  3:19   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: linux-arm-kernel

    The rk809 and rk817 are a Power Management IC (PMIC) for multimedia
    and handheld devices. It contains the following components:

        - Regulators
        - RTC
        - Clocking

    Both RK809 and RK817 chips are using a similar register map,
    so we can reuse the RTC and Clocking and regulators functionality.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/mfd/Kconfig       |   6 +-
 drivers/mfd/rk808.c       | 216 +++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/mfd/rk808.h | 172 ++++++++++++++++++++++++++++++++++++
 3 files changed, 389 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b860eb5..84f2f22 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -967,14 +967,14 @@ config MFD_RC5T583
 	  different functionality of the device.
 
 config MFD_RK808
-	tristate "Rockchip RK805/RK808/RK818 Power Management Chip"
+	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip"
 	depends on I2C && OF
 	select MFD_CORE
 	select REGMAP_I2C
 	select REGMAP_IRQ
 	help
-	  If you say yes here you get support for the RK805, RK808 and RK818
-	  Power Management chips.
+	  If you say yes here you get support for the RK805, RK809 and RK817,
+	  RK808 and RK818 Power Management chips.
 	  This driver provides common support for accessing the device
 	  through I2C interface. The device supports multiple sub-devices
 	  including interrupts, RTC, LDO & DCDC regulators, and onkey.
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 216fbf6..bfb5668 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -62,6 +62,29 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	return false;
 }
 
+static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+	/*
+	 * Notes:
+	 * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
+	 *   we don't use that feature.  It's better to cache.
+	 * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
+	 *   bits are cleared in case when we shutoff anyway, but better safe.
+	 */
+
+	switch (reg) {
+	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
+	case RK817_RTC_STATUS_REG:
+	case RK817_INT_STS_REG0:
+	case RK817_INT_STS_REG1:
+	case RK817_INT_STS_REG2:
+	case RK817_SYS_STS:
+		return true;
+	}
+
+	return true;
+}
+
 static const struct regmap_config rk818_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
@@ -86,6 +109,14 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	.volatile_reg = rk808_is_volatile_reg,
 };
 
+static const struct regmap_config rk817_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = RK817_GPIO_INT_CFG,
+	.cache_type = REGCACHE_NONE,
+	.volatile_reg = rk817_is_volatile_reg,
+};
+
 static struct resource rtc_resources[] = {
 	{
 		.start  = RK808_IRQ_RTC_ALARM,
@@ -94,6 +125,13 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	}
 };
 
+static struct resource rk817_rtc_resources[] = {
+	{
+		.start  = RK817_IRQ_RTC_ALARM,
+		.end    = RK817_IRQ_RTC_ALARM,
+		.flags  = IORESOURCE_IRQ,
+	}
+};
 static struct resource rk805_key_resources[] = {
 	{
 		.start  = RK805_IRQ_PWRON_FALL,
@@ -107,6 +145,19 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	}
 };
 
+static struct resource rk817_pwrkey_resources[] = {
+	{
+		.start  = RK817_IRQ_PWRON_RISE,
+		.end    = RK817_IRQ_PWRON_RISE,
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		.start  = RK817_IRQ_PWRON_FALL,
+		.end    = RK817_IRQ_PWRON_FALL,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
 static const struct mfd_cell rk805s[] = {
 	{ .name = "rk808-clkout", },
 	{ .name = "rk808-regulator", },
@@ -132,6 +183,21 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	},
 };
 
+static const struct mfd_cell rk817s[] = {
+	{ .name = "rk808-clkout",},
+	{ .name = "rk808-regulator",},
+	{
+		.name = "rk8xx-pwrkey",
+		.num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
+		.resources = &rk817_pwrkey_resources[0],
+	},
+	{
+		.name = "rk808-rtc",
+		.num_resources = ARRAY_SIZE(rk817_rtc_resources),
+		.resources = &rk817_rtc_resources[0],
+	},
+};
+
 static const struct mfd_cell rk818s[] = {
 	{ .name = "rk808-clkout", },
 	{ .name = "rk808-regulator", },
@@ -167,6 +233,13 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 						    VB_LO_SEL_3500MV },
 };
 
+static const struct rk808_reg_data rk817_pre_init_reg[] = {
+	{RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
+	{RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_H},
+	{RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK,
+					   RK817_HOTDIE_105 | RK817_TSD_140},
+};
+
 static const struct rk808_reg_data rk818_pre_init_reg[] = {
 	/* improve efficiency */
 	{ RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK,  BUCK_ILMIN_250MA },
@@ -332,6 +405,39 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	},
 };
 
+#define REGMAP_IRQ_M(_id) \
+	[_id] = {				\
+		.mask = BIT(((_id) % 8)),	\
+		.reg_offset = ((_id) / 8),	\
+	}
+
+static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
+	REGMAP_IRQ_M(0),
+	REGMAP_IRQ_M(1),
+	REGMAP_IRQ_M(2),
+	REGMAP_IRQ_M(3),
+	REGMAP_IRQ_M(4),
+	REGMAP_IRQ_M(5),
+	REGMAP_IRQ_M(6),
+	REGMAP_IRQ_M(7),
+	REGMAP_IRQ_M(8),
+	REGMAP_IRQ_M(9),
+	REGMAP_IRQ_M(10),
+	REGMAP_IRQ_M(11),
+	REGMAP_IRQ_M(12),
+	REGMAP_IRQ_M(13),
+	REGMAP_IRQ_M(14),
+	REGMAP_IRQ_M(15),
+	REGMAP_IRQ_M(16),
+	REGMAP_IRQ_M(17),
+	REGMAP_IRQ_M(18),
+	REGMAP_IRQ_M(19),
+	REGMAP_IRQ_M(20),
+	REGMAP_IRQ_M(21),
+	REGMAP_IRQ_M(22),
+	REGMAP_IRQ_M(23)
+};
+
 static struct regmap_irq_chip rk805_irq_chip = {
 	.name = "rk805",
 	.irqs = rk805_irqs,
@@ -355,6 +461,18 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 	.init_ack_masked = true,
 };
 
+static struct regmap_irq_chip rk817_irq_chip = {
+	.name = "rk817",
+	.irqs = rk817_irqs,
+	.num_irqs = ARRAY_SIZE(rk817_irqs),
+	.num_regs = 3,
+	.irq_reg_stride = 2,
+	.status_base = RK817_INT_STS_REG0,
+	.mask_base = RK817_INT_STS_MSK_REG0,
+	.ack_base = RK817_INT_STS_REG0,
+	.init_ack_masked = true,
+};
+
 static const struct regmap_irq_chip rk818_irq_chip = {
 	.name = "rk818",
 	.irqs = rk818_irqs,
@@ -423,9 +541,39 @@ static void rk818_device_shutdown(void)
 		dev_err(&rk808_i2c_client->dev, "power off error!\n");
 }
 
+static void rk8xx_device_shutdown_prepare(void)
+{
+	int ret;
+	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+	if (!rk808) {
+		dev_warn(&rk808_i2c_client->dev,
+			 "have no rk808, so do nothing here\n");
+		return;
+	}
+
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		ret = regmap_update_bits(rk808->regmap,
+					 RK817_SYS_CFG(3),
+					 RK817_SLPPIN_FUNC_MSK,
+					 SLPPIN_DN_FUN);
+		if (ret) {
+			dev_warn(&rk808_i2c_client->dev,
+				 "switch pin func to power down error!\n");
+		}
+		break;
+	default:
+		break;
+	}
+}
+
 static const struct of_device_id rk808_of_match[] = {
 	{ .compatible = "rockchip,rk805" },
 	{ .compatible = "rockchip,rk808" },
+	{ .compatible = "rockchip,rk809" },
+	{ .compatible = "rockchip,rk817" },
 	{ .compatible = "rockchip,rk818" },
 	{ },
 };
@@ -442,6 +590,7 @@ static int rk808_probe(struct i2c_client *client,
 	int nr_pre_init_regs;
 	int nr_cells;
 	int pm_off = 0, msb, lsb;
+	unsigned char pmic_id_msb = RK808_ID_MSB, pmic_id_lsb = RK808_ID_LSB;
 	int ret;
 	int i;
 
@@ -449,15 +598,20 @@ static int rk808_probe(struct i2c_client *client,
 	if (!rk808)
 		return -ENOMEM;
 
+	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;
+	}
 	/* Read chip variant */
-	msb = i2c_smbus_read_byte_data(client, RK808_ID_MSB);
+	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
 	if (msb < 0) {
 		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
 			RK808_ID_MSB);
 		return msb;
 	}
 
-	lsb = i2c_smbus_read_byte_data(client, RK808_ID_LSB);
+	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
 	if (lsb < 0) {
 		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
 			RK808_ID_LSB);
@@ -495,6 +649,16 @@ static int rk808_probe(struct i2c_client *client,
 		nr_cells = ARRAY_SIZE(rk818s);
 		pm_pwroff_fn = rk818_device_shutdown;
 		break;
+	case RK809_ID:
+	case RK817_ID:
+		rk808->regmap_cfg = &rk817_regmap_config;
+		rk808->regmap_irq_chip = &rk817_irq_chip;
+		pre_init_reg = rk817_pre_init_reg;
+		nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
+		cells = rk817s;
+		nr_cells = ARRAY_SIZE(rk817s);
+		pm_power_off_prepare = rk8xx_device_shutdown_prepare;
+		break;
 	default:
 		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
 			rk808->variant);
@@ -568,9 +732,56 @@ static int rk808_remove(struct i2c_client *client)
 	return 0;
 }
 
+static int rk8xx_suspend(struct device *dev)
+{
+	int ret = 0;
+	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		ret = regmap_update_bits(rk808->regmap,
+					 RK817_SYS_CFG(3),
+					 RK817_SLPPIN_FUNC_MSK,
+					 SLPPIN_SLP_FUN);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int rk8xx_resume(struct device *dev)
+{
+	int ret = 0;
+	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		ret = regmap_update_bits(rk808->regmap,
+					 RK817_SYS_CFG(3),
+					 RK817_SLPPIN_FUNC_MSK,
+					 SLPPIN_NULL_FUN);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static const struct dev_pm_ops rk8xx_pm_ops = {
+	.suspend = rk8xx_suspend,
+	.resume =  rk8xx_resume,
+};
+
 static const struct i2c_device_id rk808_ids[] = {
 	{ "rk805" },
 	{ "rk808" },
+	{ "rk809" },
+	{ "rk817" },
 	{ "rk818" },
 	{ },
 };
@@ -580,6 +791,7 @@ static int rk808_remove(struct i2c_client *client)
 	.driver = {
 		.name = "rk808",
 		.of_match_table = rk808_of_match,
+		.pm = &rk8xx_pm_ops,
 	},
 	.probe    = rk808_probe,
 	.remove   = rk808_remove,
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index d315659..b973b0a 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -382,6 +382,7 @@ enum rk805_reg {
 #define SWITCH1_EN	BIT(5)
 #define DEV_OFF_RST	BIT(3)
 #define DEV_OFF		BIT(0)
+#define RTC_STOP	BIT(0)
 
 #define VB_LO_ACT		BIT(4)
 #define VB_LO_SEL_3500MV	(7 << 0)
@@ -396,6 +397,175 @@ enum rk805_reg {
 #define SLEEP_FUN			(0x1 << 2)
 #define RK8XX_ID_MSK			0xfff0
 #define FPWM_MODE			BIT(7)
+enum rk817_reg_id {
+	RK817_ID_DCDC1 = 0,
+	RK817_ID_DCDC2,
+	RK817_ID_DCDC3,
+	RK817_ID_DCDC4,
+	RK817_ID_LDO1,
+	RK817_ID_LDO2,
+	RK817_ID_LDO3,
+	RK817_ID_LDO4,
+	RK817_ID_LDO5,
+	RK817_ID_LDO6,
+	RK817_ID_LDO7,
+	RK817_ID_LDO8,
+	RK817_ID_LDO9,
+	RK817_ID_BOOST,
+	RK817_ID_BOOST_OTG_SW,
+	RK817_NUM_REGULATORS
+};
+
+enum rk809_reg_id {
+	RK809_ID_DCDC5 = RK817_ID_BOOST,
+	RK809_ID_SW1,
+	RK809_ID_SW2,
+	RK809_NUM_REGULATORS
+};
+
+#define RK817_SECONDS_REG		0x00
+#define RK817_MINUTES_REG		0x01
+#define RK817_HOURS_REG			0x02
+#define RK817_DAYS_REG			0x03
+#define RK817_MONTHS_REG		0x04
+#define RK817_YEARS_REG			0x05
+#define RK817_WEEKS_REG			0x06
+#define RK817_ALARM_SECONDS_REG		0x07
+#define RK817_ALARM_MINUTES_REG		0x08
+#define RK817_ALARM_HOURS_REG		0x09
+#define RK817_ALARM_DAYS_REG		0x0a
+#define RK817_ALARM_MONTHS_REG		0x0b
+#define RK817_ALARM_YEARS_REG		0x0c
+#define RK817_RTC_CTRL_REG		0xd
+#define RK817_RTC_STATUS_REG		0xe
+#define RK817_RTC_INT_REG		0xf
+#define RK817_RTC_COMP_LSB_REG		0x10
+#define RK817_RTC_COMP_MSB_REG		0x11
+
+#define RK817_POWER_EN_REG(i)		(0xb1 + (i))
+#define RK817_POWER_SLP_EN_REG(i)	(0xb5 + (i))
+
+#define RK817_POWER_CONFIG		(0xb9)
+
+#define RK817_BUCK_CONFIG_REG(i)	(0xba + (i) * 3)
+
+#define RK817_BUCK1_ON_VSEL_REG		0xBB
+#define RK817_BUCK1_SLP_VSEL_REG	0xBC
+
+#define RK817_BUCK2_CONFIG_REG		0xBD
+#define RK817_BUCK2_ON_VSEL_REG		0xBE
+#define RK817_BUCK2_SLP_VSEL_REG	0xBF
+
+#define RK817_BUCK3_CONFIG_REG		0xC0
+#define RK817_BUCK3_ON_VSEL_REG		0xC1
+#define RK817_BUCK3_SLP_VSEL_REG	0xC2
+
+#define RK817_BUCK4_CONFIG_REG		0xC3
+#define RK817_BUCK4_ON_VSEL_REG		0xC4
+#define RK817_BUCK4_SLP_VSEL_REG	0xC5
+
+#define RK817_LDO_ON_VSEL_REG(idx)	(0xcc + (idx) * 2)
+#define RK817_BOOST_OTG_CFG		(0xde)
+
+#define RK817_ID_MSB			0xed
+#define RK817_ID_LSB			0xee
+
+#define RK817_SYS_STS			0xf0
+#define RK817_SYS_CFG(i)		(0xf1 + (i))
+
+#define RK817_ON_SOURCE_REG		0xf5
+#define RK817_OFF_SOURCE_REG		0xf6
+
+/* INTERRUPT REGISTER */
+#define RK817_INT_STS_REG0		0xf8
+#define RK817_INT_STS_MSK_REG0		0xf9
+#define RK817_INT_STS_REG1		0xfa
+#define RK817_INT_STS_MSK_REG1		0xfb
+#define RK817_INT_STS_REG2		0xfc
+#define RK817_INT_STS_MSK_REG2		0xfd
+#define RK817_GPIO_INT_CFG		0xfe
+
+/* IRQ Definitions */
+#define RK817_IRQ_PWRON_FALL		0
+#define RK817_IRQ_PWRON_RISE		1
+#define RK817_IRQ_PWRON			2
+#define RK817_IRQ_PWMON_LP		3
+#define RK817_IRQ_HOTDIE		4
+#define RK817_IRQ_RTC_ALARM		5
+#define RK817_IRQ_RTC_PERIOD		6
+#define RK817_IRQ_VB_LO			7
+#define RK817_IRQ_PLUG_IN		(8 + 0)
+#define RK817_IRQ_PLUG_OUT		(8 + 1)
+#define RK817_IRQ_CHRG_TERM		(8 + 2)
+#define RK817_IRQ_CHRG_TIME		(8 + 3)
+#define RK817_IRQ_CHRG_TS		(8 + 4)
+#define RK817_IRQ_USB_OV		(8 + 5)
+#define RK817_IRQ_CHRG_IN_CLMP		(8 + 6)
+#define RK817_IRQ_BAT_DIS_ILIM		(8 + 7)
+#define RK817_IRQ_GATE_GPIO		(16 + 0)
+#define RK817_IRQ_TS_GPIO		(16 + 1)
+#define RK817_IRQ_CODEC_PD		(16 + 2)
+#define RK817_IRQ_CODEC_PO		(16 + 3)
+#define RK817_IRQ_CLASSD_MUTE_DONE	(16 + 4)
+#define RK817_IRQ_CLASSD_OCP		(16 + 5)
+#define RK817_IRQ_BAT_OVP		(16 + 6)
+#define RK817_IRQ_CHRG_BAT_HI		(16 + 7)
+#define RK817_IRQ_END			(RK817_IRQ_CHRG_BAT_HI + 1)
+
+/*
+ * rtc_ctrl 0xd
+ * same as 808, except bit4
+ */
+#define RK817_RTC_CTRL_RSV4		BIT(4)
+
+/* power config 0xb9 */
+#define RK817_BUCK3_FB_RES_MSK		BIT(6)
+#define RK817_BUCK3_FB_RES_INTER	BIT(6)
+#define RK817_BUCK3_FB_RES_EXT		0
+
+/* buck config 0xba */
+#define RK817_RAMP_RATE_OFFSET		6
+#define RK817_RAMP_RATE_MASK		(0x3 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_3MV_PER_US	(0x0 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_6_3MV_PER_US	(0x1 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_12_5MV_PER_US	(0x2 << RK817_RAMP_RATE_OFFSET)
+#define RK817_RAMP_RATE_25MV_PER_US	(0x3 << RK817_RAMP_RATE_OFFSET)
+
+/* sys_cfg1 0xf2 */
+#define RK817_HOTDIE_TEMP_MSK		(0x3 << 4)
+#define RK817_HOTDIE_85			(0x0 << 4)
+#define RK817_HOTDIE_95			(0x1 << 4)
+#define RK817_HOTDIE_105		(0x2 << 4)
+#define RK817_HOTDIE_115		(0x3 << 4)
+
+#define RK817_TSD_TEMP_MSK		BIT(6)
+#define RK817_TSD_140			0
+#define RK817_TSD_160			BIT(6)
+
+#define RK817_CLK32KOUT2_EN		BIT(7)
+
+/* sys_cfg3 0xf4 */
+#define RK817_SLPPIN_FUNC_MSK		(0x3 << 3)
+#define SLPPIN_NULL_FUN			(0x0 << 3)
+#define SLPPIN_SLP_FUN			(0x1 << 3)
+#define SLPPIN_DN_FUN			(0x2 << 3)
+#define SLPPIN_RST_FUN			(0x3 << 3)
+
+#define RK817_RST_FUNC_MSK		(0x3 << 6)
+#define RK817_RST_FUNC_SFT		(6)
+#define RK817_RST_FUNC_CNT		(3)
+#define RK817_RST_FUNC_DEV		(0) /* reset the dev */
+#define RK817_RST_FUNC_REG		(0x1 << 6) /* reset the reg only */
+
+#define RK817_SLPPOL_MSK		BIT(5)
+#define RK817_SLPPOL_H			BIT(5)
+#define RK817_SLPPOL_L			(0)
+
+/* gpio&int 0xfe */
+#define RK817_INT_POL_MSK		BIT(1)
+#define RK817_INT_POL_H			BIT(1)
+#define RK817_INT_POL_L			0
+#define RK809_BUCK5_CONFIG(i)		(RK817_BOOST_OTG_CFG + (i) * 1)
 
 enum {
 	BUCK_ILMIN_50MA,
@@ -443,6 +613,8 @@ enum {
 enum {
 	RK805_ID = 0x8050,
 	RK808_ID = 0x0000,
+	RK809_ID = 0x8090,
+	RK817_ID = 0x8170,
 	RK818_ID = 0x8181,
 };
 
-- 
1.9.1

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

* [PATCH 2/5] regulator: rk808: Add regulator driver for RK809 and RK817.
  2018-07-23  3:19 ` Tony Xie
  (?)
  (?)
@ 2018-07-23  3:19   ` Tony Xie
  -1 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: linux-rtc, a.zummo, alexandre.belloni, tony.xie, huangtao,
	devicetree, sboyd, zhangqing, linux-kernel, xsf, linux-rockchip,
	broonie, lee.jones, linux-clk, linux-arm-kernel, chenjh

ICAgIEFkZCBzdXBwb3J0IGZvciB0aGUgcms4MDkgYW5kIHJrODE3IHJlZ3VsYXRvciBkcml2ZXIu
CiAgICBUaGVpciBzcGVjaWZpY2F0aW9ucyBhcmUgYXMgZm9sbG93c++8mgogICAgMeOAgVRoZSBS
SzgwOSBhbmQgUks4MDkgY29uc2lzdCBvZiA1IERDRENzLCA5IExET3MKICAgICAgIGFuZCBoYXZl
IHRoZSBzYW1lIHJlZ2lzdGVycyBmb3IgdGhlc2UgY29tcG9uZW50cyBleGNlcHQgZGNkYzUuCiAg
ICAy44CBVGhlIGRjZGM1IGlzIGEgYm9vc3QgZGNkYyBmb3IgUks4MTcgYW5kIGlzIGEgYnVjayBm
b3IgUks4MDkuCiAgICAz44CBVGhlIFJLODE3IGhhcyBvbmUgc3dpdGNoIGJ1dCBUaGUgUms4MDkg
aGFzIHR3by4KCiAgICBUaGUgb3V0cHV0IHZvbHRhZ2VzIGFyZSBjb25maWd1cmFibGUgYW5kIGFy
ZSBtZWFudCB0byBzdXBwbHkgcG93ZXIKICAgIHRvIHRoZSBtYWluIHByb2Nlc3NvciBhbmQgb3Ro
ZXIgY29tcG9uZW50cy4KClNpZ25lZC1vZmYtYnk6IFRvbnkgWGllIDx0b255LnhpZUByb2NrLWNo
aXBzLmNvbT4KLS0tCiBkcml2ZXJzL3JlZ3VsYXRvci9LY29uZmlnICAgICAgICAgICB8ICAgNCAr
LQogZHJpdmVycy9yZWd1bGF0b3Ivcms4MDgtcmVndWxhdG9yLmMgfCA2MzMgKysrKysrKysrKysr
KysrKysrKysrKysrKysrKysrKysrKystCiBpbmNsdWRlL2xpbnV4L21mZC9yazgwOC5oICAgICAg
ICAgICB8ICAgMyArCiAzIGZpbGVzIGNoYW5nZWQsIDYzNyBpbnNlcnRpb25zKCspLCAzIGRlbGV0
aW9ucygtKQoKZGlmZiAtLWdpdCBhL2RyaXZlcnMvcmVndWxhdG9yL0tjb25maWcgYi9kcml2ZXJz
L3JlZ3VsYXRvci9LY29uZmlnCmluZGV4IDVkYmNjZjUuLjI3ZmY4OWYgMTAwNjQ0Ci0tLSBhL2Ry
aXZlcnMvcmVndWxhdG9yL0tjb25maWcKKysrIGIvZHJpdmVycy9yZWd1bGF0b3IvS2NvbmZpZwpA
QCAtNzE2LDExICs3MTYsMTEgQEAgY29uZmlnIFJFR1VMQVRPUl9SQzVUNTgzCiAJICBvdXRwdXRz
IHdoaWNoIGNhbiBiZSBjb250cm9sbGVkIGJ5IGkyYyBjb21tdW5pY2F0aW9uLgogCiBjb25maWcg
UkVHVUxBVE9SX1JLODA4Ci0JdHJpc3RhdGUgIlJvY2tjaGlwIFJLODA1L1JLODA4L1JLODE4IFBv
d2VyIHJlZ3VsYXRvcnMiCisJdHJpc3RhdGUgIlJvY2tjaGlwIFJLODA1L1JLODA4L1JLODA5L1JL
ODE3L1JLODE4IFBvd2VyIHJlZ3VsYXRvcnMiCiAJZGVwZW5kcyBvbiBNRkRfUks4MDgKIAloZWxw
CiAJICBTZWxlY3QgdGhpcyBvcHRpb24gdG8gZW5hYmxlIHRoZSBwb3dlciByZWd1bGF0b3Igb2Yg
Uk9DS0NISVAKLQkgIFBNSUMgUks4MDUsUks4MDggYW5kIFJLODE4LgorCSAgUE1JQyBSSzgwNSxS
SzgwOSZSSzgxNyxSSzgwOCBhbmQgUks4MTguCiAJICBUaGlzIGRyaXZlciBzdXBwb3J0cyB0aGUg
Y29udHJvbCBvZiBkaWZmZXJlbnQgcG93ZXIgcmFpbHMgb2YgZGV2aWNlCiAJICB0aHJvdWdoIHJl
Z3VsYXRvciBpbnRlcmZhY2UuIFRoZSBkZXZpY2Ugc3VwcG9ydHMgbXVsdGlwbGUgRENEQy9MRE8K
IAkgIG91dHB1dHMgd2hpY2ggY2FuIGJlIGNvbnRyb2xsZWQgYnkgaTJjIGNvbW11bmljYXRpb24u
CmRpZmYgLS1naXQgYS9kcml2ZXJzL3JlZ3VsYXRvci9yazgwOC1yZWd1bGF0b3IuYyBiL2RyaXZl
cnMvcmVndWxhdG9yL3JrODA4LXJlZ3VsYXRvci5jCmluZGV4IDIxM2I2ODcuLjllZGNlMjIgMTAw
NjQ0Ci0tLSBhL2RyaXZlcnMvcmVndWxhdG9yL3JrODA4LXJlZ3VsYXRvci5jCisrKyBiL2RyaXZl
cnMvcmVndWxhdG9yL3JrODA4LXJlZ3VsYXRvci5jCkBAIC0zNiw2ICszNiwxMiBAQAogI2RlZmlu
ZSBSSzgwOF9CVUNLNF9WU0VMX01BU0sJMHhmCiAjZGVmaW5lIFJLODA4X0xET19WU0VMX01BU0sJ
MHgxZgogCisjZGVmaW5lIFJLODA5X0JVQ0s1X1ZTRUxfTUFTSwkJMHg3CisKKyNkZWZpbmUgUks4
MTdfTERPX1ZTRUxfTUFTSwkJMHg3ZgorI2RlZmluZSBSSzgxN19CT09TVF9WU0VMX01BU0sJCTB4
NworI2RlZmluZSBSSzgxN19CVUNLX1ZTRUxfTUFTSwkJMHg3ZgorCiAjZGVmaW5lIFJLODE4X0JV
Q0tfVlNFTF9NQVNLCQkweDNmCiAjZGVmaW5lIFJLODE4X0JVQ0s0X1ZTRUxfTUFTSwkJMHgxZgog
I2RlZmluZSBSSzgxOF9MRE9fVlNFTF9NQVNLCQkweDFmCkBAIC02NSw2ICs3MSw5IEBACiAvKiBt
YXggc3RlcHMgZm9yIGluY3JlYXNlIHZvbHRhZ2Ugb2YgQnVjazEvMiwgZXF1YWwgMTAwbXYqLwog
I2RlZmluZSBNQVhfU1RFUFNfT05FX1RJTUUgOAogCisjZGVmaW5lIEVOQUJMRV9NQVNLKGlkKQkJ
CShCSVQoaWQpIHwgQklUKDQgKyAoaWQpKSkKKyNkZWZpbmUgRElTQUJMRV9WQUwoaWQpCQkJKEJJ
VCg0ICsgKGlkKSkpCisKICNkZWZpbmUgUks4MDVfREVTQyhfaWQsIF9tYXRjaCwgX3N1cHBseSwg
X21pbiwgX21heCwgX3N0ZXAsIF92cmVnLCAgICAgIFwKIAlfdm1hc2ssIF9lcmVnLCBfZW1hc2ss
IF9ldGltZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogCVtfaWRdID0geyAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCkBA
IC04Niw2ICs5NSw3MCBAQAogCQkub3BzICAgICAgICAgICAgPSAmcms4MDVfcmVnX29wcywgICAg
ICAgICAgICAgICAgICAgICAgIFwKIAl9CiAKKyNkZWZpbmUgUks4MTdfREVTQyhfaWQsIF9tYXRj
aCwgX3N1cHBseSwgX21pbiwgX21heCwgX3N0ZXAsIF92cmVnLAlcCisJX3ZtYXNrLCBfZXJlZywg
X2VtYXNrLCBfZW52YWwsIF9kaXN2YWwsIF9ldGltZSkJCVwKKwl7CQkJCQkJCVwKKwkJLm5hbWUJ
CT0gKF9tYXRjaCksCQkJCVwKKwkJLnN1cHBseV9uYW1lCT0gKF9zdXBwbHkpLAkJCQlcCisJCS5v
Zl9tYXRjaAk9IG9mX21hdGNoX3B0cihfbWF0Y2gpLAkJCVwKKwkJLnJlZ3VsYXRvcnNfbm9kZSA9
IG9mX21hdGNoX3B0cigicmVndWxhdG9ycyIpLAkJXAorCQkudHlwZQkJPSBSRUdVTEFUT1JfVk9M
VEFHRSwJCQlcCisJCS5pZAkJPSAoX2lkKSwJCQkJXAorCQkubl92b2x0YWdlcwk9ICgoKF9tYXgp
IC0gKF9taW4pKSAvIChfc3RlcCkgKyAxKSwJXAorCQkub3duZXIJCT0gVEhJU19NT0RVTEUsCQkJ
CVwKKwkJLm1pbl91VgkJPSAoX21pbikgKiAxMDAwLAkJCVwKKwkJLnVWX3N0ZXAJPSAoX3N0ZXAp
ICogMTAwMCwJCQlcCisJCS52c2VsX3JlZwk9IChfdnJlZyksCQkJCVwKKwkJLnZzZWxfbWFzawk9
IChfdm1hc2spLAkJCQlcCisJCS5lbmFibGVfcmVnCT0gKF9lcmVnKSwJCQkJXAorCQkuZW5hYmxl
X21hc2sJPSAoX2VtYXNrKSwJCQkJXAorCQkuZW5hYmxlX3ZhbCAgICAgPSAoX2VudmFsKSwJCQkJ
XAorCQkuZGlzYWJsZV92YWwgICAgID0gKF9kaXN2YWwpLAkJCQlcCisJCS5lbmFibGVfdGltZQk9
IChfZXRpbWUpLAkJCQlcCisJCS5vcHMJCT0gJnJrODE3X3JlZ19vcHMsCQkJXAorCX0KKworI2Rl
ZmluZSBSSzgxN19CT09TVF9ERVNDKF9pZCwgX21hdGNoLCBfc3VwcGx5LCBfbWluLCBfbWF4LCBf
c3RlcCwgX3ZyZWcsXAorCV92bWFzaywgX2VyZWcsIF9lbWFzaywgX2VudmFsLCBfZGlzdmFsLCBf
ZXRpbWUsIG1fZHJvcCkJCVwKKwl7CQkJCQkJCVwKKwkJLm5hbWUJCT0gKF9tYXRjaCksCQkJCVwK
KwkJLnN1cHBseV9uYW1lCT0gKF9zdXBwbHkpLAkJCQlcCisJCS5vZl9tYXRjaAk9IG9mX21hdGNo
X3B0cihfbWF0Y2gpLAkJCVwKKwkJLnJlZ3VsYXRvcnNfbm9kZSA9IG9mX21hdGNoX3B0cigicmVn
dWxhdG9ycyIpLAkJXAorCQkudHlwZQkJPSBSRUdVTEFUT1JfVk9MVEFHRSwJCQlcCisJCS5pZAkJ
PSAoX2lkKSwJCQkJXAorCQkubl92b2x0YWdlcwk9ICgoKF9tYXgpIC0gKF9taW4pKSAvIChfc3Rl
cCkgKyAxKSwJXAorCQkub3duZXIJCT0gVEhJU19NT0RVTEUsCQkJCVwKKwkJLm1pbl91VgkJPSAo
X21pbikgKiAxMDAwLAkJCVwKKwkJLnVWX3N0ZXAJPSAoX3N0ZXApICogMTAwMCwJCQlcCisJCS52
c2VsX3JlZwk9IChfdnJlZyksCQkJCVwKKwkJLnZzZWxfbWFzawk9IChfdm1hc2spLAkJCQlcCisJ
CS5lbmFibGVfcmVnCT0gKF9lcmVnKSwJCQkJXAorCQkuZW5hYmxlX21hc2sJPSAoX2VtYXNrKSwJ
CQkJXAorCQkuZW5hYmxlX3ZhbCAgICAgPSAoX2VudmFsKSwJCQkJXAorCQkuZGlzYWJsZV92YWwg
ICAgID0gKF9kaXN2YWwpLAkJCQlcCisJCS5lbmFibGVfdGltZQk9IChfZXRpbWUpLAkJCQlcCisJ
CS5taW5fZHJvcG91dF91ViA9IChtX2Ryb3ApICogMTAwMCwJCQlcCisJCS5vcHMJCT0gJnJrODE3
X2Jvb3N0X29wcywJCQlcCisJfQorCisjZGVmaW5lIFJLODE3X0RFU0NfU1dJVENIKF9pZCwgX21h
dGNoLCBfc3VwcGx5LCBfZXJlZywgX2VtYXNrLFwKKwlfZW52YWwsIF9kaXN2YWwpCQlcCisJewkJ
CQkJCQlcCisJCS5uYW1lCQk9IChfbWF0Y2gpLAkJCQlcCisJCS5zdXBwbHlfbmFtZQk9IChfc3Vw
cGx5KSwJCQkJXAorCQkub2ZfbWF0Y2gJPSBvZl9tYXRjaF9wdHIoX21hdGNoKSwJCQlcCisJCS5y
ZWd1bGF0b3JzX25vZGUgPSBvZl9tYXRjaF9wdHIoInJlZ3VsYXRvcnMiKSwJCVwKKwkJLnR5cGUJ
CT0gUkVHVUxBVE9SX1ZPTFRBR0UsCQkJXAorCQkuaWQJCT0gKF9pZCksCQkJCVwKKwkJLmVuYWJs
ZV9yZWcJPSAoX2VyZWcpLAkJCQlcCisJCS5lbmFibGVfbWFzawk9IChfZW1hc2spLAkJCQlcCisJ
CS5lbmFibGVfdmFsICAgICA9IChfZW52YWwpLAkJCQlcCisJCS5kaXNhYmxlX3ZhbCAgICAgPSAo
X2Rpc3ZhbCksCQkJCVwKKwkJLm93bmVyCQk9IFRISVNfTU9EVUxFLAkJCQlcCisJCS5vcHMJCT0g
JnJrODE3X3N3aXRjaF9vcHMJCQlcCisJfQorCiAjZGVmaW5lIFJLOFhYX0RFU0MoX2lkLCBfbWF0
Y2gsIF9zdXBwbHksIF9taW4sIF9tYXgsIF9zdGVwLCBfdnJlZywJXAogCV92bWFzaywgX2VyZWcs
IF9lbWFzaywgX2V0aW1lKQkJCQkJXAogCVtfaWRdID0gewkJCQkJCQlcCkBAIC0xMjEsNyArMTk0
LDYgQEAKIAkJLm9wcwkJPSAmcms4MDhfc3dpdGNoX29wcwkJCVwKIAl9CiAKLQogc3RydWN0IHJr
ODA4X3JlZ3VsYXRvcl9kYXRhIHsKIAlzdHJ1Y3QgZ3Bpb19kZXNjICpkdnNfZ3Bpb1syXTsKIH07
CkBAIC0xMzgsNiArMjEwLDUxIEBAIHN0cnVjdCByazgwOF9yZWd1bGF0b3JfZGF0YSB7CiAJUkVH
VUxBVE9SX0xJTkVBUl9SQU5HRSgyNTAwMDAwLCAxNSwgMTUsIDApLAogfTsKIAorI2RlZmluZSBS
SzgwOV9CVUNLNV9TRUxfQ05UCQkoOCkKKworc3RhdGljIGNvbnN0IHN0cnVjdCByZWd1bGF0b3Jf
bGluZWFyX3JhbmdlIHJrODA5X2J1Y2s1X3ZvbHRhZ2VfcmFuZ2VzW10gPSB7CisJUkVHVUxBVE9S
X0xJTkVBUl9SQU5HRSgxNTAwMDAwLCAwLCAwLCAwKSwKKwlSRUdVTEFUT1JfTElORUFSX1JBTkdF
KDE4MDAwMDAsIDEsIDMsIDIwMDAwMCksCisJUkVHVUxBVE9SX0xJTkVBUl9SQU5HRSgyODAwMDAw
LCA0LCA1LCAyMDAwMDApLAorCVJFR1VMQVRPUl9MSU5FQVJfUkFOR0UoMzMwMDAwMCwgNiwgNywg
MzAwMDAwKSwKK307CisKKyNkZWZpbmUgUks4MTdfQlVDSzFfTUlOMCA1MDAwMDAKKyNkZWZpbmUg
Uks4MTdfQlVDSzFfTUFYMCAxNTAwMDAwCisKKyNkZWZpbmUgUks4MTdfQlVDSzFfTUlOMSAxNjAw
MDAwCisjZGVmaW5lIFJLODE3X0JVQ0sxX01BWDEgMjQwMDAwMAorCisjZGVmaW5lIFJLODE3X0JV
Q0szX01BWDEgMzQwMDAwMAorCisjZGVmaW5lIFJLODE3X0JVQ0sxX1NUUDAgMTI1MDAKKyNkZWZp
bmUgUks4MTdfQlVDSzFfU1RQMSAxMDAwMDAKKworI2RlZmluZSBSSzgxN19CVUNLMV9TRUwwICgo
Uks4MTdfQlVDSzFfTUFYMCAtIFJLODE3X0JVQ0sxX01JTjApIC9cCisJCQkJCQkgIFJLODE3X0JV
Q0sxX1NUUDApCisjZGVmaW5lIFJLODE3X0JVQ0sxX1NFTDEgKChSSzgxN19CVUNLMV9NQVgxIC0g
Uks4MTdfQlVDSzFfTUlOMSkgL1wKKwkJCQkJCSAgUks4MTdfQlVDSzFfU1RQMSkKKworI2RlZmlu
ZSBSSzgxN19CVUNLM19TRUwxICgoUks4MTdfQlVDSzNfTUFYMSAtIFJLODE3X0JVQ0sxX01JTjEp
IC9cCisJCQkJCQkgIFJLODE3X0JVQ0sxX1NUUDEpCisKKyNkZWZpbmUgUks4MTdfQlVDSzFfU0VM
X0NOVCAoUks4MTdfQlVDSzFfU0VMMCArIFJLODE3X0JVQ0sxX1NFTDEgKyAxKQorI2RlZmluZSBS
SzgxN19CVUNLM19TRUxfQ05UIChSSzgxN19CVUNLMV9TRUwwICsgUks4MTdfQlVDSzNfU0VMMSAr
IDEpCisKK3N0YXRpYyBjb25zdCBzdHJ1Y3QgcmVndWxhdG9yX2xpbmVhcl9yYW5nZSByazgxN19i
dWNrMV92b2x0YWdlX3Jhbmdlc1tdID0geworCVJFR1VMQVRPUl9MSU5FQVJfUkFOR0UoUks4MTdf
QlVDSzFfTUlOMCwgMCwKKwkJCSAgICAgICBSSzgxN19CVUNLMV9TRUwwLCBSSzgxN19CVUNLMV9T
VFAwKSwKKwlSRUdVTEFUT1JfTElORUFSX1JBTkdFKFJLODE3X0JVQ0sxX01JTjEsIFJLODE3X0JV
Q0sxX1NFTDAgKyAxLAorCQkJICAgICAgIFJLODE3X0JVQ0sxX1NFTF9DTlQsIFJLODE3X0JVQ0sx
X1NUUDEpLAorfTsKKworc3RhdGljIGNvbnN0IHN0cnVjdCByZWd1bGF0b3JfbGluZWFyX3Jhbmdl
IHJrODE3X2J1Y2szX3ZvbHRhZ2VfcmFuZ2VzW10gPSB7CisJUkVHVUxBVE9SX0xJTkVBUl9SQU5H
RShSSzgxN19CVUNLMV9NSU4wLCAwLAorCQkJICAgICAgIFJLODE3X0JVQ0sxX1NFTDAsIFJLODE3
X0JVQ0sxX1NUUDApLAorCVJFR1VMQVRPUl9MSU5FQVJfUkFOR0UoUks4MTdfQlVDSzFfTUlOMSwg
Uks4MTdfQlVDSzFfU0VMMCArIDEsCisJCQkgICAgICAgUks4MTdfQlVDSzNfU0VMX0NOVCwgUks4
MTdfQlVDSzFfU1RQMSksCit9OworCiBzdGF0aWMgaW50IHJrODA4X2J1Y2sxXzJfZ2V0X3ZvbHRh
Z2Vfc2VsX3JlZ21hcChzdHJ1Y3QgcmVndWxhdG9yX2RldiAqcmRldikKIHsKIAlzdHJ1Y3Qgcms4
MDhfcmVndWxhdG9yX2RhdGEgKnBkYXRhID0gcmRldl9nZXRfZHJ2ZGF0YShyZGV2KTsKQEAgLTI4
OSw2ICs0MDYsMzUgQEAgc3RhdGljIGludCByazgwOF9zZXRfcmFtcF9kZWxheShzdHJ1Y3QgcmVn
dWxhdG9yX2RldiAqcmRldiwgaW50IHJhbXBfZGVsYXkpCiAJCQkJICBSSzgwOF9SQU1QX1JBVEVf
TUFTSywgcmFtcF92YWx1ZSk7CiB9CiAKKy8qCisgKiBSSzgxNyBSSzgwOQorICovCitzdGF0aWMg
aW50IHJrODE3X3NldF9yYW1wX2RlbGF5KHN0cnVjdCByZWd1bGF0b3JfZGV2ICpyZGV2LCBpbnQg
cmFtcF9kZWxheSkKK3sKKwl1bnNpZ25lZCBpbnQgcmFtcF92YWx1ZSA9IFJLODE3X1JBTVBfUkFU
RV8yNU1WX1BFUl9VUzsKKwl1bnNpZ25lZCBpbnQgcmVnID0gUks4MTdfQlVDS19DT05GSUdfUkVH
KHJkZXZfZ2V0X2lkKHJkZXYpKTsKKworCXN3aXRjaCAocmFtcF9kZWxheSkgeworCWNhc2UgMCAu
Li4gMzAwMDoKKwkJcmFtcF92YWx1ZSA9IFJLODE3X1JBTVBfUkFURV8zTVZfUEVSX1VTOworCQli
cmVhazsKKwljYXNlIDMwMDEgLi4uIDYzMDA6CisJCXJhbXBfdmFsdWUgPSBSSzgxN19SQU1QX1JB
VEVfNl8zTVZfUEVSX1VTOworCQlicmVhazsKKwljYXNlIDYzMDEgLi4uIDEyNTAwOgorCQlyYW1w
X3ZhbHVlID0gUks4MTdfUkFNUF9SQVRFXzEyXzVNVl9QRVJfVVM7CisJCWJyZWFrOworCWNhc2Ug
MTI1MDEgLi4uIDI1MDAwOgorCQlicmVhazsKKwlkZWZhdWx0OgorCQlwcl93YXJuKCIlcyByYW1w
X2RlbGF5OiAlZCBub3Qgc3VwcG9ydGVkLCBzZXR0aW5nIDEwMDAwXG4iLAorCQkJcmRldi0+ZGVz
Yy0+bmFtZSwgcmFtcF9kZWxheSk7CisJfQorCisJcmV0dXJuIHJlZ21hcF91cGRhdGVfYml0cyhy
ZGV2LT5yZWdtYXAsIHJlZywKKwkJCQkgIFJLODE3X1JBTVBfUkFURV9NQVNLLCByYW1wX3ZhbHVl
KTsKK30KKwogc3RhdGljIGludCByazgwOF9zZXRfc3VzcGVuZF92b2x0YWdlKHN0cnVjdCByZWd1
bGF0b3JfZGV2ICpyZGV2LCBpbnQgdXYpCiB7CiAJdW5zaWduZWQgaW50IHJlZzsKQEAgLTMwNCw2
ICs0NTAsMjkgQEAgc3RhdGljIGludCByazgwOF9zZXRfc3VzcGVuZF92b2x0YWdlKHN0cnVjdCBy
ZWd1bGF0b3JfZGV2ICpyZGV2LCBpbnQgdXYpCiAJCQkJICBzZWwpOwogfQogCitzdGF0aWMgaW50
IHJrODE3X2NoZWNrX3N1c3BlbmRfdm9sdGFnZShpbnQgaWQpCit7CisJaWYgKGlkID49IFJLODE3
X0lEX0RDREMxICYmIGlkIDw9IFJLODE3X0lEX0xETzkpCisJCXJldHVybiAwOworCXJldHVybiAt
MTsKK30KKworc3RhdGljIGludCByazgxN19zZXRfc3VzcGVuZF92b2x0YWdlKHN0cnVjdCByZWd1
bGF0b3JfZGV2ICpyZGV2LCBpbnQgdXYpCit7CisJdW5zaWduZWQgaW50IHJlZzsKKwlpbnQgaWQg
PSByZGV2X2dldF9pZChyZGV2KTsKKwlpbnQgc2VsID0gcmVndWxhdG9yX21hcF92b2x0YWdlX2xp
bmVhcihyZGV2LCB1diwgdXYpOworCS8qIG9ubHkgbGRvMX5sZG85ICovCisJaWYgKHNlbCA8IDAg
fHwgcms4MTdfY2hlY2tfc3VzcGVuZF92b2x0YWdlKGlkKSkKKwkJcmV0dXJuIC1FSU5WQUw7CisK
KwlyZWcgPSByZGV2LT5kZXNjLT52c2VsX3JlZyArIFJLODA4X1NMUF9SRUdfT0ZGU0VUOworCisJ
cmV0dXJuIHJlZ21hcF91cGRhdGVfYml0cyhyZGV2LT5yZWdtYXAsIHJlZywKKwkJCQkgIHJkZXYt
PmRlc2MtPnZzZWxfbWFzaywKKwkJCQkgIHNlbCk7Cit9CisKIHN0YXRpYyBpbnQgcms4MDhfc2V0
X3N1c3BlbmRfdm9sdGFnZV9yYW5nZShzdHJ1Y3QgcmVndWxhdG9yX2RldiAqcmRldiwgaW50IHV2
KQogewogCXVuc2lnbmVkIGludCByZWc7CkBAIC0zNjMsNiArNTMyLDEyOSBAQCBzdGF0aWMgaW50
IHJrODA4X3NldF9zdXNwZW5kX2Rpc2FibGUoc3RydWN0IHJlZ3VsYXRvcl9kZXYgKnJkZXYpCiAJ
CQkJICByZGV2LT5kZXNjLT5lbmFibGVfbWFzayk7CiB9CiAKK3N0YXRpYyBpbnQgcms4MTdfc2V0
X3N1c3BlbmRfZW5hYmxlX2N0cmwoc3RydWN0IHJlZ3VsYXRvcl9kZXYgKnJkZXYsCisJCQkJCSB1
bnNpZ25lZCBpbnQgZW4pCit7CisJdW5zaWduZWQgaW50IHJlZzsKKwlpbnQgaWQgPSByZGV2X2dl
dF9pZChyZGV2KTsKKwl1bnNpZ25lZCBpbnQgaWRfc2xwLCBtc2ssIHZhbDsKKworCWlmIChpZCA+
PSBSSzgxN19JRF9EQ0RDMSAmJiBpZCA8PSBSSzgxN19JRF9EQ0RDNCkKKwkJaWRfc2xwID0gaWQ7
CisJZWxzZSBpZiAoaWQgPj0gUks4MTdfSURfTERPMSAmJiBpZCA8PSBSSzgxN19JRF9MRE84KQor
CQlpZF9zbHAgPSA4ICsgKGlkIC0gUks4MTdfSURfTERPMSk7CisJZWxzZSBpZiAoaWQgPj0gUks4
MTdfSURfTERPOSAmJiBpZCA8PSBSSzgwOV9JRF9TVzIpCisJCWlkX3NscCA9IDQgKyAoaWQgLSBS
SzgxN19JRF9MRE85KTsKKwllbHNlCisJCXJldHVybiAtRUlOVkFMOworCisJcmVnID0gUks4MTdf
UE9XRVJfU0xQX0VOX1JFRyhpZF9zbHAgLyA4KTsKKworCW1zayA9IEJJVChpZF9zbHAgJSA4KTsK
KwlpZiAoZW4pCisJCXZhbCA9IG1zazsKKwllbHNlCisJCXZhbCA9IDA7CisKKwlyZXR1cm4gcmVn
bWFwX3VwZGF0ZV9iaXRzKHJkZXYtPnJlZ21hcCwgcmVnLCBtc2ssIHZhbCk7Cit9CisKK3N0YXRp
YyBpbnQgcms4MTdfc2V0X3N1c3BlbmRfZW5hYmxlKHN0cnVjdCByZWd1bGF0b3JfZGV2ICpyZGV2
KQoreworCXJldHVybiByazgxN19zZXRfc3VzcGVuZF9lbmFibGVfY3RybChyZGV2LCAxKTsKK30K
Kworc3RhdGljIGludCByazgxN19zZXRfc3VzcGVuZF9kaXNhYmxlKHN0cnVjdCByZWd1bGF0b3Jf
ZGV2ICpyZGV2KQoreworCXJldHVybiByazgxN19zZXRfc3VzcGVuZF9lbmFibGVfY3RybChyZGV2
LCAwKTsKK30KKworc3RhdGljIGludCByazh4eF9zZXRfc3VzcGVuZF9tb2RlKHN0cnVjdCByZWd1
bGF0b3JfZGV2ICpyZGV2LCB1bnNpZ25lZCBpbnQgbW9kZSkKK3sKKwl1bnNpZ25lZCBpbnQgcmVn
OworCisJcmVnID0gcmRldi0+ZGVzYy0+dnNlbF9yZWcgKyBSSzgwOF9TTFBfUkVHX09GRlNFVDsK
KworCXN3aXRjaCAobW9kZSkgeworCWNhc2UgUkVHVUxBVE9SX01PREVfRkFTVDoKKwkJcmV0dXJu
IHJlZ21hcF91cGRhdGVfYml0cyhyZGV2LT5yZWdtYXAsIHJlZywKKwkJCQkJICBQV01fTU9ERV9N
U0ssIEZQV01fTU9ERSk7CisJY2FzZSBSRUdVTEFUT1JfTU9ERV9OT1JNQUw6CisJCXJldHVybiBy
ZWdtYXBfdXBkYXRlX2JpdHMocmRldi0+cmVnbWFwLCByZWcsCisJCQkJCSAgUFdNX01PREVfTVNL
LCBBVVRPX1BXTV9NT0RFKTsKKwlkZWZhdWx0OgorCQlwcl9lcnIoImRvIG5vdCBzdXBwb3J0IHRo
aXMgbW9kZVxuIik7CisJCXJldHVybiAtRUlOVkFMOworCX0KKworCXJldHVybiAwOworfQorCitz
dGF0aWMgaW50IHJrOHh4X3NldF9tb2RlKHN0cnVjdCByZWd1bGF0b3JfZGV2ICpyZGV2LCB1bnNp
Z25lZCBpbnQgbW9kZSkKK3sKKwlzd2l0Y2ggKG1vZGUpIHsKKwljYXNlIFJFR1VMQVRPUl9NT0RF
X0ZBU1Q6CisJCXJldHVybiByZWdtYXBfdXBkYXRlX2JpdHMocmRldi0+cmVnbWFwLCByZGV2LT5k
ZXNjLT52c2VsX3JlZywKKwkJCQkJICBQV01fTU9ERV9NU0ssIEZQV01fTU9ERSk7CisJY2FzZSBS
RUdVTEFUT1JfTU9ERV9OT1JNQUw6CisJCXJldHVybiByZWdtYXBfdXBkYXRlX2JpdHMocmRldi0+
cmVnbWFwLCByZGV2LT5kZXNjLT52c2VsX3JlZywKKwkJCQkJICBQV01fTU9ERV9NU0ssIEFVVE9f
UFdNX01PREUpOworCWRlZmF1bHQ6CisJCXByX2VycigiZG8gbm90IHN1cHBvcnQgdGhpcyBtb2Rl
XG4iKTsKKwkJcmV0dXJuIC1FSU5WQUw7CisJfQorCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB1
bnNpZ25lZCBpbnQgcms4eHhfZ2V0X21vZGUoc3RydWN0IHJlZ3VsYXRvcl9kZXYgKnJkZXYpCit7
CisJdW5zaWduZWQgaW50IHZhbDsKKwlpbnQgZXJyOworCisJZXJyID0gcmVnbWFwX3JlYWQocmRl
di0+cmVnbWFwLCByZGV2LT5kZXNjLT52c2VsX3JlZywgJnZhbCk7CisJaWYgKGVycikKKwkJcmV0
dXJuIGVycjsKKworCWlmICh2YWwgJiBGUFdNX01PREUpCisJCXJldHVybiBSRUdVTEFUT1JfTU9E
RV9GQVNUOworCWVsc2UKKwkJcmV0dXJuIFJFR1VMQVRPUl9NT0RFX05PUk1BTDsKK30KKworc3Rh
dGljIGludCByazh4eF9pc19lbmFibGVkX3dtc2tfcmVnbWFwKHN0cnVjdCByZWd1bGF0b3JfZGV2
ICpyZGV2KQoreworCXVuc2lnbmVkIGludCB2YWw7CisJaW50IHJldDsKKworCXJldCA9IHJlZ21h
cF9yZWFkKHJkZXYtPnJlZ21hcCwgcmRldi0+ZGVzYy0+ZW5hYmxlX3JlZywgJnZhbCk7CisJaWYg
KHJldCAhPSAwKQorCQlyZXR1cm4gcmV0OworCisJLyogYWRkIHdyaXRlIG1hc2sgYml0ICovCisJ
dmFsIHw9IChyZGV2LT5kZXNjLT5lbmFibGVfbWFzayAmIDB4ZjApOworCXZhbCAmPSByZGV2LT5k
ZXNjLT5lbmFibGVfbWFzazsKKworCWlmIChyZGV2LT5kZXNjLT5lbmFibGVfaXNfaW52ZXJ0ZWQp
IHsKKwkJaWYgKHJkZXYtPmRlc2MtPmVuYWJsZV92YWwpCisJCQlyZXR1cm4gdmFsICE9IHJkZXYt
PmRlc2MtPmVuYWJsZV92YWw7CisJCXJldHVybiAodmFsID09IDApOworCX0KKwlpZiAocmRldi0+
ZGVzYy0+ZW5hYmxlX3ZhbCkKKwkJcmV0dXJuIHZhbCA9PSByZGV2LT5kZXNjLT5lbmFibGVfdmFs
OworCXJldHVybiB2YWwgIT0gMDsKK30KKworc3RhdGljIHVuc2lnbmVkIGludCByazh4eF9yZWd1
bGF0b3Jfb2ZfbWFwX21vZGUodW5zaWduZWQgaW50IG1vZGUpCit7CisJaWYgKG1vZGUgPT0gMSkK
KwkJcmV0dXJuIFJFR1VMQVRPUl9NT0RFX0ZBU1Q7CisJaWYgKG1vZGUgPT0gMikKKwkJcmV0dXJu
IFJFR1VMQVRPUl9NT0RFX05PUk1BTDsKKworCXJldHVybiAtRUlOVkFMOworfQorCiBzdGF0aWMg
c3RydWN0IHJlZ3VsYXRvcl9vcHMgcms4MDVfcmVnX29wcyA9IHsKIAkJLmxpc3Rfdm9sdGFnZSAg
ICAgICAgICAgPSByZWd1bGF0b3JfbGlzdF92b2x0YWdlX2xpbmVhciwKIAkJLm1hcF92b2x0YWdl
ICAgICAgICAgICAgPSByZWd1bGF0b3JfbWFwX3ZvbHRhZ2VfbGluZWFyLApAQCAtNDMzLDYgKzcy
NSw3MSBAQCBzdGF0aWMgaW50IHJrODA4X3NldF9zdXNwZW5kX2Rpc2FibGUoc3RydWN0IHJlZ3Vs
YXRvcl9kZXYgKnJkZXYpCiAJLnNldF9zdXNwZW5kX2Rpc2FibGUJPSByazgwOF9zZXRfc3VzcGVu
ZF9kaXNhYmxlLAogfTsKIAorc3RhdGljIHN0cnVjdCByZWd1bGF0b3Jfb3BzIHJrODA5X2J1Y2s1
X29wc19yYW5nZSA9IHsKKwkubGlzdF92b2x0YWdlCQk9IHJlZ3VsYXRvcl9saXN0X3ZvbHRhZ2Vf
bGluZWFyX3JhbmdlLAorCS5tYXBfdm9sdGFnZQkJPSByZWd1bGF0b3JfbWFwX3ZvbHRhZ2VfbGlu
ZWFyX3JhbmdlLAorCS5nZXRfdm9sdGFnZV9zZWwJPSByZWd1bGF0b3JfZ2V0X3ZvbHRhZ2Vfc2Vs
X3JlZ21hcCwKKwkuc2V0X3ZvbHRhZ2Vfc2VsCT0gcmVndWxhdG9yX3NldF92b2x0YWdlX3NlbF9y
ZWdtYXAsCisJLnNldF92b2x0YWdlX3RpbWVfc2VsCT0gcmVndWxhdG9yX3NldF92b2x0YWdlX3Rp
bWVfc2VsLAorCS5lbmFibGUJCQk9IHJlZ3VsYXRvcl9lbmFibGVfcmVnbWFwLAorCS5kaXNhYmxl
CQk9IHJlZ3VsYXRvcl9kaXNhYmxlX3JlZ21hcCwKKwkuaXNfZW5hYmxlZAkJPSByazh4eF9pc19l
bmFibGVkX3dtc2tfcmVnbWFwLAorCS5zZXRfc3VzcGVuZF92b2x0YWdlCT0gcms4MDhfc2V0X3N1
c3BlbmRfdm9sdGFnZV9yYW5nZSwKKwkuc2V0X3N1c3BlbmRfZW5hYmxlCT0gcms4MTdfc2V0X3N1
c3BlbmRfZW5hYmxlLAorCS5zZXRfc3VzcGVuZF9kaXNhYmxlCT0gcms4MTdfc2V0X3N1c3BlbmRf
ZGlzYWJsZSwKK307CisKK3N0YXRpYyBzdHJ1Y3QgcmVndWxhdG9yX29wcyByazgxN19yZWdfb3Bz
ID0geworCS5saXN0X3ZvbHRhZ2UJCT0gcmVndWxhdG9yX2xpc3Rfdm9sdGFnZV9saW5lYXIsCisJ
Lm1hcF92b2x0YWdlCQk9IHJlZ3VsYXRvcl9tYXBfdm9sdGFnZV9saW5lYXIsCisJLmdldF92b2x0
YWdlX3NlbAk9IHJlZ3VsYXRvcl9nZXRfdm9sdGFnZV9zZWxfcmVnbWFwLAorCS5zZXRfdm9sdGFn
ZV9zZWwJPSByZWd1bGF0b3Jfc2V0X3ZvbHRhZ2Vfc2VsX3JlZ21hcCwKKwkuZW5hYmxlCQkJPSBy
ZWd1bGF0b3JfZW5hYmxlX3JlZ21hcCwKKwkuZGlzYWJsZQkJPSByZWd1bGF0b3JfZGlzYWJsZV9y
ZWdtYXAsCisJLmlzX2VuYWJsZWQJCT0gcms4eHhfaXNfZW5hYmxlZF93bXNrX3JlZ21hcCwKKwku
c2V0X3N1c3BlbmRfdm9sdGFnZQk9IHJrODE3X3NldF9zdXNwZW5kX3ZvbHRhZ2UsCisJLnNldF9z
dXNwZW5kX2VuYWJsZQk9IHJrODE3X3NldF9zdXNwZW5kX2VuYWJsZSwKKwkuc2V0X3N1c3BlbmRf
ZGlzYWJsZQk9IHJrODE3X3NldF9zdXNwZW5kX2Rpc2FibGUsCit9OworCitzdGF0aWMgc3RydWN0
IHJlZ3VsYXRvcl9vcHMgcms4MTdfYm9vc3Rfb3BzID0geworCS5saXN0X3ZvbHRhZ2UJCT0gcmVn
dWxhdG9yX2xpc3Rfdm9sdGFnZV9saW5lYXIsCisJLm1hcF92b2x0YWdlCQk9IHJlZ3VsYXRvcl9t
YXBfdm9sdGFnZV9saW5lYXIsCisJLmdldF92b2x0YWdlX3NlbAk9IHJlZ3VsYXRvcl9nZXRfdm9s
dGFnZV9zZWxfcmVnbWFwLAorCS5zZXRfdm9sdGFnZV9zZWwJPSByZWd1bGF0b3Jfc2V0X3ZvbHRh
Z2Vfc2VsX3JlZ21hcCwKKwkuZW5hYmxlCQkJPSByZWd1bGF0b3JfZW5hYmxlX3JlZ21hcCwKKwku
ZGlzYWJsZQkJPSByZWd1bGF0b3JfZGlzYWJsZV9yZWdtYXAsCisJLmlzX2VuYWJsZWQJCT0gcms4
eHhfaXNfZW5hYmxlZF93bXNrX3JlZ21hcCwKKwkuc2V0X3N1c3BlbmRfZW5hYmxlCT0gcms4MTdf
c2V0X3N1c3BlbmRfZW5hYmxlLAorCS5zZXRfc3VzcGVuZF9kaXNhYmxlCT0gcms4MTdfc2V0X3N1
c3BlbmRfZGlzYWJsZSwKK307CisKK3N0YXRpYyBzdHJ1Y3QgcmVndWxhdG9yX29wcyByazgxN19i
dWNrX29wc19yYW5nZSA9IHsKKwkubGlzdF92b2x0YWdlCQk9IHJlZ3VsYXRvcl9saXN0X3ZvbHRh
Z2VfbGluZWFyX3JhbmdlLAorCS5tYXBfdm9sdGFnZQkJPSByZWd1bGF0b3JfbWFwX3ZvbHRhZ2Vf
bGluZWFyX3JhbmdlLAorCS5nZXRfdm9sdGFnZV9zZWwJPSByZWd1bGF0b3JfZ2V0X3ZvbHRhZ2Vf
c2VsX3JlZ21hcCwKKwkuc2V0X3ZvbHRhZ2Vfc2VsCT0gcmVndWxhdG9yX3NldF92b2x0YWdlX3Nl
bF9yZWdtYXAsCisJLnNldF92b2x0YWdlX3RpbWVfc2VsCT0gcmVndWxhdG9yX3NldF92b2x0YWdl
X3RpbWVfc2VsLAorCS5lbmFibGUJCQk9IHJlZ3VsYXRvcl9lbmFibGVfcmVnbWFwLAorCS5kaXNh
YmxlCQk9IHJlZ3VsYXRvcl9kaXNhYmxlX3JlZ21hcCwKKwkuaXNfZW5hYmxlZAkJPSByazh4eF9p
c19lbmFibGVkX3dtc2tfcmVnbWFwLAorCS5zZXRfbW9kZQkJPSByazh4eF9zZXRfbW9kZSwKKwku
Z2V0X21vZGUJCT0gcms4eHhfZ2V0X21vZGUsCisJLnNldF9zdXNwZW5kX21vZGUJPSByazh4eF9z
ZXRfc3VzcGVuZF9tb2RlLAorCS5zZXRfcmFtcF9kZWxheQkJPSByazgxN19zZXRfcmFtcF9kZWxh
eSwKKwkuc2V0X3N1c3BlbmRfdm9sdGFnZQk9IHJrODA4X3NldF9zdXNwZW5kX3ZvbHRhZ2VfcmFu
Z2UsCisJLnNldF9zdXNwZW5kX2VuYWJsZQk9IHJrODE3X3NldF9zdXNwZW5kX2VuYWJsZSwKKwku
c2V0X3N1c3BlbmRfZGlzYWJsZQk9IHJrODE3X3NldF9zdXNwZW5kX2Rpc2FibGUsCit9OworCitz
dGF0aWMgc3RydWN0IHJlZ3VsYXRvcl9vcHMgcms4MTdfc3dpdGNoX29wcyA9IHsKKwkuZW5hYmxl
CQkJPSByZWd1bGF0b3JfZW5hYmxlX3JlZ21hcCwKKwkuZGlzYWJsZQkJPSByZWd1bGF0b3JfZGlz
YWJsZV9yZWdtYXAsCisJLmlzX2VuYWJsZWQJCT0gcmVndWxhdG9yX2lzX2VuYWJsZWRfcmVnbWFw
LAorCS5zZXRfc3VzcGVuZF9lbmFibGUJPSByazgxN19zZXRfc3VzcGVuZF9lbmFibGUsCisJLnNl
dF9zdXNwZW5kX2Rpc2FibGUJPSByazgxN19zZXRfc3VzcGVuZF9kaXNhYmxlLAorfTsKKwogc3Rh
dGljIGNvbnN0IHN0cnVjdCByZWd1bGF0b3JfZGVzYyByazgwNV9yZWdbXSA9IHsKIAl7CiAJCS5u
YW1lID0gIkRDRENfUkVHMSIsCkBAIC01ODksNiArOTQ2LDI3MSBAQCBzdGF0aWMgaW50IHJrODA4
X3NldF9zdXNwZW5kX2Rpc2FibGUoc3RydWN0IHJlZ3VsYXRvcl9kZXYgKnJkZXYpCiAJCVJLODA4
X0RDRENfRU5fUkVHLCBCSVQoNikpLAogfTsKIAorc3RhdGljIGNvbnN0IHN0cnVjdCByZWd1bGF0
b3JfZGVzYyByazgwOV9yZWdbXSA9IHsKKwl7CisJCS5uYW1lID0gIkRDRENfUkVHMSIsCisJCS5z
dXBwbHlfbmFtZSA9ICJ2Y2MxIiwKKwkJLm9mX21hdGNoID0gb2ZfbWF0Y2hfcHRyKCJEQ0RDX1JF
RzEiKSwKKwkJLnJlZ3VsYXRvcnNfbm9kZSA9IG9mX21hdGNoX3B0cigicmVndWxhdG9ycyIpLAor
CQkuaWQgPSBSSzgxN19JRF9EQ0RDMSwKKwkJLm9wcyA9ICZyazgxN19idWNrX29wc19yYW5nZSwK
KwkJLnR5cGUgPSBSRUdVTEFUT1JfVk9MVEFHRSwKKwkJLm5fdm9sdGFnZXMgPSBSSzgxN19CVUNL
MV9TRUxfQ05UICsgMSwKKwkJLmxpbmVhcl9yYW5nZXMgPSByazgxN19idWNrMV92b2x0YWdlX3Jh
bmdlcywKKwkJLm5fbGluZWFyX3JhbmdlcyA9IEFSUkFZX1NJWkUocms4MTdfYnVjazFfdm9sdGFn
ZV9yYW5nZXMpLAorCQkudnNlbF9yZWcgPSBSSzgxN19CVUNLMV9PTl9WU0VMX1JFRywKKwkJLnZz
ZWxfbWFzayA9IFJLODE3X0JVQ0tfVlNFTF9NQVNLLAorCQkuZW5hYmxlX3JlZyA9IFJLODE3X1BP
V0VSX0VOX1JFRygwKSwKKwkJLmVuYWJsZV9tYXNrID0gRU5BQkxFX01BU0soUks4MTdfSURfRENE
QzEpLAorCQkuZW5hYmxlX3ZhbCA9IEVOQUJMRV9NQVNLKFJLODE3X0lEX0RDREMxKSwKKwkJLmRp
c2FibGVfdmFsID0gRElTQUJMRV9WQUwoUks4MTdfSURfRENEQzEpLAorCQkub2ZfbWFwX21vZGUg
PSByazh4eF9yZWd1bGF0b3Jfb2ZfbWFwX21vZGUsCisJCS5vd25lciA9IFRISVNfTU9EVUxFLAor
CX0sIHsKKwkJLm5hbWUgPSAiRENEQ19SRUcyIiwKKwkJLnN1cHBseV9uYW1lID0gInZjYzIiLAor
CQkub2ZfbWF0Y2ggPSBvZl9tYXRjaF9wdHIoIkRDRENfUkVHMiIpLAorCQkucmVndWxhdG9yc19u
b2RlID0gb2ZfbWF0Y2hfcHRyKCJyZWd1bGF0b3JzIiksCisJCS5pZCA9IFJLODE3X0lEX0RDREMy
LAorCQkub3BzID0gJnJrODE3X2J1Y2tfb3BzX3JhbmdlLAorCQkudHlwZSA9IFJFR1VMQVRPUl9W
T0xUQUdFLAorCQkubl92b2x0YWdlcyA9IFJLODE3X0JVQ0sxX1NFTF9DTlQgKyAxLAorCQkubGlu
ZWFyX3JhbmdlcyA9IHJrODE3X2J1Y2sxX3ZvbHRhZ2VfcmFuZ2VzLAorCQkubl9saW5lYXJfcmFu
Z2VzID0gQVJSQVlfU0laRShyazgxN19idWNrMV92b2x0YWdlX3JhbmdlcyksCisJCS52c2VsX3Jl
ZyA9IFJLODE3X0JVQ0syX09OX1ZTRUxfUkVHLAorCQkudnNlbF9tYXNrID0gUks4MTdfQlVDS19W
U0VMX01BU0ssCisJCS5lbmFibGVfcmVnID0gUks4MTdfUE9XRVJfRU5fUkVHKDApLAorCQkuZW5h
YmxlX21hc2sgPSBFTkFCTEVfTUFTSyhSSzgxN19JRF9EQ0RDMiksCisJCS5lbmFibGVfdmFsID0g
RU5BQkxFX01BU0soUks4MTdfSURfRENEQzIpLAorCQkuZGlzYWJsZV92YWwgPSBESVNBQkxFX1ZB
TChSSzgxN19JRF9EQ0RDMiksCisJCS5vZl9tYXBfbW9kZSA9IHJrOHh4X3JlZ3VsYXRvcl9vZl9t
YXBfbW9kZSwKKwkJLm93bmVyID0gVEhJU19NT0RVTEUsCisJfSwgeworCQkubmFtZSA9ICJEQ0RD
X1JFRzMiLAorCQkuc3VwcGx5X25hbWUgPSAidmNjMyIsCisJCS5vZl9tYXRjaCA9IG9mX21hdGNo
X3B0cigiRENEQ19SRUczIiksCisJCS5yZWd1bGF0b3JzX25vZGUgPSBvZl9tYXRjaF9wdHIoInJl
Z3VsYXRvcnMiKSwKKwkJLmlkID0gUks4MTdfSURfRENEQzMsCisJCS5vcHMgPSAmcms4MTdfYnVj
a19vcHNfcmFuZ2UsCisJCS50eXBlID0gUkVHVUxBVE9SX1ZPTFRBR0UsCisJCS5uX3ZvbHRhZ2Vz
ID0gUks4MTdfQlVDSzFfU0VMX0NOVCArIDEsCisJCS5saW5lYXJfcmFuZ2VzID0gcms4MTdfYnVj
azFfdm9sdGFnZV9yYW5nZXMsCisJCS5uX2xpbmVhcl9yYW5nZXMgPSBBUlJBWV9TSVpFKHJrODE3
X2J1Y2sxX3ZvbHRhZ2VfcmFuZ2VzKSwKKwkJLnZzZWxfcmVnID0gUks4MTdfQlVDSzNfT05fVlNF
TF9SRUcsCisJCS52c2VsX21hc2sgPSBSSzgxN19CVUNLX1ZTRUxfTUFTSywKKwkJLmVuYWJsZV9y
ZWcgPSBSSzgxN19QT1dFUl9FTl9SRUcoMCksCisJCS5lbmFibGVfbWFzayA9IEVOQUJMRV9NQVNL
KFJLODE3X0lEX0RDREMzKSwKKwkJLmVuYWJsZV92YWwgPSBFTkFCTEVfTUFTSyhSSzgxN19JRF9E
Q0RDMyksCisJCS5kaXNhYmxlX3ZhbCA9IERJU0FCTEVfVkFMKFJLODE3X0lEX0RDREMzKSwKKwkJ
Lm9mX21hcF9tb2RlID0gcms4eHhfcmVndWxhdG9yX29mX21hcF9tb2RlLAorCQkub3duZXIgPSBU
SElTX01PRFVMRSwKKwl9LCB7CisJCS5uYW1lID0gIkRDRENfUkVHNCIsCisJCS5zdXBwbHlfbmFt
ZSA9ICJ2Y2M0IiwKKwkJLm9mX21hdGNoID0gb2ZfbWF0Y2hfcHRyKCJEQ0RDX1JFRzQiKSwKKwkJ
LnJlZ3VsYXRvcnNfbm9kZSA9IG9mX21hdGNoX3B0cigicmVndWxhdG9ycyIpLAorCQkuaWQgPSBS
SzgxN19JRF9EQ0RDNCwKKwkJLm9wcyA9ICZyazgxN19idWNrX29wc19yYW5nZSwKKwkJLnR5cGUg
PSBSRUdVTEFUT1JfVk9MVEFHRSwKKwkJLm5fdm9sdGFnZXMgPSBSSzgxN19CVUNLM19TRUxfQ05U
ICsgMSwKKwkJLmxpbmVhcl9yYW5nZXMgPSByazgxN19idWNrM192b2x0YWdlX3JhbmdlcywKKwkJ
Lm5fbGluZWFyX3JhbmdlcyA9IEFSUkFZX1NJWkUocms4MTdfYnVjazNfdm9sdGFnZV9yYW5nZXMp
LAorCQkudnNlbF9yZWcgPSBSSzgxN19CVUNLNF9PTl9WU0VMX1JFRywKKwkJLnZzZWxfbWFzayA9
IFJLODE3X0JVQ0tfVlNFTF9NQVNLLAorCQkuZW5hYmxlX3JlZyA9IFJLODE3X1BPV0VSX0VOX1JF
RygwKSwKKwkJLmVuYWJsZV9tYXNrID0gRU5BQkxFX01BU0soUks4MTdfSURfRENEQzQpLAorCQku
ZW5hYmxlX3ZhbCA9IEVOQUJMRV9NQVNLKFJLODE3X0lEX0RDREM0KSwKKwkJLmRpc2FibGVfdmFs
ID0gRElTQUJMRV9WQUwoUks4MTdfSURfRENEQzQpLAorCQkub2ZfbWFwX21vZGUgPSByazh4eF9y
ZWd1bGF0b3Jfb2ZfbWFwX21vZGUsCisJCS5vd25lciA9IFRISVNfTU9EVUxFLAorCX0sCisJewor
CQkubmFtZSA9ICJEQ0RDX1JFRzUiLAorCQkuc3VwcGx5X25hbWUgPSAidmNjOSIsCisJCS5vZl9t
YXRjaCA9IG9mX21hdGNoX3B0cigiRENEQ19SRUc1IiksCisJCS5yZWd1bGF0b3JzX25vZGUgPSBv
Zl9tYXRjaF9wdHIoInJlZ3VsYXRvcnMiKSwKKwkJLmlkID0gUks4MDlfSURfRENEQzUsCisJCS5v
cHMgPSAmcms4MDlfYnVjazVfb3BzX3JhbmdlLAorCQkudHlwZSA9IFJFR1VMQVRPUl9WT0xUQUdF
LAorCQkubl92b2x0YWdlcyA9IFJLODA5X0JVQ0s1X1NFTF9DTlQsCisJCS5saW5lYXJfcmFuZ2Vz
ID0gcms4MDlfYnVjazVfdm9sdGFnZV9yYW5nZXMsCisJCS5uX2xpbmVhcl9yYW5nZXMgPSBBUlJB
WV9TSVpFKHJrODA5X2J1Y2s1X3ZvbHRhZ2VfcmFuZ2VzKSwKKwkJLnZzZWxfcmVnID0gUks4MDlf
QlVDSzVfQ09ORklHKDApLAorCQkudnNlbF9tYXNrID0gUks4MDlfQlVDSzVfVlNFTF9NQVNLLAor
CQkuZW5hYmxlX3JlZyA9IFJLODE3X1BPV0VSX0VOX1JFRygzKSwKKwkJLmVuYWJsZV9tYXNrID0g
RU5BQkxFX01BU0soMSksCisJCS5lbmFibGVfdmFsID0gRU5BQkxFX01BU0soMSksCisJCS5kaXNh
YmxlX3ZhbCA9IERJU0FCTEVfVkFMKDEpLAorCQkub2ZfbWFwX21vZGUgPSByazh4eF9yZWd1bGF0
b3Jfb2ZfbWFwX21vZGUsCisJCS5vd25lciA9IFRISVNfTU9EVUxFLAorCX0sCisJUks4MTdfREVT
QyhSSzgxN19JRF9MRE8xLCAiTERPX1JFRzEiLCAidmNjNSIsIDYwMCwgMzQwMCwgMjUsCisJCSAg
IFJLODE3X0xET19PTl9WU0VMX1JFRygwKSwgUks4MTdfTERPX1ZTRUxfTUFTSywKKwkJICAgUks4
MTdfUE9XRVJfRU5fUkVHKDEpLCBFTkFCTEVfTUFTSygwKSwgRU5BQkxFX01BU0soMCksCisJCSAg
IERJU0FCTEVfVkFMKDApLCA0MDApLAorCVJLODE3X0RFU0MoUks4MTdfSURfTERPMiwgIkxET19S
RUcyIiwgInZjYzUiLCA2MDAsIDM0MDAsIDI1LAorCQkgICBSSzgxN19MRE9fT05fVlNFTF9SRUco
MSksIFJLODE3X0xET19WU0VMX01BU0ssCisJCSAgIFJLODE3X1BPV0VSX0VOX1JFRygxKSwgRU5B
QkxFX01BU0soMSksIEVOQUJMRV9NQVNLKDEpLAorCQkgICBESVNBQkxFX1ZBTCgxKSwgNDAwKSwK
KwlSSzgxN19ERVNDKFJLODE3X0lEX0xETzMsICJMRE9fUkVHMyIsICJ2Y2M1IiwgNjAwLCAzNDAw
LCAyNSwKKwkJICAgUks4MTdfTERPX09OX1ZTRUxfUkVHKDIpLCBSSzgxN19MRE9fVlNFTF9NQVNL
LAorCQkgICBSSzgxN19QT1dFUl9FTl9SRUcoMSksIEVOQUJMRV9NQVNLKDIpLCBFTkFCTEVfTUFT
SygyKSwKKwkJICAgRElTQUJMRV9WQUwoMiksIDQwMCksCisJUks4MTdfREVTQyhSSzgxN19JRF9M
RE80LCAiTERPX1JFRzQiLCAidmNjNiIsIDYwMCwgMzQwMCwgMjUsCisJCSAgIFJLODE3X0xET19P
Tl9WU0VMX1JFRygzKSwgUks4MTdfTERPX1ZTRUxfTUFTSywKKwkJICAgUks4MTdfUE9XRVJfRU5f
UkVHKDEpLCBFTkFCTEVfTUFTSygzKSwgRU5BQkxFX01BU0soMyksCisJCSAgIERJU0FCTEVfVkFM
KDMpLCA0MDApLAorCVJLODE3X0RFU0MoUks4MTdfSURfTERPNSwgIkxET19SRUc1IiwgInZjYzYi
LCA2MDAsIDM0MDAsIDI1LAorCQkgICBSSzgxN19MRE9fT05fVlNFTF9SRUcoNCksIFJLODE3X0xE
T19WU0VMX01BU0ssCisJCSAgIFJLODE3X1BPV0VSX0VOX1JFRygyKSwgRU5BQkxFX01BU0soMCks
IEVOQUJMRV9NQVNLKDApLAorCQkgICBESVNBQkxFX1ZBTCgwKSwgNDAwKSwKKwlSSzgxN19ERVND
KFJLODE3X0lEX0xETzYsICJMRE9fUkVHNiIsICJ2Y2M2IiwgNjAwLCAzNDAwLCAyNSwKKwkJICAg
Uks4MTdfTERPX09OX1ZTRUxfUkVHKDUpLCBSSzgxN19MRE9fVlNFTF9NQVNLLAorCQkgICBSSzgx
N19QT1dFUl9FTl9SRUcoMiksIEVOQUJMRV9NQVNLKDEpLCBFTkFCTEVfTUFTSygxKSwKKwkJICAg
RElTQUJMRV9WQUwoMSksIDQwMCksCisJUks4MTdfREVTQyhSSzgxN19JRF9MRE83LCAiTERPX1JF
RzciLCAidmNjNyIsIDYwMCwgMzQwMCwgMjUsCisJCSAgIFJLODE3X0xET19PTl9WU0VMX1JFRyg2
KSwgUks4MTdfTERPX1ZTRUxfTUFTSywKKwkJICAgUks4MTdfUE9XRVJfRU5fUkVHKDIpLCBFTkFC
TEVfTUFTSygyKSwgRU5BQkxFX01BU0soMiksCisJCSAgIERJU0FCTEVfVkFMKDIpLCA0MDApLAor
CVJLODE3X0RFU0MoUks4MTdfSURfTERPOCwgIkxET19SRUc4IiwgInZjYzciLCA2MDAsIDM0MDAs
IDI1LAorCQkgICBSSzgxN19MRE9fT05fVlNFTF9SRUcoNyksIFJLODE3X0xET19WU0VMX01BU0ss
CisJCSAgIFJLODE3X1BPV0VSX0VOX1JFRygyKSwgRU5BQkxFX01BU0soMyksIEVOQUJMRV9NQVNL
KDMpLAorCQkgICBESVNBQkxFX1ZBTCgzKSwgNDAwKSwKKwlSSzgxN19ERVNDKFJLODE3X0lEX0xE
TzksICJMRE9fUkVHOSIsICJ2Y2M3IiwgNjAwLCAzNDAwLCAyNSwKKwkJICAgUks4MTdfTERPX09O
X1ZTRUxfUkVHKDgpLCBSSzgxN19MRE9fVlNFTF9NQVNLLAorCQkgICBSSzgxN19QT1dFUl9FTl9S
RUcoMyksIEVOQUJMRV9NQVNLKDApLCBFTkFCTEVfTUFTSygwKSwKKwkJICAgRElTQUJMRV9WQUwo
MCksIDQwMCksCisJUks4MTdfREVTQ19TV0lUQ0goUks4MDlfSURfU1cxLCAiU1dJVENIX1JFRzEi
LCAidmNjOCIsCisJCQkgIFJLODE3X1BPV0VSX0VOX1JFRygzKSwgRU5BQkxFX01BU0soMyksCisJ
CQkgIEVOQUJMRV9NQVNLKDMpLCBESVNBQkxFX1ZBTCgzKSksCisJUks4MTdfREVTQ19TV0lUQ0go
Uks4MDlfSURfU1cyLCAiU1dJVENIX1JFRzIiLCAidmNjOSIsCisJCQkgIFJLODE3X1BPV0VSX0VO
X1JFRygzKSwgRU5BQkxFX01BU0soMiksCisJCQkgIEVOQUJMRV9NQVNLKDIpLCBESVNBQkxFX1ZB
TCgyKSksCit9OworCitzdGF0aWMgY29uc3Qgc3RydWN0IHJlZ3VsYXRvcl9kZXNjIHJrODE3X3Jl
Z1tdID0geworCXsKKwkJLm5hbWUgPSAiRENEQ19SRUcxIiwKKwkJLnN1cHBseV9uYW1lID0gInZj
YzEiLAorCQkub2ZfbWF0Y2ggPSBvZl9tYXRjaF9wdHIoIkRDRENfUkVHMSIpLAorCQkucmVndWxh
dG9yc19ub2RlID0gb2ZfbWF0Y2hfcHRyKCJyZWd1bGF0b3JzIiksCisJCS5pZCA9IFJLODE3X0lE
X0RDREMxLAorCQkub3BzID0gJnJrODE3X2J1Y2tfb3BzX3JhbmdlLAorCQkudHlwZSA9IFJFR1VM
QVRPUl9WT0xUQUdFLAorCQkubl92b2x0YWdlcyA9IFJLODE3X0JVQ0sxX1NFTF9DTlQgKyAxLAor
CQkubGluZWFyX3JhbmdlcyA9IHJrODE3X2J1Y2sxX3ZvbHRhZ2VfcmFuZ2VzLAorCQkubl9saW5l
YXJfcmFuZ2VzID0gQVJSQVlfU0laRShyazgxN19idWNrMV92b2x0YWdlX3JhbmdlcyksCisJCS52
c2VsX3JlZyA9IFJLODE3X0JVQ0sxX09OX1ZTRUxfUkVHLAorCQkudnNlbF9tYXNrID0gUks4MTdf
QlVDS19WU0VMX01BU0ssCisJCS5lbmFibGVfcmVnID0gUks4MTdfUE9XRVJfRU5fUkVHKDApLAor
CQkuZW5hYmxlX21hc2sgPSBFTkFCTEVfTUFTSyhSSzgxN19JRF9EQ0RDMSksCisJCS5lbmFibGVf
dmFsID0gRU5BQkxFX01BU0soUks4MTdfSURfRENEQzEpLAorCQkuZGlzYWJsZV92YWwgPSBESVNB
QkxFX1ZBTChSSzgxN19JRF9EQ0RDMSksCisJCS5vZl9tYXBfbW9kZSA9IHJrOHh4X3JlZ3VsYXRv
cl9vZl9tYXBfbW9kZSwKKwkJLm93bmVyID0gVEhJU19NT0RVTEUsCisJfSwgeworCQkubmFtZSA9
ICJEQ0RDX1JFRzIiLAorCQkuc3VwcGx5X25hbWUgPSAidmNjMiIsCisJCS5vZl9tYXRjaCA9IG9m
X21hdGNoX3B0cigiRENEQ19SRUcyIiksCisJCS5yZWd1bGF0b3JzX25vZGUgPSBvZl9tYXRjaF9w
dHIoInJlZ3VsYXRvcnMiKSwKKwkJLmlkID0gUks4MTdfSURfRENEQzIsCisJCS5vcHMgPSAmcms4
MTdfYnVja19vcHNfcmFuZ2UsCisJCS50eXBlID0gUkVHVUxBVE9SX1ZPTFRBR0UsCisJCS5uX3Zv
bHRhZ2VzID0gUks4MTdfQlVDSzFfU0VMX0NOVCArIDEsCisJCS5saW5lYXJfcmFuZ2VzID0gcms4
MTdfYnVjazFfdm9sdGFnZV9yYW5nZXMsCisJCS5uX2xpbmVhcl9yYW5nZXMgPSBBUlJBWV9TSVpF
KHJrODE3X2J1Y2sxX3ZvbHRhZ2VfcmFuZ2VzKSwKKwkJLnZzZWxfcmVnID0gUks4MTdfQlVDSzJf
T05fVlNFTF9SRUcsCisJCS52c2VsX21hc2sgPSBSSzgxN19CVUNLX1ZTRUxfTUFTSywKKwkJLmVu
YWJsZV9yZWcgPSBSSzgxN19QT1dFUl9FTl9SRUcoMCksCisJCS5lbmFibGVfbWFzayA9IEVOQUJM
RV9NQVNLKFJLODE3X0lEX0RDREMyKSwKKwkJLmVuYWJsZV92YWwgPSBFTkFCTEVfTUFTSyhSSzgx
N19JRF9EQ0RDMiksCisJCS5kaXNhYmxlX3ZhbCA9IERJU0FCTEVfVkFMKFJLODE3X0lEX0RDREMy
KSwKKwkJLm9mX21hcF9tb2RlID0gcms4eHhfcmVndWxhdG9yX29mX21hcF9tb2RlLAorCQkub3du
ZXIgPSBUSElTX01PRFVMRSwKKwl9LCB7CisJCS5uYW1lID0gIkRDRENfUkVHMyIsCisJCS5zdXBw
bHlfbmFtZSA9ICJ2Y2MzIiwKKwkJLm9mX21hdGNoID0gb2ZfbWF0Y2hfcHRyKCJEQ0RDX1JFRzMi
KSwKKwkJLnJlZ3VsYXRvcnNfbm9kZSA9IG9mX21hdGNoX3B0cigicmVndWxhdG9ycyIpLAorCQku
aWQgPSBSSzgxN19JRF9EQ0RDMywKKwkJLm9wcyA9ICZyazgxN19idWNrX29wc19yYW5nZSwKKwkJ
LnR5cGUgPSBSRUdVTEFUT1JfVk9MVEFHRSwKKwkJLm5fdm9sdGFnZXMgPSBSSzgxN19CVUNLMV9T
RUxfQ05UICsgMSwKKwkJLmxpbmVhcl9yYW5nZXMgPSByazgxN19idWNrMV92b2x0YWdlX3Jhbmdl
cywKKwkJLm5fbGluZWFyX3JhbmdlcyA9IEFSUkFZX1NJWkUocms4MTdfYnVjazFfdm9sdGFnZV9y
YW5nZXMpLAorCQkudnNlbF9yZWcgPSBSSzgxN19CVUNLM19PTl9WU0VMX1JFRywKKwkJLnZzZWxf
bWFzayA9IFJLODE3X0JVQ0tfVlNFTF9NQVNLLAorCQkuZW5hYmxlX3JlZyA9IFJLODE3X1BPV0VS
X0VOX1JFRygwKSwKKwkJLmVuYWJsZV9tYXNrID0gRU5BQkxFX01BU0soUks4MTdfSURfRENEQzMp
LAorCQkuZW5hYmxlX3ZhbCA9IEVOQUJMRV9NQVNLKFJLODE3X0lEX0RDREMzKSwKKwkJLmRpc2Fi
bGVfdmFsID0gRElTQUJMRV9WQUwoUks4MTdfSURfRENEQzMpLAorCQkub2ZfbWFwX21vZGUgPSBy
azh4eF9yZWd1bGF0b3Jfb2ZfbWFwX21vZGUsCisJCS5vd25lciA9IFRISVNfTU9EVUxFLAorCX0s
IHsKKwkJLm5hbWUgPSAiRENEQ19SRUc0IiwKKwkJLnN1cHBseV9uYW1lID0gInZjYzQiLAorCQku
b2ZfbWF0Y2ggPSBvZl9tYXRjaF9wdHIoIkRDRENfUkVHNCIpLAorCQkucmVndWxhdG9yc19ub2Rl
ID0gb2ZfbWF0Y2hfcHRyKCJyZWd1bGF0b3JzIiksCisJCS5pZCA9IFJLODE3X0lEX0RDREM0LAor
CQkub3BzID0gJnJrODE3X2J1Y2tfb3BzX3JhbmdlLAorCQkudHlwZSA9IFJFR1VMQVRPUl9WT0xU
QUdFLAorCQkubl92b2x0YWdlcyA9IFJLODE3X0JVQ0szX1NFTF9DTlQgKyAxLAorCQkubGluZWFy
X3JhbmdlcyA9IHJrODE3X2J1Y2szX3ZvbHRhZ2VfcmFuZ2VzLAorCQkubl9saW5lYXJfcmFuZ2Vz
ID0gQVJSQVlfU0laRShyazgxN19idWNrM192b2x0YWdlX3JhbmdlcyksCisJCS52c2VsX3JlZyA9
IFJLODE3X0JVQ0s0X09OX1ZTRUxfUkVHLAorCQkudnNlbF9tYXNrID0gUks4MTdfQlVDS19WU0VM
X01BU0ssCisJCS5lbmFibGVfcmVnID0gUks4MTdfUE9XRVJfRU5fUkVHKDApLAorCQkuZW5hYmxl
X21hc2sgPSBFTkFCTEVfTUFTSyhSSzgxN19JRF9EQ0RDNCksCisJCS5lbmFibGVfdmFsID0gRU5B
QkxFX01BU0soUks4MTdfSURfRENEQzQpLAorCQkuZGlzYWJsZV92YWwgPSBESVNBQkxFX1ZBTChS
SzgxN19JRF9EQ0RDNCksCisJCS5vZl9tYXBfbW9kZSA9IHJrOHh4X3JlZ3VsYXRvcl9vZl9tYXBf
bW9kZSwKKwkJLm93bmVyID0gVEhJU19NT0RVTEUsCisJfSwKKwlSSzgxN19ERVNDKFJLODE3X0lE
X0xETzEsICJMRE9fUkVHMSIsICJ2Y2M1IiwgNjAwLCAzNDAwLCAyNSwKKwkJICAgUks4MTdfTERP
X09OX1ZTRUxfUkVHKDApLCBSSzgxN19MRE9fVlNFTF9NQVNLLAorCQkgICBSSzgxN19QT1dFUl9F
Tl9SRUcoMSksIEVOQUJMRV9NQVNLKDApLCBFTkFCTEVfTUFTSygwKSwKKwkJICAgRElTQUJMRV9W
QUwoMCksIDQwMCksCisJUks4MTdfREVTQyhSSzgxN19JRF9MRE8yLCAiTERPX1JFRzIiLCAidmNj
NSIsIDYwMCwgMzQwMCwgMjUsCisJCSAgIFJLODE3X0xET19PTl9WU0VMX1JFRygxKSwgUks4MTdf
TERPX1ZTRUxfTUFTSywKKwkJICAgUks4MTdfUE9XRVJfRU5fUkVHKDEpLCBFTkFCTEVfTUFTSygx
KSwgRU5BQkxFX01BU0soMSksCisJCSAgIERJU0FCTEVfVkFMKDEpLCA0MDApLAorCVJLODE3X0RF
U0MoUks4MTdfSURfTERPMywgIkxET19SRUczIiwgInZjYzUiLCA2MDAsIDM0MDAsIDI1LAorCQkg
ICBSSzgxN19MRE9fT05fVlNFTF9SRUcoMiksIFJLODE3X0xET19WU0VMX01BU0ssCisJCSAgIFJL
ODE3X1BPV0VSX0VOX1JFRygxKSwgRU5BQkxFX01BU0soMiksIEVOQUJMRV9NQVNLKDIpLAorCQkg
ICBESVNBQkxFX1ZBTCgyKSwgNDAwKSwKKwlSSzgxN19ERVNDKFJLODE3X0lEX0xETzQsICJMRE9f
UkVHNCIsICJ2Y2M2IiwgNjAwLCAzNDAwLCAyNSwKKwkJICAgUks4MTdfTERPX09OX1ZTRUxfUkVH
KDMpLCBSSzgxN19MRE9fVlNFTF9NQVNLLAorCQkgICBSSzgxN19QT1dFUl9FTl9SRUcoMSksIEVO
QUJMRV9NQVNLKDMpLCBFTkFCTEVfTUFTSygzKSwKKwkJICAgRElTQUJMRV9WQUwoMyksIDQwMCks
CisJUks4MTdfREVTQyhSSzgxN19JRF9MRE81LCAiTERPX1JFRzUiLCAidmNjNiIsIDYwMCwgMzQw
MCwgMjUsCisJCSAgIFJLODE3X0xET19PTl9WU0VMX1JFRyg0KSwgUks4MTdfTERPX1ZTRUxfTUFT
SywKKwkJICAgUks4MTdfUE9XRVJfRU5fUkVHKDIpLCBFTkFCTEVfTUFTSygwKSwgRU5BQkxFX01B
U0soMCksCisJCSAgIERJU0FCTEVfVkFMKDApLCA0MDApLAorCVJLODE3X0RFU0MoUks4MTdfSURf
TERPNiwgIkxET19SRUc2IiwgInZjYzYiLCA2MDAsIDM0MDAsIDI1LAorCQkgICBSSzgxN19MRE9f
T05fVlNFTF9SRUcoNSksIFJLODE3X0xET19WU0VMX01BU0ssCisJCSAgIFJLODE3X1BPV0VSX0VO
X1JFRygyKSwgRU5BQkxFX01BU0soMSksIEVOQUJMRV9NQVNLKDEpLAorCQkgICBESVNBQkxFX1ZB
TCgxKSwgNDAwKSwKKwlSSzgxN19ERVNDKFJLODE3X0lEX0xETzcsICJMRE9fUkVHNyIsICJ2Y2M3
IiwgNjAwLCAzNDAwLCAyNSwKKwkJICAgUks4MTdfTERPX09OX1ZTRUxfUkVHKDYpLCBSSzgxN19M
RE9fVlNFTF9NQVNLLAorCQkgICBSSzgxN19QT1dFUl9FTl9SRUcoMiksIEVOQUJMRV9NQVNLKDIp
LCBFTkFCTEVfTUFTSygyKSwKKwkJICAgRElTQUJMRV9WQUwoMiksIDQwMCksCisJUks4MTdfREVT
QyhSSzgxN19JRF9MRE84LCAiTERPX1JFRzgiLCAidmNjNyIsIDYwMCwgMzQwMCwgMjUsCisJCSAg
IFJLODE3X0xET19PTl9WU0VMX1JFRyg3KSwgUks4MTdfTERPX1ZTRUxfTUFTSywKKwkJICAgUks4
MTdfUE9XRVJfRU5fUkVHKDIpLCBFTkFCTEVfTUFTSygzKSwgRU5BQkxFX01BU0soMyksCisJCSAg
IERJU0FCTEVfVkFMKDMpLCA0MDApLAorCVJLODE3X0RFU0MoUks4MTdfSURfTERPOSwgIkxET19S
RUc5IiwgInZjYzciLCA2MDAsIDM0MDAsIDI1LAorCQkgICBSSzgxN19MRE9fT05fVlNFTF9SRUco
OCksIFJLODE3X0xET19WU0VMX01BU0ssCisJCSAgIFJLODE3X1BPV0VSX0VOX1JFRygzKSwgRU5B
QkxFX01BU0soMCksIEVOQUJMRV9NQVNLKDApLAorCQkgICBESVNBQkxFX1ZBTCgwKSwgNDAwKSwK
KwlSSzgxN19CT09TVF9ERVNDKFJLODE3X0lEX0JPT1NULCAiQk9PU1QiLCAidmNjOCIsIDQ3MDAs
IDU0MDAsIDEwMCwKKwkJCSBSSzgxN19CT09TVF9PVEdfQ0ZHLCBSSzgxN19CT09TVF9WU0VMX01B
U0ssCisJCQkgUks4MTdfUE9XRVJfRU5fUkVHKDMpLCBFTkFCTEVfTUFTSygxKSwgRU5BQkxFX01B
U0soMSksCisJCSAgIERJU0FCTEVfVkFMKDEpLCA0MDAsIDM1MDAgLSA1NDAwKSwKKwlSSzgxN19E
RVNDX1NXSVRDSChSSzgxN19JRF9CT09TVF9PVEdfU1csICJPVEdfU1dJVENIIiwgInZjYzkiLAor
CQkJICBSSzgxN19QT1dFUl9FTl9SRUcoMyksIEVOQUJMRV9NQVNLKDIpLAorCQkJICBFTkFCTEVf
TUFTSygyKSwgRElTQUJMRV9WQUwoMikpLAorfTsKKwogc3RhdGljIGNvbnN0IHN0cnVjdCByZWd1
bGF0b3JfZGVzYyByazgxOF9yZWdbXSA9IHsKIAl7CiAJCS5uYW1lID0gIkRDRENfUkVHMSIsCkBA
IC03NTksNiArMTM4MSwxNCBAQCBzdGF0aWMgaW50IHJrODA4X3JlZ3VsYXRvcl9wcm9iZShzdHJ1
Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQogCQlyZWd1bGF0b3JzID0gcms4MDhfcmVnOwogCQlu
cmVndWxhdG9ycyA9IFJLODA4X05VTV9SRUdVTEFUT1JTOwogCQlicmVhazsKKwljYXNlIFJLODA5
X0lEOgorCQlyZWd1bGF0b3JzID0gcms4MDlfcmVnOworCQlucmVndWxhdG9ycyA9IFJLODA5X05V
TV9SRUdVTEFUT1JTOworCQlicmVhazsKKwljYXNlIFJLODE3X0lEOgorCQlyZWd1bGF0b3JzID0g
cms4MTdfcmVnOworCQlucmVndWxhdG9ycyA9IFJLODE3X05VTV9SRUdVTEFUT1JTOworCQlicmVh
azsKIAljYXNlIFJLODE4X0lEOgogCQlyZWd1bGF0b3JzID0gcms4MThfcmVnOwogCQlucmVndWxh
dG9ycyA9IFJLODE4X05VTV9SRUdVTEFUT1JTOwpAQCAtNzk3LDYgKzE0MjcsNyBAQCBzdGF0aWMg
aW50IHJrODA4X3JlZ3VsYXRvcl9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQog
bW9kdWxlX3BsYXRmb3JtX2RyaXZlcihyazgwOF9yZWd1bGF0b3JfZHJpdmVyKTsKIAogTU9EVUxF
X0RFU0NSSVBUSU9OKCJyZWd1bGF0b3IgZHJpdmVyIGZvciB0aGUgUks4MDgvUks4MTggc2VyaWVz
IFBNSUNzIik7CitNT0RVTEVfQVVUSE9SKCJUb255IHhpZSA8dG9ueS54aWVAcm9jay1jaGlwcy5j
b20+Iik7CiBNT0RVTEVfQVVUSE9SKCJDaHJpcyBaaG9uZyA8enl3QHJvY2stY2hpcHMuY29tPiIp
OwogTU9EVUxFX0FVVEhPUigiWmhhbmcgUWluZyA8emhhbmdxaW5nQHJvY2stY2hpcHMuY29tPiIp
OwogTU9EVUxFX0FVVEhPUigiV2FkaW0gRWdvcm92IDx3LmVnb3JvdkBwaHl0ZWMuZGU+Iik7CmRp
ZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4L21mZC9yazgwOC5oIGIvaW5jbHVkZS9saW51eC9tZmQv
cms4MDguaAppbmRleCBiOTczYjBhLi5iNGNlMjM3MyAxMDA2NDQKLS0tIGEvaW5jbHVkZS9saW51
eC9tZmQvcms4MDguaAorKysgYi9pbmNsdWRlL2xpbnV4L21mZC9yazgwOC5oCkBAIC0zOTYsNyAr
Mzk2LDEwIEBAIGVudW0gcms4MDVfcmVnIHsKICNkZWZpbmUgU0hVVERPV05fRlVOCQkJKDB4MiA8
PCAyKQogI2RlZmluZSBTTEVFUF9GVU4JCQkoMHgxIDw8IDIpCiAjZGVmaW5lIFJLOFhYX0lEX01T
SwkJCTB4ZmZmMAorI2RlZmluZSBQV01fTU9ERV9NU0sJCQlCSVQoNykKICNkZWZpbmUgRlBXTV9N
T0RFCQkJQklUKDcpCisjZGVmaW5lIEFVVE9fUFdNX01PREUJCQkwCisKIGVudW0gcms4MTdfcmVn
X2lkIHsKIAlSSzgxN19JRF9EQ0RDMSA9IDAsCiAJUks4MTdfSURfRENEQzIsCi0tIAoxLjkuMQoK
CgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1h
cm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5v
cmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0t
a2VybmVsCg==

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

* [PATCH 2/5] regulator: rk808: Add regulator driver for RK809 and RK817.
@ 2018-07-23  3:19   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: linux-rtc, a.zummo, alexandre.belloni, tony.xie, huangtao,
	devicetree, sboyd, zhangqing, linux-kernel, xsf, linux-rockchip,
	broonie, lee.jones, linux-clk, linux-arm-kernel, chenjh

    Add support for the rk809 and rk817 regulator driver.
    Their specifications are as follows:
    1、The RK809 and RK809 consist of 5 DCDCs, 9 LDOs
       and have the same registers for these components except dcdc5.
    2、The dcdc5 is a boost dcdc for RK817 and is a buck for RK809.
    3、The RK817 has one switch but The Rk809 has two.

    The output voltages are configurable and are meant to supply power
    to the main processor and other components.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/regulator/Kconfig           |   4 +-
 drivers/regulator/rk808-regulator.c | 633 +++++++++++++++++++++++++++++++++++-
 include/linux/mfd/rk808.h           |   3 +
 3 files changed, 637 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 5dbccf5..27ff89f 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -716,11 +716,11 @@ config REGULATOR_RC5T583
 	  outputs which can be controlled by i2c communication.
 
 config REGULATOR_RK808
-	tristate "Rockchip RK805/RK808/RK818 Power regulators"
+	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators"
 	depends on MFD_RK808
 	help
 	  Select this option to enable the power regulator of ROCKCHIP
-	  PMIC RK805,RK808 and RK818.
+	  PMIC RK805,RK809&RK817,RK808 and RK818.
 	  This driver supports the control of different power rails of device
 	  through regulator interface. The device supports multiple DCDC/LDO
 	  outputs which can be controlled by i2c communication.
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index 213b687..9edce22 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -36,6 +36,12 @@
 #define RK808_BUCK4_VSEL_MASK	0xf
 #define RK808_LDO_VSEL_MASK	0x1f
 
+#define RK809_BUCK5_VSEL_MASK		0x7
+
+#define RK817_LDO_VSEL_MASK		0x7f
+#define RK817_BOOST_VSEL_MASK		0x7
+#define RK817_BUCK_VSEL_MASK		0x7f
+
 #define RK818_BUCK_VSEL_MASK		0x3f
 #define RK818_BUCK4_VSEL_MASK		0x1f
 #define RK818_LDO_VSEL_MASK		0x1f
@@ -65,6 +71,9 @@
 /* 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 RK805_DESC(_id, _match, _supply, _min, _max, _step, _vreg,      \
 	_vmask, _ereg, _emask, _etime)                                  \
 	[_id] = {                                                       \
@@ -86,6 +95,70 @@
 		.ops            = &rk805_reg_ops,                       \
 	}
 
+#define RK817_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\
+	_vmask, _ereg, _emask, _enval, _disval, _etime)		\
+	{							\
+		.name		= (_match),				\
+		.supply_name	= (_supply),				\
+		.of_match	= of_match_ptr(_match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.type		= REGULATOR_VOLTAGE,			\
+		.id		= (_id),				\
+		.n_voltages	= (((_max) - (_min)) / (_step) + 1),	\
+		.owner		= THIS_MODULE,				\
+		.min_uV		= (_min) * 1000,			\
+		.uV_step	= (_step) * 1000,			\
+		.vsel_reg	= (_vreg),				\
+		.vsel_mask	= (_vmask),				\
+		.enable_reg	= (_ereg),				\
+		.enable_mask	= (_emask),				\
+		.enable_val     = (_enval),				\
+		.disable_val     = (_disval),				\
+		.enable_time	= (_etime),				\
+		.ops		= &rk817_reg_ops,			\
+	}
+
+#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"),		\
+		.type		= REGULATOR_VOLTAGE,			\
+		.id		= (_id),				\
+		.n_voltages	= (((_max) - (_min)) / (_step) + 1),	\
+		.owner		= THIS_MODULE,				\
+		.min_uV		= (_min) * 1000,			\
+		.uV_step	= (_step) * 1000,			\
+		.vsel_reg	= (_vreg),				\
+		.vsel_mask	= (_vmask),				\
+		.enable_reg	= (_ereg),				\
+		.enable_mask	= (_emask),				\
+		.enable_val     = (_enval),				\
+		.disable_val     = (_disval),				\
+		.enable_time	= (_etime),				\
+		.min_dropout_uV = (m_drop) * 1000,			\
+		.ops		= &rk817_boost_ops,			\
+	}
+
+#define RK817_DESC_SWITCH(_id, _match, _supply, _ereg, _emask,\
+	_enval, _disval)		\
+	{							\
+		.name		= (_match),				\
+		.supply_name	= (_supply),				\
+		.of_match	= of_match_ptr(_match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.type		= REGULATOR_VOLTAGE,			\
+		.id		= (_id),				\
+		.enable_reg	= (_ereg),				\
+		.enable_mask	= (_emask),				\
+		.enable_val     = (_enval),				\
+		.disable_val     = (_disval),				\
+		.owner		= THIS_MODULE,				\
+		.ops		= &rk817_switch_ops			\
+	}
+
 #define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, _etime)					\
 	[_id] = {							\
@@ -121,7 +194,6 @@
 		.ops		= &rk808_switch_ops			\
 	}
 
-
 struct rk808_regulator_data {
 	struct gpio_desc *dvs_gpio[2];
 };
@@ -138,6 +210,51 @@ struct rk808_regulator_data {
 	REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0),
 };
 
+#define RK809_BUCK5_SEL_CNT		(8)
+
+static const struct regulator_linear_range rk809_buck5_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1500000, 0, 0, 0),
+	REGULATOR_LINEAR_RANGE(1800000, 1, 3, 200000),
+	REGULATOR_LINEAR_RANGE(2800000, 4, 5, 200000),
+	REGULATOR_LINEAR_RANGE(3300000, 6, 7, 300000),
+};
+
+#define RK817_BUCK1_MIN0 500000
+#define RK817_BUCK1_MAX0 1500000
+
+#define RK817_BUCK1_MIN1 1600000
+#define RK817_BUCK1_MAX1 2400000
+
+#define RK817_BUCK3_MAX1 3400000
+
+#define RK817_BUCK1_STP0 12500
+#define RK817_BUCK1_STP1 100000
+
+#define RK817_BUCK1_SEL0 ((RK817_BUCK1_MAX0 - RK817_BUCK1_MIN0) /\
+						  RK817_BUCK1_STP0)
+#define RK817_BUCK1_SEL1 ((RK817_BUCK1_MAX1 - RK817_BUCK1_MIN1) /\
+						  RK817_BUCK1_STP1)
+
+#define RK817_BUCK3_SEL1 ((RK817_BUCK3_MAX1 - RK817_BUCK1_MIN1) /\
+						  RK817_BUCK1_STP1)
+
+#define RK817_BUCK1_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK1_SEL1 + 1)
+#define RK817_BUCK3_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK3_SEL1 + 1)
+
+static const struct regulator_linear_range rk817_buck1_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN0, 0,
+			       RK817_BUCK1_SEL0, RK817_BUCK1_STP0),
+	REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1,
+			       RK817_BUCK1_SEL_CNT, RK817_BUCK1_STP1),
+};
+
+static const struct regulator_linear_range rk817_buck3_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN0, 0,
+			       RK817_BUCK1_SEL0, RK817_BUCK1_STP0),
+	REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1,
+			       RK817_BUCK3_SEL_CNT, RK817_BUCK1_STP1),
+};
+
 static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
 {
 	struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
@@ -289,6 +406,35 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
 				  RK808_RAMP_RATE_MASK, ramp_value);
 }
 
+/*
+ * RK817 RK809
+ */
+static int rk817_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
+{
+	unsigned int ramp_value = RK817_RAMP_RATE_25MV_PER_US;
+	unsigned int reg = RK817_BUCK_CONFIG_REG(rdev_get_id(rdev));
+
+	switch (ramp_delay) {
+	case 0 ... 3000:
+		ramp_value = RK817_RAMP_RATE_3MV_PER_US;
+		break;
+	case 3001 ... 6300:
+		ramp_value = RK817_RAMP_RATE_6_3MV_PER_US;
+		break;
+	case 6301 ... 12500:
+		ramp_value = RK817_RAMP_RATE_12_5MV_PER_US;
+		break;
+	case 12501 ... 25000:
+		break;
+	default:
+		pr_warn("%s ramp_delay: %d not supported, setting 10000\n",
+			rdev->desc->name, ramp_delay);
+	}
+
+	return regmap_update_bits(rdev->regmap, reg,
+				  RK817_RAMP_RATE_MASK, ramp_value);
+}
+
 static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
 {
 	unsigned int reg;
@@ -304,6 +450,29 @@ static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
 				  sel);
 }
 
+static int rk817_check_suspend_voltage(int id)
+{
+	if (id >= RK817_ID_DCDC1 && id <= RK817_ID_LDO9)
+		return 0;
+	return -1;
+}
+
+static int rk817_set_suspend_voltage(struct regulator_dev *rdev, int uv)
+{
+	unsigned int reg;
+	int id = rdev_get_id(rdev);
+	int sel = regulator_map_voltage_linear(rdev, uv, uv);
+	/* only ldo1~ldo9 */
+	if (sel < 0 || rk817_check_suspend_voltage(id))
+		return -EINVAL;
+
+	reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET;
+
+	return regmap_update_bits(rdev->regmap, reg,
+				  rdev->desc->vsel_mask,
+				  sel);
+}
+
 static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
 {
 	unsigned int reg;
@@ -363,6 +532,129 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
 				  rdev->desc->enable_mask);
 }
 
+static int rk817_set_suspend_enable_ctrl(struct regulator_dev *rdev,
+					 unsigned int en)
+{
+	unsigned int reg;
+	int id = rdev_get_id(rdev);
+	unsigned int id_slp, msk, val;
+
+	if (id >= RK817_ID_DCDC1 && id <= RK817_ID_DCDC4)
+		id_slp = id;
+	else if (id >= RK817_ID_LDO1 && id <= RK817_ID_LDO8)
+		id_slp = 8 + (id - RK817_ID_LDO1);
+	else if (id >= RK817_ID_LDO9 && id <= RK809_ID_SW2)
+		id_slp = 4 + (id - RK817_ID_LDO9);
+	else
+		return -EINVAL;
+
+	reg = RK817_POWER_SLP_EN_REG(id_slp / 8);
+
+	msk = BIT(id_slp % 8);
+	if (en)
+		val = msk;
+	else
+		val = 0;
+
+	return regmap_update_bits(rdev->regmap, reg, msk, val);
+}
+
+static int rk817_set_suspend_enable(struct regulator_dev *rdev)
+{
+	return rk817_set_suspend_enable_ctrl(rdev, 1);
+}
+
+static int rk817_set_suspend_disable(struct regulator_dev *rdev)
+{
+	return rk817_set_suspend_enable_ctrl(rdev, 0);
+}
+
+static int rk8xx_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	unsigned int reg;
+
+	reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET;
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		return regmap_update_bits(rdev->regmap, reg,
+					  PWM_MODE_MSK, FPWM_MODE);
+	case REGULATOR_MODE_NORMAL:
+		return regmap_update_bits(rdev->regmap, reg,
+					  PWM_MODE_MSK, AUTO_PWM_MODE);
+	default:
+		pr_err("do not support this mode\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rk8xx_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
+					  PWM_MODE_MSK, FPWM_MODE);
+	case REGULATOR_MODE_NORMAL:
+		return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
+					  PWM_MODE_MSK, AUTO_PWM_MODE);
+	default:
+		pr_err("do not support this mode\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned int rk8xx_get_mode(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	int err;
+
+	err = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
+	if (err)
+		return err;
+
+	if (val & FPWM_MODE)
+		return REGULATOR_MODE_FAST;
+	else
+		return REGULATOR_MODE_NORMAL;
+}
+
+static int rk8xx_is_enabled_wmsk_regmap(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
+	if (ret != 0)
+		return ret;
+
+	/* add write mask bit */
+	val |= (rdev->desc->enable_mask & 0xf0);
+	val &= rdev->desc->enable_mask;
+
+	if (rdev->desc->enable_is_inverted) {
+		if (rdev->desc->enable_val)
+			return val != rdev->desc->enable_val;
+		return (val == 0);
+	}
+	if (rdev->desc->enable_val)
+		return val == rdev->desc->enable_val;
+	return val != 0;
+}
+
+static unsigned int rk8xx_regulator_of_map_mode(unsigned int mode)
+{
+	if (mode == 1)
+		return REGULATOR_MODE_FAST;
+	if (mode == 2)
+		return REGULATOR_MODE_NORMAL;
+
+	return -EINVAL;
+}
+
 static struct regulator_ops rk805_reg_ops = {
 		.list_voltage           = regulator_list_voltage_linear,
 		.map_voltage            = regulator_map_voltage_linear,
@@ -433,6 +725,71 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
 	.set_suspend_disable	= rk808_set_suspend_disable,
 };
 
+static struct regulator_ops rk809_buck5_ops_range = {
+	.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,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= rk8xx_is_enabled_wmsk_regmap,
+	.set_suspend_voltage	= rk808_set_suspend_voltage_range,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
+static struct regulator_ops rk817_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,
+	.set_suspend_voltage	= rk817_set_suspend_voltage,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
+static struct regulator_ops rk817_boost_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,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
+static struct regulator_ops rk817_buck_ops_range = {
+	.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,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= rk8xx_is_enabled_wmsk_regmap,
+	.set_mode		= rk8xx_set_mode,
+	.get_mode		= rk8xx_get_mode,
+	.set_suspend_mode	= rk8xx_set_suspend_mode,
+	.set_ramp_delay		= rk817_set_ramp_delay,
+	.set_suspend_voltage	= rk808_set_suspend_voltage_range,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
+static struct regulator_ops rk817_switch_ops = {
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
 static const struct regulator_desc rk805_reg[] = {
 	{
 		.name = "DCDC_REG1",
@@ -589,6 +946,271 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
 		RK808_DCDC_EN_REG, BIT(6)),
 };
 
+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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK1_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC1),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC1),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC1),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK2_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC2),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC2),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC2),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK3_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC3),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC3),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK3_SEL_CNT + 1,
+		.linear_ranges = rk817_buck3_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck3_voltage_ranges),
+		.vsel_reg = RK817_BUCK4_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC4),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC4),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC4),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	},
+	{
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.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),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	},
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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), ENABLE_MASK(1),
+		   DISABLE_VAL(1), 400),
+	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), ENABLE_MASK(2),
+		   DISABLE_VAL(2), 400),
+	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), ENABLE_MASK(3),
+		   DISABLE_VAL(3), 400),
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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), ENABLE_MASK(1),
+		   DISABLE_VAL(1), 400),
+	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), ENABLE_MASK(2),
+		   DISABLE_VAL(2), 400),
+	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), ENABLE_MASK(3),
+		   DISABLE_VAL(3), 400),
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	RK817_DESC_SWITCH(RK809_ID_SW1, "SWITCH_REG1", "vcc8",
+			  RK817_POWER_EN_REG(3), ENABLE_MASK(3),
+			  ENABLE_MASK(3), DISABLE_VAL(3)),
+	RK817_DESC_SWITCH(RK809_ID_SW2, "SWITCH_REG2", "vcc9",
+			  RK817_POWER_EN_REG(3), ENABLE_MASK(2),
+			  ENABLE_MASK(2), DISABLE_VAL(2)),
+};
+
+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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK1_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC1),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC1),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC1),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK2_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC2),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC2),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC2),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK3_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC3),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC3),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK3_SEL_CNT + 1,
+		.linear_ranges = rk817_buck3_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck3_voltage_ranges),
+		.vsel_reg = RK817_BUCK4_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC4),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC4),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC4),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	},
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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), ENABLE_MASK(1),
+		   DISABLE_VAL(1), 400),
+	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), ENABLE_MASK(2),
+		   DISABLE_VAL(2), 400),
+	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), ENABLE_MASK(3),
+		   DISABLE_VAL(3), 400),
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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), ENABLE_MASK(1),
+		   DISABLE_VAL(1), 400),
+	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), ENABLE_MASK(2),
+		   DISABLE_VAL(2), 400),
+	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), ENABLE_MASK(3),
+		   DISABLE_VAL(3), 400),
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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, 3500 - 5400),
+	RK817_DESC_SWITCH(RK817_ID_BOOST_OTG_SW, "OTG_SWITCH", "vcc9",
+			  RK817_POWER_EN_REG(3), ENABLE_MASK(2),
+			  ENABLE_MASK(2), DISABLE_VAL(2)),
+};
+
 static const struct regulator_desc rk818_reg[] = {
 	{
 		.name = "DCDC_REG1",
@@ -759,6 +1381,14 @@ static int rk808_regulator_probe(struct platform_device *pdev)
 		regulators = rk808_reg;
 		nregulators = RK808_NUM_REGULATORS;
 		break;
+	case RK809_ID:
+		regulators = rk809_reg;
+		nregulators = RK809_NUM_REGULATORS;
+		break;
+	case RK817_ID:
+		regulators = rk817_reg;
+		nregulators = RK817_NUM_REGULATORS;
+		break;
 	case RK818_ID:
 		regulators = rk818_reg;
 		nregulators = RK818_NUM_REGULATORS;
@@ -797,6 +1427,7 @@ static int rk808_regulator_probe(struct platform_device *pdev)
 module_platform_driver(rk808_regulator_driver);
 
 MODULE_DESCRIPTION("regulator driver for the RK808/RK818 series PMICs");
+MODULE_AUTHOR("Tony xie <tony.xie@rock-chips.com>");
 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index b973b0a..b4ce2373 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -396,7 +396,10 @@ enum rk805_reg {
 #define SHUTDOWN_FUN			(0x2 << 2)
 #define SLEEP_FUN			(0x1 << 2)
 #define RK8XX_ID_MSK			0xfff0
+#define PWM_MODE_MSK			BIT(7)
 #define FPWM_MODE			BIT(7)
+#define AUTO_PWM_MODE			0
+
 enum rk817_reg_id {
 	RK817_ID_DCDC1 = 0,
 	RK817_ID_DCDC2,
-- 
1.9.1



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/5] regulator: rk808: Add regulator driver for RK809 and RK817.
@ 2018-07-23  3:19   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: broonie, lee.jones, a.zummo, alexandre.belloni, sboyd, linux-clk,
	linux-rtc, linux-arm-kernel, linux-rockchip, devicetree,
	linux-kernel, chenjh, xsf, zhangqing, huangtao, tony.xie

    Add support for the rk809 and rk817 regulator driver.
    Their specifications are as follows:
    1、The RK809 and RK809 consist of 5 DCDCs, 9 LDOs
       and have the same registers for these components except dcdc5.
    2、The dcdc5 is a boost dcdc for RK817 and is a buck for RK809.
    3、The RK817 has one switch but The Rk809 has two.

    The output voltages are configurable and are meant to supply power
    to the main processor and other components.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/regulator/Kconfig           |   4 +-
 drivers/regulator/rk808-regulator.c | 633 +++++++++++++++++++++++++++++++++++-
 include/linux/mfd/rk808.h           |   3 +
 3 files changed, 637 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 5dbccf5..27ff89f 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -716,11 +716,11 @@ config REGULATOR_RC5T583
 	  outputs which can be controlled by i2c communication.
 
 config REGULATOR_RK808
-	tristate "Rockchip RK805/RK808/RK818 Power regulators"
+	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators"
 	depends on MFD_RK808
 	help
 	  Select this option to enable the power regulator of ROCKCHIP
-	  PMIC RK805,RK808 and RK818.
+	  PMIC RK805,RK809&RK817,RK808 and RK818.
 	  This driver supports the control of different power rails of device
 	  through regulator interface. The device supports multiple DCDC/LDO
 	  outputs which can be controlled by i2c communication.
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index 213b687..9edce22 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -36,6 +36,12 @@
 #define RK808_BUCK4_VSEL_MASK	0xf
 #define RK808_LDO_VSEL_MASK	0x1f
 
+#define RK809_BUCK5_VSEL_MASK		0x7
+
+#define RK817_LDO_VSEL_MASK		0x7f
+#define RK817_BOOST_VSEL_MASK		0x7
+#define RK817_BUCK_VSEL_MASK		0x7f
+
 #define RK818_BUCK_VSEL_MASK		0x3f
 #define RK818_BUCK4_VSEL_MASK		0x1f
 #define RK818_LDO_VSEL_MASK		0x1f
@@ -65,6 +71,9 @@
 /* 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 RK805_DESC(_id, _match, _supply, _min, _max, _step, _vreg,      \
 	_vmask, _ereg, _emask, _etime)                                  \
 	[_id] = {                                                       \
@@ -86,6 +95,70 @@
 		.ops            = &rk805_reg_ops,                       \
 	}
 
+#define RK817_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\
+	_vmask, _ereg, _emask, _enval, _disval, _etime)		\
+	{							\
+		.name		= (_match),				\
+		.supply_name	= (_supply),				\
+		.of_match	= of_match_ptr(_match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.type		= REGULATOR_VOLTAGE,			\
+		.id		= (_id),				\
+		.n_voltages	= (((_max) - (_min)) / (_step) + 1),	\
+		.owner		= THIS_MODULE,				\
+		.min_uV		= (_min) * 1000,			\
+		.uV_step	= (_step) * 1000,			\
+		.vsel_reg	= (_vreg),				\
+		.vsel_mask	= (_vmask),				\
+		.enable_reg	= (_ereg),				\
+		.enable_mask	= (_emask),				\
+		.enable_val     = (_enval),				\
+		.disable_val     = (_disval),				\
+		.enable_time	= (_etime),				\
+		.ops		= &rk817_reg_ops,			\
+	}
+
+#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"),		\
+		.type		= REGULATOR_VOLTAGE,			\
+		.id		= (_id),				\
+		.n_voltages	= (((_max) - (_min)) / (_step) + 1),	\
+		.owner		= THIS_MODULE,				\
+		.min_uV		= (_min) * 1000,			\
+		.uV_step	= (_step) * 1000,			\
+		.vsel_reg	= (_vreg),				\
+		.vsel_mask	= (_vmask),				\
+		.enable_reg	= (_ereg),				\
+		.enable_mask	= (_emask),				\
+		.enable_val     = (_enval),				\
+		.disable_val     = (_disval),				\
+		.enable_time	= (_etime),				\
+		.min_dropout_uV = (m_drop) * 1000,			\
+		.ops		= &rk817_boost_ops,			\
+	}
+
+#define RK817_DESC_SWITCH(_id, _match, _supply, _ereg, _emask,\
+	_enval, _disval)		\
+	{							\
+		.name		= (_match),				\
+		.supply_name	= (_supply),				\
+		.of_match	= of_match_ptr(_match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.type		= REGULATOR_VOLTAGE,			\
+		.id		= (_id),				\
+		.enable_reg	= (_ereg),				\
+		.enable_mask	= (_emask),				\
+		.enable_val     = (_enval),				\
+		.disable_val     = (_disval),				\
+		.owner		= THIS_MODULE,				\
+		.ops		= &rk817_switch_ops			\
+	}
+
 #define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, _etime)					\
 	[_id] = {							\
@@ -121,7 +194,6 @@
 		.ops		= &rk808_switch_ops			\
 	}
 
-
 struct rk808_regulator_data {
 	struct gpio_desc *dvs_gpio[2];
 };
@@ -138,6 +210,51 @@ struct rk808_regulator_data {
 	REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0),
 };
 
+#define RK809_BUCK5_SEL_CNT		(8)
+
+static const struct regulator_linear_range rk809_buck5_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1500000, 0, 0, 0),
+	REGULATOR_LINEAR_RANGE(1800000, 1, 3, 200000),
+	REGULATOR_LINEAR_RANGE(2800000, 4, 5, 200000),
+	REGULATOR_LINEAR_RANGE(3300000, 6, 7, 300000),
+};
+
+#define RK817_BUCK1_MIN0 500000
+#define RK817_BUCK1_MAX0 1500000
+
+#define RK817_BUCK1_MIN1 1600000
+#define RK817_BUCK1_MAX1 2400000
+
+#define RK817_BUCK3_MAX1 3400000
+
+#define RK817_BUCK1_STP0 12500
+#define RK817_BUCK1_STP1 100000
+
+#define RK817_BUCK1_SEL0 ((RK817_BUCK1_MAX0 - RK817_BUCK1_MIN0) /\
+						  RK817_BUCK1_STP0)
+#define RK817_BUCK1_SEL1 ((RK817_BUCK1_MAX1 - RK817_BUCK1_MIN1) /\
+						  RK817_BUCK1_STP1)
+
+#define RK817_BUCK3_SEL1 ((RK817_BUCK3_MAX1 - RK817_BUCK1_MIN1) /\
+						  RK817_BUCK1_STP1)
+
+#define RK817_BUCK1_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK1_SEL1 + 1)
+#define RK817_BUCK3_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK3_SEL1 + 1)
+
+static const struct regulator_linear_range rk817_buck1_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN0, 0,
+			       RK817_BUCK1_SEL0, RK817_BUCK1_STP0),
+	REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1,
+			       RK817_BUCK1_SEL_CNT, RK817_BUCK1_STP1),
+};
+
+static const struct regulator_linear_range rk817_buck3_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN0, 0,
+			       RK817_BUCK1_SEL0, RK817_BUCK1_STP0),
+	REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1,
+			       RK817_BUCK3_SEL_CNT, RK817_BUCK1_STP1),
+};
+
 static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
 {
 	struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
@@ -289,6 +406,35 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
 				  RK808_RAMP_RATE_MASK, ramp_value);
 }
 
+/*
+ * RK817 RK809
+ */
+static int rk817_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
+{
+	unsigned int ramp_value = RK817_RAMP_RATE_25MV_PER_US;
+	unsigned int reg = RK817_BUCK_CONFIG_REG(rdev_get_id(rdev));
+
+	switch (ramp_delay) {
+	case 0 ... 3000:
+		ramp_value = RK817_RAMP_RATE_3MV_PER_US;
+		break;
+	case 3001 ... 6300:
+		ramp_value = RK817_RAMP_RATE_6_3MV_PER_US;
+		break;
+	case 6301 ... 12500:
+		ramp_value = RK817_RAMP_RATE_12_5MV_PER_US;
+		break;
+	case 12501 ... 25000:
+		break;
+	default:
+		pr_warn("%s ramp_delay: %d not supported, setting 10000\n",
+			rdev->desc->name, ramp_delay);
+	}
+
+	return regmap_update_bits(rdev->regmap, reg,
+				  RK817_RAMP_RATE_MASK, ramp_value);
+}
+
 static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
 {
 	unsigned int reg;
@@ -304,6 +450,29 @@ static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
 				  sel);
 }
 
+static int rk817_check_suspend_voltage(int id)
+{
+	if (id >= RK817_ID_DCDC1 && id <= RK817_ID_LDO9)
+		return 0;
+	return -1;
+}
+
+static int rk817_set_suspend_voltage(struct regulator_dev *rdev, int uv)
+{
+	unsigned int reg;
+	int id = rdev_get_id(rdev);
+	int sel = regulator_map_voltage_linear(rdev, uv, uv);
+	/* only ldo1~ldo9 */
+	if (sel < 0 || rk817_check_suspend_voltage(id))
+		return -EINVAL;
+
+	reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET;
+
+	return regmap_update_bits(rdev->regmap, reg,
+				  rdev->desc->vsel_mask,
+				  sel);
+}
+
 static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
 {
 	unsigned int reg;
@@ -363,6 +532,129 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
 				  rdev->desc->enable_mask);
 }
 
+static int rk817_set_suspend_enable_ctrl(struct regulator_dev *rdev,
+					 unsigned int en)
+{
+	unsigned int reg;
+	int id = rdev_get_id(rdev);
+	unsigned int id_slp, msk, val;
+
+	if (id >= RK817_ID_DCDC1 && id <= RK817_ID_DCDC4)
+		id_slp = id;
+	else if (id >= RK817_ID_LDO1 && id <= RK817_ID_LDO8)
+		id_slp = 8 + (id - RK817_ID_LDO1);
+	else if (id >= RK817_ID_LDO9 && id <= RK809_ID_SW2)
+		id_slp = 4 + (id - RK817_ID_LDO9);
+	else
+		return -EINVAL;
+
+	reg = RK817_POWER_SLP_EN_REG(id_slp / 8);
+
+	msk = BIT(id_slp % 8);
+	if (en)
+		val = msk;
+	else
+		val = 0;
+
+	return regmap_update_bits(rdev->regmap, reg, msk, val);
+}
+
+static int rk817_set_suspend_enable(struct regulator_dev *rdev)
+{
+	return rk817_set_suspend_enable_ctrl(rdev, 1);
+}
+
+static int rk817_set_suspend_disable(struct regulator_dev *rdev)
+{
+	return rk817_set_suspend_enable_ctrl(rdev, 0);
+}
+
+static int rk8xx_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	unsigned int reg;
+
+	reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET;
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		return regmap_update_bits(rdev->regmap, reg,
+					  PWM_MODE_MSK, FPWM_MODE);
+	case REGULATOR_MODE_NORMAL:
+		return regmap_update_bits(rdev->regmap, reg,
+					  PWM_MODE_MSK, AUTO_PWM_MODE);
+	default:
+		pr_err("do not support this mode\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rk8xx_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
+					  PWM_MODE_MSK, FPWM_MODE);
+	case REGULATOR_MODE_NORMAL:
+		return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
+					  PWM_MODE_MSK, AUTO_PWM_MODE);
+	default:
+		pr_err("do not support this mode\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned int rk8xx_get_mode(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	int err;
+
+	err = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
+	if (err)
+		return err;
+
+	if (val & FPWM_MODE)
+		return REGULATOR_MODE_FAST;
+	else
+		return REGULATOR_MODE_NORMAL;
+}
+
+static int rk8xx_is_enabled_wmsk_regmap(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
+	if (ret != 0)
+		return ret;
+
+	/* add write mask bit */
+	val |= (rdev->desc->enable_mask & 0xf0);
+	val &= rdev->desc->enable_mask;
+
+	if (rdev->desc->enable_is_inverted) {
+		if (rdev->desc->enable_val)
+			return val != rdev->desc->enable_val;
+		return (val == 0);
+	}
+	if (rdev->desc->enable_val)
+		return val == rdev->desc->enable_val;
+	return val != 0;
+}
+
+static unsigned int rk8xx_regulator_of_map_mode(unsigned int mode)
+{
+	if (mode == 1)
+		return REGULATOR_MODE_FAST;
+	if (mode == 2)
+		return REGULATOR_MODE_NORMAL;
+
+	return -EINVAL;
+}
+
 static struct regulator_ops rk805_reg_ops = {
 		.list_voltage           = regulator_list_voltage_linear,
 		.map_voltage            = regulator_map_voltage_linear,
@@ -433,6 +725,71 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
 	.set_suspend_disable	= rk808_set_suspend_disable,
 };
 
+static struct regulator_ops rk809_buck5_ops_range = {
+	.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,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= rk8xx_is_enabled_wmsk_regmap,
+	.set_suspend_voltage	= rk808_set_suspend_voltage_range,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
+static struct regulator_ops rk817_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,
+	.set_suspend_voltage	= rk817_set_suspend_voltage,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
+static struct regulator_ops rk817_boost_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,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
+static struct regulator_ops rk817_buck_ops_range = {
+	.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,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= rk8xx_is_enabled_wmsk_regmap,
+	.set_mode		= rk8xx_set_mode,
+	.get_mode		= rk8xx_get_mode,
+	.set_suspend_mode	= rk8xx_set_suspend_mode,
+	.set_ramp_delay		= rk817_set_ramp_delay,
+	.set_suspend_voltage	= rk808_set_suspend_voltage_range,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
+static struct regulator_ops rk817_switch_ops = {
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
 static const struct regulator_desc rk805_reg[] = {
 	{
 		.name = "DCDC_REG1",
@@ -589,6 +946,271 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
 		RK808_DCDC_EN_REG, BIT(6)),
 };
 
+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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK1_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC1),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC1),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC1),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK2_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC2),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC2),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC2),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK3_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC3),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC3),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK3_SEL_CNT + 1,
+		.linear_ranges = rk817_buck3_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck3_voltage_ranges),
+		.vsel_reg = RK817_BUCK4_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC4),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC4),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC4),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	},
+	{
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.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),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	},
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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), ENABLE_MASK(1),
+		   DISABLE_VAL(1), 400),
+	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), ENABLE_MASK(2),
+		   DISABLE_VAL(2), 400),
+	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), ENABLE_MASK(3),
+		   DISABLE_VAL(3), 400),
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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), ENABLE_MASK(1),
+		   DISABLE_VAL(1), 400),
+	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), ENABLE_MASK(2),
+		   DISABLE_VAL(2), 400),
+	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), ENABLE_MASK(3),
+		   DISABLE_VAL(3), 400),
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	RK817_DESC_SWITCH(RK809_ID_SW1, "SWITCH_REG1", "vcc8",
+			  RK817_POWER_EN_REG(3), ENABLE_MASK(3),
+			  ENABLE_MASK(3), DISABLE_VAL(3)),
+	RK817_DESC_SWITCH(RK809_ID_SW2, "SWITCH_REG2", "vcc9",
+			  RK817_POWER_EN_REG(3), ENABLE_MASK(2),
+			  ENABLE_MASK(2), DISABLE_VAL(2)),
+};
+
+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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK1_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC1),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC1),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC1),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK2_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC2),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC2),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC2),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK3_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC3),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC3),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK3_SEL_CNT + 1,
+		.linear_ranges = rk817_buck3_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck3_voltage_ranges),
+		.vsel_reg = RK817_BUCK4_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC4),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC4),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC4),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	},
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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), ENABLE_MASK(1),
+		   DISABLE_VAL(1), 400),
+	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), ENABLE_MASK(2),
+		   DISABLE_VAL(2), 400),
+	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), ENABLE_MASK(3),
+		   DISABLE_VAL(3), 400),
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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), ENABLE_MASK(1),
+		   DISABLE_VAL(1), 400),
+	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), ENABLE_MASK(2),
+		   DISABLE_VAL(2), 400),
+	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), ENABLE_MASK(3),
+		   DISABLE_VAL(3), 400),
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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, 3500 - 5400),
+	RK817_DESC_SWITCH(RK817_ID_BOOST_OTG_SW, "OTG_SWITCH", "vcc9",
+			  RK817_POWER_EN_REG(3), ENABLE_MASK(2),
+			  ENABLE_MASK(2), DISABLE_VAL(2)),
+};
+
 static const struct regulator_desc rk818_reg[] = {
 	{
 		.name = "DCDC_REG1",
@@ -759,6 +1381,14 @@ static int rk808_regulator_probe(struct platform_device *pdev)
 		regulators = rk808_reg;
 		nregulators = RK808_NUM_REGULATORS;
 		break;
+	case RK809_ID:
+		regulators = rk809_reg;
+		nregulators = RK809_NUM_REGULATORS;
+		break;
+	case RK817_ID:
+		regulators = rk817_reg;
+		nregulators = RK817_NUM_REGULATORS;
+		break;
 	case RK818_ID:
 		regulators = rk818_reg;
 		nregulators = RK818_NUM_REGULATORS;
@@ -797,6 +1427,7 @@ static int rk808_regulator_probe(struct platform_device *pdev)
 module_platform_driver(rk808_regulator_driver);
 
 MODULE_DESCRIPTION("regulator driver for the RK808/RK818 series PMICs");
+MODULE_AUTHOR("Tony xie <tony.xie@rock-chips.com>");
 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index b973b0a..b4ce2373 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -396,7 +396,10 @@ enum rk805_reg {
 #define SHUTDOWN_FUN			(0x2 << 2)
 #define SLEEP_FUN			(0x1 << 2)
 #define RK8XX_ID_MSK			0xfff0
+#define PWM_MODE_MSK			BIT(7)
 #define FPWM_MODE			BIT(7)
+#define AUTO_PWM_MODE			0
+
 enum rk817_reg_id {
 	RK817_ID_DCDC1 = 0,
 	RK817_ID_DCDC2,
-- 
1.9.1

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

* [PATCH 2/5] regulator: rk808: Add regulator driver for RK809 and RK817.
@ 2018-07-23  3:19   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: linux-arm-kernel

    Add support for the rk809 and rk817 regulator driver.
    Their specifications are as follows?
    1?The RK809 and RK809 consist of 5 DCDCs, 9 LDOs
       and have the same registers for these components except dcdc5.
    2?The dcdc5 is a boost dcdc for RK817 and is a buck for RK809.
    3?The RK817 has one switch but The Rk809 has two.

    The output voltages are configurable and are meant to supply power
    to the main processor and other components.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/regulator/Kconfig           |   4 +-
 drivers/regulator/rk808-regulator.c | 633 +++++++++++++++++++++++++++++++++++-
 include/linux/mfd/rk808.h           |   3 +
 3 files changed, 637 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 5dbccf5..27ff89f 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -716,11 +716,11 @@ config REGULATOR_RC5T583
 	  outputs which can be controlled by i2c communication.
 
 config REGULATOR_RK808
-	tristate "Rockchip RK805/RK808/RK818 Power regulators"
+	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators"
 	depends on MFD_RK808
 	help
 	  Select this option to enable the power regulator of ROCKCHIP
-	  PMIC RK805,RK808 and RK818.
+	  PMIC RK805,RK809&RK817,RK808 and RK818.
 	  This driver supports the control of different power rails of device
 	  through regulator interface. The device supports multiple DCDC/LDO
 	  outputs which can be controlled by i2c communication.
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index 213b687..9edce22 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -36,6 +36,12 @@
 #define RK808_BUCK4_VSEL_MASK	0xf
 #define RK808_LDO_VSEL_MASK	0x1f
 
+#define RK809_BUCK5_VSEL_MASK		0x7
+
+#define RK817_LDO_VSEL_MASK		0x7f
+#define RK817_BOOST_VSEL_MASK		0x7
+#define RK817_BUCK_VSEL_MASK		0x7f
+
 #define RK818_BUCK_VSEL_MASK		0x3f
 #define RK818_BUCK4_VSEL_MASK		0x1f
 #define RK818_LDO_VSEL_MASK		0x1f
@@ -65,6 +71,9 @@
 /* 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 RK805_DESC(_id, _match, _supply, _min, _max, _step, _vreg,      \
 	_vmask, _ereg, _emask, _etime)                                  \
 	[_id] = {                                                       \
@@ -86,6 +95,70 @@
 		.ops            = &rk805_reg_ops,                       \
 	}
 
+#define RK817_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\
+	_vmask, _ereg, _emask, _enval, _disval, _etime)		\
+	{							\
+		.name		= (_match),				\
+		.supply_name	= (_supply),				\
+		.of_match	= of_match_ptr(_match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.type		= REGULATOR_VOLTAGE,			\
+		.id		= (_id),				\
+		.n_voltages	= (((_max) - (_min)) / (_step) + 1),	\
+		.owner		= THIS_MODULE,				\
+		.min_uV		= (_min) * 1000,			\
+		.uV_step	= (_step) * 1000,			\
+		.vsel_reg	= (_vreg),				\
+		.vsel_mask	= (_vmask),				\
+		.enable_reg	= (_ereg),				\
+		.enable_mask	= (_emask),				\
+		.enable_val     = (_enval),				\
+		.disable_val     = (_disval),				\
+		.enable_time	= (_etime),				\
+		.ops		= &rk817_reg_ops,			\
+	}
+
+#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"),		\
+		.type		= REGULATOR_VOLTAGE,			\
+		.id		= (_id),				\
+		.n_voltages	= (((_max) - (_min)) / (_step) + 1),	\
+		.owner		= THIS_MODULE,				\
+		.min_uV		= (_min) * 1000,			\
+		.uV_step	= (_step) * 1000,			\
+		.vsel_reg	= (_vreg),				\
+		.vsel_mask	= (_vmask),				\
+		.enable_reg	= (_ereg),				\
+		.enable_mask	= (_emask),				\
+		.enable_val     = (_enval),				\
+		.disable_val     = (_disval),				\
+		.enable_time	= (_etime),				\
+		.min_dropout_uV = (m_drop) * 1000,			\
+		.ops		= &rk817_boost_ops,			\
+	}
+
+#define RK817_DESC_SWITCH(_id, _match, _supply, _ereg, _emask,\
+	_enval, _disval)		\
+	{							\
+		.name		= (_match),				\
+		.supply_name	= (_supply),				\
+		.of_match	= of_match_ptr(_match),			\
+		.regulators_node = of_match_ptr("regulators"),		\
+		.type		= REGULATOR_VOLTAGE,			\
+		.id		= (_id),				\
+		.enable_reg	= (_ereg),				\
+		.enable_mask	= (_emask),				\
+		.enable_val     = (_enval),				\
+		.disable_val     = (_disval),				\
+		.owner		= THIS_MODULE,				\
+		.ops		= &rk817_switch_ops			\
+	}
+
 #define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, _etime)					\
 	[_id] = {							\
@@ -121,7 +194,6 @@
 		.ops		= &rk808_switch_ops			\
 	}
 
-
 struct rk808_regulator_data {
 	struct gpio_desc *dvs_gpio[2];
 };
@@ -138,6 +210,51 @@ struct rk808_regulator_data {
 	REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0),
 };
 
+#define RK809_BUCK5_SEL_CNT		(8)
+
+static const struct regulator_linear_range rk809_buck5_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(1500000, 0, 0, 0),
+	REGULATOR_LINEAR_RANGE(1800000, 1, 3, 200000),
+	REGULATOR_LINEAR_RANGE(2800000, 4, 5, 200000),
+	REGULATOR_LINEAR_RANGE(3300000, 6, 7, 300000),
+};
+
+#define RK817_BUCK1_MIN0 500000
+#define RK817_BUCK1_MAX0 1500000
+
+#define RK817_BUCK1_MIN1 1600000
+#define RK817_BUCK1_MAX1 2400000
+
+#define RK817_BUCK3_MAX1 3400000
+
+#define RK817_BUCK1_STP0 12500
+#define RK817_BUCK1_STP1 100000
+
+#define RK817_BUCK1_SEL0 ((RK817_BUCK1_MAX0 - RK817_BUCK1_MIN0) /\
+						  RK817_BUCK1_STP0)
+#define RK817_BUCK1_SEL1 ((RK817_BUCK1_MAX1 - RK817_BUCK1_MIN1) /\
+						  RK817_BUCK1_STP1)
+
+#define RK817_BUCK3_SEL1 ((RK817_BUCK3_MAX1 - RK817_BUCK1_MIN1) /\
+						  RK817_BUCK1_STP1)
+
+#define RK817_BUCK1_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK1_SEL1 + 1)
+#define RK817_BUCK3_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK3_SEL1 + 1)
+
+static const struct regulator_linear_range rk817_buck1_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN0, 0,
+			       RK817_BUCK1_SEL0, RK817_BUCK1_STP0),
+	REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1,
+			       RK817_BUCK1_SEL_CNT, RK817_BUCK1_STP1),
+};
+
+static const struct regulator_linear_range rk817_buck3_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN0, 0,
+			       RK817_BUCK1_SEL0, RK817_BUCK1_STP0),
+	REGULATOR_LINEAR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1,
+			       RK817_BUCK3_SEL_CNT, RK817_BUCK1_STP1),
+};
+
 static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
 {
 	struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
@@ -289,6 +406,35 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
 				  RK808_RAMP_RATE_MASK, ramp_value);
 }
 
+/*
+ * RK817 RK809
+ */
+static int rk817_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
+{
+	unsigned int ramp_value = RK817_RAMP_RATE_25MV_PER_US;
+	unsigned int reg = RK817_BUCK_CONFIG_REG(rdev_get_id(rdev));
+
+	switch (ramp_delay) {
+	case 0 ... 3000:
+		ramp_value = RK817_RAMP_RATE_3MV_PER_US;
+		break;
+	case 3001 ... 6300:
+		ramp_value = RK817_RAMP_RATE_6_3MV_PER_US;
+		break;
+	case 6301 ... 12500:
+		ramp_value = RK817_RAMP_RATE_12_5MV_PER_US;
+		break;
+	case 12501 ... 25000:
+		break;
+	default:
+		pr_warn("%s ramp_delay: %d not supported, setting 10000\n",
+			rdev->desc->name, ramp_delay);
+	}
+
+	return regmap_update_bits(rdev->regmap, reg,
+				  RK817_RAMP_RATE_MASK, ramp_value);
+}
+
 static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
 {
 	unsigned int reg;
@@ -304,6 +450,29 @@ static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)
 				  sel);
 }
 
+static int rk817_check_suspend_voltage(int id)
+{
+	if (id >= RK817_ID_DCDC1 && id <= RK817_ID_LDO9)
+		return 0;
+	return -1;
+}
+
+static int rk817_set_suspend_voltage(struct regulator_dev *rdev, int uv)
+{
+	unsigned int reg;
+	int id = rdev_get_id(rdev);
+	int sel = regulator_map_voltage_linear(rdev, uv, uv);
+	/* only ldo1~ldo9 */
+	if (sel < 0 || rk817_check_suspend_voltage(id))
+		return -EINVAL;
+
+	reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET;
+
+	return regmap_update_bits(rdev->regmap, reg,
+				  rdev->desc->vsel_mask,
+				  sel);
+}
+
 static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
 {
 	unsigned int reg;
@@ -363,6 +532,129 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
 				  rdev->desc->enable_mask);
 }
 
+static int rk817_set_suspend_enable_ctrl(struct regulator_dev *rdev,
+					 unsigned int en)
+{
+	unsigned int reg;
+	int id = rdev_get_id(rdev);
+	unsigned int id_slp, msk, val;
+
+	if (id >= RK817_ID_DCDC1 && id <= RK817_ID_DCDC4)
+		id_slp = id;
+	else if (id >= RK817_ID_LDO1 && id <= RK817_ID_LDO8)
+		id_slp = 8 + (id - RK817_ID_LDO1);
+	else if (id >= RK817_ID_LDO9 && id <= RK809_ID_SW2)
+		id_slp = 4 + (id - RK817_ID_LDO9);
+	else
+		return -EINVAL;
+
+	reg = RK817_POWER_SLP_EN_REG(id_slp / 8);
+
+	msk = BIT(id_slp % 8);
+	if (en)
+		val = msk;
+	else
+		val = 0;
+
+	return regmap_update_bits(rdev->regmap, reg, msk, val);
+}
+
+static int rk817_set_suspend_enable(struct regulator_dev *rdev)
+{
+	return rk817_set_suspend_enable_ctrl(rdev, 1);
+}
+
+static int rk817_set_suspend_disable(struct regulator_dev *rdev)
+{
+	return rk817_set_suspend_enable_ctrl(rdev, 0);
+}
+
+static int rk8xx_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	unsigned int reg;
+
+	reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET;
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		return regmap_update_bits(rdev->regmap, reg,
+					  PWM_MODE_MSK, FPWM_MODE);
+	case REGULATOR_MODE_NORMAL:
+		return regmap_update_bits(rdev->regmap, reg,
+					  PWM_MODE_MSK, AUTO_PWM_MODE);
+	default:
+		pr_err("do not support this mode\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rk8xx_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
+					  PWM_MODE_MSK, FPWM_MODE);
+	case REGULATOR_MODE_NORMAL:
+		return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
+					  PWM_MODE_MSK, AUTO_PWM_MODE);
+	default:
+		pr_err("do not support this mode\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned int rk8xx_get_mode(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	int err;
+
+	err = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
+	if (err)
+		return err;
+
+	if (val & FPWM_MODE)
+		return REGULATOR_MODE_FAST;
+	else
+		return REGULATOR_MODE_NORMAL;
+}
+
+static int rk8xx_is_enabled_wmsk_regmap(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
+	if (ret != 0)
+		return ret;
+
+	/* add write mask bit */
+	val |= (rdev->desc->enable_mask & 0xf0);
+	val &= rdev->desc->enable_mask;
+
+	if (rdev->desc->enable_is_inverted) {
+		if (rdev->desc->enable_val)
+			return val != rdev->desc->enable_val;
+		return (val == 0);
+	}
+	if (rdev->desc->enable_val)
+		return val == rdev->desc->enable_val;
+	return val != 0;
+}
+
+static unsigned int rk8xx_regulator_of_map_mode(unsigned int mode)
+{
+	if (mode == 1)
+		return REGULATOR_MODE_FAST;
+	if (mode == 2)
+		return REGULATOR_MODE_NORMAL;
+
+	return -EINVAL;
+}
+
 static struct regulator_ops rk805_reg_ops = {
 		.list_voltage           = regulator_list_voltage_linear,
 		.map_voltage            = regulator_map_voltage_linear,
@@ -433,6 +725,71 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
 	.set_suspend_disable	= rk808_set_suspend_disable,
 };
 
+static struct regulator_ops rk809_buck5_ops_range = {
+	.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,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= rk8xx_is_enabled_wmsk_regmap,
+	.set_suspend_voltage	= rk808_set_suspend_voltage_range,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
+static struct regulator_ops rk817_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,
+	.set_suspend_voltage	= rk817_set_suspend_voltage,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
+static struct regulator_ops rk817_boost_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,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
+static struct regulator_ops rk817_buck_ops_range = {
+	.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,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= rk8xx_is_enabled_wmsk_regmap,
+	.set_mode		= rk8xx_set_mode,
+	.get_mode		= rk8xx_get_mode,
+	.set_suspend_mode	= rk8xx_set_suspend_mode,
+	.set_ramp_delay		= rk817_set_ramp_delay,
+	.set_suspend_voltage	= rk808_set_suspend_voltage_range,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
+static struct regulator_ops rk817_switch_ops = {
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+	.set_suspend_enable	= rk817_set_suspend_enable,
+	.set_suspend_disable	= rk817_set_suspend_disable,
+};
+
 static const struct regulator_desc rk805_reg[] = {
 	{
 		.name = "DCDC_REG1",
@@ -589,6 +946,271 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
 		RK808_DCDC_EN_REG, BIT(6)),
 };
 
+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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK1_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC1),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC1),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC1),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK2_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC2),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC2),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC2),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK3_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC3),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC3),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK3_SEL_CNT + 1,
+		.linear_ranges = rk817_buck3_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck3_voltage_ranges),
+		.vsel_reg = RK817_BUCK4_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC4),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC4),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC4),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	},
+	{
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.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),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	},
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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), ENABLE_MASK(1),
+		   DISABLE_VAL(1), 400),
+	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), ENABLE_MASK(2),
+		   DISABLE_VAL(2), 400),
+	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), ENABLE_MASK(3),
+		   DISABLE_VAL(3), 400),
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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), ENABLE_MASK(1),
+		   DISABLE_VAL(1), 400),
+	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), ENABLE_MASK(2),
+		   DISABLE_VAL(2), 400),
+	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), ENABLE_MASK(3),
+		   DISABLE_VAL(3), 400),
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	RK817_DESC_SWITCH(RK809_ID_SW1, "SWITCH_REG1", "vcc8",
+			  RK817_POWER_EN_REG(3), ENABLE_MASK(3),
+			  ENABLE_MASK(3), DISABLE_VAL(3)),
+	RK817_DESC_SWITCH(RK809_ID_SW2, "SWITCH_REG2", "vcc9",
+			  RK817_POWER_EN_REG(3), ENABLE_MASK(2),
+			  ENABLE_MASK(2), DISABLE_VAL(2)),
+};
+
+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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK1_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC1),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC1),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC1),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK2_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC2),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC2),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC2),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK1_SEL_CNT + 1,
+		.linear_ranges = rk817_buck1_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges),
+		.vsel_reg = RK817_BUCK3_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC3),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC3),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC3),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	}, {
+		.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,
+		.type = REGULATOR_VOLTAGE,
+		.n_voltages = RK817_BUCK3_SEL_CNT + 1,
+		.linear_ranges = rk817_buck3_voltage_ranges,
+		.n_linear_ranges = ARRAY_SIZE(rk817_buck3_voltage_ranges),
+		.vsel_reg = RK817_BUCK4_ON_VSEL_REG,
+		.vsel_mask = RK817_BUCK_VSEL_MASK,
+		.enable_reg = RK817_POWER_EN_REG(0),
+		.enable_mask = ENABLE_MASK(RK817_ID_DCDC4),
+		.enable_val = ENABLE_MASK(RK817_ID_DCDC4),
+		.disable_val = DISABLE_VAL(RK817_ID_DCDC4),
+		.of_map_mode = rk8xx_regulator_of_map_mode,
+		.owner = THIS_MODULE,
+	},
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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), ENABLE_MASK(1),
+		   DISABLE_VAL(1), 400),
+	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), ENABLE_MASK(2),
+		   DISABLE_VAL(2), 400),
+	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), ENABLE_MASK(3),
+		   DISABLE_VAL(3), 400),
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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), ENABLE_MASK(1),
+		   DISABLE_VAL(1), 400),
+	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), ENABLE_MASK(2),
+		   DISABLE_VAL(2), 400),
+	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), ENABLE_MASK(3),
+		   DISABLE_VAL(3), 400),
+	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), ENABLE_MASK(0),
+		   DISABLE_VAL(0), 400),
+	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, 3500 - 5400),
+	RK817_DESC_SWITCH(RK817_ID_BOOST_OTG_SW, "OTG_SWITCH", "vcc9",
+			  RK817_POWER_EN_REG(3), ENABLE_MASK(2),
+			  ENABLE_MASK(2), DISABLE_VAL(2)),
+};
+
 static const struct regulator_desc rk818_reg[] = {
 	{
 		.name = "DCDC_REG1",
@@ -759,6 +1381,14 @@ static int rk808_regulator_probe(struct platform_device *pdev)
 		regulators = rk808_reg;
 		nregulators = RK808_NUM_REGULATORS;
 		break;
+	case RK809_ID:
+		regulators = rk809_reg;
+		nregulators = RK809_NUM_REGULATORS;
+		break;
+	case RK817_ID:
+		regulators = rk817_reg;
+		nregulators = RK817_NUM_REGULATORS;
+		break;
 	case RK818_ID:
 		regulators = rk818_reg;
 		nregulators = RK818_NUM_REGULATORS;
@@ -797,6 +1427,7 @@ static int rk808_regulator_probe(struct platform_device *pdev)
 module_platform_driver(rk808_regulator_driver);
 
 MODULE_DESCRIPTION("regulator driver for the RK808/RK818 series PMICs");
+MODULE_AUTHOR("Tony xie <tony.xie@rock-chips.com>");
 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index b973b0a..b4ce2373 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -396,7 +396,10 @@ enum rk805_reg {
 #define SHUTDOWN_FUN			(0x2 << 2)
 #define SLEEP_FUN			(0x1 << 2)
 #define RK8XX_ID_MSK			0xfff0
+#define PWM_MODE_MSK			BIT(7)
 #define FPWM_MODE			BIT(7)
+#define AUTO_PWM_MODE			0
+
 enum rk817_reg_id {
 	RK817_ID_DCDC1 = 0,
 	RK817_ID_DCDC2,
-- 
1.9.1

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

* [PATCH 3/5] mfd: dt-bindings: Add RK809 and RK817 device tree bindings document
  2018-07-23  3:19 ` Tony Xie
  (?)
  (?)
@ 2018-07-23  3:19   ` Tony Xie
  -1 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: linux-rtc, a.zummo, alexandre.belloni, tony.xie, huangtao,
	devicetree, sboyd, zhangqing, linux-kernel, xsf, linux-rockchip,
	broonie, lee.jones, linux-clk, linux-arm-kernel, chenjh

Add device tree bindings documentation for Rockchip's RK809 & RK817 PMIC.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 Documentation/devicetree/bindings/mfd/rk808.txt | 55 +++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt
index 91b6522..31c9f3d 100644
--- a/Documentation/devicetree/bindings/mfd/rk808.txt
+++ b/Documentation/devicetree/bindings/mfd/rk808.txt
@@ -3,11 +3,15 @@ RK8XX Power Management Integrated Circuit
 The rk8xx family current members:
 rk805
 rk808
+rk809
+rk817
 rk818
 
 Required properties:
 - compatible: "rockchip,rk805"
 - compatible: "rockchip,rk808"
+- compatible: "rockchip,rk809"
+- compatible: "rockchip,rk817"
 - compatible: "rockchip,rk818"
 - reg: I2C slave address
 - interrupt-parent: The parent interrupt controller.
@@ -46,6 +50,28 @@ Optional RK808 properties:
   the gpio controller. If DVS GPIOs aren't present, voltage changes will happen
   very quickly with no slow ramp time.
 
+Optional RK809 properties:
+- vcc1-supply:  The input supply for DCDC_REG1
+- vcc2-supply:  The input supply for DCDC_REG2
+- vcc3-supply:  The input supply for DCDC_REG3
+- vcc4-supply:  The input supply for DCDC_REG4
+- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
+- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
+- vcc7-supply:  The input supply for LDO_REG7, LDO_REG8, LDO_REG9
+- vcc8-supply:  The input supply for SWITCH_REG1
+- vcc9-supply:  The input supply for DCDC_REG5, SWITCH_REG2
+
+Optional RK817 properties:
+- vcc1-supply:  The input supply for DCDC_REG1
+- vcc2-supply:  The input supply for DCDC_REG2
+- vcc3-supply:  The input supply for DCDC_REG3
+- vcc4-supply:  The input supply for DCDC_REG4
+- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
+- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
+- vcc7-supply:  The input supply for LDO_REG7, LDO_REG8, LDO_REG9
+- vcc8-supply:  The input supply for BOOST
+- vcc9-supply:  The input supply for OTG_SWITCH
+
 Optional RK818 properties:
 - vcc1-supply:  The input supply for DCDC_REG1
 - vcc2-supply:  The input supply for DCDC_REG2
@@ -87,6 +113,28 @@ number as described in RK808 datasheet.
 	- SWITCH_REGn
 		- valid values for n are 1 to 2
 
+Following regulators of the RK809 PMIC block are supported. Note that
+the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
+number as described in RK808 datasheet.
+
+	- DCDC_REGn
+		- valid values for n are 1 to 5.
+	- LDO_REGn
+		- valid values for n are 1 to 9.
+	- SWITCH_REGn
+		- valid values for n are 1 to 2.
+
+Following regulators of the RK817 PMIC block are supported. Note that
+the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
+number as described in RK818 datasheet.
+
+	- DCDC_REGn
+		- valid values for n are 1 to 4.
+	- LDO_REGn
+		- valid values for n are 1 to 9.
+	- BOOST
+	- OTG_SWITCH
+
 Following regulators of the RK818 PMIC block are supported. Note that
 the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
 number as described in RK818 datasheet.
@@ -99,6 +147,13 @@ number as described in RK818 datasheet.
 	- HDMI_SWITCH
 	- OTG_SWITCH
 
+There are three pins needed to config, named "gpio_ts" "gpio_gt" "gpio_slp".
+	The gpio_gt and gpio_ts pins support the gpio function.
+	The gpio_slp pin is for controlling the pmic states, as below:
+		- reset
+		- power down
+		- sleep
+
 Standard regulator bindings are used inside regulator subnodes. Check
   Documentation/devicetree/bindings/regulator/regulator.txt
 for more details
-- 
1.9.1



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 3/5] mfd: dt-bindings: Add RK809 and RK817 device tree bindings document
@ 2018-07-23  3:19   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: linux-rtc, a.zummo, alexandre.belloni, tony.xie, huangtao,
	devicetree, sboyd, zhangqing, linux-kernel, xsf, linux-rockchip,
	broonie, lee.jones, linux-clk, linux-arm-kernel, chenjh

Add device tree bindings documentation for Rockchip's RK809 & RK817 PMIC.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 Documentation/devicetree/bindings/mfd/rk808.txt | 55 +++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt
index 91b6522..31c9f3d 100644
--- a/Documentation/devicetree/bindings/mfd/rk808.txt
+++ b/Documentation/devicetree/bindings/mfd/rk808.txt
@@ -3,11 +3,15 @@ RK8XX Power Management Integrated Circuit
 The rk8xx family current members:
 rk805
 rk808
+rk809
+rk817
 rk818
 
 Required properties:
 - compatible: "rockchip,rk805"
 - compatible: "rockchip,rk808"
+- compatible: "rockchip,rk809"
+- compatible: "rockchip,rk817"
 - compatible: "rockchip,rk818"
 - reg: I2C slave address
 - interrupt-parent: The parent interrupt controller.
@@ -46,6 +50,28 @@ Optional RK808 properties:
   the gpio controller. If DVS GPIOs aren't present, voltage changes will happen
   very quickly with no slow ramp time.
 
+Optional RK809 properties:
+- vcc1-supply:  The input supply for DCDC_REG1
+- vcc2-supply:  The input supply for DCDC_REG2
+- vcc3-supply:  The input supply for DCDC_REG3
+- vcc4-supply:  The input supply for DCDC_REG4
+- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
+- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
+- vcc7-supply:  The input supply for LDO_REG7, LDO_REG8, LDO_REG9
+- vcc8-supply:  The input supply for SWITCH_REG1
+- vcc9-supply:  The input supply for DCDC_REG5, SWITCH_REG2
+
+Optional RK817 properties:
+- vcc1-supply:  The input supply for DCDC_REG1
+- vcc2-supply:  The input supply for DCDC_REG2
+- vcc3-supply:  The input supply for DCDC_REG3
+- vcc4-supply:  The input supply for DCDC_REG4
+- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
+- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
+- vcc7-supply:  The input supply for LDO_REG7, LDO_REG8, LDO_REG9
+- vcc8-supply:  The input supply for BOOST
+- vcc9-supply:  The input supply for OTG_SWITCH
+
 Optional RK818 properties:
 - vcc1-supply:  The input supply for DCDC_REG1
 - vcc2-supply:  The input supply for DCDC_REG2
@@ -87,6 +113,28 @@ number as described in RK808 datasheet.
 	- SWITCH_REGn
 		- valid values for n are 1 to 2
 
+Following regulators of the RK809 PMIC block are supported. Note that
+the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
+number as described in RK808 datasheet.
+
+	- DCDC_REGn
+		- valid values for n are 1 to 5.
+	- LDO_REGn
+		- valid values for n are 1 to 9.
+	- SWITCH_REGn
+		- valid values for n are 1 to 2.
+
+Following regulators of the RK817 PMIC block are supported. Note that
+the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
+number as described in RK818 datasheet.
+
+	- DCDC_REGn
+		- valid values for n are 1 to 4.
+	- LDO_REGn
+		- valid values for n are 1 to 9.
+	- BOOST
+	- OTG_SWITCH
+
 Following regulators of the RK818 PMIC block are supported. Note that
 the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
 number as described in RK818 datasheet.
@@ -99,6 +147,13 @@ number as described in RK818 datasheet.
 	- HDMI_SWITCH
 	- OTG_SWITCH
 
+There are three pins needed to config, named "gpio_ts" "gpio_gt" "gpio_slp".
+	The gpio_gt and gpio_ts pins support the gpio function.
+	The gpio_slp pin is for controlling the pmic states, as below:
+		- reset
+		- power down
+		- sleep
+
 Standard regulator bindings are used inside regulator subnodes. Check
   Documentation/devicetree/bindings/regulator/regulator.txt
 for more details
-- 
1.9.1

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

* [PATCH 3/5] mfd: dt-bindings: Add RK809 and RK817 device tree bindings document
@ 2018-07-23  3:19   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: broonie, lee.jones, a.zummo, alexandre.belloni, sboyd, linux-clk,
	linux-rtc, linux-arm-kernel, linux-rockchip, devicetree,
	linux-kernel, chenjh, xsf, zhangqing, huangtao, tony.xie

Add device tree bindings documentation for Rockchip's RK809 & RK817 PMIC.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 Documentation/devicetree/bindings/mfd/rk808.txt | 55 +++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt
index 91b6522..31c9f3d 100644
--- a/Documentation/devicetree/bindings/mfd/rk808.txt
+++ b/Documentation/devicetree/bindings/mfd/rk808.txt
@@ -3,11 +3,15 @@ RK8XX Power Management Integrated Circuit
 The rk8xx family current members:
 rk805
 rk808
+rk809
+rk817
 rk818
 
 Required properties:
 - compatible: "rockchip,rk805"
 - compatible: "rockchip,rk808"
+- compatible: "rockchip,rk809"
+- compatible: "rockchip,rk817"
 - compatible: "rockchip,rk818"
 - reg: I2C slave address
 - interrupt-parent: The parent interrupt controller.
@@ -46,6 +50,28 @@ Optional RK808 properties:
   the gpio controller. If DVS GPIOs aren't present, voltage changes will happen
   very quickly with no slow ramp time.
 
+Optional RK809 properties:
+- vcc1-supply:  The input supply for DCDC_REG1
+- vcc2-supply:  The input supply for DCDC_REG2
+- vcc3-supply:  The input supply for DCDC_REG3
+- vcc4-supply:  The input supply for DCDC_REG4
+- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
+- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
+- vcc7-supply:  The input supply for LDO_REG7, LDO_REG8, LDO_REG9
+- vcc8-supply:  The input supply for SWITCH_REG1
+- vcc9-supply:  The input supply for DCDC_REG5, SWITCH_REG2
+
+Optional RK817 properties:
+- vcc1-supply:  The input supply for DCDC_REG1
+- vcc2-supply:  The input supply for DCDC_REG2
+- vcc3-supply:  The input supply for DCDC_REG3
+- vcc4-supply:  The input supply for DCDC_REG4
+- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
+- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
+- vcc7-supply:  The input supply for LDO_REG7, LDO_REG8, LDO_REG9
+- vcc8-supply:  The input supply for BOOST
+- vcc9-supply:  The input supply for OTG_SWITCH
+
 Optional RK818 properties:
 - vcc1-supply:  The input supply for DCDC_REG1
 - vcc2-supply:  The input supply for DCDC_REG2
@@ -87,6 +113,28 @@ number as described in RK808 datasheet.
 	- SWITCH_REGn
 		- valid values for n are 1 to 2
 
+Following regulators of the RK809 PMIC block are supported. Note that
+the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
+number as described in RK808 datasheet.
+
+	- DCDC_REGn
+		- valid values for n are 1 to 5.
+	- LDO_REGn
+		- valid values for n are 1 to 9.
+	- SWITCH_REGn
+		- valid values for n are 1 to 2.
+
+Following regulators of the RK817 PMIC block are supported. Note that
+the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
+number as described in RK818 datasheet.
+
+	- DCDC_REGn
+		- valid values for n are 1 to 4.
+	- LDO_REGn
+		- valid values for n are 1 to 9.
+	- BOOST
+	- OTG_SWITCH
+
 Following regulators of the RK818 PMIC block are supported. Note that
 the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
 number as described in RK818 datasheet.
@@ -99,6 +147,13 @@ number as described in RK818 datasheet.
 	- HDMI_SWITCH
 	- OTG_SWITCH
 
+There are three pins needed to config, named "gpio_ts" "gpio_gt" "gpio_slp".
+	The gpio_gt and gpio_ts pins support the gpio function.
+	The gpio_slp pin is for controlling the pmic states, as below:
+		- reset
+		- power down
+		- sleep
+
 Standard regulator bindings are used inside regulator subnodes. Check
   Documentation/devicetree/bindings/regulator/regulator.txt
 for more details
-- 
1.9.1

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

* [PATCH 3/5] mfd: dt-bindings: Add RK809 and RK817 device tree bindings document
@ 2018-07-23  3:19   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: linux-arm-kernel

Add device tree bindings documentation for Rockchip's RK809 & RK817 PMIC.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 Documentation/devicetree/bindings/mfd/rk808.txt | 55 +++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt
index 91b6522..31c9f3d 100644
--- a/Documentation/devicetree/bindings/mfd/rk808.txt
+++ b/Documentation/devicetree/bindings/mfd/rk808.txt
@@ -3,11 +3,15 @@ RK8XX Power Management Integrated Circuit
 The rk8xx family current members:
 rk805
 rk808
+rk809
+rk817
 rk818
 
 Required properties:
 - compatible: "rockchip,rk805"
 - compatible: "rockchip,rk808"
+- compatible: "rockchip,rk809"
+- compatible: "rockchip,rk817"
 - compatible: "rockchip,rk818"
 - reg: I2C slave address
 - interrupt-parent: The parent interrupt controller.
@@ -46,6 +50,28 @@ Optional RK808 properties:
   the gpio controller. If DVS GPIOs aren't present, voltage changes will happen
   very quickly with no slow ramp time.
 
+Optional RK809 properties:
+- vcc1-supply:  The input supply for DCDC_REG1
+- vcc2-supply:  The input supply for DCDC_REG2
+- vcc3-supply:  The input supply for DCDC_REG3
+- vcc4-supply:  The input supply for DCDC_REG4
+- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
+- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
+- vcc7-supply:  The input supply for LDO_REG7, LDO_REG8, LDO_REG9
+- vcc8-supply:  The input supply for SWITCH_REG1
+- vcc9-supply:  The input supply for DCDC_REG5, SWITCH_REG2
+
+Optional RK817 properties:
+- vcc1-supply:  The input supply for DCDC_REG1
+- vcc2-supply:  The input supply for DCDC_REG2
+- vcc3-supply:  The input supply for DCDC_REG3
+- vcc4-supply:  The input supply for DCDC_REG4
+- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
+- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
+- vcc7-supply:  The input supply for LDO_REG7, LDO_REG8, LDO_REG9
+- vcc8-supply:  The input supply for BOOST
+- vcc9-supply:  The input supply for OTG_SWITCH
+
 Optional RK818 properties:
 - vcc1-supply:  The input supply for DCDC_REG1
 - vcc2-supply:  The input supply for DCDC_REG2
@@ -87,6 +113,28 @@ number as described in RK808 datasheet.
 	- SWITCH_REGn
 		- valid values for n are 1 to 2
 
+Following regulators of the RK809 PMIC block are supported. Note that
+the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
+number as described in RK808 datasheet.
+
+	- DCDC_REGn
+		- valid values for n are 1 to 5.
+	- LDO_REGn
+		- valid values for n are 1 to 9.
+	- SWITCH_REGn
+		- valid values for n are 1 to 2.
+
+Following regulators of the RK817 PMIC block are supported. Note that
+the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
+number as described in RK818 datasheet.
+
+	- DCDC_REGn
+		- valid values for n are 1 to 4.
+	- LDO_REGn
+		- valid values for n are 1 to 9.
+	- BOOST
+	- OTG_SWITCH
+
 Following regulators of the RK818 PMIC block are supported. Note that
 the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
 number as described in RK818 datasheet.
@@ -99,6 +147,13 @@ number as described in RK818 datasheet.
 	- HDMI_SWITCH
 	- OTG_SWITCH
 
+There are three pins needed to config, named "gpio_ts" "gpio_gt" "gpio_slp".
+	The gpio_gt and gpio_ts pins support the gpio function.
+	The gpio_slp pin is for controlling the pmic states, as below:
+		- reset
+		- power down
+		- sleep
+
 Standard regulator bindings are used inside regulator subnodes. Check
   Documentation/devicetree/bindings/regulator/regulator.txt
 for more details
-- 
1.9.1

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

* [PATCH 4/5] RTC: RK808: add RTC driver for RK809 and RK817.
  2018-07-23  3:19 ` Tony Xie
  (?)
  (?)
@ 2018-07-23  3:19   ` Tony Xie
  -1 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: linux-rtc, a.zummo, alexandre.belloni, tony.xie, huangtao,
	devicetree, sboyd, zhangqing, linux-kernel, xsf, linux-rockchip,
	broonie, lee.jones, linux-clk, linux-arm-kernel, chenjh

RK809 and RK817 are power management IC chips for multimedia products.
Most of their functions and registers are same, including the rtc.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/rtc/Kconfig     |  4 +--
 drivers/rtc/rtc-rk808.c | 68 +++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index a2ba5db..1aaf935 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -371,11 +371,11 @@ config RTC_DRV_MAX77686
 	  will be called rtc-max77686.
 
 config RTC_DRV_RK808
-	tristate "Rockchip RK805/RK808/RK818 RTC"
+	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC"
 	depends on MFD_RK808
 	help
 	  If you say yes here you will get support for the
-	  RTC of RK805, RK808 and RK818 PMIC.
+	  RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC.
 
 	  This driver can also be built as a module. If so, the module
 	  will be called rk808-rtc.
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
index 739c0d4..5bacdaf 100644
--- a/drivers/rtc/rtc-rk808.c
+++ b/drivers/rtc/rtc-rk808.c
@@ -50,9 +50,18 @@
 #define NUM_TIME_REGS	(RK808_WEEKS_REG - RK808_SECONDS_REG + 1)
 #define NUM_ALARM_REGS	(RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1)
 
+struct rk_rtc_compat_reg {
+	unsigned int ctrl_reg;
+	unsigned int status_reg;
+	unsigned int alarm_seconds_reg;
+	unsigned int int_reg;
+	unsigned int seconds_reg;
+};
+
 struct rk808_rtc {
 	struct rk808 *rk808;
 	struct rtc_device *rtc;
+	struct rk_rtc_compat_reg *creg;
 	int irq;
 };
 
@@ -101,7 +110,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 	int ret;
 
 	/* Force an update of the shadowed registers right now */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_RTC_GET_TIME,
 				 BIT_RTC_CTRL_REG_RTC_GET_TIME);
 	if (ret) {
@@ -115,7 +124,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 	 * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
 	 * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
 	 */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_RTC_GET_TIME,
 				 0);
 	if (ret) {
@@ -123,7 +132,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 		return ret;
 	}
 
-	ret = regmap_bulk_read(rk808->regmap, RK808_SECONDS_REG,
+	ret = regmap_bulk_read(rk808->regmap, rk808_rtc->creg->seconds_reg,
 			       rtc_data, NUM_TIME_REGS);
 	if (ret) {
 		dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret);
@@ -166,7 +175,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	rtc_data[6] = bin2bcd(tm->tm_wday);
 
 	/* Stop RTC while updating the RTC registers */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M);
 	if (ret) {
@@ -174,14 +183,14 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
 		return ret;
 	}
 
-	ret = regmap_bulk_write(rk808->regmap, RK808_SECONDS_REG,
+	ret = regmap_bulk_write(rk808->regmap, rk808_rtc->creg->seconds_reg,
 				rtc_data, NUM_TIME_REGS);
 	if (ret) {
 		dev_err(dev, "Failed to bull write rtc_data: %d\n", ret);
 		return ret;
 	}
 	/* Start RTC again */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
 	if (ret) {
 		dev_err(dev, "Failed to update RTC control: %d\n", ret);
@@ -199,8 +208,13 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	uint32_t int_reg;
 	int ret;
 
-	ret = regmap_bulk_read(rk808->regmap, RK808_ALARM_SECONDS_REG,
+	ret = regmap_bulk_read(rk808->regmap,
+			       rk808_rtc->creg->alarm_seconds_reg,
 			       alrm_data, NUM_ALARM_REGS);
+	if (ret) {
+		dev_err(dev, "Failed to read RTC alarm date REG: %d\n", ret);
+		return ret;
+	}
 
 	alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK);
 	alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK);
@@ -210,7 +224,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100;
 	rockchip_to_gregorian(&alrm->time);
 
-	ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg);
+	ret = regmap_read(rk808->regmap, rk808_rtc->creg->int_reg, &int_reg);
 	if (ret) {
 		dev_err(dev, "Failed to read RTC INT REG: %d\n", ret);
 		return ret;
@@ -231,7 +245,7 @@ static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
 	struct rk808 *rk808 = rk808_rtc->rk808;
 	int ret;
 
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
 				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0);
 
 	return ret;
@@ -242,7 +256,7 @@ static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
 	struct rk808 *rk808 = rk808_rtc->rk808;
 	int ret;
 
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
 				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M,
 				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
 
@@ -274,7 +288,8 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1);
 	alrm_data[5] = bin2bcd(alrm->time.tm_year - 100);
 
-	ret = regmap_bulk_write(rk808->regmap, RK808_ALARM_SECONDS_REG,
+	ret = regmap_bulk_write(rk808->regmap,
+				rk808_rtc->creg->alarm_seconds_reg,
 				alrm_data, NUM_ALARM_REGS);
 	if (ret) {
 		dev_err(dev, "Failed to bulk write: %d\n", ret);
@@ -318,7 +333,7 @@ static irqreturn_t rk808_alarm_irq(int irq, void *data)
 	struct i2c_client *client = rk808->i2c;
 	int ret;
 
-	ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
+	ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
 			   RTC_STATUS_MASK);
 	if (ret) {
 		dev_err(&client->dev,
@@ -371,6 +386,22 @@ static int rk808_rtc_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(rk808_rtc_pm_ops,
 	rk808_rtc_suspend, rk808_rtc_resume);
 
+static struct rk_rtc_compat_reg rk808_creg = {
+	.ctrl_reg = RK808_RTC_CTRL_REG,
+	.status_reg = RK808_RTC_STATUS_REG,
+	.alarm_seconds_reg = RK808_ALARM_SECONDS_REG,
+	.int_reg = RK808_RTC_INT_REG,
+	.seconds_reg = RK808_SECONDS_REG,
+};
+
+static struct rk_rtc_compat_reg rk817_creg = {
+	.ctrl_reg = RK817_RTC_CTRL_REG,
+	.status_reg = RK817_RTC_STATUS_REG,
+	.alarm_seconds_reg = RK817_ALARM_SECONDS_REG,
+	.int_reg = RK817_RTC_INT_REG,
+	.seconds_reg = RK817_SECONDS_REG,
+};
+
 static int rk808_rtc_probe(struct platform_device *pdev)
 {
 	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
@@ -381,11 +412,20 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 	if (rk808_rtc == NULL)
 		return -ENOMEM;
 
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		rk808_rtc->creg = &rk817_creg;
+		break;
+	default:
+		rk808_rtc->creg = &rk808_creg;
+		break;
+	}
 	platform_set_drvdata(pdev, rk808_rtc);
 	rk808_rtc->rk808 = rk808;
 
 	/* start rtc running by default, and use shadowed timer. */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M |
 				 BIT_RTC_CTRL_REG_RTC_READSEL_M,
 				 BIT_RTC_CTRL_REG_RTC_READSEL_M);
@@ -395,7 +435,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
+	ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
 			   RTC_STATUS_MASK);
 	if (ret) {
 		dev_err(&pdev->dev,
-- 
1.9.1



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 4/5] RTC: RK808: add RTC driver for RK809 and RK817.
@ 2018-07-23  3:19   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: linux-rtc, a.zummo, alexandre.belloni, tony.xie, huangtao,
	devicetree, sboyd, zhangqing, linux-kernel, xsf, linux-rockchip,
	broonie, lee.jones, linux-clk, linux-arm-kernel, chenjh

RK809 and RK817 are power management IC chips for multimedia products.
Most of their functions and registers are same, including the rtc.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/rtc/Kconfig     |  4 +--
 drivers/rtc/rtc-rk808.c | 68 +++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index a2ba5db..1aaf935 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -371,11 +371,11 @@ config RTC_DRV_MAX77686
 	  will be called rtc-max77686.
 
 config RTC_DRV_RK808
-	tristate "Rockchip RK805/RK808/RK818 RTC"
+	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC"
 	depends on MFD_RK808
 	help
 	  If you say yes here you will get support for the
-	  RTC of RK805, RK808 and RK818 PMIC.
+	  RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC.
 
 	  This driver can also be built as a module. If so, the module
 	  will be called rk808-rtc.
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
index 739c0d4..5bacdaf 100644
--- a/drivers/rtc/rtc-rk808.c
+++ b/drivers/rtc/rtc-rk808.c
@@ -50,9 +50,18 @@
 #define NUM_TIME_REGS	(RK808_WEEKS_REG - RK808_SECONDS_REG + 1)
 #define NUM_ALARM_REGS	(RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1)
 
+struct rk_rtc_compat_reg {
+	unsigned int ctrl_reg;
+	unsigned int status_reg;
+	unsigned int alarm_seconds_reg;
+	unsigned int int_reg;
+	unsigned int seconds_reg;
+};
+
 struct rk808_rtc {
 	struct rk808 *rk808;
 	struct rtc_device *rtc;
+	struct rk_rtc_compat_reg *creg;
 	int irq;
 };
 
@@ -101,7 +110,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 	int ret;
 
 	/* Force an update of the shadowed registers right now */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_RTC_GET_TIME,
 				 BIT_RTC_CTRL_REG_RTC_GET_TIME);
 	if (ret) {
@@ -115,7 +124,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 	 * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
 	 * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
 	 */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_RTC_GET_TIME,
 				 0);
 	if (ret) {
@@ -123,7 +132,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 		return ret;
 	}
 
-	ret = regmap_bulk_read(rk808->regmap, RK808_SECONDS_REG,
+	ret = regmap_bulk_read(rk808->regmap, rk808_rtc->creg->seconds_reg,
 			       rtc_data, NUM_TIME_REGS);
 	if (ret) {
 		dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret);
@@ -166,7 +175,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	rtc_data[6] = bin2bcd(tm->tm_wday);
 
 	/* Stop RTC while updating the RTC registers */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M);
 	if (ret) {
@@ -174,14 +183,14 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
 		return ret;
 	}
 
-	ret = regmap_bulk_write(rk808->regmap, RK808_SECONDS_REG,
+	ret = regmap_bulk_write(rk808->regmap, rk808_rtc->creg->seconds_reg,
 				rtc_data, NUM_TIME_REGS);
 	if (ret) {
 		dev_err(dev, "Failed to bull write rtc_data: %d\n", ret);
 		return ret;
 	}
 	/* Start RTC again */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
 	if (ret) {
 		dev_err(dev, "Failed to update RTC control: %d\n", ret);
@@ -199,8 +208,13 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	uint32_t int_reg;
 	int ret;
 
-	ret = regmap_bulk_read(rk808->regmap, RK808_ALARM_SECONDS_REG,
+	ret = regmap_bulk_read(rk808->regmap,
+			       rk808_rtc->creg->alarm_seconds_reg,
 			       alrm_data, NUM_ALARM_REGS);
+	if (ret) {
+		dev_err(dev, "Failed to read RTC alarm date REG: %d\n", ret);
+		return ret;
+	}
 
 	alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK);
 	alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK);
@@ -210,7 +224,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100;
 	rockchip_to_gregorian(&alrm->time);
 
-	ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg);
+	ret = regmap_read(rk808->regmap, rk808_rtc->creg->int_reg, &int_reg);
 	if (ret) {
 		dev_err(dev, "Failed to read RTC INT REG: %d\n", ret);
 		return ret;
@@ -231,7 +245,7 @@ static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
 	struct rk808 *rk808 = rk808_rtc->rk808;
 	int ret;
 
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
 				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0);
 
 	return ret;
@@ -242,7 +256,7 @@ static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
 	struct rk808 *rk808 = rk808_rtc->rk808;
 	int ret;
 
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
 				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M,
 				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
 
@@ -274,7 +288,8 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1);
 	alrm_data[5] = bin2bcd(alrm->time.tm_year - 100);
 
-	ret = regmap_bulk_write(rk808->regmap, RK808_ALARM_SECONDS_REG,
+	ret = regmap_bulk_write(rk808->regmap,
+				rk808_rtc->creg->alarm_seconds_reg,
 				alrm_data, NUM_ALARM_REGS);
 	if (ret) {
 		dev_err(dev, "Failed to bulk write: %d\n", ret);
@@ -318,7 +333,7 @@ static irqreturn_t rk808_alarm_irq(int irq, void *data)
 	struct i2c_client *client = rk808->i2c;
 	int ret;
 
-	ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
+	ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
 			   RTC_STATUS_MASK);
 	if (ret) {
 		dev_err(&client->dev,
@@ -371,6 +386,22 @@ static int rk808_rtc_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(rk808_rtc_pm_ops,
 	rk808_rtc_suspend, rk808_rtc_resume);
 
+static struct rk_rtc_compat_reg rk808_creg = {
+	.ctrl_reg = RK808_RTC_CTRL_REG,
+	.status_reg = RK808_RTC_STATUS_REG,
+	.alarm_seconds_reg = RK808_ALARM_SECONDS_REG,
+	.int_reg = RK808_RTC_INT_REG,
+	.seconds_reg = RK808_SECONDS_REG,
+};
+
+static struct rk_rtc_compat_reg rk817_creg = {
+	.ctrl_reg = RK817_RTC_CTRL_REG,
+	.status_reg = RK817_RTC_STATUS_REG,
+	.alarm_seconds_reg = RK817_ALARM_SECONDS_REG,
+	.int_reg = RK817_RTC_INT_REG,
+	.seconds_reg = RK817_SECONDS_REG,
+};
+
 static int rk808_rtc_probe(struct platform_device *pdev)
 {
 	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
@@ -381,11 +412,20 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 	if (rk808_rtc == NULL)
 		return -ENOMEM;
 
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		rk808_rtc->creg = &rk817_creg;
+		break;
+	default:
+		rk808_rtc->creg = &rk808_creg;
+		break;
+	}
 	platform_set_drvdata(pdev, rk808_rtc);
 	rk808_rtc->rk808 = rk808;
 
 	/* start rtc running by default, and use shadowed timer. */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M |
 				 BIT_RTC_CTRL_REG_RTC_READSEL_M,
 				 BIT_RTC_CTRL_REG_RTC_READSEL_M);
@@ -395,7 +435,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
+	ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
 			   RTC_STATUS_MASK);
 	if (ret) {
 		dev_err(&pdev->dev,
-- 
1.9.1

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

* [PATCH 4/5] RTC: RK808: add RTC driver for RK809 and RK817.
@ 2018-07-23  3:19   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: heiko
  Cc: broonie, lee.jones, a.zummo, alexandre.belloni, sboyd, linux-clk,
	linux-rtc, linux-arm-kernel, linux-rockchip, devicetree,
	linux-kernel, chenjh, xsf, zhangqing, huangtao, tony.xie

RK809 and RK817 are power management IC chips for multimedia products.
Most of their functions and registers are same, including the rtc.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/rtc/Kconfig     |  4 +--
 drivers/rtc/rtc-rk808.c | 68 +++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index a2ba5db..1aaf935 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -371,11 +371,11 @@ config RTC_DRV_MAX77686
 	  will be called rtc-max77686.
 
 config RTC_DRV_RK808
-	tristate "Rockchip RK805/RK808/RK818 RTC"
+	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC"
 	depends on MFD_RK808
 	help
 	  If you say yes here you will get support for the
-	  RTC of RK805, RK808 and RK818 PMIC.
+	  RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC.
 
 	  This driver can also be built as a module. If so, the module
 	  will be called rk808-rtc.
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
index 739c0d4..5bacdaf 100644
--- a/drivers/rtc/rtc-rk808.c
+++ b/drivers/rtc/rtc-rk808.c
@@ -50,9 +50,18 @@
 #define NUM_TIME_REGS	(RK808_WEEKS_REG - RK808_SECONDS_REG + 1)
 #define NUM_ALARM_REGS	(RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1)
 
+struct rk_rtc_compat_reg {
+	unsigned int ctrl_reg;
+	unsigned int status_reg;
+	unsigned int alarm_seconds_reg;
+	unsigned int int_reg;
+	unsigned int seconds_reg;
+};
+
 struct rk808_rtc {
 	struct rk808 *rk808;
 	struct rtc_device *rtc;
+	struct rk_rtc_compat_reg *creg;
 	int irq;
 };
 
@@ -101,7 +110,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 	int ret;
 
 	/* Force an update of the shadowed registers right now */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_RTC_GET_TIME,
 				 BIT_RTC_CTRL_REG_RTC_GET_TIME);
 	if (ret) {
@@ -115,7 +124,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 	 * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
 	 * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
 	 */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_RTC_GET_TIME,
 				 0);
 	if (ret) {
@@ -123,7 +132,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 		return ret;
 	}
 
-	ret = regmap_bulk_read(rk808->regmap, RK808_SECONDS_REG,
+	ret = regmap_bulk_read(rk808->regmap, rk808_rtc->creg->seconds_reg,
 			       rtc_data, NUM_TIME_REGS);
 	if (ret) {
 		dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret);
@@ -166,7 +175,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	rtc_data[6] = bin2bcd(tm->tm_wday);
 
 	/* Stop RTC while updating the RTC registers */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M);
 	if (ret) {
@@ -174,14 +183,14 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
 		return ret;
 	}
 
-	ret = regmap_bulk_write(rk808->regmap, RK808_SECONDS_REG,
+	ret = regmap_bulk_write(rk808->regmap, rk808_rtc->creg->seconds_reg,
 				rtc_data, NUM_TIME_REGS);
 	if (ret) {
 		dev_err(dev, "Failed to bull write rtc_data: %d\n", ret);
 		return ret;
 	}
 	/* Start RTC again */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
 	if (ret) {
 		dev_err(dev, "Failed to update RTC control: %d\n", ret);
@@ -199,8 +208,13 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	uint32_t int_reg;
 	int ret;
 
-	ret = regmap_bulk_read(rk808->regmap, RK808_ALARM_SECONDS_REG,
+	ret = regmap_bulk_read(rk808->regmap,
+			       rk808_rtc->creg->alarm_seconds_reg,
 			       alrm_data, NUM_ALARM_REGS);
+	if (ret) {
+		dev_err(dev, "Failed to read RTC alarm date REG: %d\n", ret);
+		return ret;
+	}
 
 	alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK);
 	alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK);
@@ -210,7 +224,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100;
 	rockchip_to_gregorian(&alrm->time);
 
-	ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg);
+	ret = regmap_read(rk808->regmap, rk808_rtc->creg->int_reg, &int_reg);
 	if (ret) {
 		dev_err(dev, "Failed to read RTC INT REG: %d\n", ret);
 		return ret;
@@ -231,7 +245,7 @@ static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
 	struct rk808 *rk808 = rk808_rtc->rk808;
 	int ret;
 
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
 				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0);
 
 	return ret;
@@ -242,7 +256,7 @@ static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
 	struct rk808 *rk808 = rk808_rtc->rk808;
 	int ret;
 
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
 				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M,
 				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
 
@@ -274,7 +288,8 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1);
 	alrm_data[5] = bin2bcd(alrm->time.tm_year - 100);
 
-	ret = regmap_bulk_write(rk808->regmap, RK808_ALARM_SECONDS_REG,
+	ret = regmap_bulk_write(rk808->regmap,
+				rk808_rtc->creg->alarm_seconds_reg,
 				alrm_data, NUM_ALARM_REGS);
 	if (ret) {
 		dev_err(dev, "Failed to bulk write: %d\n", ret);
@@ -318,7 +333,7 @@ static irqreturn_t rk808_alarm_irq(int irq, void *data)
 	struct i2c_client *client = rk808->i2c;
 	int ret;
 
-	ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
+	ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
 			   RTC_STATUS_MASK);
 	if (ret) {
 		dev_err(&client->dev,
@@ -371,6 +386,22 @@ static int rk808_rtc_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(rk808_rtc_pm_ops,
 	rk808_rtc_suspend, rk808_rtc_resume);
 
+static struct rk_rtc_compat_reg rk808_creg = {
+	.ctrl_reg = RK808_RTC_CTRL_REG,
+	.status_reg = RK808_RTC_STATUS_REG,
+	.alarm_seconds_reg = RK808_ALARM_SECONDS_REG,
+	.int_reg = RK808_RTC_INT_REG,
+	.seconds_reg = RK808_SECONDS_REG,
+};
+
+static struct rk_rtc_compat_reg rk817_creg = {
+	.ctrl_reg = RK817_RTC_CTRL_REG,
+	.status_reg = RK817_RTC_STATUS_REG,
+	.alarm_seconds_reg = RK817_ALARM_SECONDS_REG,
+	.int_reg = RK817_RTC_INT_REG,
+	.seconds_reg = RK817_SECONDS_REG,
+};
+
 static int rk808_rtc_probe(struct platform_device *pdev)
 {
 	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
@@ -381,11 +412,20 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 	if (rk808_rtc == NULL)
 		return -ENOMEM;
 
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		rk808_rtc->creg = &rk817_creg;
+		break;
+	default:
+		rk808_rtc->creg = &rk808_creg;
+		break;
+	}
 	platform_set_drvdata(pdev, rk808_rtc);
 	rk808_rtc->rk808 = rk808;
 
 	/* start rtc running by default, and use shadowed timer. */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M |
 				 BIT_RTC_CTRL_REG_RTC_READSEL_M,
 				 BIT_RTC_CTRL_REG_RTC_READSEL_M);
@@ -395,7 +435,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
+	ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
 			   RTC_STATUS_MASK);
 	if (ret) {
 		dev_err(&pdev->dev,
-- 
1.9.1

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

* [PATCH 4/5] RTC: RK808: add RTC driver for RK809 and RK817.
@ 2018-07-23  3:19   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  3:19 UTC (permalink / raw)
  To: linux-arm-kernel

RK809 and RK817 are power management IC chips for multimedia products.
Most of their functions and registers are same, including the rtc.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/rtc/Kconfig     |  4 +--
 drivers/rtc/rtc-rk808.c | 68 +++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index a2ba5db..1aaf935 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -371,11 +371,11 @@ config RTC_DRV_MAX77686
 	  will be called rtc-max77686.
 
 config RTC_DRV_RK808
-	tristate "Rockchip RK805/RK808/RK818 RTC"
+	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC"
 	depends on MFD_RK808
 	help
 	  If you say yes here you will get support for the
-	  RTC of RK805, RK808 and RK818 PMIC.
+	  RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC.
 
 	  This driver can also be built as a module. If so, the module
 	  will be called rk808-rtc.
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
index 739c0d4..5bacdaf 100644
--- a/drivers/rtc/rtc-rk808.c
+++ b/drivers/rtc/rtc-rk808.c
@@ -50,9 +50,18 @@
 #define NUM_TIME_REGS	(RK808_WEEKS_REG - RK808_SECONDS_REG + 1)
 #define NUM_ALARM_REGS	(RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1)
 
+struct rk_rtc_compat_reg {
+	unsigned int ctrl_reg;
+	unsigned int status_reg;
+	unsigned int alarm_seconds_reg;
+	unsigned int int_reg;
+	unsigned int seconds_reg;
+};
+
 struct rk808_rtc {
 	struct rk808 *rk808;
 	struct rtc_device *rtc;
+	struct rk_rtc_compat_reg *creg;
 	int irq;
 };
 
@@ -101,7 +110,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 	int ret;
 
 	/* Force an update of the shadowed registers right now */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_RTC_GET_TIME,
 				 BIT_RTC_CTRL_REG_RTC_GET_TIME);
 	if (ret) {
@@ -115,7 +124,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 	 * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
 	 * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
 	 */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_RTC_GET_TIME,
 				 0);
 	if (ret) {
@@ -123,7 +132,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
 		return ret;
 	}
 
-	ret = regmap_bulk_read(rk808->regmap, RK808_SECONDS_REG,
+	ret = regmap_bulk_read(rk808->regmap, rk808_rtc->creg->seconds_reg,
 			       rtc_data, NUM_TIME_REGS);
 	if (ret) {
 		dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret);
@@ -166,7 +175,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	rtc_data[6] = bin2bcd(tm->tm_wday);
 
 	/* Stop RTC while updating the RTC registers */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M);
 	if (ret) {
@@ -174,14 +183,14 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
 		return ret;
 	}
 
-	ret = regmap_bulk_write(rk808->regmap, RK808_SECONDS_REG,
+	ret = regmap_bulk_write(rk808->regmap, rk808_rtc->creg->seconds_reg,
 				rtc_data, NUM_TIME_REGS);
 	if (ret) {
 		dev_err(dev, "Failed to bull write rtc_data: %d\n", ret);
 		return ret;
 	}
 	/* Start RTC again */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
 	if (ret) {
 		dev_err(dev, "Failed to update RTC control: %d\n", ret);
@@ -199,8 +208,13 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	uint32_t int_reg;
 	int ret;
 
-	ret = regmap_bulk_read(rk808->regmap, RK808_ALARM_SECONDS_REG,
+	ret = regmap_bulk_read(rk808->regmap,
+			       rk808_rtc->creg->alarm_seconds_reg,
 			       alrm_data, NUM_ALARM_REGS);
+	if (ret) {
+		dev_err(dev, "Failed to read RTC alarm date REG: %d\n", ret);
+		return ret;
+	}
 
 	alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK);
 	alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK);
@@ -210,7 +224,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100;
 	rockchip_to_gregorian(&alrm->time);
 
-	ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg);
+	ret = regmap_read(rk808->regmap, rk808_rtc->creg->int_reg, &int_reg);
 	if (ret) {
 		dev_err(dev, "Failed to read RTC INT REG: %d\n", ret);
 		return ret;
@@ -231,7 +245,7 @@ static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
 	struct rk808 *rk808 = rk808_rtc->rk808;
 	int ret;
 
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
 				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0);
 
 	return ret;
@@ -242,7 +256,7 @@ static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
 	struct rk808 *rk808 = rk808_rtc->rk808;
 	int ret;
 
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
 				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M,
 				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
 
@@ -274,7 +288,8 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 	alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1);
 	alrm_data[5] = bin2bcd(alrm->time.tm_year - 100);
 
-	ret = regmap_bulk_write(rk808->regmap, RK808_ALARM_SECONDS_REG,
+	ret = regmap_bulk_write(rk808->regmap,
+				rk808_rtc->creg->alarm_seconds_reg,
 				alrm_data, NUM_ALARM_REGS);
 	if (ret) {
 		dev_err(dev, "Failed to bulk write: %d\n", ret);
@@ -318,7 +333,7 @@ static irqreturn_t rk808_alarm_irq(int irq, void *data)
 	struct i2c_client *client = rk808->i2c;
 	int ret;
 
-	ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
+	ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
 			   RTC_STATUS_MASK);
 	if (ret) {
 		dev_err(&client->dev,
@@ -371,6 +386,22 @@ static int rk808_rtc_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(rk808_rtc_pm_ops,
 	rk808_rtc_suspend, rk808_rtc_resume);
 
+static struct rk_rtc_compat_reg rk808_creg = {
+	.ctrl_reg = RK808_RTC_CTRL_REG,
+	.status_reg = RK808_RTC_STATUS_REG,
+	.alarm_seconds_reg = RK808_ALARM_SECONDS_REG,
+	.int_reg = RK808_RTC_INT_REG,
+	.seconds_reg = RK808_SECONDS_REG,
+};
+
+static struct rk_rtc_compat_reg rk817_creg = {
+	.ctrl_reg = RK817_RTC_CTRL_REG,
+	.status_reg = RK817_RTC_STATUS_REG,
+	.alarm_seconds_reg = RK817_ALARM_SECONDS_REG,
+	.int_reg = RK817_RTC_INT_REG,
+	.seconds_reg = RK817_SECONDS_REG,
+};
+
 static int rk808_rtc_probe(struct platform_device *pdev)
 {
 	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
@@ -381,11 +412,20 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 	if (rk808_rtc == NULL)
 		return -ENOMEM;
 
+	switch (rk808->variant) {
+	case RK809_ID:
+	case RK817_ID:
+		rk808_rtc->creg = &rk817_creg;
+		break;
+	default:
+		rk808_rtc->creg = &rk808_creg;
+		break;
+	}
 	platform_set_drvdata(pdev, rk808_rtc);
 	rk808_rtc->rk808 = rk808;
 
 	/* start rtc running by default, and use shadowed timer. */
-	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
+	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
 				 BIT_RTC_CTRL_REG_STOP_RTC_M |
 				 BIT_RTC_CTRL_REG_RTC_READSEL_M,
 				 BIT_RTC_CTRL_REG_RTC_READSEL_M);
@@ -395,7 +435,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
+	ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
 			   RTC_STATUS_MASK);
 	if (ret) {
 		dev_err(&pdev->dev,
-- 
1.9.1

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

* Re: [PATCH 3/5] mfd: dt-bindings: Add RK809 and RK817 device tree bindings document
  2018-07-23  3:19   ` Tony Xie
@ 2018-07-23  8:29     ` Michal Vokáč
  -1 siblings, 0 replies; 33+ messages in thread
From: Michal Vokáč @ 2018-07-23  8:29 UTC (permalink / raw)
  To: Tony Xie
  Cc: heiko, broonie, lee.jones, a.zummo, alexandre.belloni, sboyd,
	linux-clk, linux-rtc, linux-arm-kernel, linux-rockchip,
	devicetree, linux-kernel, chenjh, xsf, zhangqing, huangtao

On 23.7.2018 05:19, Tony Xie wrote:
> Add device tree bindings documentation for Rockchip's RK809 & RK817 PMIC.
> 
> Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
> ---
>   Documentation/devicetree/bindings/mfd/rk808.txt | 55 +++++++++++++++++++++++++
>   1 file changed, 55 insertions(+)
> 

Hi Tony,
Seems something went wrong with your series. The introductory email can be
found only in linux-arm-kernel list but nowhere else and I can not find
the fifth patch at all.

Formal notes to this patch.
- Documentation/binding patches should go first in your series.
- Subject line should be: "dt-bindings: mfd: ..."
- Try to avoid the words [documentation, device tree, bindings] in subject.

See this patch [1] from Rob and add him to the recipients for v2.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=44acf10587907ff77c28fd97906220b2d8eb4f05

Best regards,
Michal

> diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt
> index 91b6522..31c9f3d 100644
> --- a/Documentation/devicetree/bindings/mfd/rk808.txt
> +++ b/Documentation/devicetree/bindings/mfd/rk808.txt
> @@ -3,11 +3,15 @@ RK8XX Power Management Integrated Circuit
>   The rk8xx family current members:
>   rk805
>   rk808
> +rk809
> +rk817
>   rk818
>   
>   Required properties:
>   - compatible: "rockchip,rk805"
>   - compatible: "rockchip,rk808"
> +- compatible: "rockchip,rk809"
> +- compatible: "rockchip,rk817"
>   - compatible: "rockchip,rk818"
>   - reg: I2C slave address
>   - interrupt-parent: The parent interrupt controller.
> @@ -46,6 +50,28 @@ Optional RK808 properties:
>     the gpio controller. If DVS GPIOs aren't present, voltage changes will happen
>     very quickly with no slow ramp time.
>   
> +Optional RK809 properties:
> +- vcc1-supply:  The input supply for DCDC_REG1
> +- vcc2-supply:  The input supply for DCDC_REG2
> +- vcc3-supply:  The input supply for DCDC_REG3
> +- vcc4-supply:  The input supply for DCDC_REG4
> +- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
> +- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
> +- vcc7-supply:  The input supply for LDO_REG7, LDO_REG8, LDO_REG9
> +- vcc8-supply:  The input supply for SWITCH_REG1
> +- vcc9-supply:  The input supply for DCDC_REG5, SWITCH_REG2
> +
> +Optional RK817 properties:
> +- vcc1-supply:  The input supply for DCDC_REG1
> +- vcc2-supply:  The input supply for DCDC_REG2
> +- vcc3-supply:  The input supply for DCDC_REG3
> +- vcc4-supply:  The input supply for DCDC_REG4
> +- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
> +- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
> +- vcc7-supply:  The input supply for LDO_REG7, LDO_REG8, LDO_REG9
> +- vcc8-supply:  The input supply for BOOST
> +- vcc9-supply:  The input supply for OTG_SWITCH
> +
>   Optional RK818 properties:
>   - vcc1-supply:  The input supply for DCDC_REG1
>   - vcc2-supply:  The input supply for DCDC_REG2
> @@ -87,6 +113,28 @@ number as described in RK808 datasheet.
>   	- SWITCH_REGn
>   		- valid values for n are 1 to 2
>   
> +Following regulators of the RK809 PMIC block are supported. Note that
> +the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
> +number as described in RK808 datasheet.
> +
> +	- DCDC_REGn
> +		- valid values for n are 1 to 5.
> +	- LDO_REGn
> +		- valid values for n are 1 to 9.
> +	- SWITCH_REGn
> +		- valid values for n are 1 to 2.
> +
> +Following regulators of the RK817 PMIC block are supported. Note that
> +the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
> +number as described in RK818 datasheet.
> +
> +	- DCDC_REGn
> +		- valid values for n are 1 to 4.
> +	- LDO_REGn
> +		- valid values for n are 1 to 9.
> +	- BOOST
> +	- OTG_SWITCH
> +
>   Following regulators of the RK818 PMIC block are supported. Note that
>   the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
>   number as described in RK818 datasheet.
> @@ -99,6 +147,13 @@ number as described in RK818 datasheet.
>   	- HDMI_SWITCH
>   	- OTG_SWITCH
>   
> +There are three pins needed to config, named "gpio_ts" "gpio_gt" "gpio_slp".
> +	The gpio_gt and gpio_ts pins support the gpio function.
> +	The gpio_slp pin is for controlling the pmic states, as below:
> +		- reset
> +		- power down
> +		- sleep
> +
>   Standard regulator bindings are used inside regulator subnodes. Check
>     Documentation/devicetree/bindings/regulator/regulator.txt
>   for more details
> 


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

* [PATCH 3/5] mfd: dt-bindings: Add RK809 and RK817 device tree bindings document
@ 2018-07-23  8:29     ` Michal Vokáč
  0 siblings, 0 replies; 33+ messages in thread
From: Michal Vokáč @ 2018-07-23  8:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 23.7.2018 05:19, Tony Xie wrote:
> Add device tree bindings documentation for Rockchip's RK809 & RK817 PMIC.
> 
> Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
> ---
>   Documentation/devicetree/bindings/mfd/rk808.txt | 55 +++++++++++++++++++++++++
>   1 file changed, 55 insertions(+)
> 

Hi Tony,
Seems something went wrong with your series. The introductory email can be
found only in linux-arm-kernel list but nowhere else and I can not find
the fifth patch at all.

Formal notes to this patch.
- Documentation/binding patches should go first in your series.
- Subject line should be: "dt-bindings: mfd: ..."
- Try to avoid the words [documentation, device tree, bindings] in subject.

See this patch [1] from Rob and add him to the recipients for v2.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=44acf10587907ff77c28fd97906220b2d8eb4f05

Best regards,
Michal

> diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt
> index 91b6522..31c9f3d 100644
> --- a/Documentation/devicetree/bindings/mfd/rk808.txt
> +++ b/Documentation/devicetree/bindings/mfd/rk808.txt
> @@ -3,11 +3,15 @@ RK8XX Power Management Integrated Circuit
>   The rk8xx family current members:
>   rk805
>   rk808
> +rk809
> +rk817
>   rk818
>   
>   Required properties:
>   - compatible: "rockchip,rk805"
>   - compatible: "rockchip,rk808"
> +- compatible: "rockchip,rk809"
> +- compatible: "rockchip,rk817"
>   - compatible: "rockchip,rk818"
>   - reg: I2C slave address
>   - interrupt-parent: The parent interrupt controller.
> @@ -46,6 +50,28 @@ Optional RK808 properties:
>     the gpio controller. If DVS GPIOs aren't present, voltage changes will happen
>     very quickly with no slow ramp time.
>   
> +Optional RK809 properties:
> +- vcc1-supply:  The input supply for DCDC_REG1
> +- vcc2-supply:  The input supply for DCDC_REG2
> +- vcc3-supply:  The input supply for DCDC_REG3
> +- vcc4-supply:  The input supply for DCDC_REG4
> +- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
> +- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
> +- vcc7-supply:  The input supply for LDO_REG7, LDO_REG8, LDO_REG9
> +- vcc8-supply:  The input supply for SWITCH_REG1
> +- vcc9-supply:  The input supply for DCDC_REG5, SWITCH_REG2
> +
> +Optional RK817 properties:
> +- vcc1-supply:  The input supply for DCDC_REG1
> +- vcc2-supply:  The input supply for DCDC_REG2
> +- vcc3-supply:  The input supply for DCDC_REG3
> +- vcc4-supply:  The input supply for DCDC_REG4
> +- vcc5-supply:  The input supply for LDO_REG1, LDO_REG2, LDO_REG3
> +- vcc6-supply:  The input supply for LDO_REG4, LDO_REG5, LDO_REG6
> +- vcc7-supply:  The input supply for LDO_REG7, LDO_REG8, LDO_REG9
> +- vcc8-supply:  The input supply for BOOST
> +- vcc9-supply:  The input supply for OTG_SWITCH
> +
>   Optional RK818 properties:
>   - vcc1-supply:  The input supply for DCDC_REG1
>   - vcc2-supply:  The input supply for DCDC_REG2
> @@ -87,6 +113,28 @@ number as described in RK808 datasheet.
>   	- SWITCH_REGn
>   		- valid values for n are 1 to 2
>   
> +Following regulators of the RK809 PMIC block are supported. Note that
> +the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
> +number as described in RK808 datasheet.
> +
> +	- DCDC_REGn
> +		- valid values for n are 1 to 5.
> +	- LDO_REGn
> +		- valid values for n are 1 to 9.
> +	- SWITCH_REGn
> +		- valid values for n are 1 to 2.
> +
> +Following regulators of the RK817 PMIC block are supported. Note that
> +the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
> +number as described in RK818 datasheet.
> +
> +	- DCDC_REGn
> +		- valid values for n are 1 to 4.
> +	- LDO_REGn
> +		- valid values for n are 1 to 9.
> +	- BOOST
> +	- OTG_SWITCH
> +
>   Following regulators of the RK818 PMIC block are supported. Note that
>   the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
>   number as described in RK818 datasheet.
> @@ -99,6 +147,13 @@ number as described in RK818 datasheet.
>   	- HDMI_SWITCH
>   	- OTG_SWITCH
>   
> +There are three pins needed to config, named "gpio_ts" "gpio_gt" "gpio_slp".
> +	The gpio_gt and gpio_ts pins support the gpio function.
> +	The gpio_slp pin is for controlling the pmic states, as below:
> +		- reset
> +		- power down
> +		- sleep
> +
>   Standard regulator bindings are used inside regulator subnodes. Check
>     Documentation/devicetree/bindings/regulator/regulator.txt
>   for more details
> 

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

* [PATCH 5/5] clk: RK808: add clkout driver for RK809 and RK817.
  2018-07-23  3:19 ` Tony Xie
@ 2018-07-23  8:40   ` Tony Xie
  -1 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  8:40 UTC (permalink / raw)
  To: heiko
  Cc: broonie, lee.jones, a.zummo, alexandre.belloni, sboyd, linux-clk,
	linux-rtc, linux-arm-kernel, linux-rockchip, devicetree,
	linux-kernel, chenjh, xsf, zhangqing, huangtao, tony.xie

RK809 and RK817 are power management IC chips for multimedia products.
most of their functions and registers are same, including the clkout
funciton.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/clk/Kconfig     |  6 ++---
 drivers/clk/clk-rk808.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 721572a..fc1427c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -46,11 +46,11 @@ config COMMON_CLK_MAX77686
 	  clock.
 
 config COMMON_CLK_RK808
-	tristate "Clock driver for RK805/RK808/RK818"
+	tristate "Clock driver for RK805/RK808/RK809/RK817/RK818"
 	depends on MFD_RK808
 	---help---
-	  This driver supports RK805, RK808 and RK818 crystal oscillator clock. These
-	  multi-function devices have two fixed-rate oscillators,
+	  This driver supports RK805, RK809 and RK817, RK808 and RK818 crystal oscillator clock.
+          These multi-function devices have two fixed-rate oscillators,
 	  clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
 	  by control register.
 
diff --git a/drivers/clk/clk-rk808.c b/drivers/clk/clk-rk808.c
index 6461f28..c5d3492 100644
--- a/drivers/clk/clk-rk808.c
+++ b/drivers/clk/clk-rk808.c
@@ -96,6 +96,66 @@ static int rk808_clkout2_is_prepared(struct clk_hw *hw)
 	return idx ? &rk808_clkout->clkout2_hw : &rk808_clkout->clkout1_hw;
 }
 
+static int rk817_clkout2_enable(struct clk_hw *hw, bool enable)
+{
+	struct rk808_clkout *rk808_clkout = container_of(hw,
+							 struct rk808_clkout,
+							 clkout2_hw);
+	struct rk808 *rk808 = rk808_clkout->rk808;
+
+	return regmap_update_bits(rk808->regmap, RK817_SYS_CFG(1),
+				  RK817_CLK32KOUT2_EN,
+				  enable ? RK817_CLK32KOUT2_EN : 0);
+}
+
+static int rk817_clkout2_prepare(struct clk_hw *hw)
+{
+	return rk817_clkout2_enable(hw, true);
+}
+
+static void rk817_clkout2_unprepare(struct clk_hw *hw)
+{
+	rk817_clkout2_enable(hw, false);
+}
+
+static int rk817_clkout2_is_prepared(struct clk_hw *hw)
+{
+	struct rk808_clkout *rk808_clkout = container_of(hw,
+							 struct rk808_clkout,
+							 clkout2_hw);
+	struct rk808 *rk808 = rk808_clkout->rk808;
+	unsigned int val;
+
+	int ret = regmap_read(rk808->regmap, RK817_SYS_CFG(1), &val);
+
+	if (ret < 0)
+		return ret;
+
+	return (val & RK817_CLK32KOUT2_EN) ? 1 : 0;
+}
+
+static const struct clk_ops rk817_clkout2_ops = {
+	.prepare = rk817_clkout2_prepare,
+	.unprepare = rk817_clkout2_unprepare,
+	.is_prepared = rk817_clkout2_is_prepared,
+	.recalc_rate = rk808_clkout_recalc_rate,
+};
+
+static const struct clk_ops *rkpmic_get_ops(long variant)
+{
+	switch (variant) {
+	case RK809_ID:
+	case RK817_ID:
+		return &rk817_clkout2_ops;
+	case RK805_ID:
+	case RK808_ID:
+	case RK818_ID:
+		return &rk808_clkout2_ops;
+	}
+
+	return &rk808_clkout2_ops;
+}
+
 static int rk808_clkout_probe(struct platform_device *pdev)
 {
 	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
@@ -127,7 +187,7 @@ static int rk808_clkout_probe(struct platform_device *pdev)
 		return ret;
 
 	init.name = "rk808-clkout2";
-	init.ops = &rk808_clkout2_ops;
+	init.ops = rkpmic_get_ops(rk808->variant);
 	rk808_clkout->clkout2_hw.init = &init;
 
 	/* optional override of the clockname */
-- 
1.9.1



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

* [PATCH 5/5] clk: RK808: add clkout driver for RK809 and RK817.
@ 2018-07-23  8:40   ` Tony Xie
  0 siblings, 0 replies; 33+ messages in thread
From: Tony Xie @ 2018-07-23  8:40 UTC (permalink / raw)
  To: linux-arm-kernel

RK809 and RK817 are power management IC chips for multimedia products.
most of their functions and registers are same, including the clkout
funciton.

Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
---
 drivers/clk/Kconfig     |  6 ++---
 drivers/clk/clk-rk808.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 721572a..fc1427c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -46,11 +46,11 @@ config COMMON_CLK_MAX77686
 	  clock.
 
 config COMMON_CLK_RK808
-	tristate "Clock driver for RK805/RK808/RK818"
+	tristate "Clock driver for RK805/RK808/RK809/RK817/RK818"
 	depends on MFD_RK808
 	---help---
-	  This driver supports RK805, RK808 and RK818 crystal oscillator clock. These
-	  multi-function devices have two fixed-rate oscillators,
+	  This driver supports RK805, RK809 and RK817, RK808 and RK818 crystal oscillator clock.
+          These multi-function devices have two fixed-rate oscillators,
 	  clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
 	  by control register.
 
diff --git a/drivers/clk/clk-rk808.c b/drivers/clk/clk-rk808.c
index 6461f28..c5d3492 100644
--- a/drivers/clk/clk-rk808.c
+++ b/drivers/clk/clk-rk808.c
@@ -96,6 +96,66 @@ static int rk808_clkout2_is_prepared(struct clk_hw *hw)
 	return idx ? &rk808_clkout->clkout2_hw : &rk808_clkout->clkout1_hw;
 }
 
+static int rk817_clkout2_enable(struct clk_hw *hw, bool enable)
+{
+	struct rk808_clkout *rk808_clkout = container_of(hw,
+							 struct rk808_clkout,
+							 clkout2_hw);
+	struct rk808 *rk808 = rk808_clkout->rk808;
+
+	return regmap_update_bits(rk808->regmap, RK817_SYS_CFG(1),
+				  RK817_CLK32KOUT2_EN,
+				  enable ? RK817_CLK32KOUT2_EN : 0);
+}
+
+static int rk817_clkout2_prepare(struct clk_hw *hw)
+{
+	return rk817_clkout2_enable(hw, true);
+}
+
+static void rk817_clkout2_unprepare(struct clk_hw *hw)
+{
+	rk817_clkout2_enable(hw, false);
+}
+
+static int rk817_clkout2_is_prepared(struct clk_hw *hw)
+{
+	struct rk808_clkout *rk808_clkout = container_of(hw,
+							 struct rk808_clkout,
+							 clkout2_hw);
+	struct rk808 *rk808 = rk808_clkout->rk808;
+	unsigned int val;
+
+	int ret = regmap_read(rk808->regmap, RK817_SYS_CFG(1), &val);
+
+	if (ret < 0)
+		return ret;
+
+	return (val & RK817_CLK32KOUT2_EN) ? 1 : 0;
+}
+
+static const struct clk_ops rk817_clkout2_ops = {
+	.prepare = rk817_clkout2_prepare,
+	.unprepare = rk817_clkout2_unprepare,
+	.is_prepared = rk817_clkout2_is_prepared,
+	.recalc_rate = rk808_clkout_recalc_rate,
+};
+
+static const struct clk_ops *rkpmic_get_ops(long variant)
+{
+	switch (variant) {
+	case RK809_ID:
+	case RK817_ID:
+		return &rk817_clkout2_ops;
+	case RK805_ID:
+	case RK808_ID:
+	case RK818_ID:
+		return &rk808_clkout2_ops;
+	}
+
+	return &rk808_clkout2_ops;
+}
+
 static int rk808_clkout_probe(struct platform_device *pdev)
 {
 	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
@@ -127,7 +187,7 @@ static int rk808_clkout_probe(struct platform_device *pdev)
 		return ret;
 
 	init.name = "rk808-clkout2";
-	init.ops = &rk808_clkout2_ops;
+	init.ops = rkpmic_get_ops(rk808->variant);
 	rk808_clkout->clkout2_hw.init = &init;
 
 	/* optional override of the clockname */
-- 
1.9.1

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

* Re: [PATCH 4/5] RTC: RK808: add RTC driver for RK809 and RK817.
  2018-07-23  3:19   ` Tony Xie
@ 2018-07-23  8:52     ` Alexandre Belloni
  -1 siblings, 0 replies; 33+ messages in thread
From: Alexandre Belloni @ 2018-07-23  8:52 UTC (permalink / raw)
  To: Tony Xie
  Cc: heiko, broonie, lee.jones, a.zummo, sboyd, linux-clk, linux-rtc,
	linux-arm-kernel, linux-rockchip, devicetree, linux-kernel,
	chenjh, xsf, zhangqing, huangtao

Hi,

The subject should be rtc: rk808: add RK809 and RK817 support

With that fixed:

On 23/07/2018 11:19:04+0800, Tony Xie wrote:
> RK809 and RK817 are power management IC chips for multimedia products.
> Most of their functions and registers are same, including the rtc.
> 
> Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

> ---
>  drivers/rtc/Kconfig     |  4 +--
>  drivers/rtc/rtc-rk808.c | 68 +++++++++++++++++++++++++++++++++++++++----------
>  2 files changed, 56 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index a2ba5db..1aaf935 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -371,11 +371,11 @@ config RTC_DRV_MAX77686
>  	  will be called rtc-max77686.
>  
>  config RTC_DRV_RK808
> -	tristate "Rockchip RK805/RK808/RK818 RTC"
> +	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC"
>  	depends on MFD_RK808
>  	help
>  	  If you say yes here you will get support for the
> -	  RTC of RK805, RK808 and RK818 PMIC.
> +	  RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC.
>  
>  	  This driver can also be built as a module. If so, the module
>  	  will be called rk808-rtc.
> diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
> index 739c0d4..5bacdaf 100644
> --- a/drivers/rtc/rtc-rk808.c
> +++ b/drivers/rtc/rtc-rk808.c
> @@ -50,9 +50,18 @@
>  #define NUM_TIME_REGS	(RK808_WEEKS_REG - RK808_SECONDS_REG + 1)
>  #define NUM_ALARM_REGS	(RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1)
>  
> +struct rk_rtc_compat_reg {
> +	unsigned int ctrl_reg;
> +	unsigned int status_reg;
> +	unsigned int alarm_seconds_reg;
> +	unsigned int int_reg;
> +	unsigned int seconds_reg;
> +};
> +
>  struct rk808_rtc {
>  	struct rk808 *rk808;
>  	struct rtc_device *rtc;
> +	struct rk_rtc_compat_reg *creg;
>  	int irq;
>  };
>  
> @@ -101,7 +110,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
>  	int ret;
>  
>  	/* Force an update of the shadowed registers right now */
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
>  				 BIT_RTC_CTRL_REG_RTC_GET_TIME,
>  				 BIT_RTC_CTRL_REG_RTC_GET_TIME);
>  	if (ret) {
> @@ -115,7 +124,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
>  	 * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
>  	 * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
>  	 */
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
>  				 BIT_RTC_CTRL_REG_RTC_GET_TIME,
>  				 0);
>  	if (ret) {
> @@ -123,7 +132,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
>  		return ret;
>  	}
>  
> -	ret = regmap_bulk_read(rk808->regmap, RK808_SECONDS_REG,
> +	ret = regmap_bulk_read(rk808->regmap, rk808_rtc->creg->seconds_reg,
>  			       rtc_data, NUM_TIME_REGS);
>  	if (ret) {
>  		dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret);
> @@ -166,7 +175,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
>  	rtc_data[6] = bin2bcd(tm->tm_wday);
>  
>  	/* Stop RTC while updating the RTC registers */
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
>  				 BIT_RTC_CTRL_REG_STOP_RTC_M,
>  				 BIT_RTC_CTRL_REG_STOP_RTC_M);
>  	if (ret) {
> @@ -174,14 +183,14 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
>  		return ret;
>  	}
>  
> -	ret = regmap_bulk_write(rk808->regmap, RK808_SECONDS_REG,
> +	ret = regmap_bulk_write(rk808->regmap, rk808_rtc->creg->seconds_reg,
>  				rtc_data, NUM_TIME_REGS);
>  	if (ret) {
>  		dev_err(dev, "Failed to bull write rtc_data: %d\n", ret);
>  		return ret;
>  	}
>  	/* Start RTC again */
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
>  				 BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
>  	if (ret) {
>  		dev_err(dev, "Failed to update RTC control: %d\n", ret);
> @@ -199,8 +208,13 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
>  	uint32_t int_reg;
>  	int ret;
>  
> -	ret = regmap_bulk_read(rk808->regmap, RK808_ALARM_SECONDS_REG,
> +	ret = regmap_bulk_read(rk808->regmap,
> +			       rk808_rtc->creg->alarm_seconds_reg,
>  			       alrm_data, NUM_ALARM_REGS);
> +	if (ret) {
> +		dev_err(dev, "Failed to read RTC alarm date REG: %d\n", ret);
> +		return ret;
> +	}
>  
>  	alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK);
>  	alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK);
> @@ -210,7 +224,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
>  	alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100;
>  	rockchip_to_gregorian(&alrm->time);
>  
> -	ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg);
> +	ret = regmap_read(rk808->regmap, rk808_rtc->creg->int_reg, &int_reg);
>  	if (ret) {
>  		dev_err(dev, "Failed to read RTC INT REG: %d\n", ret);
>  		return ret;
> @@ -231,7 +245,7 @@ static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
>  	struct rk808 *rk808 = rk808_rtc->rk808;
>  	int ret;
>  
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
>  				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0);
>  
>  	return ret;
> @@ -242,7 +256,7 @@ static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
>  	struct rk808 *rk808 = rk808_rtc->rk808;
>  	int ret;
>  
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
>  				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M,
>  				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
>  
> @@ -274,7 +288,8 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
>  	alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1);
>  	alrm_data[5] = bin2bcd(alrm->time.tm_year - 100);
>  
> -	ret = regmap_bulk_write(rk808->regmap, RK808_ALARM_SECONDS_REG,
> +	ret = regmap_bulk_write(rk808->regmap,
> +				rk808_rtc->creg->alarm_seconds_reg,
>  				alrm_data, NUM_ALARM_REGS);
>  	if (ret) {
>  		dev_err(dev, "Failed to bulk write: %d\n", ret);
> @@ -318,7 +333,7 @@ static irqreturn_t rk808_alarm_irq(int irq, void *data)
>  	struct i2c_client *client = rk808->i2c;
>  	int ret;
>  
> -	ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
> +	ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
>  			   RTC_STATUS_MASK);
>  	if (ret) {
>  		dev_err(&client->dev,
> @@ -371,6 +386,22 @@ static int rk808_rtc_resume(struct device *dev)
>  static SIMPLE_DEV_PM_OPS(rk808_rtc_pm_ops,
>  	rk808_rtc_suspend, rk808_rtc_resume);
>  
> +static struct rk_rtc_compat_reg rk808_creg = {
> +	.ctrl_reg = RK808_RTC_CTRL_REG,
> +	.status_reg = RK808_RTC_STATUS_REG,
> +	.alarm_seconds_reg = RK808_ALARM_SECONDS_REG,
> +	.int_reg = RK808_RTC_INT_REG,
> +	.seconds_reg = RK808_SECONDS_REG,
> +};
> +
> +static struct rk_rtc_compat_reg rk817_creg = {
> +	.ctrl_reg = RK817_RTC_CTRL_REG,
> +	.status_reg = RK817_RTC_STATUS_REG,
> +	.alarm_seconds_reg = RK817_ALARM_SECONDS_REG,
> +	.int_reg = RK817_RTC_INT_REG,
> +	.seconds_reg = RK817_SECONDS_REG,
> +};
> +
>  static int rk808_rtc_probe(struct platform_device *pdev)
>  {
>  	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
> @@ -381,11 +412,20 @@ static int rk808_rtc_probe(struct platform_device *pdev)
>  	if (rk808_rtc == NULL)
>  		return -ENOMEM;
>  
> +	switch (rk808->variant) {
> +	case RK809_ID:
> +	case RK817_ID:
> +		rk808_rtc->creg = &rk817_creg;
> +		break;
> +	default:
> +		rk808_rtc->creg = &rk808_creg;
> +		break;
> +	}
>  	platform_set_drvdata(pdev, rk808_rtc);
>  	rk808_rtc->rk808 = rk808;
>  
>  	/* start rtc running by default, and use shadowed timer. */
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
>  				 BIT_RTC_CTRL_REG_STOP_RTC_M |
>  				 BIT_RTC_CTRL_REG_RTC_READSEL_M,
>  				 BIT_RTC_CTRL_REG_RTC_READSEL_M);
> @@ -395,7 +435,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> -	ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
> +	ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
>  			   RTC_STATUS_MASK);
>  	if (ret) {
>  		dev_err(&pdev->dev,
> -- 
> 1.9.1
> 
> 

-- 
Alexandre Belloni, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

* [PATCH 4/5] RTC: RK808: add RTC driver for RK809 and RK817.
@ 2018-07-23  8:52     ` Alexandre Belloni
  0 siblings, 0 replies; 33+ messages in thread
From: Alexandre Belloni @ 2018-07-23  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

The subject should be rtc: rk808: add RK809 and RK817 support

With that fixed:

On 23/07/2018 11:19:04+0800, Tony Xie wrote:
> RK809 and RK817 are power management IC chips for multimedia products.
> Most of their functions and registers are same, including the rtc.
> 
> Signed-off-by: Tony Xie <tony.xie@rock-chips.com>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

> ---
>  drivers/rtc/Kconfig     |  4 +--
>  drivers/rtc/rtc-rk808.c | 68 +++++++++++++++++++++++++++++++++++++++----------
>  2 files changed, 56 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index a2ba5db..1aaf935 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -371,11 +371,11 @@ config RTC_DRV_MAX77686
>  	  will be called rtc-max77686.
>  
>  config RTC_DRV_RK808
> -	tristate "Rockchip RK805/RK808/RK818 RTC"
> +	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC"
>  	depends on MFD_RK808
>  	help
>  	  If you say yes here you will get support for the
> -	  RTC of RK805, RK808 and RK818 PMIC.
> +	  RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC.
>  
>  	  This driver can also be built as a module. If so, the module
>  	  will be called rk808-rtc.
> diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c
> index 739c0d4..5bacdaf 100644
> --- a/drivers/rtc/rtc-rk808.c
> +++ b/drivers/rtc/rtc-rk808.c
> @@ -50,9 +50,18 @@
>  #define NUM_TIME_REGS	(RK808_WEEKS_REG - RK808_SECONDS_REG + 1)
>  #define NUM_ALARM_REGS	(RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1)
>  
> +struct rk_rtc_compat_reg {
> +	unsigned int ctrl_reg;
> +	unsigned int status_reg;
> +	unsigned int alarm_seconds_reg;
> +	unsigned int int_reg;
> +	unsigned int seconds_reg;
> +};
> +
>  struct rk808_rtc {
>  	struct rk808 *rk808;
>  	struct rtc_device *rtc;
> +	struct rk_rtc_compat_reg *creg;
>  	int irq;
>  };
>  
> @@ -101,7 +110,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
>  	int ret;
>  
>  	/* Force an update of the shadowed registers right now */
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
>  				 BIT_RTC_CTRL_REG_RTC_GET_TIME,
>  				 BIT_RTC_CTRL_REG_RTC_GET_TIME);
>  	if (ret) {
> @@ -115,7 +124,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
>  	 * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
>  	 * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
>  	 */
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
>  				 BIT_RTC_CTRL_REG_RTC_GET_TIME,
>  				 0);
>  	if (ret) {
> @@ -123,7 +132,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
>  		return ret;
>  	}
>  
> -	ret = regmap_bulk_read(rk808->regmap, RK808_SECONDS_REG,
> +	ret = regmap_bulk_read(rk808->regmap, rk808_rtc->creg->seconds_reg,
>  			       rtc_data, NUM_TIME_REGS);
>  	if (ret) {
>  		dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret);
> @@ -166,7 +175,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
>  	rtc_data[6] = bin2bcd(tm->tm_wday);
>  
>  	/* Stop RTC while updating the RTC registers */
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
>  				 BIT_RTC_CTRL_REG_STOP_RTC_M,
>  				 BIT_RTC_CTRL_REG_STOP_RTC_M);
>  	if (ret) {
> @@ -174,14 +183,14 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
>  		return ret;
>  	}
>  
> -	ret = regmap_bulk_write(rk808->regmap, RK808_SECONDS_REG,
> +	ret = regmap_bulk_write(rk808->regmap, rk808_rtc->creg->seconds_reg,
>  				rtc_data, NUM_TIME_REGS);
>  	if (ret) {
>  		dev_err(dev, "Failed to bull write rtc_data: %d\n", ret);
>  		return ret;
>  	}
>  	/* Start RTC again */
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
>  				 BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
>  	if (ret) {
>  		dev_err(dev, "Failed to update RTC control: %d\n", ret);
> @@ -199,8 +208,13 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
>  	uint32_t int_reg;
>  	int ret;
>  
> -	ret = regmap_bulk_read(rk808->regmap, RK808_ALARM_SECONDS_REG,
> +	ret = regmap_bulk_read(rk808->regmap,
> +			       rk808_rtc->creg->alarm_seconds_reg,
>  			       alrm_data, NUM_ALARM_REGS);
> +	if (ret) {
> +		dev_err(dev, "Failed to read RTC alarm date REG: %d\n", ret);
> +		return ret;
> +	}
>  
>  	alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK);
>  	alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK);
> @@ -210,7 +224,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
>  	alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100;
>  	rockchip_to_gregorian(&alrm->time);
>  
> -	ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg);
> +	ret = regmap_read(rk808->regmap, rk808_rtc->creg->int_reg, &int_reg);
>  	if (ret) {
>  		dev_err(dev, "Failed to read RTC INT REG: %d\n", ret);
>  		return ret;
> @@ -231,7 +245,7 @@ static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
>  	struct rk808 *rk808 = rk808_rtc->rk808;
>  	int ret;
>  
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
>  				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0);
>  
>  	return ret;
> @@ -242,7 +256,7 @@ static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
>  	struct rk808 *rk808 = rk808_rtc->rk808;
>  	int ret;
>  
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
>  				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M,
>  				 BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
>  
> @@ -274,7 +288,8 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
>  	alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1);
>  	alrm_data[5] = bin2bcd(alrm->time.tm_year - 100);
>  
> -	ret = regmap_bulk_write(rk808->regmap, RK808_ALARM_SECONDS_REG,
> +	ret = regmap_bulk_write(rk808->regmap,
> +				rk808_rtc->creg->alarm_seconds_reg,
>  				alrm_data, NUM_ALARM_REGS);
>  	if (ret) {
>  		dev_err(dev, "Failed to bulk write: %d\n", ret);
> @@ -318,7 +333,7 @@ static irqreturn_t rk808_alarm_irq(int irq, void *data)
>  	struct i2c_client *client = rk808->i2c;
>  	int ret;
>  
> -	ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
> +	ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
>  			   RTC_STATUS_MASK);
>  	if (ret) {
>  		dev_err(&client->dev,
> @@ -371,6 +386,22 @@ static int rk808_rtc_resume(struct device *dev)
>  static SIMPLE_DEV_PM_OPS(rk808_rtc_pm_ops,
>  	rk808_rtc_suspend, rk808_rtc_resume);
>  
> +static struct rk_rtc_compat_reg rk808_creg = {
> +	.ctrl_reg = RK808_RTC_CTRL_REG,
> +	.status_reg = RK808_RTC_STATUS_REG,
> +	.alarm_seconds_reg = RK808_ALARM_SECONDS_REG,
> +	.int_reg = RK808_RTC_INT_REG,
> +	.seconds_reg = RK808_SECONDS_REG,
> +};
> +
> +static struct rk_rtc_compat_reg rk817_creg = {
> +	.ctrl_reg = RK817_RTC_CTRL_REG,
> +	.status_reg = RK817_RTC_STATUS_REG,
> +	.alarm_seconds_reg = RK817_ALARM_SECONDS_REG,
> +	.int_reg = RK817_RTC_INT_REG,
> +	.seconds_reg = RK817_SECONDS_REG,
> +};
> +
>  static int rk808_rtc_probe(struct platform_device *pdev)
>  {
>  	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
> @@ -381,11 +412,20 @@ static int rk808_rtc_probe(struct platform_device *pdev)
>  	if (rk808_rtc == NULL)
>  		return -ENOMEM;
>  
> +	switch (rk808->variant) {
> +	case RK809_ID:
> +	case RK817_ID:
> +		rk808_rtc->creg = &rk817_creg;
> +		break;
> +	default:
> +		rk808_rtc->creg = &rk808_creg;
> +		break;
> +	}
>  	platform_set_drvdata(pdev, rk808_rtc);
>  	rk808_rtc->rk808 = rk808;
>  
>  	/* start rtc running by default, and use shadowed timer. */
> -	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,
> +	ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
>  				 BIT_RTC_CTRL_REG_STOP_RTC_M |
>  				 BIT_RTC_CTRL_REG_RTC_READSEL_M,
>  				 BIT_RTC_CTRL_REG_RTC_READSEL_M);
> @@ -395,7 +435,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> -	ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG,
> +	ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
>  			   RTC_STATUS_MASK);
>  	if (ret) {
>  		dev_err(&pdev->dev,
> -- 
> 1.9.1
> 
> 

-- 
Alexandre Belloni, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

* Re: [PATCH 1/5] mfd: rk808: Add RK817 and RK809 support
  2018-07-23  3:19   ` Tony Xie
  (?)
  (?)
@ 2018-07-23 21:59     ` kbuild test robot
  -1 siblings, 0 replies; 33+ messages in thread
From: kbuild test robot @ 2018-07-23 21:59 UTC (permalink / raw)
  To: Tony Xie
  Cc: linux-rtc, a.zummo, alexandre.belloni, tony.xie, huangtao, heiko,
	devicetree, sboyd, zhangqing, linux-kernel, xsf, linux-rockchip,
	broonie, kbuild-all, lee.jones, linux-clk, linux-arm-kernel,
	chenjh

[-- Attachment #1: Type: text/plain, Size: 11770 bytes --]

Hi Tony,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on ljones-mfd/for-mfd-next]
[also build test WARNING on v4.18-rc6 next-20180723]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Tony-Xie/mfd-rk808-Add-RK817-and-RK809-support/20180724-040547
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=xtensa 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   drivers//mfd/rk808.c: In function 'rk808_probe':
>> drivers//mfd/rk808.c:715:16: warning: 'pm_pwroff_fn' may be used uninitialized in this function [-Wmaybe-uninitialized]
      pm_power_off = pm_pwroff_fn;
      ~~~~~~~~~~~~~^~~~~~~~~~~~~~

vim +/pm_pwroff_fn +715 drivers//mfd/rk808.c

2eedcbfc0 Wadim Egorov    2016-08-29  581  
f69a7cf74 Chris Zhong     2014-09-03  582  static int rk808_probe(struct i2c_client *client,
f69a7cf74 Chris Zhong     2014-09-03  583  		       const struct i2c_device_id *id)
f69a7cf74 Chris Zhong     2014-09-03  584  {
f69a7cf74 Chris Zhong     2014-09-03  585  	struct device_node *np = client->dev.of_node;
f69a7cf74 Chris Zhong     2014-09-03  586  	struct rk808 *rk808;
2eedcbfc0 Wadim Egorov    2016-08-29  587  	const struct rk808_reg_data *pre_init_reg;
2eedcbfc0 Wadim Egorov    2016-08-29  588  	const struct mfd_cell *cells;
b2e2c8509 Jianhong Chen   2016-10-17  589  	void (*pm_pwroff_fn)(void);
2eedcbfc0 Wadim Egorov    2016-08-29  590  	int nr_pre_init_regs;
2eedcbfc0 Wadim Egorov    2016-08-29  591  	int nr_cells;
9d6105e19 Elaine Zhang    2017-08-21  592  	int pm_off = 0, msb, lsb;
1e99c2e53 Tony Xie        2018-07-23  593  	unsigned char pmic_id_msb = RK808_ID_MSB, pmic_id_lsb = RK808_ID_LSB;
f69a7cf74 Chris Zhong     2014-09-03  594  	int ret;
f69a7cf74 Chris Zhong     2014-09-03  595  	int i;
f69a7cf74 Chris Zhong     2014-09-03  596  
f69a7cf74 Chris Zhong     2014-09-03  597  	rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
f69a7cf74 Chris Zhong     2014-09-03  598  	if (!rk808)
f69a7cf74 Chris Zhong     2014-09-03  599  		return -ENOMEM;
f69a7cf74 Chris Zhong     2014-09-03  600  
1e99c2e53 Tony Xie        2018-07-23  601  	if (of_device_is_compatible(np, "rockchip,rk817") ||
1e99c2e53 Tony Xie        2018-07-23  602  	    of_device_is_compatible(np, "rockchip,rk809")) {
1e99c2e53 Tony Xie        2018-07-23  603  		pmic_id_msb = RK817_ID_MSB;
1e99c2e53 Tony Xie        2018-07-23  604  		pmic_id_lsb = RK817_ID_LSB;
1e99c2e53 Tony Xie        2018-07-23  605  	}
9d6105e19 Elaine Zhang    2017-08-21  606  	/* Read chip variant */
1e99c2e53 Tony Xie        2018-07-23  607  	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
9d6105e19 Elaine Zhang    2017-08-21  608  	if (msb < 0) {
9d6105e19 Elaine Zhang    2017-08-21  609  		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
2eedcbfc0 Wadim Egorov    2016-08-29  610  			RK808_ID_MSB);
9d6105e19 Elaine Zhang    2017-08-21  611  		return msb;
2eedcbfc0 Wadim Egorov    2016-08-29  612  	}
2eedcbfc0 Wadim Egorov    2016-08-29  613  
1e99c2e53 Tony Xie        2018-07-23  614  	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
9d6105e19 Elaine Zhang    2017-08-21  615  	if (lsb < 0) {
9d6105e19 Elaine Zhang    2017-08-21  616  		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
9d6105e19 Elaine Zhang    2017-08-21  617  			RK808_ID_LSB);
9d6105e19 Elaine Zhang    2017-08-21  618  		return lsb;
9d6105e19 Elaine Zhang    2017-08-21  619  	}
9d6105e19 Elaine Zhang    2017-08-21  620  
9d6105e19 Elaine Zhang    2017-08-21  621  	rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
9d6105e19 Elaine Zhang    2017-08-21  622  	dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
2eedcbfc0 Wadim Egorov    2016-08-29  623  
2eedcbfc0 Wadim Egorov    2016-08-29  624  	switch (rk808->variant) {
990f05f6a Elaine Zhang    2017-08-21  625  	case RK805_ID:
990f05f6a Elaine Zhang    2017-08-21  626  		rk808->regmap_cfg = &rk805_regmap_config;
990f05f6a Elaine Zhang    2017-08-21  627  		rk808->regmap_irq_chip = &rk805_irq_chip;
990f05f6a Elaine Zhang    2017-08-21  628  		pre_init_reg = rk805_pre_init_reg;
990f05f6a Elaine Zhang    2017-08-21  629  		nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
990f05f6a Elaine Zhang    2017-08-21  630  		cells = rk805s;
990f05f6a Elaine Zhang    2017-08-21  631  		nr_cells = ARRAY_SIZE(rk805s);
990f05f6a Elaine Zhang    2017-08-21  632  		pm_pwroff_fn = rk805_device_shutdown;
990f05f6a Elaine Zhang    2017-08-21  633  		break;
2eedcbfc0 Wadim Egorov    2016-08-29  634  	case RK808_ID:
2eedcbfc0 Wadim Egorov    2016-08-29  635  		rk808->regmap_cfg = &rk808_regmap_config;
2eedcbfc0 Wadim Egorov    2016-08-29  636  		rk808->regmap_irq_chip = &rk808_irq_chip;
2eedcbfc0 Wadim Egorov    2016-08-29  637  		pre_init_reg = rk808_pre_init_reg;
2eedcbfc0 Wadim Egorov    2016-08-29  638  		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
2eedcbfc0 Wadim Egorov    2016-08-29  639  		cells = rk808s;
2eedcbfc0 Wadim Egorov    2016-08-29  640  		nr_cells = ARRAY_SIZE(rk808s);
b2e2c8509 Jianhong Chen   2016-10-17  641  		pm_pwroff_fn = rk808_device_shutdown;
2eedcbfc0 Wadim Egorov    2016-08-29  642  		break;
2eedcbfc0 Wadim Egorov    2016-08-29  643  	case RK818_ID:
2eedcbfc0 Wadim Egorov    2016-08-29  644  		rk808->regmap_cfg = &rk818_regmap_config;
2eedcbfc0 Wadim Egorov    2016-08-29  645  		rk808->regmap_irq_chip = &rk818_irq_chip;
2eedcbfc0 Wadim Egorov    2016-08-29  646  		pre_init_reg = rk818_pre_init_reg;
2eedcbfc0 Wadim Egorov    2016-08-29  647  		nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
2eedcbfc0 Wadim Egorov    2016-08-29  648  		cells = rk818s;
2eedcbfc0 Wadim Egorov    2016-08-29  649  		nr_cells = ARRAY_SIZE(rk818s);
b2e2c8509 Jianhong Chen   2016-10-17  650  		pm_pwroff_fn = rk818_device_shutdown;
2eedcbfc0 Wadim Egorov    2016-08-29  651  		break;
1e99c2e53 Tony Xie        2018-07-23  652  	case RK809_ID:
1e99c2e53 Tony Xie        2018-07-23  653  	case RK817_ID:
1e99c2e53 Tony Xie        2018-07-23  654  		rk808->regmap_cfg = &rk817_regmap_config;
1e99c2e53 Tony Xie        2018-07-23  655  		rk808->regmap_irq_chip = &rk817_irq_chip;
1e99c2e53 Tony Xie        2018-07-23  656  		pre_init_reg = rk817_pre_init_reg;
1e99c2e53 Tony Xie        2018-07-23  657  		nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
1e99c2e53 Tony Xie        2018-07-23  658  		cells = rk817s;
1e99c2e53 Tony Xie        2018-07-23  659  		nr_cells = ARRAY_SIZE(rk817s);
1e99c2e53 Tony Xie        2018-07-23  660  		pm_power_off_prepare = rk8xx_device_shutdown_prepare;
1e99c2e53 Tony Xie        2018-07-23  661  		break;
2eedcbfc0 Wadim Egorov    2016-08-29  662  	default:
2eedcbfc0 Wadim Egorov    2016-08-29  663  		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
2eedcbfc0 Wadim Egorov    2016-08-29  664  			rk808->variant);
2eedcbfc0 Wadim Egorov    2016-08-29  665  		return -EINVAL;
2eedcbfc0 Wadim Egorov    2016-08-29  666  	}
2eedcbfc0 Wadim Egorov    2016-08-29  667  
2eedcbfc0 Wadim Egorov    2016-08-29  668  	rk808->i2c = client;
2eedcbfc0 Wadim Egorov    2016-08-29  669  	i2c_set_clientdata(client, rk808);
2eedcbfc0 Wadim Egorov    2016-08-29  670  
2eedcbfc0 Wadim Egorov    2016-08-29  671  	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
f69a7cf74 Chris Zhong     2014-09-03  672  	if (IS_ERR(rk808->regmap)) {
f69a7cf74 Chris Zhong     2014-09-03  673  		dev_err(&client->dev, "regmap initialization failed\n");
f69a7cf74 Chris Zhong     2014-09-03  674  		return PTR_ERR(rk808->regmap);
f69a7cf74 Chris Zhong     2014-09-03  675  	}
f69a7cf74 Chris Zhong     2014-09-03  676  
2eedcbfc0 Wadim Egorov    2016-08-29  677  	if (!client->irq) {
2eedcbfc0 Wadim Egorov    2016-08-29  678  		dev_err(&client->dev, "No interrupt support, no core IRQ\n");
2eedcbfc0 Wadim Egorov    2016-08-29  679  		return -EINVAL;
f69a7cf74 Chris Zhong     2014-09-03  680  	}
f69a7cf74 Chris Zhong     2014-09-03  681  
f69a7cf74 Chris Zhong     2014-09-03  682  	ret = regmap_add_irq_chip(rk808->regmap, client->irq,
f69a7cf74 Chris Zhong     2014-09-03  683  				  IRQF_ONESHOT, -1,
2eedcbfc0 Wadim Egorov    2016-08-29  684  				  rk808->regmap_irq_chip, &rk808->irq_data);
f69a7cf74 Chris Zhong     2014-09-03  685  	if (ret) {
f69a7cf74 Chris Zhong     2014-09-03  686  		dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
f69a7cf74 Chris Zhong     2014-09-03  687  		return ret;
f69a7cf74 Chris Zhong     2014-09-03  688  	}
f69a7cf74 Chris Zhong     2014-09-03  689  
2eedcbfc0 Wadim Egorov    2016-08-29  690  	for (i = 0; i < nr_pre_init_regs; i++) {
2eedcbfc0 Wadim Egorov    2016-08-29  691  		ret = regmap_update_bits(rk808->regmap,
2eedcbfc0 Wadim Egorov    2016-08-29  692  					pre_init_reg[i].addr,
2eedcbfc0 Wadim Egorov    2016-08-29  693  					pre_init_reg[i].mask,
2eedcbfc0 Wadim Egorov    2016-08-29  694  					pre_init_reg[i].value);
2eedcbfc0 Wadim Egorov    2016-08-29  695  		if (ret) {
2eedcbfc0 Wadim Egorov    2016-08-29  696  			dev_err(&client->dev,
2eedcbfc0 Wadim Egorov    2016-08-29  697  				"0x%x write err\n",
2eedcbfc0 Wadim Egorov    2016-08-29  698  				pre_init_reg[i].addr);
2eedcbfc0 Wadim Egorov    2016-08-29  699  			return ret;
2eedcbfc0 Wadim Egorov    2016-08-29  700  		}
2eedcbfc0 Wadim Egorov    2016-08-29  701  	}
f69a7cf74 Chris Zhong     2014-09-03  702  
2eedcbfc0 Wadim Egorov    2016-08-29  703  	ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
2eedcbfc0 Wadim Egorov    2016-08-29  704  			      cells, nr_cells, NULL, 0,
d5623161a Laxman Dewangan 2016-04-08  705  			      regmap_irq_get_domain(rk808->irq_data));
f69a7cf74 Chris Zhong     2014-09-03  706  	if (ret) {
f69a7cf74 Chris Zhong     2014-09-03  707  		dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
f69a7cf74 Chris Zhong     2014-09-03  708  		goto err_irq;
f69a7cf74 Chris Zhong     2014-09-03  709  	}
f69a7cf74 Chris Zhong     2014-09-03  710  
f69a7cf74 Chris Zhong     2014-09-03  711  	pm_off = of_property_read_bool(np,
f69a7cf74 Chris Zhong     2014-09-03  712  				"rockchip,system-power-controller");
f69a7cf74 Chris Zhong     2014-09-03  713  	if (pm_off && !pm_power_off) {
f69a7cf74 Chris Zhong     2014-09-03  714  		rk808_i2c_client = client;
b2e2c8509 Jianhong Chen   2016-10-17 @715  		pm_power_off = pm_pwroff_fn;
f69a7cf74 Chris Zhong     2014-09-03  716  	}
f69a7cf74 Chris Zhong     2014-09-03  717  
f69a7cf74 Chris Zhong     2014-09-03  718  	return 0;
f69a7cf74 Chris Zhong     2014-09-03  719  
f69a7cf74 Chris Zhong     2014-09-03  720  err_irq:
f69a7cf74 Chris Zhong     2014-09-03  721  	regmap_del_irq_chip(client->irq, rk808->irq_data);
f69a7cf74 Chris Zhong     2014-09-03  722  	return ret;
f69a7cf74 Chris Zhong     2014-09-03  723  }
f69a7cf74 Chris Zhong     2014-09-03  724  

:::::: The code at line 715 was first introduced by commit
:::::: b2e2c85091710159b305735d557f4ef4695f5dff mfd: rk808: RK818 uses DEV_OFF to power off supplies

:::::: TO: Jianhong Chen <chenjh@rock-chips.com>
:::::: CC: Lee Jones <lee.jones@linaro.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 54212 bytes --]

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 1/5] mfd: rk808: Add RK817 and RK809 support
@ 2018-07-23 21:59     ` kbuild test robot
  0 siblings, 0 replies; 33+ messages in thread
From: kbuild test robot @ 2018-07-23 21:59 UTC (permalink / raw)
  Cc: linux-rtc, a.zummo, alexandre.belloni, tony.xie, huangtao, heiko,
	devicetree, sboyd, zhangqing, linux-kernel, xsf, linux-rockchip,
	broonie, kbuild-all, lee.jones, linux-clk, linux-arm-kernel,
	chenjh

[-- Attachment #1: Type: text/plain, Size: 11770 bytes --]

Hi Tony,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on ljones-mfd/for-mfd-next]
[also build test WARNING on v4.18-rc6 next-20180723]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Tony-Xie/mfd-rk808-Add-RK817-and-RK809-support/20180724-040547
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=xtensa 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   drivers//mfd/rk808.c: In function 'rk808_probe':
>> drivers//mfd/rk808.c:715:16: warning: 'pm_pwroff_fn' may be used uninitialized in this function [-Wmaybe-uninitialized]
      pm_power_off = pm_pwroff_fn;
      ~~~~~~~~~~~~~^~~~~~~~~~~~~~

vim +/pm_pwroff_fn +715 drivers//mfd/rk808.c

2eedcbfc0 Wadim Egorov    2016-08-29  581  
f69a7cf74 Chris Zhong     2014-09-03  582  static int rk808_probe(struct i2c_client *client,
f69a7cf74 Chris Zhong     2014-09-03  583  		       const struct i2c_device_id *id)
f69a7cf74 Chris Zhong     2014-09-03  584  {
f69a7cf74 Chris Zhong     2014-09-03  585  	struct device_node *np = client->dev.of_node;
f69a7cf74 Chris Zhong     2014-09-03  586  	struct rk808 *rk808;
2eedcbfc0 Wadim Egorov    2016-08-29  587  	const struct rk808_reg_data *pre_init_reg;
2eedcbfc0 Wadim Egorov    2016-08-29  588  	const struct mfd_cell *cells;
b2e2c8509 Jianhong Chen   2016-10-17  589  	void (*pm_pwroff_fn)(void);
2eedcbfc0 Wadim Egorov    2016-08-29  590  	int nr_pre_init_regs;
2eedcbfc0 Wadim Egorov    2016-08-29  591  	int nr_cells;
9d6105e19 Elaine Zhang    2017-08-21  592  	int pm_off = 0, msb, lsb;
1e99c2e53 Tony Xie        2018-07-23  593  	unsigned char pmic_id_msb = RK808_ID_MSB, pmic_id_lsb = RK808_ID_LSB;
f69a7cf74 Chris Zhong     2014-09-03  594  	int ret;
f69a7cf74 Chris Zhong     2014-09-03  595  	int i;
f69a7cf74 Chris Zhong     2014-09-03  596  
f69a7cf74 Chris Zhong     2014-09-03  597  	rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
f69a7cf74 Chris Zhong     2014-09-03  598  	if (!rk808)
f69a7cf74 Chris Zhong     2014-09-03  599  		return -ENOMEM;
f69a7cf74 Chris Zhong     2014-09-03  600  
1e99c2e53 Tony Xie        2018-07-23  601  	if (of_device_is_compatible(np, "rockchip,rk817") ||
1e99c2e53 Tony Xie        2018-07-23  602  	    of_device_is_compatible(np, "rockchip,rk809")) {
1e99c2e53 Tony Xie        2018-07-23  603  		pmic_id_msb = RK817_ID_MSB;
1e99c2e53 Tony Xie        2018-07-23  604  		pmic_id_lsb = RK817_ID_LSB;
1e99c2e53 Tony Xie        2018-07-23  605  	}
9d6105e19 Elaine Zhang    2017-08-21  606  	/* Read chip variant */
1e99c2e53 Tony Xie        2018-07-23  607  	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
9d6105e19 Elaine Zhang    2017-08-21  608  	if (msb < 0) {
9d6105e19 Elaine Zhang    2017-08-21  609  		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
2eedcbfc0 Wadim Egorov    2016-08-29  610  			RK808_ID_MSB);
9d6105e19 Elaine Zhang    2017-08-21  611  		return msb;
2eedcbfc0 Wadim Egorov    2016-08-29  612  	}
2eedcbfc0 Wadim Egorov    2016-08-29  613  
1e99c2e53 Tony Xie        2018-07-23  614  	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
9d6105e19 Elaine Zhang    2017-08-21  615  	if (lsb < 0) {
9d6105e19 Elaine Zhang    2017-08-21  616  		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
9d6105e19 Elaine Zhang    2017-08-21  617  			RK808_ID_LSB);
9d6105e19 Elaine Zhang    2017-08-21  618  		return lsb;
9d6105e19 Elaine Zhang    2017-08-21  619  	}
9d6105e19 Elaine Zhang    2017-08-21  620  
9d6105e19 Elaine Zhang    2017-08-21  621  	rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
9d6105e19 Elaine Zhang    2017-08-21  622  	dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
2eedcbfc0 Wadim Egorov    2016-08-29  623  
2eedcbfc0 Wadim Egorov    2016-08-29  624  	switch (rk808->variant) {
990f05f6a Elaine Zhang    2017-08-21  625  	case RK805_ID:
990f05f6a Elaine Zhang    2017-08-21  626  		rk808->regmap_cfg = &rk805_regmap_config;
990f05f6a Elaine Zhang    2017-08-21  627  		rk808->regmap_irq_chip = &rk805_irq_chip;
990f05f6a Elaine Zhang    2017-08-21  628  		pre_init_reg = rk805_pre_init_reg;
990f05f6a Elaine Zhang    2017-08-21  629  		nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
990f05f6a Elaine Zhang    2017-08-21  630  		cells = rk805s;
990f05f6a Elaine Zhang    2017-08-21  631  		nr_cells = ARRAY_SIZE(rk805s);
990f05f6a Elaine Zhang    2017-08-21  632  		pm_pwroff_fn = rk805_device_shutdown;
990f05f6a Elaine Zhang    2017-08-21  633  		break;
2eedcbfc0 Wadim Egorov    2016-08-29  634  	case RK808_ID:
2eedcbfc0 Wadim Egorov    2016-08-29  635  		rk808->regmap_cfg = &rk808_regmap_config;
2eedcbfc0 Wadim Egorov    2016-08-29  636  		rk808->regmap_irq_chip = &rk808_irq_chip;
2eedcbfc0 Wadim Egorov    2016-08-29  637  		pre_init_reg = rk808_pre_init_reg;
2eedcbfc0 Wadim Egorov    2016-08-29  638  		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
2eedcbfc0 Wadim Egorov    2016-08-29  639  		cells = rk808s;
2eedcbfc0 Wadim Egorov    2016-08-29  640  		nr_cells = ARRAY_SIZE(rk808s);
b2e2c8509 Jianhong Chen   2016-10-17  641  		pm_pwroff_fn = rk808_device_shutdown;
2eedcbfc0 Wadim Egorov    2016-08-29  642  		break;
2eedcbfc0 Wadim Egorov    2016-08-29  643  	case RK818_ID:
2eedcbfc0 Wadim Egorov    2016-08-29  644  		rk808->regmap_cfg = &rk818_regmap_config;
2eedcbfc0 Wadim Egorov    2016-08-29  645  		rk808->regmap_irq_chip = &rk818_irq_chip;
2eedcbfc0 Wadim Egorov    2016-08-29  646  		pre_init_reg = rk818_pre_init_reg;
2eedcbfc0 Wadim Egorov    2016-08-29  647  		nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
2eedcbfc0 Wadim Egorov    2016-08-29  648  		cells = rk818s;
2eedcbfc0 Wadim Egorov    2016-08-29  649  		nr_cells = ARRAY_SIZE(rk818s);
b2e2c8509 Jianhong Chen   2016-10-17  650  		pm_pwroff_fn = rk818_device_shutdown;
2eedcbfc0 Wadim Egorov    2016-08-29  651  		break;
1e99c2e53 Tony Xie        2018-07-23  652  	case RK809_ID:
1e99c2e53 Tony Xie        2018-07-23  653  	case RK817_ID:
1e99c2e53 Tony Xie        2018-07-23  654  		rk808->regmap_cfg = &rk817_regmap_config;
1e99c2e53 Tony Xie        2018-07-23  655  		rk808->regmap_irq_chip = &rk817_irq_chip;
1e99c2e53 Tony Xie        2018-07-23  656  		pre_init_reg = rk817_pre_init_reg;
1e99c2e53 Tony Xie        2018-07-23  657  		nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
1e99c2e53 Tony Xie        2018-07-23  658  		cells = rk817s;
1e99c2e53 Tony Xie        2018-07-23  659  		nr_cells = ARRAY_SIZE(rk817s);
1e99c2e53 Tony Xie        2018-07-23  660  		pm_power_off_prepare = rk8xx_device_shutdown_prepare;
1e99c2e53 Tony Xie        2018-07-23  661  		break;
2eedcbfc0 Wadim Egorov    2016-08-29  662  	default:
2eedcbfc0 Wadim Egorov    2016-08-29  663  		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
2eedcbfc0 Wadim Egorov    2016-08-29  664  			rk808->variant);
2eedcbfc0 Wadim Egorov    2016-08-29  665  		return -EINVAL;
2eedcbfc0 Wadim Egorov    2016-08-29  666  	}
2eedcbfc0 Wadim Egorov    2016-08-29  667  
2eedcbfc0 Wadim Egorov    2016-08-29  668  	rk808->i2c = client;
2eedcbfc0 Wadim Egorov    2016-08-29  669  	i2c_set_clientdata(client, rk808);
2eedcbfc0 Wadim Egorov    2016-08-29  670  
2eedcbfc0 Wadim Egorov    2016-08-29  671  	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
f69a7cf74 Chris Zhong     2014-09-03  672  	if (IS_ERR(rk808->regmap)) {
f69a7cf74 Chris Zhong     2014-09-03  673  		dev_err(&client->dev, "regmap initialization failed\n");
f69a7cf74 Chris Zhong     2014-09-03  674  		return PTR_ERR(rk808->regmap);
f69a7cf74 Chris Zhong     2014-09-03  675  	}
f69a7cf74 Chris Zhong     2014-09-03  676  
2eedcbfc0 Wadim Egorov    2016-08-29  677  	if (!client->irq) {
2eedcbfc0 Wadim Egorov    2016-08-29  678  		dev_err(&client->dev, "No interrupt support, no core IRQ\n");
2eedcbfc0 Wadim Egorov    2016-08-29  679  		return -EINVAL;
f69a7cf74 Chris Zhong     2014-09-03  680  	}
f69a7cf74 Chris Zhong     2014-09-03  681  
f69a7cf74 Chris Zhong     2014-09-03  682  	ret = regmap_add_irq_chip(rk808->regmap, client->irq,
f69a7cf74 Chris Zhong     2014-09-03  683  				  IRQF_ONESHOT, -1,
2eedcbfc0 Wadim Egorov    2016-08-29  684  				  rk808->regmap_irq_chip, &rk808->irq_data);
f69a7cf74 Chris Zhong     2014-09-03  685  	if (ret) {
f69a7cf74 Chris Zhong     2014-09-03  686  		dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
f69a7cf74 Chris Zhong     2014-09-03  687  		return ret;
f69a7cf74 Chris Zhong     2014-09-03  688  	}
f69a7cf74 Chris Zhong     2014-09-03  689  
2eedcbfc0 Wadim Egorov    2016-08-29  690  	for (i = 0; i < nr_pre_init_regs; i++) {
2eedcbfc0 Wadim Egorov    2016-08-29  691  		ret = regmap_update_bits(rk808->regmap,
2eedcbfc0 Wadim Egorov    2016-08-29  692  					pre_init_reg[i].addr,
2eedcbfc0 Wadim Egorov    2016-08-29  693  					pre_init_reg[i].mask,
2eedcbfc0 Wadim Egorov    2016-08-29  694  					pre_init_reg[i].value);
2eedcbfc0 Wadim Egorov    2016-08-29  695  		if (ret) {
2eedcbfc0 Wadim Egorov    2016-08-29  696  			dev_err(&client->dev,
2eedcbfc0 Wadim Egorov    2016-08-29  697  				"0x%x write err\n",
2eedcbfc0 Wadim Egorov    2016-08-29  698  				pre_init_reg[i].addr);
2eedcbfc0 Wadim Egorov    2016-08-29  699  			return ret;
2eedcbfc0 Wadim Egorov    2016-08-29  700  		}
2eedcbfc0 Wadim Egorov    2016-08-29  701  	}
f69a7cf74 Chris Zhong     2014-09-03  702  
2eedcbfc0 Wadim Egorov    2016-08-29  703  	ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
2eedcbfc0 Wadim Egorov    2016-08-29  704  			      cells, nr_cells, NULL, 0,
d5623161a Laxman Dewangan 2016-04-08  705  			      regmap_irq_get_domain(rk808->irq_data));
f69a7cf74 Chris Zhong     2014-09-03  706  	if (ret) {
f69a7cf74 Chris Zhong     2014-09-03  707  		dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
f69a7cf74 Chris Zhong     2014-09-03  708  		goto err_irq;
f69a7cf74 Chris Zhong     2014-09-03  709  	}
f69a7cf74 Chris Zhong     2014-09-03  710  
f69a7cf74 Chris Zhong     2014-09-03  711  	pm_off = of_property_read_bool(np,
f69a7cf74 Chris Zhong     2014-09-03  712  				"rockchip,system-power-controller");
f69a7cf74 Chris Zhong     2014-09-03  713  	if (pm_off && !pm_power_off) {
f69a7cf74 Chris Zhong     2014-09-03  714  		rk808_i2c_client = client;
b2e2c8509 Jianhong Chen   2016-10-17 @715  		pm_power_off = pm_pwroff_fn;
f69a7cf74 Chris Zhong     2014-09-03  716  	}
f69a7cf74 Chris Zhong     2014-09-03  717  
f69a7cf74 Chris Zhong     2014-09-03  718  	return 0;
f69a7cf74 Chris Zhong     2014-09-03  719  
f69a7cf74 Chris Zhong     2014-09-03  720  err_irq:
f69a7cf74 Chris Zhong     2014-09-03  721  	regmap_del_irq_chip(client->irq, rk808->irq_data);
f69a7cf74 Chris Zhong     2014-09-03  722  	return ret;
f69a7cf74 Chris Zhong     2014-09-03  723  }
f69a7cf74 Chris Zhong     2014-09-03  724  

:::::: The code at line 715 was first introduced by commit
:::::: b2e2c85091710159b305735d557f4ef4695f5dff mfd: rk808: RK818 uses DEV_OFF to power off supplies

:::::: TO: Jianhong Chen <chenjh@rock-chips.com>
:::::: CC: Lee Jones <lee.jones@linaro.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 54212 bytes --]

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 1/5] mfd: rk808: Add RK817 and RK809 support
@ 2018-07-23 21:59     ` kbuild test robot
  0 siblings, 0 replies; 33+ messages in thread
From: kbuild test robot @ 2018-07-23 21:59 UTC (permalink / raw)
  To: Tony Xie
  Cc: kbuild-all, heiko, broonie, lee.jones, a.zummo, alexandre.belloni,
	sboyd, linux-clk, linux-rtc, linux-arm-kernel, linux-rockchip,
	devicetree, linux-kernel, chenjh, xsf, zhangqing, huangtao,
	tony.xie

[-- Attachment #1: Type: text/plain, Size: 11770 bytes --]

Hi Tony,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on ljones-mfd/for-mfd-next]
[also build test WARNING on v4.18-rc6 next-20180723]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Tony-Xie/mfd-rk808-Add-RK817-and-RK809-support/20180724-040547
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=xtensa 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   drivers//mfd/rk808.c: In function 'rk808_probe':
>> drivers//mfd/rk808.c:715:16: warning: 'pm_pwroff_fn' may be used uninitialized in this function [-Wmaybe-uninitialized]
      pm_power_off = pm_pwroff_fn;
      ~~~~~~~~~~~~~^~~~~~~~~~~~~~

vim +/pm_pwroff_fn +715 drivers//mfd/rk808.c

2eedcbfc0 Wadim Egorov    2016-08-29  581  
f69a7cf74 Chris Zhong     2014-09-03  582  static int rk808_probe(struct i2c_client *client,
f69a7cf74 Chris Zhong     2014-09-03  583  		       const struct i2c_device_id *id)
f69a7cf74 Chris Zhong     2014-09-03  584  {
f69a7cf74 Chris Zhong     2014-09-03  585  	struct device_node *np = client->dev.of_node;
f69a7cf74 Chris Zhong     2014-09-03  586  	struct rk808 *rk808;
2eedcbfc0 Wadim Egorov    2016-08-29  587  	const struct rk808_reg_data *pre_init_reg;
2eedcbfc0 Wadim Egorov    2016-08-29  588  	const struct mfd_cell *cells;
b2e2c8509 Jianhong Chen   2016-10-17  589  	void (*pm_pwroff_fn)(void);
2eedcbfc0 Wadim Egorov    2016-08-29  590  	int nr_pre_init_regs;
2eedcbfc0 Wadim Egorov    2016-08-29  591  	int nr_cells;
9d6105e19 Elaine Zhang    2017-08-21  592  	int pm_off = 0, msb, lsb;
1e99c2e53 Tony Xie        2018-07-23  593  	unsigned char pmic_id_msb = RK808_ID_MSB, pmic_id_lsb = RK808_ID_LSB;
f69a7cf74 Chris Zhong     2014-09-03  594  	int ret;
f69a7cf74 Chris Zhong     2014-09-03  595  	int i;
f69a7cf74 Chris Zhong     2014-09-03  596  
f69a7cf74 Chris Zhong     2014-09-03  597  	rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
f69a7cf74 Chris Zhong     2014-09-03  598  	if (!rk808)
f69a7cf74 Chris Zhong     2014-09-03  599  		return -ENOMEM;
f69a7cf74 Chris Zhong     2014-09-03  600  
1e99c2e53 Tony Xie        2018-07-23  601  	if (of_device_is_compatible(np, "rockchip,rk817") ||
1e99c2e53 Tony Xie        2018-07-23  602  	    of_device_is_compatible(np, "rockchip,rk809")) {
1e99c2e53 Tony Xie        2018-07-23  603  		pmic_id_msb = RK817_ID_MSB;
1e99c2e53 Tony Xie        2018-07-23  604  		pmic_id_lsb = RK817_ID_LSB;
1e99c2e53 Tony Xie        2018-07-23  605  	}
9d6105e19 Elaine Zhang    2017-08-21  606  	/* Read chip variant */
1e99c2e53 Tony Xie        2018-07-23  607  	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
9d6105e19 Elaine Zhang    2017-08-21  608  	if (msb < 0) {
9d6105e19 Elaine Zhang    2017-08-21  609  		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
2eedcbfc0 Wadim Egorov    2016-08-29  610  			RK808_ID_MSB);
9d6105e19 Elaine Zhang    2017-08-21  611  		return msb;
2eedcbfc0 Wadim Egorov    2016-08-29  612  	}
2eedcbfc0 Wadim Egorov    2016-08-29  613  
1e99c2e53 Tony Xie        2018-07-23  614  	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
9d6105e19 Elaine Zhang    2017-08-21  615  	if (lsb < 0) {
9d6105e19 Elaine Zhang    2017-08-21  616  		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
9d6105e19 Elaine Zhang    2017-08-21  617  			RK808_ID_LSB);
9d6105e19 Elaine Zhang    2017-08-21  618  		return lsb;
9d6105e19 Elaine Zhang    2017-08-21  619  	}
9d6105e19 Elaine Zhang    2017-08-21  620  
9d6105e19 Elaine Zhang    2017-08-21  621  	rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
9d6105e19 Elaine Zhang    2017-08-21  622  	dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
2eedcbfc0 Wadim Egorov    2016-08-29  623  
2eedcbfc0 Wadim Egorov    2016-08-29  624  	switch (rk808->variant) {
990f05f6a Elaine Zhang    2017-08-21  625  	case RK805_ID:
990f05f6a Elaine Zhang    2017-08-21  626  		rk808->regmap_cfg = &rk805_regmap_config;
990f05f6a Elaine Zhang    2017-08-21  627  		rk808->regmap_irq_chip = &rk805_irq_chip;
990f05f6a Elaine Zhang    2017-08-21  628  		pre_init_reg = rk805_pre_init_reg;
990f05f6a Elaine Zhang    2017-08-21  629  		nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
990f05f6a Elaine Zhang    2017-08-21  630  		cells = rk805s;
990f05f6a Elaine Zhang    2017-08-21  631  		nr_cells = ARRAY_SIZE(rk805s);
990f05f6a Elaine Zhang    2017-08-21  632  		pm_pwroff_fn = rk805_device_shutdown;
990f05f6a Elaine Zhang    2017-08-21  633  		break;
2eedcbfc0 Wadim Egorov    2016-08-29  634  	case RK808_ID:
2eedcbfc0 Wadim Egorov    2016-08-29  635  		rk808->regmap_cfg = &rk808_regmap_config;
2eedcbfc0 Wadim Egorov    2016-08-29  636  		rk808->regmap_irq_chip = &rk808_irq_chip;
2eedcbfc0 Wadim Egorov    2016-08-29  637  		pre_init_reg = rk808_pre_init_reg;
2eedcbfc0 Wadim Egorov    2016-08-29  638  		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
2eedcbfc0 Wadim Egorov    2016-08-29  639  		cells = rk808s;
2eedcbfc0 Wadim Egorov    2016-08-29  640  		nr_cells = ARRAY_SIZE(rk808s);
b2e2c8509 Jianhong Chen   2016-10-17  641  		pm_pwroff_fn = rk808_device_shutdown;
2eedcbfc0 Wadim Egorov    2016-08-29  642  		break;
2eedcbfc0 Wadim Egorov    2016-08-29  643  	case RK818_ID:
2eedcbfc0 Wadim Egorov    2016-08-29  644  		rk808->regmap_cfg = &rk818_regmap_config;
2eedcbfc0 Wadim Egorov    2016-08-29  645  		rk808->regmap_irq_chip = &rk818_irq_chip;
2eedcbfc0 Wadim Egorov    2016-08-29  646  		pre_init_reg = rk818_pre_init_reg;
2eedcbfc0 Wadim Egorov    2016-08-29  647  		nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
2eedcbfc0 Wadim Egorov    2016-08-29  648  		cells = rk818s;
2eedcbfc0 Wadim Egorov    2016-08-29  649  		nr_cells = ARRAY_SIZE(rk818s);
b2e2c8509 Jianhong Chen   2016-10-17  650  		pm_pwroff_fn = rk818_device_shutdown;
2eedcbfc0 Wadim Egorov    2016-08-29  651  		break;
1e99c2e53 Tony Xie        2018-07-23  652  	case RK809_ID:
1e99c2e53 Tony Xie        2018-07-23  653  	case RK817_ID:
1e99c2e53 Tony Xie        2018-07-23  654  		rk808->regmap_cfg = &rk817_regmap_config;
1e99c2e53 Tony Xie        2018-07-23  655  		rk808->regmap_irq_chip = &rk817_irq_chip;
1e99c2e53 Tony Xie        2018-07-23  656  		pre_init_reg = rk817_pre_init_reg;
1e99c2e53 Tony Xie        2018-07-23  657  		nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
1e99c2e53 Tony Xie        2018-07-23  658  		cells = rk817s;
1e99c2e53 Tony Xie        2018-07-23  659  		nr_cells = ARRAY_SIZE(rk817s);
1e99c2e53 Tony Xie        2018-07-23  660  		pm_power_off_prepare = rk8xx_device_shutdown_prepare;
1e99c2e53 Tony Xie        2018-07-23  661  		break;
2eedcbfc0 Wadim Egorov    2016-08-29  662  	default:
2eedcbfc0 Wadim Egorov    2016-08-29  663  		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
2eedcbfc0 Wadim Egorov    2016-08-29  664  			rk808->variant);
2eedcbfc0 Wadim Egorov    2016-08-29  665  		return -EINVAL;
2eedcbfc0 Wadim Egorov    2016-08-29  666  	}
2eedcbfc0 Wadim Egorov    2016-08-29  667  
2eedcbfc0 Wadim Egorov    2016-08-29  668  	rk808->i2c = client;
2eedcbfc0 Wadim Egorov    2016-08-29  669  	i2c_set_clientdata(client, rk808);
2eedcbfc0 Wadim Egorov    2016-08-29  670  
2eedcbfc0 Wadim Egorov    2016-08-29  671  	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
f69a7cf74 Chris Zhong     2014-09-03  672  	if (IS_ERR(rk808->regmap)) {
f69a7cf74 Chris Zhong     2014-09-03  673  		dev_err(&client->dev, "regmap initialization failed\n");
f69a7cf74 Chris Zhong     2014-09-03  674  		return PTR_ERR(rk808->regmap);
f69a7cf74 Chris Zhong     2014-09-03  675  	}
f69a7cf74 Chris Zhong     2014-09-03  676  
2eedcbfc0 Wadim Egorov    2016-08-29  677  	if (!client->irq) {
2eedcbfc0 Wadim Egorov    2016-08-29  678  		dev_err(&client->dev, "No interrupt support, no core IRQ\n");
2eedcbfc0 Wadim Egorov    2016-08-29  679  		return -EINVAL;
f69a7cf74 Chris Zhong     2014-09-03  680  	}
f69a7cf74 Chris Zhong     2014-09-03  681  
f69a7cf74 Chris Zhong     2014-09-03  682  	ret = regmap_add_irq_chip(rk808->regmap, client->irq,
f69a7cf74 Chris Zhong     2014-09-03  683  				  IRQF_ONESHOT, -1,
2eedcbfc0 Wadim Egorov    2016-08-29  684  				  rk808->regmap_irq_chip, &rk808->irq_data);
f69a7cf74 Chris Zhong     2014-09-03  685  	if (ret) {
f69a7cf74 Chris Zhong     2014-09-03  686  		dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
f69a7cf74 Chris Zhong     2014-09-03  687  		return ret;
f69a7cf74 Chris Zhong     2014-09-03  688  	}
f69a7cf74 Chris Zhong     2014-09-03  689  
2eedcbfc0 Wadim Egorov    2016-08-29  690  	for (i = 0; i < nr_pre_init_regs; i++) {
2eedcbfc0 Wadim Egorov    2016-08-29  691  		ret = regmap_update_bits(rk808->regmap,
2eedcbfc0 Wadim Egorov    2016-08-29  692  					pre_init_reg[i].addr,
2eedcbfc0 Wadim Egorov    2016-08-29  693  					pre_init_reg[i].mask,
2eedcbfc0 Wadim Egorov    2016-08-29  694  					pre_init_reg[i].value);
2eedcbfc0 Wadim Egorov    2016-08-29  695  		if (ret) {
2eedcbfc0 Wadim Egorov    2016-08-29  696  			dev_err(&client->dev,
2eedcbfc0 Wadim Egorov    2016-08-29  697  				"0x%x write err\n",
2eedcbfc0 Wadim Egorov    2016-08-29  698  				pre_init_reg[i].addr);
2eedcbfc0 Wadim Egorov    2016-08-29  699  			return ret;
2eedcbfc0 Wadim Egorov    2016-08-29  700  		}
2eedcbfc0 Wadim Egorov    2016-08-29  701  	}
f69a7cf74 Chris Zhong     2014-09-03  702  
2eedcbfc0 Wadim Egorov    2016-08-29  703  	ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
2eedcbfc0 Wadim Egorov    2016-08-29  704  			      cells, nr_cells, NULL, 0,
d5623161a Laxman Dewangan 2016-04-08  705  			      regmap_irq_get_domain(rk808->irq_data));
f69a7cf74 Chris Zhong     2014-09-03  706  	if (ret) {
f69a7cf74 Chris Zhong     2014-09-03  707  		dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
f69a7cf74 Chris Zhong     2014-09-03  708  		goto err_irq;
f69a7cf74 Chris Zhong     2014-09-03  709  	}
f69a7cf74 Chris Zhong     2014-09-03  710  
f69a7cf74 Chris Zhong     2014-09-03  711  	pm_off = of_property_read_bool(np,
f69a7cf74 Chris Zhong     2014-09-03  712  				"rockchip,system-power-controller");
f69a7cf74 Chris Zhong     2014-09-03  713  	if (pm_off && !pm_power_off) {
f69a7cf74 Chris Zhong     2014-09-03  714  		rk808_i2c_client = client;
b2e2c8509 Jianhong Chen   2016-10-17 @715  		pm_power_off = pm_pwroff_fn;
f69a7cf74 Chris Zhong     2014-09-03  716  	}
f69a7cf74 Chris Zhong     2014-09-03  717  
f69a7cf74 Chris Zhong     2014-09-03  718  	return 0;
f69a7cf74 Chris Zhong     2014-09-03  719  
f69a7cf74 Chris Zhong     2014-09-03  720  err_irq:
f69a7cf74 Chris Zhong     2014-09-03  721  	regmap_del_irq_chip(client->irq, rk808->irq_data);
f69a7cf74 Chris Zhong     2014-09-03  722  	return ret;
f69a7cf74 Chris Zhong     2014-09-03  723  }
f69a7cf74 Chris Zhong     2014-09-03  724  

:::::: The code at line 715 was first introduced by commit
:::::: b2e2c85091710159b305735d557f4ef4695f5dff mfd: rk808: RK818 uses DEV_OFF to power off supplies

:::::: TO: Jianhong Chen <chenjh@rock-chips.com>
:::::: CC: Lee Jones <lee.jones@linaro.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 54212 bytes --]

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

* [PATCH 1/5] mfd: rk808: Add RK817 and RK809 support
@ 2018-07-23 21:59     ` kbuild test robot
  0 siblings, 0 replies; 33+ messages in thread
From: kbuild test robot @ 2018-07-23 21:59 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tony,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on ljones-mfd/for-mfd-next]
[also build test WARNING on v4.18-rc6 next-20180723]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Tony-Xie/mfd-rk808-Add-RK817-and-RK809-support/20180724-040547
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=xtensa 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   drivers//mfd/rk808.c: In function 'rk808_probe':
>> drivers//mfd/rk808.c:715:16: warning: 'pm_pwroff_fn' may be used uninitialized in this function [-Wmaybe-uninitialized]
      pm_power_off = pm_pwroff_fn;
      ~~~~~~~~~~~~~^~~~~~~~~~~~~~

vim +/pm_pwroff_fn +715 drivers//mfd/rk808.c

2eedcbfc0 Wadim Egorov    2016-08-29  581  
f69a7cf74 Chris Zhong     2014-09-03  582  static int rk808_probe(struct i2c_client *client,
f69a7cf74 Chris Zhong     2014-09-03  583  		       const struct i2c_device_id *id)
f69a7cf74 Chris Zhong     2014-09-03  584  {
f69a7cf74 Chris Zhong     2014-09-03  585  	struct device_node *np = client->dev.of_node;
f69a7cf74 Chris Zhong     2014-09-03  586  	struct rk808 *rk808;
2eedcbfc0 Wadim Egorov    2016-08-29  587  	const struct rk808_reg_data *pre_init_reg;
2eedcbfc0 Wadim Egorov    2016-08-29  588  	const struct mfd_cell *cells;
b2e2c8509 Jianhong Chen   2016-10-17  589  	void (*pm_pwroff_fn)(void);
2eedcbfc0 Wadim Egorov    2016-08-29  590  	int nr_pre_init_regs;
2eedcbfc0 Wadim Egorov    2016-08-29  591  	int nr_cells;
9d6105e19 Elaine Zhang    2017-08-21  592  	int pm_off = 0, msb, lsb;
1e99c2e53 Tony Xie        2018-07-23  593  	unsigned char pmic_id_msb = RK808_ID_MSB, pmic_id_lsb = RK808_ID_LSB;
f69a7cf74 Chris Zhong     2014-09-03  594  	int ret;
f69a7cf74 Chris Zhong     2014-09-03  595  	int i;
f69a7cf74 Chris Zhong     2014-09-03  596  
f69a7cf74 Chris Zhong     2014-09-03  597  	rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
f69a7cf74 Chris Zhong     2014-09-03  598  	if (!rk808)
f69a7cf74 Chris Zhong     2014-09-03  599  		return -ENOMEM;
f69a7cf74 Chris Zhong     2014-09-03  600  
1e99c2e53 Tony Xie        2018-07-23  601  	if (of_device_is_compatible(np, "rockchip,rk817") ||
1e99c2e53 Tony Xie        2018-07-23  602  	    of_device_is_compatible(np, "rockchip,rk809")) {
1e99c2e53 Tony Xie        2018-07-23  603  		pmic_id_msb = RK817_ID_MSB;
1e99c2e53 Tony Xie        2018-07-23  604  		pmic_id_lsb = RK817_ID_LSB;
1e99c2e53 Tony Xie        2018-07-23  605  	}
9d6105e19 Elaine Zhang    2017-08-21  606  	/* Read chip variant */
1e99c2e53 Tony Xie        2018-07-23  607  	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
9d6105e19 Elaine Zhang    2017-08-21  608  	if (msb < 0) {
9d6105e19 Elaine Zhang    2017-08-21  609  		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
2eedcbfc0 Wadim Egorov    2016-08-29  610  			RK808_ID_MSB);
9d6105e19 Elaine Zhang    2017-08-21  611  		return msb;
2eedcbfc0 Wadim Egorov    2016-08-29  612  	}
2eedcbfc0 Wadim Egorov    2016-08-29  613  
1e99c2e53 Tony Xie        2018-07-23  614  	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
9d6105e19 Elaine Zhang    2017-08-21  615  	if (lsb < 0) {
9d6105e19 Elaine Zhang    2017-08-21  616  		dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
9d6105e19 Elaine Zhang    2017-08-21  617  			RK808_ID_LSB);
9d6105e19 Elaine Zhang    2017-08-21  618  		return lsb;
9d6105e19 Elaine Zhang    2017-08-21  619  	}
9d6105e19 Elaine Zhang    2017-08-21  620  
9d6105e19 Elaine Zhang    2017-08-21  621  	rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
9d6105e19 Elaine Zhang    2017-08-21  622  	dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
2eedcbfc0 Wadim Egorov    2016-08-29  623  
2eedcbfc0 Wadim Egorov    2016-08-29  624  	switch (rk808->variant) {
990f05f6a Elaine Zhang    2017-08-21  625  	case RK805_ID:
990f05f6a Elaine Zhang    2017-08-21  626  		rk808->regmap_cfg = &rk805_regmap_config;
990f05f6a Elaine Zhang    2017-08-21  627  		rk808->regmap_irq_chip = &rk805_irq_chip;
990f05f6a Elaine Zhang    2017-08-21  628  		pre_init_reg = rk805_pre_init_reg;
990f05f6a Elaine Zhang    2017-08-21  629  		nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
990f05f6a Elaine Zhang    2017-08-21  630  		cells = rk805s;
990f05f6a Elaine Zhang    2017-08-21  631  		nr_cells = ARRAY_SIZE(rk805s);
990f05f6a Elaine Zhang    2017-08-21  632  		pm_pwroff_fn = rk805_device_shutdown;
990f05f6a Elaine Zhang    2017-08-21  633  		break;
2eedcbfc0 Wadim Egorov    2016-08-29  634  	case RK808_ID:
2eedcbfc0 Wadim Egorov    2016-08-29  635  		rk808->regmap_cfg = &rk808_regmap_config;
2eedcbfc0 Wadim Egorov    2016-08-29  636  		rk808->regmap_irq_chip = &rk808_irq_chip;
2eedcbfc0 Wadim Egorov    2016-08-29  637  		pre_init_reg = rk808_pre_init_reg;
2eedcbfc0 Wadim Egorov    2016-08-29  638  		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
2eedcbfc0 Wadim Egorov    2016-08-29  639  		cells = rk808s;
2eedcbfc0 Wadim Egorov    2016-08-29  640  		nr_cells = ARRAY_SIZE(rk808s);
b2e2c8509 Jianhong Chen   2016-10-17  641  		pm_pwroff_fn = rk808_device_shutdown;
2eedcbfc0 Wadim Egorov    2016-08-29  642  		break;
2eedcbfc0 Wadim Egorov    2016-08-29  643  	case RK818_ID:
2eedcbfc0 Wadim Egorov    2016-08-29  644  		rk808->regmap_cfg = &rk818_regmap_config;
2eedcbfc0 Wadim Egorov    2016-08-29  645  		rk808->regmap_irq_chip = &rk818_irq_chip;
2eedcbfc0 Wadim Egorov    2016-08-29  646  		pre_init_reg = rk818_pre_init_reg;
2eedcbfc0 Wadim Egorov    2016-08-29  647  		nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
2eedcbfc0 Wadim Egorov    2016-08-29  648  		cells = rk818s;
2eedcbfc0 Wadim Egorov    2016-08-29  649  		nr_cells = ARRAY_SIZE(rk818s);
b2e2c8509 Jianhong Chen   2016-10-17  650  		pm_pwroff_fn = rk818_device_shutdown;
2eedcbfc0 Wadim Egorov    2016-08-29  651  		break;
1e99c2e53 Tony Xie        2018-07-23  652  	case RK809_ID:
1e99c2e53 Tony Xie        2018-07-23  653  	case RK817_ID:
1e99c2e53 Tony Xie        2018-07-23  654  		rk808->regmap_cfg = &rk817_regmap_config;
1e99c2e53 Tony Xie        2018-07-23  655  		rk808->regmap_irq_chip = &rk817_irq_chip;
1e99c2e53 Tony Xie        2018-07-23  656  		pre_init_reg = rk817_pre_init_reg;
1e99c2e53 Tony Xie        2018-07-23  657  		nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
1e99c2e53 Tony Xie        2018-07-23  658  		cells = rk817s;
1e99c2e53 Tony Xie        2018-07-23  659  		nr_cells = ARRAY_SIZE(rk817s);
1e99c2e53 Tony Xie        2018-07-23  660  		pm_power_off_prepare = rk8xx_device_shutdown_prepare;
1e99c2e53 Tony Xie        2018-07-23  661  		break;
2eedcbfc0 Wadim Egorov    2016-08-29  662  	default:
2eedcbfc0 Wadim Egorov    2016-08-29  663  		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
2eedcbfc0 Wadim Egorov    2016-08-29  664  			rk808->variant);
2eedcbfc0 Wadim Egorov    2016-08-29  665  		return -EINVAL;
2eedcbfc0 Wadim Egorov    2016-08-29  666  	}
2eedcbfc0 Wadim Egorov    2016-08-29  667  
2eedcbfc0 Wadim Egorov    2016-08-29  668  	rk808->i2c = client;
2eedcbfc0 Wadim Egorov    2016-08-29  669  	i2c_set_clientdata(client, rk808);
2eedcbfc0 Wadim Egorov    2016-08-29  670  
2eedcbfc0 Wadim Egorov    2016-08-29  671  	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
f69a7cf74 Chris Zhong     2014-09-03  672  	if (IS_ERR(rk808->regmap)) {
f69a7cf74 Chris Zhong     2014-09-03  673  		dev_err(&client->dev, "regmap initialization failed\n");
f69a7cf74 Chris Zhong     2014-09-03  674  		return PTR_ERR(rk808->regmap);
f69a7cf74 Chris Zhong     2014-09-03  675  	}
f69a7cf74 Chris Zhong     2014-09-03  676  
2eedcbfc0 Wadim Egorov    2016-08-29  677  	if (!client->irq) {
2eedcbfc0 Wadim Egorov    2016-08-29  678  		dev_err(&client->dev, "No interrupt support, no core IRQ\n");
2eedcbfc0 Wadim Egorov    2016-08-29  679  		return -EINVAL;
f69a7cf74 Chris Zhong     2014-09-03  680  	}
f69a7cf74 Chris Zhong     2014-09-03  681  
f69a7cf74 Chris Zhong     2014-09-03  682  	ret = regmap_add_irq_chip(rk808->regmap, client->irq,
f69a7cf74 Chris Zhong     2014-09-03  683  				  IRQF_ONESHOT, -1,
2eedcbfc0 Wadim Egorov    2016-08-29  684  				  rk808->regmap_irq_chip, &rk808->irq_data);
f69a7cf74 Chris Zhong     2014-09-03  685  	if (ret) {
f69a7cf74 Chris Zhong     2014-09-03  686  		dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
f69a7cf74 Chris Zhong     2014-09-03  687  		return ret;
f69a7cf74 Chris Zhong     2014-09-03  688  	}
f69a7cf74 Chris Zhong     2014-09-03  689  
2eedcbfc0 Wadim Egorov    2016-08-29  690  	for (i = 0; i < nr_pre_init_regs; i++) {
2eedcbfc0 Wadim Egorov    2016-08-29  691  		ret = regmap_update_bits(rk808->regmap,
2eedcbfc0 Wadim Egorov    2016-08-29  692  					pre_init_reg[i].addr,
2eedcbfc0 Wadim Egorov    2016-08-29  693  					pre_init_reg[i].mask,
2eedcbfc0 Wadim Egorov    2016-08-29  694  					pre_init_reg[i].value);
2eedcbfc0 Wadim Egorov    2016-08-29  695  		if (ret) {
2eedcbfc0 Wadim Egorov    2016-08-29  696  			dev_err(&client->dev,
2eedcbfc0 Wadim Egorov    2016-08-29  697  				"0x%x write err\n",
2eedcbfc0 Wadim Egorov    2016-08-29  698  				pre_init_reg[i].addr);
2eedcbfc0 Wadim Egorov    2016-08-29  699  			return ret;
2eedcbfc0 Wadim Egorov    2016-08-29  700  		}
2eedcbfc0 Wadim Egorov    2016-08-29  701  	}
f69a7cf74 Chris Zhong     2014-09-03  702  
2eedcbfc0 Wadim Egorov    2016-08-29  703  	ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
2eedcbfc0 Wadim Egorov    2016-08-29  704  			      cells, nr_cells, NULL, 0,
d5623161a Laxman Dewangan 2016-04-08  705  			      regmap_irq_get_domain(rk808->irq_data));
f69a7cf74 Chris Zhong     2014-09-03  706  	if (ret) {
f69a7cf74 Chris Zhong     2014-09-03  707  		dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
f69a7cf74 Chris Zhong     2014-09-03  708  		goto err_irq;
f69a7cf74 Chris Zhong     2014-09-03  709  	}
f69a7cf74 Chris Zhong     2014-09-03  710  
f69a7cf74 Chris Zhong     2014-09-03  711  	pm_off = of_property_read_bool(np,
f69a7cf74 Chris Zhong     2014-09-03  712  				"rockchip,system-power-controller");
f69a7cf74 Chris Zhong     2014-09-03  713  	if (pm_off && !pm_power_off) {
f69a7cf74 Chris Zhong     2014-09-03  714  		rk808_i2c_client = client;
b2e2c8509 Jianhong Chen   2016-10-17 @715  		pm_power_off = pm_pwroff_fn;
f69a7cf74 Chris Zhong     2014-09-03  716  	}
f69a7cf74 Chris Zhong     2014-09-03  717  
f69a7cf74 Chris Zhong     2014-09-03  718  	return 0;
f69a7cf74 Chris Zhong     2014-09-03  719  
f69a7cf74 Chris Zhong     2014-09-03  720  err_irq:
f69a7cf74 Chris Zhong     2014-09-03  721  	regmap_del_irq_chip(client->irq, rk808->irq_data);
f69a7cf74 Chris Zhong     2014-09-03  722  	return ret;
f69a7cf74 Chris Zhong     2014-09-03  723  }
f69a7cf74 Chris Zhong     2014-09-03  724  

:::::: The code at line 715 was first introduced by commit
:::::: b2e2c85091710159b305735d557f4ef4695f5dff mfd: rk808: RK818 uses DEV_OFF to power off supplies

:::::: TO: Jianhong Chen <chenjh@rock-chips.com>
:::::: CC: Lee Jones <lee.jones@linaro.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 54212 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180724/3d22d6cb/attachment-0001.gz>

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

* Re: [PATCH 1/5] mfd: rk808: Add RK817 and RK809 support
  2018-07-23  3:19   ` Tony Xie
  (?)
@ 2018-07-23 23:13     ` kbuild test robot
  -1 siblings, 0 replies; 33+ messages in thread
From: kbuild test robot @ 2018-07-23 23:13 UTC (permalink / raw)
  To: Tony Xie
  Cc: kbuild-all, heiko, broonie, lee.jones, a.zummo, alexandre.belloni,
	sboyd, linux-clk, linux-rtc, linux-arm-kernel, linux-rockchip,
	devicetree, linux-kernel, chenjh, xsf, zhangqing, huangtao,
	tony.xie

[-- Attachment #1: Type: text/plain, Size: 913 bytes --]

Hi Tony,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on ljones-mfd/for-mfd-next]
[also build test ERROR on v4.18-rc6 next-20180723]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Tony-Xie/mfd-rk808-Add-RK817-and-RK809-support/20180724-040547
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: i386-randconfig-a0-201829 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

>> ERROR: "pm_power_off_prepare" [drivers/mfd/rk808.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28749 bytes --]

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

* Re: [PATCH 1/5] mfd: rk808: Add RK817 and RK809 support
@ 2018-07-23 23:13     ` kbuild test robot
  0 siblings, 0 replies; 33+ messages in thread
From: kbuild test robot @ 2018-07-23 23:13 UTC (permalink / raw)
  Cc: kbuild-all, heiko, broonie, lee.jones, a.zummo, alexandre.belloni,
	sboyd, linux-clk, linux-rtc, linux-arm-kernel, linux-rockchip,
	devicetree, linux-kernel, chenjh, xsf, zhangqing, huangtao,
	tony.xie

[-- Attachment #1: Type: text/plain, Size: 913 bytes --]

Hi Tony,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on ljones-mfd/for-mfd-next]
[also build test ERROR on v4.18-rc6 next-20180723]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Tony-Xie/mfd-rk808-Add-RK817-and-RK809-support/20180724-040547
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: i386-randconfig-a0-201829 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

>> ERROR: "pm_power_off_prepare" [drivers/mfd/rk808.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28749 bytes --]

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

* [PATCH 1/5] mfd: rk808: Add RK817 and RK809 support
@ 2018-07-23 23:13     ` kbuild test robot
  0 siblings, 0 replies; 33+ messages in thread
From: kbuild test robot @ 2018-07-23 23:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tony,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on ljones-mfd/for-mfd-next]
[also build test ERROR on v4.18-rc6 next-20180723]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Tony-Xie/mfd-rk808-Add-RK817-and-RK809-support/20180724-040547
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
config: i386-randconfig-a0-201829 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

>> ERROR: "pm_power_off_prepare" [drivers/mfd/rk808.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 28749 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180724/844019f7/attachment-0001.gz>

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

end of thread, other threads:[~2018-07-24  0:18 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-23  3:19 [PATCH 0/5] support a new type of PMIC,including two chips(rk817 and rk809) Tony Xie
2018-07-23  3:19 ` Tony Xie
2018-07-23  3:19 ` Tony Xie
2018-07-23  3:19 ` Tony Xie
2018-07-23  3:19 ` [PATCH 1/5] mfd: rk808: Add RK817 and RK809 support Tony Xie
2018-07-23  3:19   ` Tony Xie
2018-07-23  3:19   ` Tony Xie
2018-07-23  3:19   ` Tony Xie
2018-07-23 21:59   ` kbuild test robot
2018-07-23 21:59     ` kbuild test robot
2018-07-23 21:59     ` kbuild test robot
2018-07-23 21:59     ` kbuild test robot
2018-07-23 23:13   ` kbuild test robot
2018-07-23 23:13     ` kbuild test robot
2018-07-23 23:13     ` kbuild test robot
2018-07-23  3:19 ` [PATCH 2/5] regulator: rk808: Add regulator driver for RK809 and RK817 Tony Xie
2018-07-23  3:19   ` Tony Xie
2018-07-23  3:19   ` Tony Xie
2018-07-23  3:19   ` Tony Xie
2018-07-23  3:19 ` [PATCH 3/5] mfd: dt-bindings: Add RK809 and RK817 device tree bindings document Tony Xie
2018-07-23  3:19   ` Tony Xie
2018-07-23  3:19   ` Tony Xie
2018-07-23  3:19   ` Tony Xie
2018-07-23  8:29   ` Michal Vokáč
2018-07-23  8:29     ` Michal Vokáč
2018-07-23  3:19 ` [PATCH 4/5] RTC: RK808: add RTC driver for RK809 and RK817 Tony Xie
2018-07-23  3:19   ` Tony Xie
2018-07-23  3:19   ` Tony Xie
2018-07-23  3:19   ` Tony Xie
2018-07-23  8:52   ` Alexandre Belloni
2018-07-23  8:52     ` Alexandre Belloni
2018-07-23  8:40 ` [PATCH 5/5] clk: RK808: add clkout " Tony Xie
2018-07-23  8:40   ` Tony Xie

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.