All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv6 00/11] Introduce RK806 Support
@ 2023-01-27 18:12 ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Hi,

The Rockchip RK3588 Evaluation Boards as well as the Rock 5
boards and probably most other RK3588 boards use SPI connected
RK806 PMICs. Downstream this is handled by a new driver, but
apart from being SPI connected this chip is quite similar to
the other Rockchip PMICs (and RK806 is promoted to also support
I2C). Thus this series instead updates the RK808 driver(s).

Changelog since PATCHv5:
 * https://lore.kernel.org/all/20230109172723.60304-1-sebastian.reichel@collabora.com/
 * add Reviewed-by from Rob Herring to the rk806 DT binding patch
 * drop useless wrapper functions for rk8xx_i2c_suspend and rk8xx_i2c_resume
 * put .num_resources after .resources for rk806_pwrkey_resources
 * simplify dual_support logic by storing IRQF_SHARED or 0 instead of bool
 * add missing spaces around + and - in rk806
 * add new patch using device_get_match_data() in rk8xx-i2c and removing
   the pointless dev_info printing the chip version
 * call devm_mfd_add_devices() with id=0 and rely on mfd_cell to have the .id
   field configured to either PLATFORM_DEVID_AUTO or PLATFORM_DEVID_NONE
 * add check if more than 128 bytes are tried to be received/sent, which would
   overflow the command register
 * add RK806_CMD_WITH_SIZE() define

Changelog since PATCHv4:
 * https://lore.kernel.org/all/20221020204251.108565-1-sebastian.reichel@collabora.com/
 * rebase to v6.2-rc1
   - dropped 'regulator: rk808: reduce 'struct rk808' usage' (queued to 6.2-rc1)
   - dropped 'regulator: rk808: Use dev_err_probe' (queued to 6.2-rc1)
   - dropped 'rtc: rk808: reduce 'struct rk808' usage' (queued to 6.2-rc1)
 * use 'MFD_RK8XX' for the MFD driver supporting all the MFD8XX chips
 * added author tags to drivers/mfd/rk8xx-core.c. They were missing because
   I moved the original header over to the i2c specific file and wrote the
   new header from scratch. I suppose it's better to have the author tags
   in both files.
 * fix Rob's comments for the rk806 YAML binding
 * add defines for rk806 command indexes
 * modify rk806 code, so that it is capable of mult-write

Changelog since PATCHv3:
 * https://lore.kernel.org/all/20220909175522.179175-1-sebastian.reichel@collabora.com/
 * Dropped removing REGMAP_I2C dependency from RK817 ASoC driver (applied)
 * Rename MFD_RK808 to MFD_RK8XX to be consistent. It makes sense to do this now,
   since the patchset touches all the child drivers anyways.
 * rebase to v6.1-rc1
 * collected a couple of Acks
 * update rk806 DT binding according to DT maintainer feedback
 * add missing pinmux config to the rk806 DT binding
 * update rk806_spi_bus_write and rk806_spi_bus_read
 * replaced some constants with sizeof or defines
 * used capitalized comments
 * rename regmap_find_closest_bigger to regulator_find_closest_bigger, not sure
   why I prefixed it with regmap_ in the first place
 * use rk8xx_is_enabled_wmsk_regmap instead of regulator_is_enabled_regmap for
   the switching regulators to correctly report the state
 * reordered the first few patches grouping the MFD patches together

Changelog since PATCHv2:
 * https://lore.kernel.org/all/20220908003107.220143-1-sebastian.reichel@collabora.com/
 * Change DT binding to not allow nldo-reg6
 * Fix DT binding to check for [np]ldo-reg instead of [np]ldo_reg
 * remove rk806_get_voltage_sel_regmap in favour of regulator_get_voltage_sel_regmap
 * drop rk806_set_voltage in favour of regulator_set_voltage_sel_regmap
 * use regulator_set_ramp_delay_regmap
 * drop possibly incorrect printing of chip id register address in case of errors

Changelog since PATCHv1:
 * https://lore.kernel.org/all/20220831215437.117880-1-sebastian.reichel@collabora.com/
 * Collect Acked-by
 * Avoid if/else checks for regulator id in rk806 regulator driver
 * Fix indentation in DTS example section of the rk806 binding
 * Use absolute path for regulator.yaml referencing in the rk806 binding
 * Reduce pattern for DCDC regulators to only allow 1-10
 * replace uppercase name with lowercase ones in regulator names
 * replace _ with - in regulator names

-- Sebastian

Sebastian Reichel (11):
  clk: RK808: reduce 'struct rk808' usage
  mfd: rk808: convert to device managed resources
  mfd: rk808: use dev_err_probe
  mfd: rk808: replace 'struct i2c_client' with 'struct device'
  mfd: rk808: split into core and i2c
  mfd: rk8xx-i2c: use device_get_match_data
  dt-bindings: mfd: add rk806 binding
  mfd: rk8xx: add rk806 support
  pinctrl: rk805: add rk806 pinctrl support
  regulator: expose regulator_find_closest_bigger
  regulator: rk808: add rk806 support

 .../bindings/mfd/rockchip,rk806.yaml          | 406 +++++++++++++++++
 drivers/clk/Kconfig                           |   2 +-
 drivers/clk/clk-rk808.c                       |  34 +-
 drivers/input/misc/Kconfig                    |   2 +-
 drivers/mfd/Kconfig                           |  21 +-
 drivers/mfd/Makefile                          |   4 +-
 drivers/mfd/{rk808.c => rk8xx-core.c}         | 352 +++++----------
 drivers/mfd/rk8xx-i2c.c                       | 185 ++++++++
 drivers/mfd/rk8xx-spi.c                       | 129 ++++++
 drivers/pinctrl/Kconfig                       |   2 +-
 drivers/pinctrl/pinctrl-rk805.c               | 189 +++++++-
 drivers/power/supply/Kconfig                  |   2 +-
 drivers/regulator/Kconfig                     |   2 +-
 drivers/regulator/helpers.c                   |  22 +-
 drivers/regulator/rk808-regulator.c           | 383 ++++++++++++++++
 drivers/rtc/Kconfig                           |   2 +-
 include/linux/mfd/rk808.h                     | 417 +++++++++++++++++-
 include/linux/regulator/driver.h              |   2 +
 sound/soc/codecs/Kconfig                      |   2 +-
 19 files changed, 1872 insertions(+), 286 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
 rename drivers/mfd/{rk808.c => rk8xx-core.c} (71%)
 create mode 100644 drivers/mfd/rk8xx-i2c.c
 create mode 100644 drivers/mfd/rk8xx-spi.c

-- 
2.39.0


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

* [PATCHv6 00/11] Introduce RK806 Support
@ 2023-01-27 18:12 ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Hi,

The Rockchip RK3588 Evaluation Boards as well as the Rock 5
boards and probably most other RK3588 boards use SPI connected
RK806 PMICs. Downstream this is handled by a new driver, but
apart from being SPI connected this chip is quite similar to
the other Rockchip PMICs (and RK806 is promoted to also support
I2C). Thus this series instead updates the RK808 driver(s).

Changelog since PATCHv5:
 * https://lore.kernel.org/all/20230109172723.60304-1-sebastian.reichel@collabora.com/
 * add Reviewed-by from Rob Herring to the rk806 DT binding patch
 * drop useless wrapper functions for rk8xx_i2c_suspend and rk8xx_i2c_resume
 * put .num_resources after .resources for rk806_pwrkey_resources
 * simplify dual_support logic by storing IRQF_SHARED or 0 instead of bool
 * add missing spaces around + and - in rk806
 * add new patch using device_get_match_data() in rk8xx-i2c and removing
   the pointless dev_info printing the chip version
 * call devm_mfd_add_devices() with id=0 and rely on mfd_cell to have the .id
   field configured to either PLATFORM_DEVID_AUTO or PLATFORM_DEVID_NONE
 * add check if more than 128 bytes are tried to be received/sent, which would
   overflow the command register
 * add RK806_CMD_WITH_SIZE() define

Changelog since PATCHv4:
 * https://lore.kernel.org/all/20221020204251.108565-1-sebastian.reichel@collabora.com/
 * rebase to v6.2-rc1
   - dropped 'regulator: rk808: reduce 'struct rk808' usage' (queued to 6.2-rc1)
   - dropped 'regulator: rk808: Use dev_err_probe' (queued to 6.2-rc1)
   - dropped 'rtc: rk808: reduce 'struct rk808' usage' (queued to 6.2-rc1)
 * use 'MFD_RK8XX' for the MFD driver supporting all the MFD8XX chips
 * added author tags to drivers/mfd/rk8xx-core.c. They were missing because
   I moved the original header over to the i2c specific file and wrote the
   new header from scratch. I suppose it's better to have the author tags
   in both files.
 * fix Rob's comments for the rk806 YAML binding
 * add defines for rk806 command indexes
 * modify rk806 code, so that it is capable of mult-write

Changelog since PATCHv3:
 * https://lore.kernel.org/all/20220909175522.179175-1-sebastian.reichel@collabora.com/
 * Dropped removing REGMAP_I2C dependency from RK817 ASoC driver (applied)
 * Rename MFD_RK808 to MFD_RK8XX to be consistent. It makes sense to do this now,
   since the patchset touches all the child drivers anyways.
 * rebase to v6.1-rc1
 * collected a couple of Acks
 * update rk806 DT binding according to DT maintainer feedback
 * add missing pinmux config to the rk806 DT binding
 * update rk806_spi_bus_write and rk806_spi_bus_read
 * replaced some constants with sizeof or defines
 * used capitalized comments
 * rename regmap_find_closest_bigger to regulator_find_closest_bigger, not sure
   why I prefixed it with regmap_ in the first place
 * use rk8xx_is_enabled_wmsk_regmap instead of regulator_is_enabled_regmap for
   the switching regulators to correctly report the state
 * reordered the first few patches grouping the MFD patches together

Changelog since PATCHv2:
 * https://lore.kernel.org/all/20220908003107.220143-1-sebastian.reichel@collabora.com/
 * Change DT binding to not allow nldo-reg6
 * Fix DT binding to check for [np]ldo-reg instead of [np]ldo_reg
 * remove rk806_get_voltage_sel_regmap in favour of regulator_get_voltage_sel_regmap
 * drop rk806_set_voltage in favour of regulator_set_voltage_sel_regmap
 * use regulator_set_ramp_delay_regmap
 * drop possibly incorrect printing of chip id register address in case of errors

Changelog since PATCHv1:
 * https://lore.kernel.org/all/20220831215437.117880-1-sebastian.reichel@collabora.com/
 * Collect Acked-by
 * Avoid if/else checks for regulator id in rk806 regulator driver
 * Fix indentation in DTS example section of the rk806 binding
 * Use absolute path for regulator.yaml referencing in the rk806 binding
 * Reduce pattern for DCDC regulators to only allow 1-10
 * replace uppercase name with lowercase ones in regulator names
 * replace _ with - in regulator names

-- Sebastian

Sebastian Reichel (11):
  clk: RK808: reduce 'struct rk808' usage
  mfd: rk808: convert to device managed resources
  mfd: rk808: use dev_err_probe
  mfd: rk808: replace 'struct i2c_client' with 'struct device'
  mfd: rk808: split into core and i2c
  mfd: rk8xx-i2c: use device_get_match_data
  dt-bindings: mfd: add rk806 binding
  mfd: rk8xx: add rk806 support
  pinctrl: rk805: add rk806 pinctrl support
  regulator: expose regulator_find_closest_bigger
  regulator: rk808: add rk806 support

 .../bindings/mfd/rockchip,rk806.yaml          | 406 +++++++++++++++++
 drivers/clk/Kconfig                           |   2 +-
 drivers/clk/clk-rk808.c                       |  34 +-
 drivers/input/misc/Kconfig                    |   2 +-
 drivers/mfd/Kconfig                           |  21 +-
 drivers/mfd/Makefile                          |   4 +-
 drivers/mfd/{rk808.c => rk8xx-core.c}         | 352 +++++----------
 drivers/mfd/rk8xx-i2c.c                       | 185 ++++++++
 drivers/mfd/rk8xx-spi.c                       | 129 ++++++
 drivers/pinctrl/Kconfig                       |   2 +-
 drivers/pinctrl/pinctrl-rk805.c               | 189 +++++++-
 drivers/power/supply/Kconfig                  |   2 +-
 drivers/regulator/Kconfig                     |   2 +-
 drivers/regulator/helpers.c                   |  22 +-
 drivers/regulator/rk808-regulator.c           | 383 ++++++++++++++++
 drivers/rtc/Kconfig                           |   2 +-
 include/linux/mfd/rk808.h                     | 417 +++++++++++++++++-
 include/linux/regulator/driver.h              |   2 +
 sound/soc/codecs/Kconfig                      |   2 +-
 19 files changed, 1872 insertions(+), 286 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
 rename drivers/mfd/{rk808.c => rk8xx-core.c} (71%)
 create mode 100644 drivers/mfd/rk8xx-i2c.c
 create mode 100644 drivers/mfd/rk8xx-spi.c

-- 
2.39.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCHv6 01/11] clk: RK808: reduce 'struct rk808' usage
  2023-01-27 18:12 ` Sebastian Reichel
@ 2023-01-27 18:12   ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Reduce usage of 'struct rk808' (driver data of the parent MFD), so
that only the chip variant field is still being accessed directly.
This allows restructuring the MFD driver to support SPI based
PMICs.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/clk/clk-rk808.c | 34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/clk-rk808.c b/drivers/clk/clk-rk808.c
index 32f833d732ed..f7412b137e5e 100644
--- a/drivers/clk/clk-rk808.c
+++ b/drivers/clk/clk-rk808.c
@@ -12,10 +12,9 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/rk808.h>
-#include <linux/i2c.h>
 
 struct rk808_clkout {
-	struct rk808 *rk808;
+	struct regmap		*regmap;
 	struct clk_hw		clkout1_hw;
 	struct clk_hw		clkout2_hw;
 };
@@ -31,9 +30,8 @@ static int rk808_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, RK808_CLK32OUT_REG,
+	return regmap_update_bits(rk808_clkout->regmap, RK808_CLK32OUT_REG,
 				  CLK32KOUT2_EN, enable ? CLK32KOUT2_EN : 0);
 }
 
@@ -52,10 +50,9 @@ static int rk808_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;
 	uint32_t val;
 
-	int ret = regmap_read(rk808->regmap, RK808_CLK32OUT_REG, &val);
+	int ret = regmap_read(rk808_clkout->regmap, RK808_CLK32OUT_REG, &val);
 
 	if (ret < 0)
 		return ret;
@@ -93,9 +90,8 @@ 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),
+	return regmap_update_bits(rk808_clkout->regmap, RK817_SYS_CFG(1),
 				  RK817_CLK32KOUT2_EN,
 				  enable ? RK817_CLK32KOUT2_EN : 0);
 }
@@ -115,10 +111,9 @@ 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);
+	int ret = regmap_read(rk808_clkout->regmap, RK817_SYS_CFG(1), &val);
 
 	if (ret < 0)
 		return 0;
@@ -153,18 +148,21 @@ static const struct clk_ops *rkpmic_get_ops(long variant)
 static int rk808_clkout_probe(struct platform_device *pdev)
 {
 	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
-	struct i2c_client *client = rk808->i2c;
-	struct device_node *node = client->dev.of_node;
+	struct device *dev = &pdev->dev;
 	struct clk_init_data init = {};
 	struct rk808_clkout *rk808_clkout;
 	int ret;
 
-	rk808_clkout = devm_kzalloc(&client->dev,
+	dev->of_node = pdev->dev.parent->of_node;
+
+	rk808_clkout = devm_kzalloc(dev,
 				    sizeof(*rk808_clkout), GFP_KERNEL);
 	if (!rk808_clkout)
 		return -ENOMEM;
 
-	rk808_clkout->rk808 = rk808;
+	rk808_clkout->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!rk808_clkout->regmap)
+		return -ENODEV;
 
 	init.parent_names = NULL;
 	init.num_parents = 0;
@@ -173,10 +171,10 @@ static int rk808_clkout_probe(struct platform_device *pdev)
 	rk808_clkout->clkout1_hw.init = &init;
 
 	/* optional override of the clockname */
-	of_property_read_string_index(node, "clock-output-names",
+	of_property_read_string_index(dev->of_node, "clock-output-names",
 				      0, &init.name);
 
-	ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout1_hw);
+	ret = devm_clk_hw_register(dev, &rk808_clkout->clkout1_hw);
 	if (ret)
 		return ret;
 
@@ -185,10 +183,10 @@ static int rk808_clkout_probe(struct platform_device *pdev)
 	rk808_clkout->clkout2_hw.init = &init;
 
 	/* optional override of the clockname */
-	of_property_read_string_index(node, "clock-output-names",
+	of_property_read_string_index(dev->of_node, "clock-output-names",
 				      1, &init.name);
 
-	ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout2_hw);
+	ret = devm_clk_hw_register(dev, &rk808_clkout->clkout2_hw);
 	if (ret)
 		return ret;
 
-- 
2.39.0


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

* [PATCHv6 01/11] clk: RK808: reduce 'struct rk808' usage
@ 2023-01-27 18:12   ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Reduce usage of 'struct rk808' (driver data of the parent MFD), so
that only the chip variant field is still being accessed directly.
This allows restructuring the MFD driver to support SPI based
PMICs.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/clk/clk-rk808.c | 34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/clk-rk808.c b/drivers/clk/clk-rk808.c
index 32f833d732ed..f7412b137e5e 100644
--- a/drivers/clk/clk-rk808.c
+++ b/drivers/clk/clk-rk808.c
@@ -12,10 +12,9 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/rk808.h>
-#include <linux/i2c.h>
 
 struct rk808_clkout {
-	struct rk808 *rk808;
+	struct regmap		*regmap;
 	struct clk_hw		clkout1_hw;
 	struct clk_hw		clkout2_hw;
 };
@@ -31,9 +30,8 @@ static int rk808_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, RK808_CLK32OUT_REG,
+	return regmap_update_bits(rk808_clkout->regmap, RK808_CLK32OUT_REG,
 				  CLK32KOUT2_EN, enable ? CLK32KOUT2_EN : 0);
 }
 
@@ -52,10 +50,9 @@ static int rk808_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;
 	uint32_t val;
 
-	int ret = regmap_read(rk808->regmap, RK808_CLK32OUT_REG, &val);
+	int ret = regmap_read(rk808_clkout->regmap, RK808_CLK32OUT_REG, &val);
 
 	if (ret < 0)
 		return ret;
@@ -93,9 +90,8 @@ 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),
+	return regmap_update_bits(rk808_clkout->regmap, RK817_SYS_CFG(1),
 				  RK817_CLK32KOUT2_EN,
 				  enable ? RK817_CLK32KOUT2_EN : 0);
 }
@@ -115,10 +111,9 @@ 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);
+	int ret = regmap_read(rk808_clkout->regmap, RK817_SYS_CFG(1), &val);
 
 	if (ret < 0)
 		return 0;
@@ -153,18 +148,21 @@ static const struct clk_ops *rkpmic_get_ops(long variant)
 static int rk808_clkout_probe(struct platform_device *pdev)
 {
 	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
-	struct i2c_client *client = rk808->i2c;
-	struct device_node *node = client->dev.of_node;
+	struct device *dev = &pdev->dev;
 	struct clk_init_data init = {};
 	struct rk808_clkout *rk808_clkout;
 	int ret;
 
-	rk808_clkout = devm_kzalloc(&client->dev,
+	dev->of_node = pdev->dev.parent->of_node;
+
+	rk808_clkout = devm_kzalloc(dev,
 				    sizeof(*rk808_clkout), GFP_KERNEL);
 	if (!rk808_clkout)
 		return -ENOMEM;
 
-	rk808_clkout->rk808 = rk808;
+	rk808_clkout->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!rk808_clkout->regmap)
+		return -ENODEV;
 
 	init.parent_names = NULL;
 	init.num_parents = 0;
@@ -173,10 +171,10 @@ static int rk808_clkout_probe(struct platform_device *pdev)
 	rk808_clkout->clkout1_hw.init = &init;
 
 	/* optional override of the clockname */
-	of_property_read_string_index(node, "clock-output-names",
+	of_property_read_string_index(dev->of_node, "clock-output-names",
 				      0, &init.name);
 
-	ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout1_hw);
+	ret = devm_clk_hw_register(dev, &rk808_clkout->clkout1_hw);
 	if (ret)
 		return ret;
 
@@ -185,10 +183,10 @@ static int rk808_clkout_probe(struct platform_device *pdev)
 	rk808_clkout->clkout2_hw.init = &init;
 
 	/* optional override of the clockname */
-	of_property_read_string_index(node, "clock-output-names",
+	of_property_read_string_index(dev->of_node, "clock-output-names",
 				      1, &init.name);
 
-	ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout2_hw);
+	ret = devm_clk_hw_register(dev, &rk808_clkout->clkout2_hw);
 	if (ret)
 		return ret;
 
-- 
2.39.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCHv6 02/11] mfd: rk808: convert to device managed resources
  2023-01-27 18:12 ` Sebastian Reichel
@ 2023-01-27 18:12   ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Fully convert the driver to device managed resources.

Acked-for-MFD-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/mfd/rk808.c | 64 ++++++++++++++++-----------------------------
 1 file changed, 22 insertions(+), 42 deletions(-)

diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index f44fc3f080a8..4f5dca76bb54 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -547,13 +547,11 @@ static const struct regmap_irq_chip rk818_irq_chip = {
 	.init_ack_masked = true,
 };
 
-static struct i2c_client *rk808_i2c_client;
-
-static void rk808_pm_power_off(void)
+static int rk808_power_off(struct sys_off_data *data)
 {
+	struct rk808 *rk808 = data->cb_data;
 	int ret;
 	unsigned int reg, bit;
-	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
 
 	switch (rk808->variant) {
 	case RK805_ID:
@@ -574,16 +572,18 @@ static void rk808_pm_power_off(void)
 		bit = DEV_OFF;
 		break;
 	default:
-		return;
+		return NOTIFY_DONE;
 	}
 	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
 	if (ret)
-		dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
+		dev_err(&rk808->i2c->dev, "Failed to shutdown device!\n");
+
+	return NOTIFY_DONE;
 }
 
-static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd)
+static int rk808_restart(struct sys_off_data *data)
 {
-	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+	struct rk808 *rk808 = data->cb_data;
 	unsigned int reg, bit;
 	int ret;
 
@@ -599,16 +599,11 @@ static int rk808_restart_notify(struct notifier_block *this, unsigned long mode,
 	}
 	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
 	if (ret)
-		dev_err(&rk808_i2c_client->dev, "Failed to restart device!\n");
+		dev_err(&rk808->i2c->dev, "Failed to restart device!\n");
 
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block rk808_restart_handler = {
-	.notifier_call = rk808_restart_notify,
-	.priority = 192,
-};
-
 static void rk8xx_shutdown(struct i2c_client *client)
 {
 	struct rk808 *rk808 = i2c_get_clientdata(client);
@@ -744,9 +739,9 @@ static int rk808_probe(struct i2c_client *client)
 		return -EINVAL;
 	}
 
-	ret = regmap_add_irq_chip(rk808->regmap, client->irq,
-				  IRQF_ONESHOT, -1,
-				  rk808->regmap_irq_chip, &rk808->irq_data);
+	ret = devm_regmap_add_irq_chip(&client->dev, rk808->regmap, client->irq,
+				       IRQF_ONESHOT, -1,
+				       rk808->regmap_irq_chip, &rk808->irq_data);
 	if (ret) {
 		dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
 		return ret;
@@ -770,17 +765,23 @@ static int rk808_probe(struct i2c_client *client)
 			      regmap_irq_get_domain(rk808->irq_data));
 	if (ret) {
 		dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
-		goto err_irq;
+		return ret;
 	}
 
 	if (of_property_read_bool(np, "rockchip,system-power-controller")) {
-		rk808_i2c_client = client;
-		pm_power_off = rk808_pm_power_off;
+		ret = devm_register_sys_off_handler(&client->dev,
+				    SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
+				    &rk808_power_off, rk808);
+		if (ret)
+			return dev_err_probe(&client->dev, ret,
+					     "failed to register poweroff handler\n");
 
 		switch (rk808->variant) {
 		case RK809_ID:
 		case RK817_ID:
-			ret = register_restart_handler(&rk808_restart_handler);
+			ret = devm_register_sys_off_handler(&client->dev,
+							    SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
+							    &rk808_restart, rk808);
 			if (ret)
 				dev_warn(&client->dev, "failed to register rst handler, %d\n", ret);
 			break;
@@ -791,26 +792,6 @@ static int rk808_probe(struct i2c_client *client)
 	}
 
 	return 0;
-
-err_irq:
-	regmap_del_irq_chip(client->irq, rk808->irq_data);
-	return ret;
-}
-
-static void rk808_remove(struct i2c_client *client)
-{
-	struct rk808 *rk808 = i2c_get_clientdata(client);
-
-	regmap_del_irq_chip(client->irq, rk808->irq_data);
-
-	/**
-	 * pm_power_off may points to a function from another module.
-	 * Check if the pointer is set by us and only then overwrite it.
-	 */
-	if (pm_power_off == rk808_pm_power_off)
-		pm_power_off = NULL;
-
-	unregister_restart_handler(&rk808_restart_handler);
 }
 
 static int __maybe_unused rk8xx_suspend(struct device *dev)
@@ -867,7 +848,6 @@ static struct i2c_driver rk808_i2c_driver = {
 		.pm = &rk8xx_pm_ops,
 	},
 	.probe_new = rk808_probe,
-	.remove   = rk808_remove,
 	.shutdown = rk8xx_shutdown,
 };
 
-- 
2.39.0


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

* [PATCHv6 02/11] mfd: rk808: convert to device managed resources
@ 2023-01-27 18:12   ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Fully convert the driver to device managed resources.

Acked-for-MFD-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/mfd/rk808.c | 64 ++++++++++++++++-----------------------------
 1 file changed, 22 insertions(+), 42 deletions(-)

diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index f44fc3f080a8..4f5dca76bb54 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -547,13 +547,11 @@ static const struct regmap_irq_chip rk818_irq_chip = {
 	.init_ack_masked = true,
 };
 
-static struct i2c_client *rk808_i2c_client;
-
-static void rk808_pm_power_off(void)
+static int rk808_power_off(struct sys_off_data *data)
 {
+	struct rk808 *rk808 = data->cb_data;
 	int ret;
 	unsigned int reg, bit;
-	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
 
 	switch (rk808->variant) {
 	case RK805_ID:
@@ -574,16 +572,18 @@ static void rk808_pm_power_off(void)
 		bit = DEV_OFF;
 		break;
 	default:
-		return;
+		return NOTIFY_DONE;
 	}
 	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
 	if (ret)
-		dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
+		dev_err(&rk808->i2c->dev, "Failed to shutdown device!\n");
+
+	return NOTIFY_DONE;
 }
 
-static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd)
+static int rk808_restart(struct sys_off_data *data)
 {
-	struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+	struct rk808 *rk808 = data->cb_data;
 	unsigned int reg, bit;
 	int ret;
 
@@ -599,16 +599,11 @@ static int rk808_restart_notify(struct notifier_block *this, unsigned long mode,
 	}
 	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
 	if (ret)
-		dev_err(&rk808_i2c_client->dev, "Failed to restart device!\n");
+		dev_err(&rk808->i2c->dev, "Failed to restart device!\n");
 
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block rk808_restart_handler = {
-	.notifier_call = rk808_restart_notify,
-	.priority = 192,
-};
-
 static void rk8xx_shutdown(struct i2c_client *client)
 {
 	struct rk808 *rk808 = i2c_get_clientdata(client);
@@ -744,9 +739,9 @@ static int rk808_probe(struct i2c_client *client)
 		return -EINVAL;
 	}
 
-	ret = regmap_add_irq_chip(rk808->regmap, client->irq,
-				  IRQF_ONESHOT, -1,
-				  rk808->regmap_irq_chip, &rk808->irq_data);
+	ret = devm_regmap_add_irq_chip(&client->dev, rk808->regmap, client->irq,
+				       IRQF_ONESHOT, -1,
+				       rk808->regmap_irq_chip, &rk808->irq_data);
 	if (ret) {
 		dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
 		return ret;
@@ -770,17 +765,23 @@ static int rk808_probe(struct i2c_client *client)
 			      regmap_irq_get_domain(rk808->irq_data));
 	if (ret) {
 		dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
-		goto err_irq;
+		return ret;
 	}
 
 	if (of_property_read_bool(np, "rockchip,system-power-controller")) {
-		rk808_i2c_client = client;
-		pm_power_off = rk808_pm_power_off;
+		ret = devm_register_sys_off_handler(&client->dev,
+				    SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
+				    &rk808_power_off, rk808);
+		if (ret)
+			return dev_err_probe(&client->dev, ret,
+					     "failed to register poweroff handler\n");
 
 		switch (rk808->variant) {
 		case RK809_ID:
 		case RK817_ID:
-			ret = register_restart_handler(&rk808_restart_handler);
+			ret = devm_register_sys_off_handler(&client->dev,
+							    SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
+							    &rk808_restart, rk808);
 			if (ret)
 				dev_warn(&client->dev, "failed to register rst handler, %d\n", ret);
 			break;
@@ -791,26 +792,6 @@ static int rk808_probe(struct i2c_client *client)
 	}
 
 	return 0;
-
-err_irq:
-	regmap_del_irq_chip(client->irq, rk808->irq_data);
-	return ret;
-}
-
-static void rk808_remove(struct i2c_client *client)
-{
-	struct rk808 *rk808 = i2c_get_clientdata(client);
-
-	regmap_del_irq_chip(client->irq, rk808->irq_data);
-
-	/**
-	 * pm_power_off may points to a function from another module.
-	 * Check if the pointer is set by us and only then overwrite it.
-	 */
-	if (pm_power_off == rk808_pm_power_off)
-		pm_power_off = NULL;
-
-	unregister_restart_handler(&rk808_restart_handler);
 }
 
 static int __maybe_unused rk8xx_suspend(struct device *dev)
@@ -867,7 +848,6 @@ static struct i2c_driver rk808_i2c_driver = {
 		.pm = &rk8xx_pm_ops,
 	},
 	.probe_new = rk808_probe,
-	.remove   = rk808_remove,
 	.shutdown = rk8xx_shutdown,
 };
 
-- 
2.39.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCHv6 03/11] mfd: rk808: use dev_err_probe
  2023-01-27 18:12 ` Sebastian Reichel
@ 2023-01-27 18:12   ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Use dev_err_probe instead of dev_err in probe function,
which simplifies code a little bit and prints the error
code.

Also drop possibly incorrect printing of chip id registers
while touching the error message.

Acked-for-MFD-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/mfd/rk808.c | 48 +++++++++++++++------------------------------
 1 file changed, 16 insertions(+), 32 deletions(-)

diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 4f5dca76bb54..01d8303fccbe 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -669,18 +669,12 @@ static int rk808_probe(struct i2c_client *client)
 
 	/* Read chip variant */
 	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;
-	}
+	if (msb < 0)
+		return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n");
 
 	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);
-		return lsb;
-	}
+	if (lsb < 0)
+		return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n");
 
 	rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
 	dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
@@ -729,44 +723,34 @@ static int rk808_probe(struct i2c_client *client)
 	i2c_set_clientdata(client, rk808);
 
 	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
-	if (IS_ERR(rk808->regmap)) {
-		dev_err(&client->dev, "regmap initialization failed\n");
-		return PTR_ERR(rk808->regmap);
-	}
+	if (IS_ERR(rk808->regmap))
+		return dev_err_probe(&client->dev, PTR_ERR(rk808->regmap),
+				     "regmap initialization failed\n");
 
-	if (!client->irq) {
-		dev_err(&client->dev, "No interrupt support, no core IRQ\n");
-		return -EINVAL;
-	}
+	if (!client->irq)
+		return dev_err_probe(&client->dev, -EINVAL, "No interrupt support, no core IRQ\n");
 
 	ret = devm_regmap_add_irq_chip(&client->dev, rk808->regmap, client->irq,
 				       IRQF_ONESHOT, -1,
 				       rk808->regmap_irq_chip, &rk808->irq_data);
-	if (ret) {
-		dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(&client->dev, ret, "Failed to add irq_chip\n");
 
 	for (i = 0; i < nr_pre_init_regs; i++) {
 		ret = regmap_update_bits(rk808->regmap,
 					pre_init_reg[i].addr,
 					pre_init_reg[i].mask,
 					pre_init_reg[i].value);
-		if (ret) {
-			dev_err(&client->dev,
-				"0x%x write err\n",
-				pre_init_reg[i].addr);
-			return ret;
-		}
+		if (ret)
+			return dev_err_probe(&client->dev, ret, "0x%x write err\n",
+					     pre_init_reg[i].addr);
 	}
 
 	ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
 			      cells, nr_cells, NULL, 0,
 			      regmap_irq_get_domain(rk808->irq_data));
-	if (ret) {
-		dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(&client->dev, ret, "failed to add MFD devices\n");
 
 	if (of_property_read_bool(np, "rockchip,system-power-controller")) {
 		ret = devm_register_sys_off_handler(&client->dev,
-- 
2.39.0


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

* [PATCHv6 03/11] mfd: rk808: use dev_err_probe
@ 2023-01-27 18:12   ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Use dev_err_probe instead of dev_err in probe function,
which simplifies code a little bit and prints the error
code.

Also drop possibly incorrect printing of chip id registers
while touching the error message.

Acked-for-MFD-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/mfd/rk808.c | 48 +++++++++++++++------------------------------
 1 file changed, 16 insertions(+), 32 deletions(-)

diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 4f5dca76bb54..01d8303fccbe 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -669,18 +669,12 @@ static int rk808_probe(struct i2c_client *client)
 
 	/* Read chip variant */
 	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;
-	}
+	if (msb < 0)
+		return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n");
 
 	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);
-		return lsb;
-	}
+	if (lsb < 0)
+		return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n");
 
 	rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
 	dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
@@ -729,44 +723,34 @@ static int rk808_probe(struct i2c_client *client)
 	i2c_set_clientdata(client, rk808);
 
 	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
-	if (IS_ERR(rk808->regmap)) {
-		dev_err(&client->dev, "regmap initialization failed\n");
-		return PTR_ERR(rk808->regmap);
-	}
+	if (IS_ERR(rk808->regmap))
+		return dev_err_probe(&client->dev, PTR_ERR(rk808->regmap),
+				     "regmap initialization failed\n");
 
-	if (!client->irq) {
-		dev_err(&client->dev, "No interrupt support, no core IRQ\n");
-		return -EINVAL;
-	}
+	if (!client->irq)
+		return dev_err_probe(&client->dev, -EINVAL, "No interrupt support, no core IRQ\n");
 
 	ret = devm_regmap_add_irq_chip(&client->dev, rk808->regmap, client->irq,
 				       IRQF_ONESHOT, -1,
 				       rk808->regmap_irq_chip, &rk808->irq_data);
-	if (ret) {
-		dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(&client->dev, ret, "Failed to add irq_chip\n");
 
 	for (i = 0; i < nr_pre_init_regs; i++) {
 		ret = regmap_update_bits(rk808->regmap,
 					pre_init_reg[i].addr,
 					pre_init_reg[i].mask,
 					pre_init_reg[i].value);
-		if (ret) {
-			dev_err(&client->dev,
-				"0x%x write err\n",
-				pre_init_reg[i].addr);
-			return ret;
-		}
+		if (ret)
+			return dev_err_probe(&client->dev, ret, "0x%x write err\n",
+					     pre_init_reg[i].addr);
 	}
 
 	ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
 			      cells, nr_cells, NULL, 0,
 			      regmap_irq_get_domain(rk808->irq_data));
-	if (ret) {
-		dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(&client->dev, ret, "failed to add MFD devices\n");
 
 	if (of_property_read_bool(np, "rockchip,system-power-controller")) {
 		ret = devm_register_sys_off_handler(&client->dev,
-- 
2.39.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCHv6 04/11] mfd: rk808: replace 'struct i2c_client' with 'struct device'
  2023-01-27 18:12 ` Sebastian Reichel
@ 2023-01-27 18:12   ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Put 'struct device' pointer into the MFD platform_data instead
of the 'struct i2c_client' pointer. This simplifies the code
and prepares the MFD for SPI support.

Acked-for-MFD-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/mfd/rk808.c       | 6 +++---
 include/linux/mfd/rk808.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 01d8303fccbe..695a3fe6b9e0 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -576,7 +576,7 @@ static int rk808_power_off(struct sys_off_data *data)
 	}
 	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
 	if (ret)
-		dev_err(&rk808->i2c->dev, "Failed to shutdown device!\n");
+		dev_err(rk808->dev, "Failed to shutdown device!\n");
 
 	return NOTIFY_DONE;
 }
@@ -599,7 +599,7 @@ static int rk808_restart(struct sys_off_data *data)
 	}
 	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
 	if (ret)
-		dev_err(&rk808->i2c->dev, "Failed to restart device!\n");
+		dev_err(rk808->dev, "Failed to restart device!\n");
 
 	return NOTIFY_DONE;
 }
@@ -719,7 +719,7 @@ static int rk808_probe(struct i2c_client *client)
 		return -EINVAL;
 	}
 
-	rk808->i2c = client;
+	rk808->dev = &client->dev;
 	i2c_set_clientdata(client, rk808);
 
 	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index 9af1f3105f80..a89ddd9ba68e 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -787,7 +787,7 @@ enum {
 };
 
 struct rk808 {
-	struct i2c_client		*i2c;
+	struct device			*dev;
 	struct regmap_irq_chip_data	*irq_data;
 	struct regmap			*regmap;
 	long				variant;
-- 
2.39.0


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

* [PATCHv6 04/11] mfd: rk808: replace 'struct i2c_client' with 'struct device'
@ 2023-01-27 18:12   ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Put 'struct device' pointer into the MFD platform_data instead
of the 'struct i2c_client' pointer. This simplifies the code
and prepares the MFD for SPI support.

Acked-for-MFD-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/mfd/rk808.c       | 6 +++---
 include/linux/mfd/rk808.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 01d8303fccbe..695a3fe6b9e0 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -576,7 +576,7 @@ static int rk808_power_off(struct sys_off_data *data)
 	}
 	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
 	if (ret)
-		dev_err(&rk808->i2c->dev, "Failed to shutdown device!\n");
+		dev_err(rk808->dev, "Failed to shutdown device!\n");
 
 	return NOTIFY_DONE;
 }
@@ -599,7 +599,7 @@ static int rk808_restart(struct sys_off_data *data)
 	}
 	ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
 	if (ret)
-		dev_err(&rk808->i2c->dev, "Failed to restart device!\n");
+		dev_err(rk808->dev, "Failed to restart device!\n");
 
 	return NOTIFY_DONE;
 }
@@ -719,7 +719,7 @@ static int rk808_probe(struct i2c_client *client)
 		return -EINVAL;
 	}
 
-	rk808->i2c = client;
+	rk808->dev = &client->dev;
 	i2c_set_clientdata(client, rk808);
 
 	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index 9af1f3105f80..a89ddd9ba68e 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -787,7 +787,7 @@ enum {
 };
 
 struct rk808 {
-	struct i2c_client		*i2c;
+	struct device			*dev;
 	struct regmap_irq_chip_data	*irq_data;
 	struct regmap			*regmap;
 	long				variant;
-- 
2.39.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCHv6 05/11] mfd: rk808: split into core and i2c
  2023-01-27 18:12 ` Sebastian Reichel
@ 2023-01-27 18:12   ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Split rk808 into a core and an i2c part in preperation for
SPI support.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/clk/Kconfig                   |   2 +-
 drivers/input/misc/Kconfig            |   2 +-
 drivers/mfd/Kconfig                   |   7 +-
 drivers/mfd/Makefile                  |   3 +-
 drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
 drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
 drivers/pinctrl/Kconfig               |   2 +-
 drivers/power/supply/Kconfig          |   2 +-
 drivers/regulator/Kconfig             |   2 +-
 drivers/rtc/Kconfig                   |   2 +-
 include/linux/mfd/rk808.h             |   6 +
 sound/soc/codecs/Kconfig              |   2 +-
 12 files changed, 256 insertions(+), 183 deletions(-)
 rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
 create mode 100644 drivers/mfd/rk8xx-i2c.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index d79905f3e174..8448d616b9aa 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -83,7 +83,7 @@ config COMMON_CLK_MAX9485
 
 config COMMON_CLK_RK808
 	tristate "Clock driver for RK805/RK808/RK809/RK817/RK818"
-	depends on MFD_RK808
+	depends on MFD_RK8XX
 	help
 	  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.
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 5c2d0c06d2a5..6a6978fc68fa 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -598,7 +598,7 @@ config INPUT_PWM_VIBRA
 
 config INPUT_RK805_PWRKEY
 	tristate "Rockchip RK805 PMIC power key support"
-	depends on MFD_RK808
+	depends on MFD_RK8XX
 	help
 	  Select this option to enable power key driver for RK805.
 
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 30db49f31866..692e38283bda 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1204,12 +1204,17 @@ config MFD_RC5T583
 	  Additional drivers must be enabled in order to use the
 	  different functionality of the device.
 
-config MFD_RK808
+config MFD_RK8XX
+	bool
+	select MFD_CORE
+
+config MFD_RK8XX_I2C
 	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip"
 	depends on I2C && OF
 	select MFD_CORE
 	select REGMAP_I2C
 	select REGMAP_IRQ
+	select MFD_RK8XX
 	help
 	  If you say yes here you get support for the RK805, RK808, RK809,
 	  RK817 and RK818 Power Management chips.
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 457471478a93..f65ef1bd0810 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -220,7 +220,8 @@ obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
 obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
 obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
 obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
-obj-$(CONFIG_MFD_RK808)		+= rk808.o
+obj-$(CONFIG_MFD_RK8XX)		+= rk8xx-core.o
+obj-$(CONFIG_MFD_RK8XX_I2C)	+= rk8xx-i2c.o
 obj-$(CONFIG_MFD_RN5T618)	+= rn5t618.o
 obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
 obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk8xx-core.c
similarity index 76%
rename from drivers/mfd/rk808.c
rename to drivers/mfd/rk8xx-core.c
index 695a3fe6b9e0..c52f5fa1a4da 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk8xx-core.c
@@ -1,18 +1,15 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * MFD core driver for Rockchip RK808/RK818
+ * MFD core driver for Rockchip RK8XX
  *
  * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (C) 2016 PHYTEC Messtechnik GmbH
  *
  * Author: Chris Zhong <zyw@rock-chips.com>
  * Author: Zhang Qing <zhangqing@rock-chips.com>
- *
- * Copyright (C) 2016 PHYTEC Messtechnik GmbH
- *
  * Author: Wadim Egorov <w.egorov@phytec.de>
  */
 
-#include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/rk808.h>
 #include <linux/mfd/core.h>
@@ -27,92 +24,6 @@ struct rk808_reg_data {
 	int value;
 };
 
-static bool rk808_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 RK808_SECONDS_REG ... RK808_WEEKS_REG:
-	case RK808_RTC_STATUS_REG:
-	case RK808_VB_MON_REG:
-	case RK808_THERMAL_REG:
-	case RK808_DCDC_UV_STS_REG:
-	case RK808_LDO_UV_STS_REG:
-	case RK808_DCDC_PG_REG:
-	case RK808_LDO_PG_REG:
-	case RK808_DEVCTRL_REG:
-	case RK808_INT_STS_REG1:
-	case RK808_INT_STS_REG2:
-		return true;
-	}
-
-	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.
-	 */
-
-	switch (reg) {
-	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
-	case RK817_RTC_STATUS_REG:
-	case RK817_CODEC_DTOP_LPT_SRST:
-	case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
-	case RK817_PMIC_CHRG_STS:
-	case RK817_PMIC_CHRG_OUT:
-	case RK817_PMIC_CHRG_IN:
-	case RK817_INT_STS_REG0:
-	case RK817_INT_STS_REG1:
-	case RK817_INT_STS_REG2:
-	case RK817_SYS_STS:
-		return true;
-	}
-
-	return false;
-}
-
-static const struct regmap_config rk818_regmap_config = {
-	.reg_bits = 8,
-	.val_bits = 8,
-	.max_register = RK818_USB_CTRL_REG,
-	.cache_type = REGCACHE_RBTREE,
-	.volatile_reg = rk808_is_volatile_reg,
-};
-
-static const struct regmap_config rk805_regmap_config = {
-	.reg_bits = 8,
-	.val_bits = 8,
-	.max_register = RK805_OFF_SOURCE_REG,
-	.cache_type = REGCACHE_RBTREE,
-	.volatile_reg = rk808_is_volatile_reg,
-};
-
-static const struct regmap_config rk808_regmap_config = {
-	.reg_bits = 8,
-	.val_bits = 8,
-	.max_register = RK808_IO_POL_REG,
-	.cache_type = REGCACHE_RBTREE,
-	.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 const struct resource rtc_resources[] = {
 	DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM),
 };
@@ -604,9 +515,9 @@ static int rk808_restart(struct sys_off_data *data)
 	return NOTIFY_DONE;
 }
 
-static void rk8xx_shutdown(struct i2c_client *client)
+void rk8xx_shutdown(struct device *dev)
 {
-	struct rk808 *rk808 = i2c_get_clientdata(client);
+	struct rk808 *rk808 = dev_get_drvdata(dev);
 	int ret;
 
 	switch (rk808->variant) {
@@ -627,61 +538,31 @@ static void rk8xx_shutdown(struct i2c_client *client)
 		return;
 	}
 	if (ret)
-		dev_warn(&client->dev,
+		dev_warn(dev,
 			 "Cannot switch to power down function\n");
 }
+EXPORT_SYMBOL_GPL(rk8xx_shutdown);
 
-static const struct of_device_id rk808_of_match[] = {
-	{ .compatible = "rockchip,rk805" },
-	{ .compatible = "rockchip,rk808" },
-	{ .compatible = "rockchip,rk809" },
-	{ .compatible = "rockchip,rk817" },
-	{ .compatible = "rockchip,rk818" },
-	{ },
-};
-MODULE_DEVICE_TABLE(of, rk808_of_match);
-
-static int rk808_probe(struct i2c_client *client)
+int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap)
 {
-	struct device_node *np = client->dev.of_node;
 	struct rk808 *rk808;
 	const struct rk808_reg_data *pre_init_reg;
 	const struct mfd_cell *cells;
 	int nr_pre_init_regs;
 	int nr_cells;
-	int msb, lsb;
-	unsigned char pmic_id_msb, pmic_id_lsb;
 	int ret;
 	int i;
 
-	rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
+	rk808 = devm_kzalloc(dev, sizeof(*rk808), GFP_KERNEL);
 	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;
-	} else {
-		pmic_id_msb = RK808_ID_MSB;
-		pmic_id_lsb = RK808_ID_LSB;
-	}
-
-	/* Read chip variant */
-	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
-	if (msb < 0)
-		return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n");
-
-	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
-	if (lsb < 0)
-		return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n");
-
-	rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
-	dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
+	rk808->dev = dev;
+	rk808->variant = variant;
+	rk808->regmap = regmap;
+	dev_set_drvdata(dev, rk808);
 
 	switch (rk808->variant) {
 	case RK805_ID:
-		rk808->regmap_cfg = &rk805_regmap_config;
 		rk808->regmap_irq_chip = &rk805_irq_chip;
 		pre_init_reg = rk805_pre_init_reg;
 		nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
@@ -689,7 +570,6 @@ static int rk808_probe(struct i2c_client *client)
 		nr_cells = ARRAY_SIZE(rk805s);
 		break;
 	case RK808_ID:
-		rk808->regmap_cfg = &rk808_regmap_config;
 		rk808->regmap_irq_chip = &rk808_irq_chip;
 		pre_init_reg = rk808_pre_init_reg;
 		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
@@ -697,7 +577,6 @@ static int rk808_probe(struct i2c_client *client)
 		nr_cells = ARRAY_SIZE(rk808s);
 		break;
 	case RK818_ID:
-		rk808->regmap_cfg = &rk818_regmap_config;
 		rk808->regmap_irq_chip = &rk818_irq_chip;
 		pre_init_reg = rk818_pre_init_reg;
 		nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
@@ -706,7 +585,6 @@ static int rk808_probe(struct i2c_client *client)
 		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);
@@ -714,27 +592,20 @@ static int rk808_probe(struct i2c_client *client)
 		nr_cells = ARRAY_SIZE(rk817s);
 		break;
 	default:
-		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
-			rk808->variant);
+		dev_err(dev, "Unsupported RK8XX ID %lu\n", rk808->variant);
 		return -EINVAL;
 	}
 
-	rk808->dev = &client->dev;
-	i2c_set_clientdata(client, rk808);
-
-	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
-	if (IS_ERR(rk808->regmap))
-		return dev_err_probe(&client->dev, PTR_ERR(rk808->regmap),
-				     "regmap initialization failed\n");
+	dev_info(dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
 
-	if (!client->irq)
-		return dev_err_probe(&client->dev, -EINVAL, "No interrupt support, no core IRQ\n");
+	if (!irq)
+		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
 
-	ret = devm_regmap_add_irq_chip(&client->dev, rk808->regmap, client->irq,
+	ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
 				       IRQF_ONESHOT, -1,
 				       rk808->regmap_irq_chip, &rk808->irq_data);
 	if (ret)
-		return dev_err_probe(&client->dev, ret, "Failed to add irq_chip\n");
+		return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
 
 	for (i = 0; i < nr_pre_init_regs; i++) {
 		ret = regmap_update_bits(rk808->regmap,
@@ -742,45 +613,46 @@ static int rk808_probe(struct i2c_client *client)
 					pre_init_reg[i].mask,
 					pre_init_reg[i].value);
 		if (ret)
-			return dev_err_probe(&client->dev, ret, "0x%x write err\n",
+			return dev_err_probe(dev, ret, "0x%x write err\n",
 					     pre_init_reg[i].addr);
 	}
 
-	ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
+	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
 			      cells, nr_cells, NULL, 0,
 			      regmap_irq_get_domain(rk808->irq_data));
 	if (ret)
-		return dev_err_probe(&client->dev, ret, "failed to add MFD devices\n");
+		return dev_err_probe(dev, ret, "failed to add MFD devices\n");
 
-	if (of_property_read_bool(np, "rockchip,system-power-controller")) {
-		ret = devm_register_sys_off_handler(&client->dev,
+	if (device_property_read_bool(dev, "rockchip,system-power-controller")) {
+		ret = devm_register_sys_off_handler(dev,
 				    SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
 				    &rk808_power_off, rk808);
 		if (ret)
-			return dev_err_probe(&client->dev, ret,
+			return dev_err_probe(dev, ret,
 					     "failed to register poweroff handler\n");
 
 		switch (rk808->variant) {
 		case RK809_ID:
 		case RK817_ID:
-			ret = devm_register_sys_off_handler(&client->dev,
+			ret = devm_register_sys_off_handler(dev,
 							    SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
 							    &rk808_restart, rk808);
 			if (ret)
-				dev_warn(&client->dev, "failed to register rst handler, %d\n", ret);
+				dev_warn(dev, "failed to register rst handler, %d\n", ret);
 			break;
 		default:
-			dev_dbg(&client->dev, "pmic controlled board reset not supported\n");
+			dev_dbg(dev, "pmic controlled board reset not supported\n");
 			break;
 		}
 	}
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(rk8xx_probe);
 
-static int __maybe_unused rk8xx_suspend(struct device *dev)
+int rk8xx_suspend(struct device *dev)
 {
-	struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
+	struct rk808 *rk808 = dev_get_drvdata(dev);
 	int ret = 0;
 
 	switch (rk808->variant) {
@@ -803,10 +675,11 @@ static int __maybe_unused rk8xx_suspend(struct device *dev)
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(rk8xx_suspend);
 
-static int __maybe_unused rk8xx_resume(struct device *dev)
+int rk8xx_resume(struct device *dev)
 {
-	struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
+	struct rk808 *rk808 = dev_get_drvdata(dev);
 	int ret = 0;
 
 	switch (rk808->variant) {
@@ -823,22 +696,10 @@ static int __maybe_unused rk8xx_resume(struct device *dev)
 
 	return ret;
 }
-static SIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume);
-
-static struct i2c_driver rk808_i2c_driver = {
-	.driver = {
-		.name = "rk808",
-		.of_match_table = rk808_of_match,
-		.pm = &rk8xx_pm_ops,
-	},
-	.probe_new = rk808_probe,
-	.shutdown = rk8xx_shutdown,
-};
-
-module_i2c_driver(rk808_i2c_driver);
+EXPORT_SYMBOL_GPL(rk8xx_resume);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
-MODULE_DESCRIPTION("RK808/RK818 PMIC driver");
+MODULE_DESCRIPTION("RK8xx PMIC core");
diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c
new file mode 100644
index 000000000000..6d121b589fec
--- /dev/null
+++ b/drivers/mfd/rk8xx-i2c.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Rockchip RK808/RK818 Core (I2C) driver
+ *
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (C) 2016 PHYTEC Messtechnik GmbH
+ *
+ * Author: Chris Zhong <zyw@rock-chips.com>
+ * Author: Zhang Qing <zhangqing@rock-chips.com>
+ * Author: Wadim Egorov <w.egorov@phytec.de>
+ */
+
+#include <linux/i2c.h>
+#include <linux/mfd/rk808.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+static bool rk808_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 RK808_SECONDS_REG ... RK808_WEEKS_REG:
+	case RK808_RTC_STATUS_REG:
+	case RK808_VB_MON_REG:
+	case RK808_THERMAL_REG:
+	case RK808_DCDC_UV_STS_REG:
+	case RK808_LDO_UV_STS_REG:
+	case RK808_DCDC_PG_REG:
+	case RK808_LDO_PG_REG:
+	case RK808_DEVCTRL_REG:
+	case RK808_INT_STS_REG1:
+	case RK808_INT_STS_REG2:
+		return true;
+	}
+
+	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.
+	 */
+
+	switch (reg) {
+	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
+	case RK817_RTC_STATUS_REG:
+	case RK817_CODEC_DTOP_LPT_SRST:
+	case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
+	case RK817_PMIC_CHRG_STS:
+	case RK817_PMIC_CHRG_OUT:
+	case RK817_PMIC_CHRG_IN:
+	case RK817_INT_STS_REG0:
+	case RK817_INT_STS_REG1:
+	case RK817_INT_STS_REG2:
+	case RK817_SYS_STS:
+		return true;
+	}
+
+	return false;
+}
+
+
+static const struct regmap_config rk818_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = RK818_USB_CTRL_REG,
+	.cache_type = REGCACHE_RBTREE,
+	.volatile_reg = rk808_is_volatile_reg,
+};
+
+static const struct regmap_config rk805_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = RK805_OFF_SOURCE_REG,
+	.cache_type = REGCACHE_RBTREE,
+	.volatile_reg = rk808_is_volatile_reg,
+};
+
+static const struct regmap_config rk808_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = RK808_IO_POL_REG,
+	.cache_type = REGCACHE_RBTREE,
+	.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 int rk8xx_i2c_get_variant(struct i2c_client *client)
+{
+	u8 pmic_id_msb, pmic_id_lsb;
+	int msb, lsb;
+
+	if (of_device_is_compatible(client->dev.of_node, "rockchip,rk817") ||
+	    of_device_is_compatible(client->dev.of_node, "rockchip,rk809")) {
+		pmic_id_msb = RK817_ID_MSB;
+		pmic_id_lsb = RK817_ID_LSB;
+	} else {
+		pmic_id_msb = RK808_ID_MSB;
+		pmic_id_lsb = RK808_ID_LSB;
+	}
+
+	/* Read chip variant */
+	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
+	if (msb < 0)
+		return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n");
+
+	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
+	if (lsb < 0)
+		return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n");
+
+	return ((msb << 8) | lsb) & RK8XX_ID_MSK;
+}
+
+static int rk8xx_i2c_probe(struct i2c_client *client)
+{
+	const struct regmap_config *regmap_cfg;
+	struct regmap *regmap;
+	int variant;
+
+	variant = rk8xx_i2c_get_variant(client);
+	if (variant < 0)
+		return variant;
+
+	switch (variant) {
+	case RK805_ID:
+		regmap_cfg = &rk805_regmap_config;
+		break;
+	case RK808_ID:
+		regmap_cfg = &rk808_regmap_config;
+		break;
+	case RK818_ID:
+		regmap_cfg = &rk818_regmap_config;
+		break;
+	case RK809_ID:
+	case RK817_ID:
+		regmap_cfg = &rk817_regmap_config;
+		break;
+	default:
+		return dev_err_probe(&client->dev, -EINVAL, "Unsupported RK8XX ID %x\n", variant);
+	}
+
+	regmap = devm_regmap_init_i2c(client, regmap_cfg);
+	if (IS_ERR(regmap))
+		return dev_err_probe(&client->dev, PTR_ERR(regmap),
+				     "regmap initialization failed\n");
+
+	return rk8xx_probe(&client->dev, variant, client->irq, regmap);
+}
+
+static void rk8xx_i2c_shutdown(struct i2c_client *client)
+{
+	rk8xx_shutdown(&client->dev);
+}
+
+static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume);
+
+static const struct of_device_id rk8xx_i2c_of_match[] = {
+	{ .compatible = "rockchip,rk805" },
+	{ .compatible = "rockchip,rk808" },
+	{ .compatible = "rockchip,rk809" },
+	{ .compatible = "rockchip,rk817" },
+	{ .compatible = "rockchip,rk818" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match);
+
+static struct i2c_driver rk8xx_i2c_driver = {
+	.driver = {
+		.name = "rk8xx-i2c",
+		.of_match_table = rk8xx_i2c_of_match,
+		.pm = &rk8xx_i2c_pm_ops,
+	},
+	.probe_new = rk8xx_i2c_probe,
+	.shutdown  = rk8xx_i2c_shutdown,
+};
+module_i2c_driver(rk8xx_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
+MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
+MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
+MODULE_DESCRIPTION("RK8xx I2C PMIC driver");
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 7d5f5458c72e..b3cbce49a087 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -407,7 +407,7 @@ config PINCTRL_PISTACHIO
 
 config PINCTRL_RK805
 	tristate "Pinctrl and GPIO driver for RK805 PMIC"
-	depends on MFD_RK808
+	depends on MFD_RK8XX
 	select GPIOLIB
 	select PINMUX
 	select GENERIC_PINCONF
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 0bbfe6a7ce4d..306a9b1f897e 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -725,7 +725,7 @@ config CHARGER_BQ256XX
 
 config CHARGER_RK817
 	tristate "Rockchip RK817 PMIC Battery Charger"
-	depends on MFD_RK808
+	depends on MFD_RK8XX
 	help
 	  Say Y to include support for Rockchip RK817 Battery Charger.
 
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 820c9a0788e5..90e79ec5b021 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1048,7 +1048,7 @@ config REGULATOR_RC5T583
 
 config REGULATOR_RK808
 	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators"
-	depends on MFD_RK808
+	depends on MFD_RK8XX
 	help
 	  Select this option to enable the power regulator of ROCKCHIP
 	  PMIC RK805,RK809&RK817,RK808 and RK818.
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 677d2601d305..313c14c4cb2d 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -395,7 +395,7 @@ config RTC_DRV_NCT3018Y
 
 config RTC_DRV_RK808
 	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC"
-	depends on MFD_RK808
+	depends on MFD_RK8XX
 	help
 	  If you say yes here you will get support for the
 	  RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC.
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index a89ddd9ba68e..4183427a80fe 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -794,4 +794,10 @@ struct rk808 {
 	const struct regmap_config	*regmap_cfg;
 	const struct regmap_irq_chip	*regmap_irq_chip;
 };
+
+void rk8xx_shutdown(struct device *dev);
+int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap);
+int rk8xx_suspend(struct device *dev);
+int rk8xx_resume(struct device *dev);
+
 #endif /* __LINUX_REGULATOR_RK808_H */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0f9d71490075..7df9bb2c458f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1211,7 +1211,7 @@ config SND_SOC_RK3328
 
 config SND_SOC_RK817
 	tristate "Rockchip RK817 audio CODEC"
-	depends on MFD_RK808 || COMPILE_TEST
+	depends on MFD_RK8XX || COMPILE_TEST
 
 config SND_SOC_RL6231
 	tristate
-- 
2.39.0


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

* [PATCHv6 05/11] mfd: rk808: split into core and i2c
@ 2023-01-27 18:12   ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Split rk808 into a core and an i2c part in preperation for
SPI support.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/clk/Kconfig                   |   2 +-
 drivers/input/misc/Kconfig            |   2 +-
 drivers/mfd/Kconfig                   |   7 +-
 drivers/mfd/Makefile                  |   3 +-
 drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
 drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
 drivers/pinctrl/Kconfig               |   2 +-
 drivers/power/supply/Kconfig          |   2 +-
 drivers/regulator/Kconfig             |   2 +-
 drivers/rtc/Kconfig                   |   2 +-
 include/linux/mfd/rk808.h             |   6 +
 sound/soc/codecs/Kconfig              |   2 +-
 12 files changed, 256 insertions(+), 183 deletions(-)
 rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
 create mode 100644 drivers/mfd/rk8xx-i2c.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index d79905f3e174..8448d616b9aa 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -83,7 +83,7 @@ config COMMON_CLK_MAX9485
 
 config COMMON_CLK_RK808
 	tristate "Clock driver for RK805/RK808/RK809/RK817/RK818"
-	depends on MFD_RK808
+	depends on MFD_RK8XX
 	help
 	  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.
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 5c2d0c06d2a5..6a6978fc68fa 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -598,7 +598,7 @@ config INPUT_PWM_VIBRA
 
 config INPUT_RK805_PWRKEY
 	tristate "Rockchip RK805 PMIC power key support"
-	depends on MFD_RK808
+	depends on MFD_RK8XX
 	help
 	  Select this option to enable power key driver for RK805.
 
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 30db49f31866..692e38283bda 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1204,12 +1204,17 @@ config MFD_RC5T583
 	  Additional drivers must be enabled in order to use the
 	  different functionality of the device.
 
-config MFD_RK808
+config MFD_RK8XX
+	bool
+	select MFD_CORE
+
+config MFD_RK8XX_I2C
 	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip"
 	depends on I2C && OF
 	select MFD_CORE
 	select REGMAP_I2C
 	select REGMAP_IRQ
+	select MFD_RK8XX
 	help
 	  If you say yes here you get support for the RK805, RK808, RK809,
 	  RK817 and RK818 Power Management chips.
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 457471478a93..f65ef1bd0810 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -220,7 +220,8 @@ obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
 obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
 obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
 obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
-obj-$(CONFIG_MFD_RK808)		+= rk808.o
+obj-$(CONFIG_MFD_RK8XX)		+= rk8xx-core.o
+obj-$(CONFIG_MFD_RK8XX_I2C)	+= rk8xx-i2c.o
 obj-$(CONFIG_MFD_RN5T618)	+= rn5t618.o
 obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
 obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk8xx-core.c
similarity index 76%
rename from drivers/mfd/rk808.c
rename to drivers/mfd/rk8xx-core.c
index 695a3fe6b9e0..c52f5fa1a4da 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk8xx-core.c
@@ -1,18 +1,15 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * MFD core driver for Rockchip RK808/RK818
+ * MFD core driver for Rockchip RK8XX
  *
  * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (C) 2016 PHYTEC Messtechnik GmbH
  *
  * Author: Chris Zhong <zyw@rock-chips.com>
  * Author: Zhang Qing <zhangqing@rock-chips.com>
- *
- * Copyright (C) 2016 PHYTEC Messtechnik GmbH
- *
  * Author: Wadim Egorov <w.egorov@phytec.de>
  */
 
-#include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/rk808.h>
 #include <linux/mfd/core.h>
@@ -27,92 +24,6 @@ struct rk808_reg_data {
 	int value;
 };
 
-static bool rk808_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 RK808_SECONDS_REG ... RK808_WEEKS_REG:
-	case RK808_RTC_STATUS_REG:
-	case RK808_VB_MON_REG:
-	case RK808_THERMAL_REG:
-	case RK808_DCDC_UV_STS_REG:
-	case RK808_LDO_UV_STS_REG:
-	case RK808_DCDC_PG_REG:
-	case RK808_LDO_PG_REG:
-	case RK808_DEVCTRL_REG:
-	case RK808_INT_STS_REG1:
-	case RK808_INT_STS_REG2:
-		return true;
-	}
-
-	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.
-	 */
-
-	switch (reg) {
-	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
-	case RK817_RTC_STATUS_REG:
-	case RK817_CODEC_DTOP_LPT_SRST:
-	case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
-	case RK817_PMIC_CHRG_STS:
-	case RK817_PMIC_CHRG_OUT:
-	case RK817_PMIC_CHRG_IN:
-	case RK817_INT_STS_REG0:
-	case RK817_INT_STS_REG1:
-	case RK817_INT_STS_REG2:
-	case RK817_SYS_STS:
-		return true;
-	}
-
-	return false;
-}
-
-static const struct regmap_config rk818_regmap_config = {
-	.reg_bits = 8,
-	.val_bits = 8,
-	.max_register = RK818_USB_CTRL_REG,
-	.cache_type = REGCACHE_RBTREE,
-	.volatile_reg = rk808_is_volatile_reg,
-};
-
-static const struct regmap_config rk805_regmap_config = {
-	.reg_bits = 8,
-	.val_bits = 8,
-	.max_register = RK805_OFF_SOURCE_REG,
-	.cache_type = REGCACHE_RBTREE,
-	.volatile_reg = rk808_is_volatile_reg,
-};
-
-static const struct regmap_config rk808_regmap_config = {
-	.reg_bits = 8,
-	.val_bits = 8,
-	.max_register = RK808_IO_POL_REG,
-	.cache_type = REGCACHE_RBTREE,
-	.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 const struct resource rtc_resources[] = {
 	DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM),
 };
@@ -604,9 +515,9 @@ static int rk808_restart(struct sys_off_data *data)
 	return NOTIFY_DONE;
 }
 
-static void rk8xx_shutdown(struct i2c_client *client)
+void rk8xx_shutdown(struct device *dev)
 {
-	struct rk808 *rk808 = i2c_get_clientdata(client);
+	struct rk808 *rk808 = dev_get_drvdata(dev);
 	int ret;
 
 	switch (rk808->variant) {
@@ -627,61 +538,31 @@ static void rk8xx_shutdown(struct i2c_client *client)
 		return;
 	}
 	if (ret)
-		dev_warn(&client->dev,
+		dev_warn(dev,
 			 "Cannot switch to power down function\n");
 }
+EXPORT_SYMBOL_GPL(rk8xx_shutdown);
 
-static const struct of_device_id rk808_of_match[] = {
-	{ .compatible = "rockchip,rk805" },
-	{ .compatible = "rockchip,rk808" },
-	{ .compatible = "rockchip,rk809" },
-	{ .compatible = "rockchip,rk817" },
-	{ .compatible = "rockchip,rk818" },
-	{ },
-};
-MODULE_DEVICE_TABLE(of, rk808_of_match);
-
-static int rk808_probe(struct i2c_client *client)
+int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap)
 {
-	struct device_node *np = client->dev.of_node;
 	struct rk808 *rk808;
 	const struct rk808_reg_data *pre_init_reg;
 	const struct mfd_cell *cells;
 	int nr_pre_init_regs;
 	int nr_cells;
-	int msb, lsb;
-	unsigned char pmic_id_msb, pmic_id_lsb;
 	int ret;
 	int i;
 
-	rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
+	rk808 = devm_kzalloc(dev, sizeof(*rk808), GFP_KERNEL);
 	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;
-	} else {
-		pmic_id_msb = RK808_ID_MSB;
-		pmic_id_lsb = RK808_ID_LSB;
-	}
-
-	/* Read chip variant */
-	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
-	if (msb < 0)
-		return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n");
-
-	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
-	if (lsb < 0)
-		return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n");
-
-	rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
-	dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
+	rk808->dev = dev;
+	rk808->variant = variant;
+	rk808->regmap = regmap;
+	dev_set_drvdata(dev, rk808);
 
 	switch (rk808->variant) {
 	case RK805_ID:
-		rk808->regmap_cfg = &rk805_regmap_config;
 		rk808->regmap_irq_chip = &rk805_irq_chip;
 		pre_init_reg = rk805_pre_init_reg;
 		nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
@@ -689,7 +570,6 @@ static int rk808_probe(struct i2c_client *client)
 		nr_cells = ARRAY_SIZE(rk805s);
 		break;
 	case RK808_ID:
-		rk808->regmap_cfg = &rk808_regmap_config;
 		rk808->regmap_irq_chip = &rk808_irq_chip;
 		pre_init_reg = rk808_pre_init_reg;
 		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
@@ -697,7 +577,6 @@ static int rk808_probe(struct i2c_client *client)
 		nr_cells = ARRAY_SIZE(rk808s);
 		break;
 	case RK818_ID:
-		rk808->regmap_cfg = &rk818_regmap_config;
 		rk808->regmap_irq_chip = &rk818_irq_chip;
 		pre_init_reg = rk818_pre_init_reg;
 		nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
@@ -706,7 +585,6 @@ static int rk808_probe(struct i2c_client *client)
 		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);
@@ -714,27 +592,20 @@ static int rk808_probe(struct i2c_client *client)
 		nr_cells = ARRAY_SIZE(rk817s);
 		break;
 	default:
-		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
-			rk808->variant);
+		dev_err(dev, "Unsupported RK8XX ID %lu\n", rk808->variant);
 		return -EINVAL;
 	}
 
-	rk808->dev = &client->dev;
-	i2c_set_clientdata(client, rk808);
-
-	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
-	if (IS_ERR(rk808->regmap))
-		return dev_err_probe(&client->dev, PTR_ERR(rk808->regmap),
-				     "regmap initialization failed\n");
+	dev_info(dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
 
-	if (!client->irq)
-		return dev_err_probe(&client->dev, -EINVAL, "No interrupt support, no core IRQ\n");
+	if (!irq)
+		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
 
-	ret = devm_regmap_add_irq_chip(&client->dev, rk808->regmap, client->irq,
+	ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
 				       IRQF_ONESHOT, -1,
 				       rk808->regmap_irq_chip, &rk808->irq_data);
 	if (ret)
-		return dev_err_probe(&client->dev, ret, "Failed to add irq_chip\n");
+		return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
 
 	for (i = 0; i < nr_pre_init_regs; i++) {
 		ret = regmap_update_bits(rk808->regmap,
@@ -742,45 +613,46 @@ static int rk808_probe(struct i2c_client *client)
 					pre_init_reg[i].mask,
 					pre_init_reg[i].value);
 		if (ret)
-			return dev_err_probe(&client->dev, ret, "0x%x write err\n",
+			return dev_err_probe(dev, ret, "0x%x write err\n",
 					     pre_init_reg[i].addr);
 	}
 
-	ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
+	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
 			      cells, nr_cells, NULL, 0,
 			      regmap_irq_get_domain(rk808->irq_data));
 	if (ret)
-		return dev_err_probe(&client->dev, ret, "failed to add MFD devices\n");
+		return dev_err_probe(dev, ret, "failed to add MFD devices\n");
 
-	if (of_property_read_bool(np, "rockchip,system-power-controller")) {
-		ret = devm_register_sys_off_handler(&client->dev,
+	if (device_property_read_bool(dev, "rockchip,system-power-controller")) {
+		ret = devm_register_sys_off_handler(dev,
 				    SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
 				    &rk808_power_off, rk808);
 		if (ret)
-			return dev_err_probe(&client->dev, ret,
+			return dev_err_probe(dev, ret,
 					     "failed to register poweroff handler\n");
 
 		switch (rk808->variant) {
 		case RK809_ID:
 		case RK817_ID:
-			ret = devm_register_sys_off_handler(&client->dev,
+			ret = devm_register_sys_off_handler(dev,
 							    SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
 							    &rk808_restart, rk808);
 			if (ret)
-				dev_warn(&client->dev, "failed to register rst handler, %d\n", ret);
+				dev_warn(dev, "failed to register rst handler, %d\n", ret);
 			break;
 		default:
-			dev_dbg(&client->dev, "pmic controlled board reset not supported\n");
+			dev_dbg(dev, "pmic controlled board reset not supported\n");
 			break;
 		}
 	}
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(rk8xx_probe);
 
-static int __maybe_unused rk8xx_suspend(struct device *dev)
+int rk8xx_suspend(struct device *dev)
 {
-	struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
+	struct rk808 *rk808 = dev_get_drvdata(dev);
 	int ret = 0;
 
 	switch (rk808->variant) {
@@ -803,10 +675,11 @@ static int __maybe_unused rk8xx_suspend(struct device *dev)
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(rk8xx_suspend);
 
-static int __maybe_unused rk8xx_resume(struct device *dev)
+int rk8xx_resume(struct device *dev)
 {
-	struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
+	struct rk808 *rk808 = dev_get_drvdata(dev);
 	int ret = 0;
 
 	switch (rk808->variant) {
@@ -823,22 +696,10 @@ static int __maybe_unused rk8xx_resume(struct device *dev)
 
 	return ret;
 }
-static SIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume);
-
-static struct i2c_driver rk808_i2c_driver = {
-	.driver = {
-		.name = "rk808",
-		.of_match_table = rk808_of_match,
-		.pm = &rk8xx_pm_ops,
-	},
-	.probe_new = rk808_probe,
-	.shutdown = rk8xx_shutdown,
-};
-
-module_i2c_driver(rk808_i2c_driver);
+EXPORT_SYMBOL_GPL(rk8xx_resume);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
 MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
-MODULE_DESCRIPTION("RK808/RK818 PMIC driver");
+MODULE_DESCRIPTION("RK8xx PMIC core");
diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c
new file mode 100644
index 000000000000..6d121b589fec
--- /dev/null
+++ b/drivers/mfd/rk8xx-i2c.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Rockchip RK808/RK818 Core (I2C) driver
+ *
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (C) 2016 PHYTEC Messtechnik GmbH
+ *
+ * Author: Chris Zhong <zyw@rock-chips.com>
+ * Author: Zhang Qing <zhangqing@rock-chips.com>
+ * Author: Wadim Egorov <w.egorov@phytec.de>
+ */
+
+#include <linux/i2c.h>
+#include <linux/mfd/rk808.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+static bool rk808_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 RK808_SECONDS_REG ... RK808_WEEKS_REG:
+	case RK808_RTC_STATUS_REG:
+	case RK808_VB_MON_REG:
+	case RK808_THERMAL_REG:
+	case RK808_DCDC_UV_STS_REG:
+	case RK808_LDO_UV_STS_REG:
+	case RK808_DCDC_PG_REG:
+	case RK808_LDO_PG_REG:
+	case RK808_DEVCTRL_REG:
+	case RK808_INT_STS_REG1:
+	case RK808_INT_STS_REG2:
+		return true;
+	}
+
+	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.
+	 */
+
+	switch (reg) {
+	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
+	case RK817_RTC_STATUS_REG:
+	case RK817_CODEC_DTOP_LPT_SRST:
+	case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
+	case RK817_PMIC_CHRG_STS:
+	case RK817_PMIC_CHRG_OUT:
+	case RK817_PMIC_CHRG_IN:
+	case RK817_INT_STS_REG0:
+	case RK817_INT_STS_REG1:
+	case RK817_INT_STS_REG2:
+	case RK817_SYS_STS:
+		return true;
+	}
+
+	return false;
+}
+
+
+static const struct regmap_config rk818_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = RK818_USB_CTRL_REG,
+	.cache_type = REGCACHE_RBTREE,
+	.volatile_reg = rk808_is_volatile_reg,
+};
+
+static const struct regmap_config rk805_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = RK805_OFF_SOURCE_REG,
+	.cache_type = REGCACHE_RBTREE,
+	.volatile_reg = rk808_is_volatile_reg,
+};
+
+static const struct regmap_config rk808_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = RK808_IO_POL_REG,
+	.cache_type = REGCACHE_RBTREE,
+	.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 int rk8xx_i2c_get_variant(struct i2c_client *client)
+{
+	u8 pmic_id_msb, pmic_id_lsb;
+	int msb, lsb;
+
+	if (of_device_is_compatible(client->dev.of_node, "rockchip,rk817") ||
+	    of_device_is_compatible(client->dev.of_node, "rockchip,rk809")) {
+		pmic_id_msb = RK817_ID_MSB;
+		pmic_id_lsb = RK817_ID_LSB;
+	} else {
+		pmic_id_msb = RK808_ID_MSB;
+		pmic_id_lsb = RK808_ID_LSB;
+	}
+
+	/* Read chip variant */
+	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
+	if (msb < 0)
+		return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n");
+
+	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
+	if (lsb < 0)
+		return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n");
+
+	return ((msb << 8) | lsb) & RK8XX_ID_MSK;
+}
+
+static int rk8xx_i2c_probe(struct i2c_client *client)
+{
+	const struct regmap_config *regmap_cfg;
+	struct regmap *regmap;
+	int variant;
+
+	variant = rk8xx_i2c_get_variant(client);
+	if (variant < 0)
+		return variant;
+
+	switch (variant) {
+	case RK805_ID:
+		regmap_cfg = &rk805_regmap_config;
+		break;
+	case RK808_ID:
+		regmap_cfg = &rk808_regmap_config;
+		break;
+	case RK818_ID:
+		regmap_cfg = &rk818_regmap_config;
+		break;
+	case RK809_ID:
+	case RK817_ID:
+		regmap_cfg = &rk817_regmap_config;
+		break;
+	default:
+		return dev_err_probe(&client->dev, -EINVAL, "Unsupported RK8XX ID %x\n", variant);
+	}
+
+	regmap = devm_regmap_init_i2c(client, regmap_cfg);
+	if (IS_ERR(regmap))
+		return dev_err_probe(&client->dev, PTR_ERR(regmap),
+				     "regmap initialization failed\n");
+
+	return rk8xx_probe(&client->dev, variant, client->irq, regmap);
+}
+
+static void rk8xx_i2c_shutdown(struct i2c_client *client)
+{
+	rk8xx_shutdown(&client->dev);
+}
+
+static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume);
+
+static const struct of_device_id rk8xx_i2c_of_match[] = {
+	{ .compatible = "rockchip,rk805" },
+	{ .compatible = "rockchip,rk808" },
+	{ .compatible = "rockchip,rk809" },
+	{ .compatible = "rockchip,rk817" },
+	{ .compatible = "rockchip,rk818" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match);
+
+static struct i2c_driver rk8xx_i2c_driver = {
+	.driver = {
+		.name = "rk8xx-i2c",
+		.of_match_table = rk8xx_i2c_of_match,
+		.pm = &rk8xx_i2c_pm_ops,
+	},
+	.probe_new = rk8xx_i2c_probe,
+	.shutdown  = rk8xx_i2c_shutdown,
+};
+module_i2c_driver(rk8xx_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
+MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
+MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
+MODULE_DESCRIPTION("RK8xx I2C PMIC driver");
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 7d5f5458c72e..b3cbce49a087 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -407,7 +407,7 @@ config PINCTRL_PISTACHIO
 
 config PINCTRL_RK805
 	tristate "Pinctrl and GPIO driver for RK805 PMIC"
-	depends on MFD_RK808
+	depends on MFD_RK8XX
 	select GPIOLIB
 	select PINMUX
 	select GENERIC_PINCONF
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 0bbfe6a7ce4d..306a9b1f897e 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -725,7 +725,7 @@ config CHARGER_BQ256XX
 
 config CHARGER_RK817
 	tristate "Rockchip RK817 PMIC Battery Charger"
-	depends on MFD_RK808
+	depends on MFD_RK8XX
 	help
 	  Say Y to include support for Rockchip RK817 Battery Charger.
 
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 820c9a0788e5..90e79ec5b021 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1048,7 +1048,7 @@ config REGULATOR_RC5T583
 
 config REGULATOR_RK808
 	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators"
-	depends on MFD_RK808
+	depends on MFD_RK8XX
 	help
 	  Select this option to enable the power regulator of ROCKCHIP
 	  PMIC RK805,RK809&RK817,RK808 and RK818.
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 677d2601d305..313c14c4cb2d 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -395,7 +395,7 @@ config RTC_DRV_NCT3018Y
 
 config RTC_DRV_RK808
 	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC"
-	depends on MFD_RK808
+	depends on MFD_RK8XX
 	help
 	  If you say yes here you will get support for the
 	  RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC.
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index a89ddd9ba68e..4183427a80fe 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -794,4 +794,10 @@ struct rk808 {
 	const struct regmap_config	*regmap_cfg;
 	const struct regmap_irq_chip	*regmap_irq_chip;
 };
+
+void rk8xx_shutdown(struct device *dev);
+int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap);
+int rk8xx_suspend(struct device *dev);
+int rk8xx_resume(struct device *dev);
+
 #endif /* __LINUX_REGULATOR_RK808_H */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0f9d71490075..7df9bb2c458f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1211,7 +1211,7 @@ config SND_SOC_RK3328
 
 config SND_SOC_RK817
 	tristate "Rockchip RK817 audio CODEC"
-	depends on MFD_RK808 || COMPILE_TEST
+	depends on MFD_RK8XX || COMPILE_TEST
 
 config SND_SOC_RL6231
 	tristate
-- 
2.39.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCHv6 06/11] mfd: rk8xx-i2c: use device_get_match_data
  2023-01-27 18:12 ` Sebastian Reichel
@ 2023-01-27 18:12   ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Simplify the device identification logic by supplying the relevant
information via of_match_data. This also removes the dev_info()
printing the chip version, since that's supplied by the match data
now.

Due to lack of hardware this change is compile-tested only.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/mfd/rk8xx-core.c |  2 -
 drivers/mfd/rk8xx-i2c.c  | 89 +++++++++++++++++-----------------------
 2 files changed, 37 insertions(+), 54 deletions(-)

diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
index c52f5fa1a4da..21c6484a951c 100644
--- a/drivers/mfd/rk8xx-core.c
+++ b/drivers/mfd/rk8xx-core.c
@@ -596,8 +596,6 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
 		return -EINVAL;
 	}
 
-	dev_info(dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
-
 	if (!irq)
 		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
 
diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c
index 6d121b589fec..2822bfa8a04a 100644
--- a/drivers/mfd/rk8xx-i2c.c
+++ b/drivers/mfd/rk8xx-i2c.c
@@ -16,6 +16,11 @@
 #include <linux/of.h>
 #include <linux/regmap.h>
 
+struct rk8xx_i2c_platform_data {
+	const struct regmap_config *regmap_cfg;
+	int variant;
+};
+
 static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 {
 	/*
@@ -103,66 +108,46 @@ static const struct regmap_config rk817_regmap_config = {
 	.volatile_reg = rk817_is_volatile_reg,
 };
 
-static int rk8xx_i2c_get_variant(struct i2c_client *client)
-{
-	u8 pmic_id_msb, pmic_id_lsb;
-	int msb, lsb;
-
-	if (of_device_is_compatible(client->dev.of_node, "rockchip,rk817") ||
-	    of_device_is_compatible(client->dev.of_node, "rockchip,rk809")) {
-		pmic_id_msb = RK817_ID_MSB;
-		pmic_id_lsb = RK817_ID_LSB;
-	} else {
-		pmic_id_msb = RK808_ID_MSB;
-		pmic_id_lsb = RK808_ID_LSB;
-	}
+static const struct rk8xx_i2c_platform_data rk805_data = {
+	.regmap_cfg = &rk805_regmap_config,
+	.variant = RK805_ID,
+};
+
+static const struct rk8xx_i2c_platform_data rk808_data = {
+	.regmap_cfg = &rk808_regmap_config,
+	.variant = RK808_ID,
+};
 
-	/* Read chip variant */
-	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
-	if (msb < 0)
-		return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n");
+static const struct rk8xx_i2c_platform_data rk809_data = {
+	.regmap_cfg = &rk817_regmap_config,
+	.variant = RK809_ID,
+};
 
-	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
-	if (lsb < 0)
-		return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n");
+static const struct rk8xx_i2c_platform_data rk817_data = {
+	.regmap_cfg = &rk817_regmap_config,
+	.variant = RK817_ID,
+};
 
-	return ((msb << 8) | lsb) & RK8XX_ID_MSK;
-}
+static const struct rk8xx_i2c_platform_data rk818_data = {
+	.regmap_cfg = &rk818_regmap_config,
+	.variant = RK818_ID,
+};
 
 static int rk8xx_i2c_probe(struct i2c_client *client)
 {
-	const struct regmap_config *regmap_cfg;
+	const struct rk8xx_i2c_platform_data *data;
 	struct regmap *regmap;
-	int variant;
 
-	variant = rk8xx_i2c_get_variant(client);
-	if (variant < 0)
-		return variant;
-
-	switch (variant) {
-	case RK805_ID:
-		regmap_cfg = &rk805_regmap_config;
-		break;
-	case RK808_ID:
-		regmap_cfg = &rk808_regmap_config;
-		break;
-	case RK818_ID:
-		regmap_cfg = &rk818_regmap_config;
-		break;
-	case RK809_ID:
-	case RK817_ID:
-		regmap_cfg = &rk817_regmap_config;
-		break;
-	default:
-		return dev_err_probe(&client->dev, -EINVAL, "Unsupported RK8XX ID %x\n", variant);
-	}
+	data = device_get_match_data(&client->dev);
+	if (!data)
+		return -ENODEV;
 
-	regmap = devm_regmap_init_i2c(client, regmap_cfg);
+	regmap = devm_regmap_init_i2c(client, data->regmap_cfg);
 	if (IS_ERR(regmap))
 		return dev_err_probe(&client->dev, PTR_ERR(regmap),
 				     "regmap initialization failed\n");
 
-	return rk8xx_probe(&client->dev, variant, client->irq, regmap);
+	return rk8xx_probe(&client->dev, data->variant, client->irq, regmap);
 }
 
 static void rk8xx_i2c_shutdown(struct i2c_client *client)
@@ -173,11 +158,11 @@ static void rk8xx_i2c_shutdown(struct i2c_client *client)
 static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume);
 
 static const struct of_device_id rk8xx_i2c_of_match[] = {
-	{ .compatible = "rockchip,rk805" },
-	{ .compatible = "rockchip,rk808" },
-	{ .compatible = "rockchip,rk809" },
-	{ .compatible = "rockchip,rk817" },
-	{ .compatible = "rockchip,rk818" },
+	{ .compatible = "rockchip,rk805", .data = &rk805_data },
+	{ .compatible = "rockchip,rk808", .data = &rk808_data },
+	{ .compatible = "rockchip,rk809", .data = &rk809_data },
+	{ .compatible = "rockchip,rk817", .data = &rk817_data },
+	{ .compatible = "rockchip,rk818", .data = &rk818_data },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match);
-- 
2.39.0


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

* [PATCHv6 06/11] mfd: rk8xx-i2c: use device_get_match_data
@ 2023-01-27 18:12   ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Simplify the device identification logic by supplying the relevant
information via of_match_data. This also removes the dev_info()
printing the chip version, since that's supplied by the match data
now.

Due to lack of hardware this change is compile-tested only.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/mfd/rk8xx-core.c |  2 -
 drivers/mfd/rk8xx-i2c.c  | 89 +++++++++++++++++-----------------------
 2 files changed, 37 insertions(+), 54 deletions(-)

diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
index c52f5fa1a4da..21c6484a951c 100644
--- a/drivers/mfd/rk8xx-core.c
+++ b/drivers/mfd/rk8xx-core.c
@@ -596,8 +596,6 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
 		return -EINVAL;
 	}
 
-	dev_info(dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
-
 	if (!irq)
 		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
 
diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c
index 6d121b589fec..2822bfa8a04a 100644
--- a/drivers/mfd/rk8xx-i2c.c
+++ b/drivers/mfd/rk8xx-i2c.c
@@ -16,6 +16,11 @@
 #include <linux/of.h>
 #include <linux/regmap.h>
 
+struct rk8xx_i2c_platform_data {
+	const struct regmap_config *regmap_cfg;
+	int variant;
+};
+
 static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
 {
 	/*
@@ -103,66 +108,46 @@ static const struct regmap_config rk817_regmap_config = {
 	.volatile_reg = rk817_is_volatile_reg,
 };
 
-static int rk8xx_i2c_get_variant(struct i2c_client *client)
-{
-	u8 pmic_id_msb, pmic_id_lsb;
-	int msb, lsb;
-
-	if (of_device_is_compatible(client->dev.of_node, "rockchip,rk817") ||
-	    of_device_is_compatible(client->dev.of_node, "rockchip,rk809")) {
-		pmic_id_msb = RK817_ID_MSB;
-		pmic_id_lsb = RK817_ID_LSB;
-	} else {
-		pmic_id_msb = RK808_ID_MSB;
-		pmic_id_lsb = RK808_ID_LSB;
-	}
+static const struct rk8xx_i2c_platform_data rk805_data = {
+	.regmap_cfg = &rk805_regmap_config,
+	.variant = RK805_ID,
+};
+
+static const struct rk8xx_i2c_platform_data rk808_data = {
+	.regmap_cfg = &rk808_regmap_config,
+	.variant = RK808_ID,
+};
 
-	/* Read chip variant */
-	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
-	if (msb < 0)
-		return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n");
+static const struct rk8xx_i2c_platform_data rk809_data = {
+	.regmap_cfg = &rk817_regmap_config,
+	.variant = RK809_ID,
+};
 
-	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
-	if (lsb < 0)
-		return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n");
+static const struct rk8xx_i2c_platform_data rk817_data = {
+	.regmap_cfg = &rk817_regmap_config,
+	.variant = RK817_ID,
+};
 
-	return ((msb << 8) | lsb) & RK8XX_ID_MSK;
-}
+static const struct rk8xx_i2c_platform_data rk818_data = {
+	.regmap_cfg = &rk818_regmap_config,
+	.variant = RK818_ID,
+};
 
 static int rk8xx_i2c_probe(struct i2c_client *client)
 {
-	const struct regmap_config *regmap_cfg;
+	const struct rk8xx_i2c_platform_data *data;
 	struct regmap *regmap;
-	int variant;
 
-	variant = rk8xx_i2c_get_variant(client);
-	if (variant < 0)
-		return variant;
-
-	switch (variant) {
-	case RK805_ID:
-		regmap_cfg = &rk805_regmap_config;
-		break;
-	case RK808_ID:
-		regmap_cfg = &rk808_regmap_config;
-		break;
-	case RK818_ID:
-		regmap_cfg = &rk818_regmap_config;
-		break;
-	case RK809_ID:
-	case RK817_ID:
-		regmap_cfg = &rk817_regmap_config;
-		break;
-	default:
-		return dev_err_probe(&client->dev, -EINVAL, "Unsupported RK8XX ID %x\n", variant);
-	}
+	data = device_get_match_data(&client->dev);
+	if (!data)
+		return -ENODEV;
 
-	regmap = devm_regmap_init_i2c(client, regmap_cfg);
+	regmap = devm_regmap_init_i2c(client, data->regmap_cfg);
 	if (IS_ERR(regmap))
 		return dev_err_probe(&client->dev, PTR_ERR(regmap),
 				     "regmap initialization failed\n");
 
-	return rk8xx_probe(&client->dev, variant, client->irq, regmap);
+	return rk8xx_probe(&client->dev, data->variant, client->irq, regmap);
 }
 
 static void rk8xx_i2c_shutdown(struct i2c_client *client)
@@ -173,11 +158,11 @@ static void rk8xx_i2c_shutdown(struct i2c_client *client)
 static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume);
 
 static const struct of_device_id rk8xx_i2c_of_match[] = {
-	{ .compatible = "rockchip,rk805" },
-	{ .compatible = "rockchip,rk808" },
-	{ .compatible = "rockchip,rk809" },
-	{ .compatible = "rockchip,rk817" },
-	{ .compatible = "rockchip,rk818" },
+	{ .compatible = "rockchip,rk805", .data = &rk805_data },
+	{ .compatible = "rockchip,rk808", .data = &rk808_data },
+	{ .compatible = "rockchip,rk809", .data = &rk809_data },
+	{ .compatible = "rockchip,rk817", .data = &rk817_data },
+	{ .compatible = "rockchip,rk818", .data = &rk818_data },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match);
-- 
2.39.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCHv6 07/11] dt-bindings: mfd: add rk806 binding
  2023-01-27 18:12 ` Sebastian Reichel
@ 2023-01-27 18:12   ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel, Rob Herring

Add DT binding document for Rockchip's RK806 PMIC.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../bindings/mfd/rockchip,rk806.yaml          | 406 ++++++++++++++++++
 1 file changed, 406 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml

diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
new file mode 100644
index 000000000000..cf2500f2e9a0
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
@@ -0,0 +1,406 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/rockchip,rk806.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RK806 Power Management Integrated Circuit
+
+maintainers:
+  - Sebastian Reichel <sebastian.reichel@collabora.com>
+
+description:
+  Rockchip RK806 series PMIC. This device consists of an spi or
+  i2c controlled MFD that includes multiple switchable regulators.
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk806
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  vcc1-supply:
+    description:
+      The input supply for dcdc-reg1.
+
+  vcc2-supply:
+    description:
+      The input supply for dcdc-reg2.
+
+  vcc3-supply:
+    description:
+      The input supply for dcdc-reg3.
+
+  vcc4-supply:
+    description:
+      The input supply for dcdc-reg4.
+
+  vcc5-supply:
+    description:
+      The input supply for dcdc-reg5.
+
+  vcc6-supply:
+    description:
+      The input supply for dcdc-reg6.
+
+  vcc7-supply:
+    description:
+      The input supply for dcdc-reg7.
+
+  vcc8-supply:
+    description:
+      The input supply for dcdc-reg8.
+
+  vcc9-supply:
+    description:
+      The input supply for dcdc-reg9.
+
+  vcc10-supply:
+    description:
+      The input supply for dcdc-reg10.
+
+  vcc11-supply:
+    description:
+      The input supply for pldo-reg1, pldo-reg2 and pldo-reg3.
+
+  vcc12-supply:
+    description:
+      The input supply for pldo-reg4 and pldo-reg5.
+
+  vcc13-supply:
+    description:
+      The input supply for nldo-reg1, nldo-reg2 and nldo-reg3.
+
+  vcc14-supply:
+    description:
+      The input supply for nldo-reg4 and nldo-reg5.
+
+  vcca-supply:
+    description:
+      The input supply for pldo-reg6.
+
+  regulators:
+    type: object
+    additionalProperties: false
+    patternProperties:
+      "^(dcdc-reg([1-9]|10)|pldo-reg[1-6]|nldo-reg[1-5])$":
+        type: object
+        $ref: /schemas/regulator/regulator.yaml#
+        unevaluatedProperties: false
+
+patternProperties:
+  '-pins$':
+    type: object
+    additionalProperties: false
+    $ref: /schemas/pinctrl/pinmux-node.yaml
+
+    properties:
+      function:
+        enum: [pin_fun0, pin_fun1, pin_fun2, pin_fun3, pin_fun4, pin_fun5]
+
+      pins:
+        $ref: /schemas/types.yaml#/definitions/string
+        enum: [gpio_pwrctrl1, gpio_pwrctrl2, gpio_pwrctrl3]
+
+allOf:
+  - $ref: /schemas/spi/spi-peripheral-props.yaml
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/pinctrl/rockchip.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/gpio/gpio.h>
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pmic@0 {
+            compatible = "rockchip,rk806";
+            reg = <0x0>;
+
+            interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+            vcc1-supply = <&vcc5v0_sys>;
+            vcc2-supply = <&vcc5v0_sys>;
+            vcc3-supply = <&vcc5v0_sys>;
+            vcc4-supply = <&vcc5v0_sys>;
+            vcc5-supply = <&vcc5v0_sys>;
+            vcc6-supply = <&vcc5v0_sys>;
+            vcc7-supply = <&vcc5v0_sys>;
+            vcc8-supply = <&vcc5v0_sys>;
+            vcc9-supply = <&vcc5v0_sys>;
+            vcc10-supply = <&vcc5v0_sys>;
+            vcc11-supply = <&vcc_2v0_pldo_s3>;
+            vcc12-supply = <&vcc5v0_sys>;
+            vcc13-supply = <&vcc5v0_sys>;
+            vcc14-supply = <&vcc_1v1_nldo_s3>;
+            vcca-supply = <&vcc5v0_sys>;
+
+            regulators {
+                vdd_gpu_s0: dcdc-reg1 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <550000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_gpu_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_npu_s0: dcdc-reg2 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <550000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_npu_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_log_s0: dcdc-reg3 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <750000>;
+                    regulator-max-microvolt = <750000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_log_s0";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <750000>;
+                    };
+                };
+
+                vdd_vdenc_s0: dcdc-reg4 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <550000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_vdenc_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_gpu_mem_s0: dcdc-reg5 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <675000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_gpu_mem_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_npu_mem_s0: dcdc-reg6 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <675000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_npu_mem_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vcc_2v0_pldo_s3: dcdc-reg7 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <2000000>;
+                    regulator-max-microvolt = <2000000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_2v0_pldo_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <2000000>;
+                    };
+                };
+
+                vdd_vdenc_mem_s0: dcdc-reg8 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <675000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_vdenc_mem_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd2_ddr_s3: dcdc-reg9 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-name = "vdd2_ddr_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                    };
+                };
+
+                vcc_1v1_nldo_s3: dcdc-reg10 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1100000>;
+                    regulator-max-microvolt = <1100000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vcc_1v1_nldo_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <1100000>;
+                    };
+                };
+
+                avcc_1v8_s0: pldo-reg1 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "avcc_1v8_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd1_1v8_ddr_s3: pldo-reg2 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd1_1v8_ddr_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <1800000>;
+                    };
+                };
+
+                vcc_1v8_s3: pldo-reg3 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vcc_1v8_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <1800000>;
+                    };
+                };
+
+                vcc_3v3_s0: pldo-reg4 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <3300000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vcc_3v3_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vccio_sd_s0: pldo-reg5 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vccio_sd_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                master_pldo6_s3: pldo-reg6 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-name = "master_pldo6_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <1800000>;
+                    };
+                };
+
+                vdd_0v75_s3: nldo-reg1 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <750000>;
+                    regulator-max-microvolt = <750000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_0v75_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <750000>;
+                    };
+                };
+
+                vdd2l_0v9_ddr_s3: nldo-reg2 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <900000>;
+                    regulator-max-microvolt = <900000>;
+                    regulator-name = "vdd2l_0v9_ddr_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <900000>;
+                    };
+                };
+
+                master_nldo3: nldo-reg3 {
+                    regulator-name = "master_nldo3";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                avdd_0v75_s0: nldo-reg4 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <750000>;
+                    regulator-max-microvolt = <750000>;
+                    regulator-name = "avdd_0v75_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_0v85_s0: nldo-reg5 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <850000>;
+                    regulator-max-microvolt = <850000>;
+                    regulator-name = "vdd_0v85_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+            };
+        };
+    };
-- 
2.39.0


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

* [PATCHv6 07/11] dt-bindings: mfd: add rk806 binding
@ 2023-01-27 18:12   ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel, Rob Herring

Add DT binding document for Rockchip's RK806 PMIC.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 .../bindings/mfd/rockchip,rk806.yaml          | 406 ++++++++++++++++++
 1 file changed, 406 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml

diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
new file mode 100644
index 000000000000..cf2500f2e9a0
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
@@ -0,0 +1,406 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/rockchip,rk806.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RK806 Power Management Integrated Circuit
+
+maintainers:
+  - Sebastian Reichel <sebastian.reichel@collabora.com>
+
+description:
+  Rockchip RK806 series PMIC. This device consists of an spi or
+  i2c controlled MFD that includes multiple switchable regulators.
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk806
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  vcc1-supply:
+    description:
+      The input supply for dcdc-reg1.
+
+  vcc2-supply:
+    description:
+      The input supply for dcdc-reg2.
+
+  vcc3-supply:
+    description:
+      The input supply for dcdc-reg3.
+
+  vcc4-supply:
+    description:
+      The input supply for dcdc-reg4.
+
+  vcc5-supply:
+    description:
+      The input supply for dcdc-reg5.
+
+  vcc6-supply:
+    description:
+      The input supply for dcdc-reg6.
+
+  vcc7-supply:
+    description:
+      The input supply for dcdc-reg7.
+
+  vcc8-supply:
+    description:
+      The input supply for dcdc-reg8.
+
+  vcc9-supply:
+    description:
+      The input supply for dcdc-reg9.
+
+  vcc10-supply:
+    description:
+      The input supply for dcdc-reg10.
+
+  vcc11-supply:
+    description:
+      The input supply for pldo-reg1, pldo-reg2 and pldo-reg3.
+
+  vcc12-supply:
+    description:
+      The input supply for pldo-reg4 and pldo-reg5.
+
+  vcc13-supply:
+    description:
+      The input supply for nldo-reg1, nldo-reg2 and nldo-reg3.
+
+  vcc14-supply:
+    description:
+      The input supply for nldo-reg4 and nldo-reg5.
+
+  vcca-supply:
+    description:
+      The input supply for pldo-reg6.
+
+  regulators:
+    type: object
+    additionalProperties: false
+    patternProperties:
+      "^(dcdc-reg([1-9]|10)|pldo-reg[1-6]|nldo-reg[1-5])$":
+        type: object
+        $ref: /schemas/regulator/regulator.yaml#
+        unevaluatedProperties: false
+
+patternProperties:
+  '-pins$':
+    type: object
+    additionalProperties: false
+    $ref: /schemas/pinctrl/pinmux-node.yaml
+
+    properties:
+      function:
+        enum: [pin_fun0, pin_fun1, pin_fun2, pin_fun3, pin_fun4, pin_fun5]
+
+      pins:
+        $ref: /schemas/types.yaml#/definitions/string
+        enum: [gpio_pwrctrl1, gpio_pwrctrl2, gpio_pwrctrl3]
+
+allOf:
+  - $ref: /schemas/spi/spi-peripheral-props.yaml
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/pinctrl/rockchip.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/gpio/gpio.h>
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pmic@0 {
+            compatible = "rockchip,rk806";
+            reg = <0x0>;
+
+            interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+            vcc1-supply = <&vcc5v0_sys>;
+            vcc2-supply = <&vcc5v0_sys>;
+            vcc3-supply = <&vcc5v0_sys>;
+            vcc4-supply = <&vcc5v0_sys>;
+            vcc5-supply = <&vcc5v0_sys>;
+            vcc6-supply = <&vcc5v0_sys>;
+            vcc7-supply = <&vcc5v0_sys>;
+            vcc8-supply = <&vcc5v0_sys>;
+            vcc9-supply = <&vcc5v0_sys>;
+            vcc10-supply = <&vcc5v0_sys>;
+            vcc11-supply = <&vcc_2v0_pldo_s3>;
+            vcc12-supply = <&vcc5v0_sys>;
+            vcc13-supply = <&vcc5v0_sys>;
+            vcc14-supply = <&vcc_1v1_nldo_s3>;
+            vcca-supply = <&vcc5v0_sys>;
+
+            regulators {
+                vdd_gpu_s0: dcdc-reg1 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <550000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_gpu_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_npu_s0: dcdc-reg2 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <550000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_npu_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_log_s0: dcdc-reg3 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <750000>;
+                    regulator-max-microvolt = <750000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_log_s0";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <750000>;
+                    };
+                };
+
+                vdd_vdenc_s0: dcdc-reg4 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <550000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_vdenc_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_gpu_mem_s0: dcdc-reg5 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <675000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_gpu_mem_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_npu_mem_s0: dcdc-reg6 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <675000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_npu_mem_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vcc_2v0_pldo_s3: dcdc-reg7 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <2000000>;
+                    regulator-max-microvolt = <2000000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_2v0_pldo_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <2000000>;
+                    };
+                };
+
+                vdd_vdenc_mem_s0: dcdc-reg8 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <675000>;
+                    regulator-max-microvolt = <950000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_vdenc_mem_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd2_ddr_s3: dcdc-reg9 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-name = "vdd2_ddr_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                    };
+                };
+
+                vcc_1v1_nldo_s3: dcdc-reg10 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1100000>;
+                    regulator-max-microvolt = <1100000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vcc_1v1_nldo_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <1100000>;
+                    };
+                };
+
+                avcc_1v8_s0: pldo-reg1 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "avcc_1v8_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd1_1v8_ddr_s3: pldo-reg2 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd1_1v8_ddr_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <1800000>;
+                    };
+                };
+
+                vcc_1v8_s3: pldo-reg3 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vcc_1v8_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <1800000>;
+                    };
+                };
+
+                vcc_3v3_s0: pldo-reg4 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <3300000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vcc_3v3_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vccio_sd_s0: pldo-reg5 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vccio_sd_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                master_pldo6_s3: pldo-reg6 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-name = "master_pldo6_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <1800000>;
+                    };
+                };
+
+                vdd_0v75_s3: nldo-reg1 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <750000>;
+                    regulator-max-microvolt = <750000>;
+                    regulator-ramp-delay = <12500>;
+                    regulator-name = "vdd_0v75_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <750000>;
+                    };
+                };
+
+                vdd2l_0v9_ddr_s3: nldo-reg2 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <900000>;
+                    regulator-max-microvolt = <900000>;
+                    regulator-name = "vdd2l_0v9_ddr_s3";
+                    regulator-state-mem {
+                        regulator-on-in-suspend;
+                        regulator-suspend-microvolt = <900000>;
+                    };
+                };
+
+                master_nldo3: nldo-reg3 {
+                    regulator-name = "master_nldo3";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                avdd_0v75_s0: nldo-reg4 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <750000>;
+                    regulator-max-microvolt = <750000>;
+                    regulator-name = "avdd_0v75_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+
+                vdd_0v85_s0: nldo-reg5 {
+                    regulator-always-on;
+                    regulator-boot-on;
+                    regulator-min-microvolt = <850000>;
+                    regulator-max-microvolt = <850000>;
+                    regulator-name = "vdd_0v85_s0";
+                    regulator-state-mem {
+                        regulator-off-in-suspend;
+                    };
+                };
+            };
+        };
+    };
-- 
2.39.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCHv6 08/11] mfd: rk8xx: add rk806 support
  2023-01-27 18:12 ` Sebastian Reichel
@ 2023-01-27 18:12   ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Add support for SPI connected rk806, which is used by the RK3588
evaluation boards. The PMIC is advertised to support I2C and SPI,
but the evaluation boards all use SPI. Thus only SPI support is
added here.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/mfd/Kconfig       |  14 ++
 drivers/mfd/Makefile      |   1 +
 drivers/mfd/rk8xx-core.c  |  69 ++++++-
 drivers/mfd/rk8xx-spi.c   | 129 ++++++++++++
 include/linux/mfd/rk808.h | 409 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 619 insertions(+), 3 deletions(-)
 create mode 100644 drivers/mfd/rk8xx-spi.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 692e38283bda..13582ea5cb44 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1222,6 +1222,20 @@ config MFD_RK8XX_I2C
 	  through I2C interface. The device supports multiple sub-devices
 	  including interrupts, RTC, LDO & DCDC regulators, and onkey.
 
+config MFD_RK8XX_SPI
+	tristate "Rockchip RK806 Power Management Chip"
+	depends on SPI && OF
+	select MFD_CORE
+	select REGMAP_SPI
+	select REGMAP_IRQ
+	select MFD_RK8XX
+	help
+	  If you say yes here you get support for the RK806 Power Management
+	  chip.
+	  This driver provides common support for accessing the device
+	  through an SPI interface. The device supports multiple sub-devices
+	  including interrupts, LDO & DCDC regulators, and power on-key.
+
 config MFD_RN5T618
 	tristate "Ricoh RN5T567/618 PMIC"
 	depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f65ef1bd0810..a88f27cd837b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -222,6 +222,7 @@ obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
 obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
 obj-$(CONFIG_MFD_RK8XX)		+= rk8xx-core.o
 obj-$(CONFIG_MFD_RK8XX_I2C)	+= rk8xx-i2c.o
+obj-$(CONFIG_MFD_RK8XX_SPI)	+= rk8xx-spi.o
 obj-$(CONFIG_MFD_RN5T618)	+= rn5t618.o
 obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
 obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
index 21c6484a951c..252030b9be4c 100644
--- a/drivers/mfd/rk8xx-core.c
+++ b/drivers/mfd/rk8xx-core.c
@@ -37,6 +37,11 @@ static const struct resource rk805_key_resources[] = {
 	DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
 };
 
+static struct resource rk806_pwrkey_resources[] = {
+	DEFINE_RES_IRQ(RK806_IRQ_PWRON_FALL),
+	DEFINE_RES_IRQ(RK806_IRQ_PWRON_RISE),
+};
+
 static const struct resource rk817_pwrkey_resources[] = {
 	DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
 	DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
@@ -64,6 +69,17 @@ static const struct mfd_cell rk805s[] = {
 	},
 };
 
+static const struct mfd_cell rk806s[] = {
+	{ .name = "rk805-pinctrl", .id = PLATFORM_DEVID_AUTO, },
+	{ .name = "rk808-regulator", .id = PLATFORM_DEVID_AUTO, },
+	{
+		.name = "rk805-pwrkey",
+		.resources = rk806_pwrkey_resources,
+		.num_resources = ARRAY_SIZE(rk806_pwrkey_resources),
+		.id = PLATFORM_DEVID_AUTO,
+	},
+};
+
 static const struct mfd_cell rk808s[] = {
 	{ .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
 	{ .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
@@ -122,6 +138,12 @@ static const struct rk808_reg_data rk805_pre_init_reg[] = {
 	{RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
 };
 
+static const struct rk808_reg_data rk806_pre_init_reg[] = {
+	{ RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
+	{ RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
+	{ RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
+};
+
 static const struct rk808_reg_data rk808_pre_init_reg[] = {
 	{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_150MA },
 	{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_200MA },
@@ -272,6 +294,27 @@ static const struct regmap_irq rk805_irqs[] = {
 	},
 };
 
+static const struct regmap_irq rk806_irqs[] = {
+	/* INT_STS0 IRQs */
+	REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),
+	REGMAP_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE),
+	REGMAP_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON),
+	REGMAP_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP),
+	REGMAP_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE),
+	REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),
+	REGMAP_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL),
+	REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),
+	/* INT_STS1 IRQs */
+	REGMAP_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0),
+	REGMAP_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1),
+	REGMAP_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2),
+	REGMAP_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR),
+	REGMAP_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO),
+	REGMAP_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO),
+	REGMAP_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO),
+	REGMAP_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT),
+};
+
 static const struct regmap_irq rk808_irqs[] = {
 	/* INT_STS */
 	[RK808_IRQ_VOUT_LO] = {
@@ -422,6 +465,18 @@ static struct regmap_irq_chip rk805_irq_chip = {
 	.init_ack_masked = true,
 };
 
+static struct regmap_irq_chip rk806_irq_chip = {
+	.name = "rk806",
+	.irqs = rk806_irqs,
+	.num_irqs = ARRAY_SIZE(rk806_irqs),
+	.num_regs = 2,
+	.irq_reg_stride = 2,
+	.mask_base = RK806_INT_MSK0,
+	.status_base = RK806_INT_STS0,
+	.ack_base = RK806_INT_STS0,
+	.init_ack_masked = true,
+};
+
 static const struct regmap_irq_chip rk808_irq_chip = {
 	.name = "rk808",
 	.irqs = rk808_irqs,
@@ -548,6 +603,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
 	struct rk808 *rk808;
 	const struct rk808_reg_data *pre_init_reg;
 	const struct mfd_cell *cells;
+	int dual_support = 0;
 	int nr_pre_init_regs;
 	int nr_cells;
 	int ret;
@@ -569,6 +625,14 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
 		cells = rk805s;
 		nr_cells = ARRAY_SIZE(rk805s);
 		break;
+	case RK806_ID:
+		rk808->regmap_irq_chip = &rk806_irq_chip;
+		pre_init_reg = rk806_pre_init_reg;
+		nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
+		cells = rk806s;
+		nr_cells = ARRAY_SIZE(rk806s);
+		dual_support = IRQF_SHARED;
+		break;
 	case RK808_ID:
 		rk808->regmap_irq_chip = &rk808_irq_chip;
 		pre_init_reg = rk808_pre_init_reg;
@@ -600,7 +664,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
 		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
 
 	ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
-				       IRQF_ONESHOT, -1,
+				       IRQF_ONESHOT | dual_support, -1,
 				       rk808->regmap_irq_chip, &rk808->irq_data);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
@@ -615,8 +679,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
 					     pre_init_reg[i].addr);
 	}
 
-	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
-			      cells, nr_cells, NULL, 0,
+	ret = devm_mfd_add_devices(dev, 0, cells, nr_cells, NULL, 0,
 			      regmap_irq_get_domain(rk808->irq_data));
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to add MFD devices\n");
diff --git a/drivers/mfd/rk8xx-spi.c b/drivers/mfd/rk8xx-spi.c
new file mode 100644
index 000000000000..3f6c5b1334f7
--- /dev/null
+++ b/drivers/mfd/rk8xx-spi.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip RK806 Core (SPI) driver
+ *
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2023 Collabora Ltd.
+ *
+ * Author: Xu Shengfei <xsf@rock-chips.com>
+ * Author: Sebastian Reichel <sebastian.reichel@collabora.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/rk808.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#define RK806_CMD		0
+#define RK806_REG_ADDR_L	1
+#define RK806_REG_ADDR_H	2
+#define RK806_CMD_WITH_SIZE(CMD, VALUE_BYTES) \
+	(RK806_CMD_ ## CMD | (VALUE_BYTES-1))
+
+static const struct regmap_range rk806_volatile_ranges[] = {
+	regmap_reg_range(RK806_POWER_EN0, RK806_POWER_EN5),
+	regmap_reg_range(RK806_DVS_START_CTRL, RK806_INT_MSK1),
+};
+
+static const struct regmap_access_table rk806_volatile_table = {
+	.yes_ranges = rk806_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(rk806_volatile_ranges),
+};
+
+static const struct regmap_config rk806_regmap_config_spi = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.cache_type = REGCACHE_RBTREE,
+	.volatile_table = &rk806_volatile_table,
+};
+
+static int rk806_spi_bus_write(void *context, const void *vdata, size_t count)
+{
+	struct device *dev = context;
+	struct spi_device *spi = to_spi_device(dev);
+	const char *data = vdata;
+	char buffer[3] = { 0 };
+	struct spi_transfer xfer[2] = { 0 };
+	/* count includes the register size */
+	size_t val_size = count - 1;
+
+	if (val_size < 1 || val_size > 128)
+		return -EINVAL;
+
+	buffer[RK806_CMD]	 = RK806_CMD_WITH_SIZE(WRITE, val_size);
+	buffer[RK806_REG_ADDR_L] = data[0];
+	buffer[RK806_REG_ADDR_H] = RK806_REG_H;
+
+	xfer[0].tx_buf = buffer;
+	xfer[0].len = sizeof(buffer);
+	xfer[1].tx_buf = data + 1;
+	xfer[1].len = count - 1;
+
+	return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
+}
+
+static int rk806_spi_bus_read(void *context, const void *vreg, size_t reg_size,
+			      void *val, size_t val_size)
+{
+	struct device *dev = context;
+	struct spi_device *spi = to_spi_device(dev);
+	const char *reg = vreg;
+	char txbuf[3] = { 0 };
+
+	if (reg_size != sizeof(char) || val_size < 1 || val_size > 128)
+		return -EINVAL;
+
+	txbuf[RK806_CMD]	= RK806_CMD_WITH_SIZE(READ, val_size);
+	txbuf[RK806_REG_ADDR_L]	= *reg;
+	txbuf[RK806_REG_ADDR_H]	= RK806_REG_H;
+
+	return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size);
+}
+
+static const struct regmap_bus rk806_regmap_bus_spi = {
+	.write = rk806_spi_bus_write,
+	.read = rk806_spi_bus_read,
+	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+static int rk8xx_spi_probe(struct spi_device *spi)
+{
+	struct regmap *regmap;
+
+	regmap = devm_regmap_init(&spi->dev, &rk806_regmap_bus_spi,
+				  &spi->dev, &rk806_regmap_config_spi);
+	if (IS_ERR(regmap))
+		return dev_err_probe(&spi->dev, PTR_ERR(regmap),
+				     "Failed to initialize register map\n");
+
+	return rk8xx_probe(&spi->dev, RK806_ID, spi->irq, regmap);
+}
+
+static const struct of_device_id rk8xx_spi_of_match[] = {
+	{ .compatible = "rockchip,rk806", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, rk8xx_spi_of_match);
+
+static const struct spi_device_id rk8xx_spi_id_table[] = {
+	{ "rk806", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, rk8xx_spi_id_table);
+
+static struct spi_driver rk8xx_spi_driver = {
+	.driver		= {
+		.name	= "rk8xx-spi",
+		.of_match_table = rk8xx_spi_of_match,
+	},
+	.probe		= rk8xx_spi_probe,
+	.id_table	= rk8xx_spi_id_table,
+};
+module_spi_driver(rk8xx_spi_driver);
+
+MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
+MODULE_DESCRIPTION("RK8xx SPI PMIC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index 4183427a80fe..78e167a92483 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -289,6 +289,414 @@ enum rk805_reg {
 #define RK805_INT_ALARM_EN		(1 << 3)
 #define RK805_INT_TIMER_EN		(1 << 2)
 
+/* RK806 */
+#define RK806_POWER_EN0			0x0
+#define RK806_POWER_EN1			0x1
+#define RK806_POWER_EN2			0x2
+#define RK806_POWER_EN3			0x3
+#define RK806_POWER_EN4			0x4
+#define RK806_POWER_EN5			0x5
+#define RK806_POWER_SLP_EN0		0x6
+#define RK806_POWER_SLP_EN1		0x7
+#define RK806_POWER_SLP_EN2		0x8
+#define RK806_POWER_DISCHRG_EN0		0x9
+#define RK806_POWER_DISCHRG_EN1		0xA
+#define RK806_POWER_DISCHRG_EN2		0xB
+#define RK806_BUCK_FB_CONFIG		0xC
+#define RK806_SLP_LP_CONFIG		0xD
+#define RK806_POWER_FPWM_EN0		0xE
+#define RK806_POWER_FPWM_EN1		0xF
+#define RK806_BUCK1_CONFIG		0x10
+#define RK806_BUCK2_CONFIG		0x11
+#define RK806_BUCK3_CONFIG		0x12
+#define RK806_BUCK4_CONFIG		0x13
+#define RK806_BUCK5_CONFIG		0x14
+#define RK806_BUCK6_CONFIG		0x15
+#define RK806_BUCK7_CONFIG		0x16
+#define RK806_BUCK8_CONFIG		0x17
+#define RK806_BUCK9_CONFIG		0x18
+#define RK806_BUCK10_CONFIG		0x19
+#define RK806_BUCK1_ON_VSEL		0x1A
+#define RK806_BUCK2_ON_VSEL		0x1B
+#define RK806_BUCK3_ON_VSEL		0x1C
+#define RK806_BUCK4_ON_VSEL		0x1D
+#define RK806_BUCK5_ON_VSEL		0x1E
+#define RK806_BUCK6_ON_VSEL		0x1F
+#define RK806_BUCK7_ON_VSEL		0x20
+#define RK806_BUCK8_ON_VSEL		0x21
+#define RK806_BUCK9_ON_VSEL		0x22
+#define RK806_BUCK10_ON_VSEL		0x23
+#define RK806_BUCK1_SLP_VSEL		0x24
+#define RK806_BUCK2_SLP_VSEL		0x25
+#define RK806_BUCK3_SLP_VSEL		0x26
+#define RK806_BUCK4_SLP_VSEL		0x27
+#define RK806_BUCK5_SLP_VSEL		0x28
+#define RK806_BUCK6_SLP_VSEL		0x29
+#define RK806_BUCK7_SLP_VSEL		0x2A
+#define RK806_BUCK8_SLP_VSEL		0x2B
+#define RK806_BUCK9_SLP_VSEL		0x2D
+#define RK806_BUCK10_SLP_VSEL		0x2E
+#define RK806_BUCK_DEBUG1		0x30
+#define RK806_BUCK_DEBUG2		0x31
+#define RK806_BUCK_DEBUG3		0x32
+#define RK806_BUCK_DEBUG4		0x33
+#define RK806_BUCK_DEBUG5		0x34
+#define RK806_BUCK_DEBUG6		0x35
+#define RK806_BUCK_DEBUG7		0x36
+#define RK806_BUCK_DEBUG8		0x37
+#define RK806_BUCK_DEBUG9		0x38
+#define RK806_BUCK_DEBUG10		0x39
+#define RK806_BUCK_DEBUG11		0x3A
+#define RK806_BUCK_DEBUG12		0x3B
+#define RK806_BUCK_DEBUG13		0x3C
+#define RK806_BUCK_DEBUG14		0x3D
+#define RK806_BUCK_DEBUG15		0x3E
+#define RK806_BUCK_DEBUG16		0x3F
+#define RK806_BUCK_DEBUG17		0x40
+#define RK806_BUCK_DEBUG18		0x41
+#define RK806_NLDO_IMAX			0x42
+#define RK806_NLDO1_ON_VSEL		0x43
+#define RK806_NLDO2_ON_VSEL		0x44
+#define RK806_NLDO3_ON_VSEL		0x45
+#define RK806_NLDO4_ON_VSEL		0x46
+#define RK806_NLDO5_ON_VSEL		0x47
+#define RK806_NLDO1_SLP_VSEL		0x48
+#define RK806_NLDO2_SLP_VSEL		0x49
+#define RK806_NLDO3_SLP_VSEL		0x4A
+#define RK806_NLDO4_SLP_VSEL		0x4B
+#define RK806_NLDO5_SLP_VSEL		0x4C
+#define RK806_PLDO_IMAX			0x4D
+#define RK806_PLDO1_ON_VSEL		0x4E
+#define RK806_PLDO2_ON_VSEL		0x4F
+#define RK806_PLDO3_ON_VSEL		0x50
+#define RK806_PLDO4_ON_VSEL		0x51
+#define RK806_PLDO5_ON_VSEL		0x52
+#define RK806_PLDO6_ON_VSEL		0x53
+#define RK806_PLDO1_SLP_VSEL		0x54
+#define RK806_PLDO2_SLP_VSEL		0x55
+#define RK806_PLDO3_SLP_VSEL		0x56
+#define RK806_PLDO4_SLP_VSEL		0x57
+#define RK806_PLDO5_SLP_VSEL		0x58
+#define RK806_PLDO6_SLP_VSEL		0x59
+#define RK806_CHIP_NAME			0x5A
+#define RK806_CHIP_VER			0x5B
+#define RK806_OTP_VER			0x5C
+#define RK806_SYS_STS			0x5D
+#define RK806_SYS_CFG0			0x5E
+#define RK806_SYS_CFG1			0x5F
+#define RK806_SYS_OPTION		0x61
+#define RK806_SLEEP_CONFIG0		0x62
+#define RK806_SLEEP_CONFIG1		0x63
+#define RK806_SLEEP_CTR_SEL0		0x64
+#define RK806_SLEEP_CTR_SEL1		0x65
+#define RK806_SLEEP_CTR_SEL2		0x66
+#define RK806_SLEEP_CTR_SEL3		0x67
+#define RK806_SLEEP_CTR_SEL4		0x68
+#define RK806_SLEEP_CTR_SEL5		0x69
+#define RK806_DVS_CTRL_SEL0		0x6A
+#define RK806_DVS_CTRL_SEL1		0x6B
+#define RK806_DVS_CTRL_SEL2		0x6C
+#define RK806_DVS_CTRL_SEL3		0x6D
+#define RK806_DVS_CTRL_SEL4		0x6E
+#define RK806_DVS_CTRL_SEL5		0x6F
+#define RK806_DVS_START_CTRL		0x70
+#define RK806_SLEEP_GPIO		0x71
+#define RK806_SYS_CFG3			0x72
+#define RK806_ON_SOURCE			0x74
+#define RK806_OFF_SOURCE		0x75
+#define RK806_PWRON_KEY			0x76
+#define RK806_INT_STS0			0x77
+#define RK806_INT_MSK0			0x78
+#define RK806_INT_STS1			0x79
+#define RK806_INT_MSK1			0x7A
+#define RK806_GPIO_INT_CONFIG		0x7B
+#define RK806_DATA_REG0			0x7C
+#define RK806_DATA_REG1			0x7D
+#define RK806_DATA_REG2			0x7E
+#define RK806_DATA_REG3			0x7F
+#define RK806_DATA_REG4			0x80
+#define RK806_DATA_REG5			0x81
+#define RK806_DATA_REG6			0x82
+#define RK806_DATA_REG7			0x83
+#define RK806_DATA_REG8			0x84
+#define RK806_DATA_REG9			0x85
+#define RK806_DATA_REG10		0x86
+#define RK806_DATA_REG11		0x87
+#define RK806_DATA_REG12		0x88
+#define RK806_DATA_REG13		0x89
+#define RK806_DATA_REG14		0x8A
+#define RK806_DATA_REG15		0x8B
+#define RK806_TM_REG			0x8C
+#define RK806_OTP_EN_REG		0x8D
+#define RK806_FUNC_OTP_EN_REG		0x8E
+#define RK806_TEST_REG1			0x8F
+#define RK806_TEST_REG2			0x90
+#define RK806_TEST_REG3			0x91
+#define RK806_TEST_REG4			0x92
+#define RK806_TEST_REG5			0x93
+#define RK806_BUCK_VSEL_OTP_REG0	0x94
+#define RK806_BUCK_VSEL_OTP_REG1	0x95
+#define RK806_BUCK_VSEL_OTP_REG2	0x96
+#define RK806_BUCK_VSEL_OTP_REG3	0x97
+#define RK806_BUCK_VSEL_OTP_REG4	0x98
+#define RK806_BUCK_VSEL_OTP_REG5	0x99
+#define RK806_BUCK_VSEL_OTP_REG6	0x9A
+#define RK806_BUCK_VSEL_OTP_REG7	0x9B
+#define RK806_BUCK_VSEL_OTP_REG8	0x9C
+#define RK806_BUCK_VSEL_OTP_REG9	0x9D
+#define RK806_NLDO1_VSEL_OTP_REG0	0x9E
+#define RK806_NLDO1_VSEL_OTP_REG1	0x9F
+#define RK806_NLDO1_VSEL_OTP_REG2	0xA0
+#define RK806_NLDO1_VSEL_OTP_REG3	0xA1
+#define RK806_NLDO1_VSEL_OTP_REG4	0xA2
+#define RK806_PLDO_VSEL_OTP_REG0	0xA3
+#define RK806_PLDO_VSEL_OTP_REG1	0xA4
+#define RK806_PLDO_VSEL_OTP_REG2	0xA5
+#define RK806_PLDO_VSEL_OTP_REG3	0xA6
+#define RK806_PLDO_VSEL_OTP_REG4	0xA7
+#define RK806_PLDO_VSEL_OTP_REG5	0xA8
+#define RK806_BUCK_EN_OTP_REG1		0xA9
+#define RK806_NLDO_EN_OTP_REG1		0xAA
+#define RK806_PLDO_EN_OTP_REG1		0xAB
+#define RK806_BUCK_FB_RES_OTP_REG1	0xAC
+#define RK806_OTP_RESEV_REG0		0xAD
+#define RK806_OTP_RESEV_REG1		0xAE
+#define RK806_OTP_RESEV_REG2		0xAF
+#define RK806_OTP_RESEV_REG3		0xB0
+#define RK806_OTP_RESEV_REG4		0xB1
+#define RK806_BUCK_SEQ_REG0		0xB2
+#define RK806_BUCK_SEQ_REG1		0xB3
+#define RK806_BUCK_SEQ_REG2		0xB4
+#define RK806_BUCK_SEQ_REG3		0xB5
+#define RK806_BUCK_SEQ_REG4		0xB6
+#define RK806_BUCK_SEQ_REG5		0xB7
+#define RK806_BUCK_SEQ_REG6		0xB8
+#define RK806_BUCK_SEQ_REG7		0xB9
+#define RK806_BUCK_SEQ_REG8		0xBA
+#define RK806_BUCK_SEQ_REG9		0xBB
+#define RK806_BUCK_SEQ_REG10		0xBC
+#define RK806_BUCK_SEQ_REG11		0xBD
+#define RK806_BUCK_SEQ_REG12		0xBE
+#define RK806_BUCK_SEQ_REG13		0xBF
+#define RK806_BUCK_SEQ_REG14		0xC0
+#define RK806_BUCK_SEQ_REG15		0xC1
+#define RK806_BUCK_SEQ_REG16		0xC2
+#define RK806_BUCK_SEQ_REG17		0xC3
+#define RK806_HK_TRIM_REG1		0xC4
+#define RK806_HK_TRIM_REG2		0xC5
+#define RK806_BUCK_REF_TRIM_REG1	0xC6
+#define RK806_BUCK_REF_TRIM_REG2	0xC7
+#define RK806_BUCK_REF_TRIM_REG3	0xC8
+#define RK806_BUCK_REF_TRIM_REG4	0xC9
+#define RK806_BUCK_REF_TRIM_REG5	0xCA
+#define RK806_BUCK_OSC_TRIM_REG1	0xCB
+#define RK806_BUCK_OSC_TRIM_REG2	0xCC
+#define RK806_BUCK_OSC_TRIM_REG3	0xCD
+#define RK806_BUCK_OSC_TRIM_REG4	0xCE
+#define RK806_BUCK_OSC_TRIM_REG5	0xCF
+#define RK806_BUCK_TRIM_ZCDIOS_REG1	0xD0
+#define RK806_BUCK_TRIM_ZCDIOS_REG2	0xD1
+#define RK806_NLDO_TRIM_REG1		0xD2
+#define RK806_NLDO_TRIM_REG2		0xD3
+#define RK806_NLDO_TRIM_REG3		0xD4
+#define RK806_PLDO_TRIM_REG1		0xD5
+#define RK806_PLDO_TRIM_REG2		0xD6
+#define RK806_PLDO_TRIM_REG3		0xD7
+#define RK806_TRIM_ICOMP_REG1		0xD8
+#define RK806_TRIM_ICOMP_REG2		0xD9
+#define RK806_EFUSE_CONTROL_REGH	0xDA
+#define RK806_FUSE_PROG_REG		0xDB
+#define RK806_MAIN_FSM_STS_REG		0xDD
+#define RK806_FSM_REG			0xDE
+#define RK806_TOP_RESEV_OFFR		0xEC
+#define RK806_TOP_RESEV_POR		0xED
+#define RK806_BUCK_VRSN_REG1		0xEE
+#define RK806_BUCK_VRSN_REG2		0xEF
+#define RK806_NLDO_RLOAD_SEL_REG1	0xF0
+#define RK806_PLDO_RLOAD_SEL_REG1	0xF1
+#define RK806_PLDO_RLOAD_SEL_REG2	0xF2
+#define RK806_BUCK_CMIN_MX_REG1		0xF3
+#define RK806_BUCK_CMIN_MX_REG2		0xF4
+#define RK806_BUCK_FREQ_SET_REG1	0xF5
+#define RK806_BUCK_FREQ_SET_REG2	0xF6
+#define RK806_BUCK_RS_MEABS_REG1	0xF7
+#define RK806_BUCK_RS_MEABS_REG2	0xF8
+#define RK806_BUCK_RS_ZDLEB_REG1	0xF9
+#define RK806_BUCK_RS_ZDLEB_REG2	0xFA
+#define RK806_BUCK_RSERVE_REG1		0xFB
+#define RK806_BUCK_RSERVE_REG2		0xFC
+#define RK806_BUCK_RSERVE_REG3		0xFD
+#define RK806_BUCK_RSERVE_REG4		0xFE
+#define RK806_BUCK_RSERVE_REG5		0xFF
+
+/* INT_STS Register field definitions */
+#define RK806_INT_STS_PWRON_FALL	BIT(0)
+#define RK806_INT_STS_PWRON_RISE	BIT(1)
+#define RK806_INT_STS_PWRON		BIT(2)
+#define RK806_INT_STS_PWRON_LP		BIT(3)
+#define RK806_INT_STS_HOTDIE		BIT(4)
+#define RK806_INT_STS_VDC_RISE		BIT(5)
+#define RK806_INT_STS_VDC_FALL		BIT(6)
+#define RK806_INT_STS_VB_LO		BIT(7)
+#define RK806_INT_STS_REV0		BIT(0)
+#define RK806_INT_STS_REV1		BIT(1)
+#define RK806_INT_STS_REV2		BIT(2)
+#define RK806_INT_STS_CRC_ERROR		BIT(3)
+#define RK806_INT_STS_SLP3_GPIO		BIT(4)
+#define RK806_INT_STS_SLP2_GPIO		BIT(5)
+#define RK806_INT_STS_SLP1_GPIO		BIT(6)
+#define RK806_INT_STS_WDT		BIT(7)
+
+/* SPI command */
+#define RK806_CMD_READ			0
+#define RK806_CMD_WRITE			BIT(7)
+#define RK806_CMD_CRC_EN		BIT(6)
+#define RK806_CMD_CRC_DIS		0
+#define RK806_CMD_LEN_MSK		0x0f
+#define RK806_REG_H			0x00
+
+#define VERSION_AB		0x01
+
+enum rk806_reg_id {
+	RK806_ID_DCDC1 = 0,
+	RK806_ID_DCDC2,
+	RK806_ID_DCDC3,
+	RK806_ID_DCDC4,
+	RK806_ID_DCDC5,
+	RK806_ID_DCDC6,
+	RK806_ID_DCDC7,
+	RK806_ID_DCDC8,
+	RK806_ID_DCDC9,
+	RK806_ID_DCDC10,
+
+	RK806_ID_NLDO1,
+	RK806_ID_NLDO2,
+	RK806_ID_NLDO3,
+	RK806_ID_NLDO4,
+	RK806_ID_NLDO5,
+
+	RK806_ID_PLDO1,
+	RK806_ID_PLDO2,
+	RK806_ID_PLDO3,
+	RK806_ID_PLDO4,
+	RK806_ID_PLDO5,
+	RK806_ID_PLDO6,
+	RK806_ID_END,
+};
+
+/* Define the RK806 IRQ numbers */
+enum rk806_irqs {
+	/* INT_STS0 registers */
+	RK806_IRQ_PWRON_FALL,
+	RK806_IRQ_PWRON_RISE,
+	RK806_IRQ_PWRON,
+	RK806_IRQ_PWRON_LP,
+	RK806_IRQ_HOTDIE,
+	RK806_IRQ_VDC_RISE,
+	RK806_IRQ_VDC_FALL,
+	RK806_IRQ_VB_LO,
+
+	/* INT_STS0 registers */
+	RK806_IRQ_REV0,
+	RK806_IRQ_REV1,
+	RK806_IRQ_REV2,
+	RK806_IRQ_CRC_ERROR,
+	RK806_IRQ_SLP3_GPIO,
+	RK806_IRQ_SLP2_GPIO,
+	RK806_IRQ_SLP1_GPIO,
+	RK806_IRQ_WDT,
+};
+
+/* VCC1 Low Voltage Threshold */
+enum rk806_lv_sel {
+	VB_LO_SEL_2800,
+	VB_LO_SEL_2900,
+	VB_LO_SEL_3000,
+	VB_LO_SEL_3100,
+	VB_LO_SEL_3200,
+	VB_LO_SEL_3300,
+	VB_LO_SEL_3400,
+	VB_LO_SEL_3500,
+};
+
+/* System Shutdown Voltage Select */
+enum rk806_uv_sel {
+	VB_UV_SEL_2700,
+	VB_UV_SEL_2800,
+	VB_UV_SEL_2900,
+	VB_UV_SEL_3000,
+	VB_UV_SEL_3100,
+	VB_UV_SEL_3200,
+	VB_UV_SEL_3300,
+	VB_UV_SEL_3400,
+};
+
+/* Pin Function */
+enum rk806_pwrctrl_fun {
+	PWRCTRL_NULL_FUN,
+	PWRCTRL_SLP_FUN,
+	PWRCTRL_POWOFF_FUN,
+	PWRCTRL_RST_FUN,
+	PWRCTRL_DVS_FUN,
+	PWRCTRL_GPIO_FUN,
+};
+
+/* Pin Polarity */
+enum rk806_pin_level {
+	POL_LOW,
+	POL_HIGH,
+};
+
+enum rk806_vsel_ctr_sel {
+	CTR_BY_NO_EFFECT,
+	CTR_BY_PWRCTRL1,
+	CTR_BY_PWRCTRL2,
+	CTR_BY_PWRCTRL3,
+};
+
+enum rk806_dvs_ctr_sel {
+	CTR_SEL_NO_EFFECT,
+	CTR_SEL_DVS_START1,
+	CTR_SEL_DVS_START2,
+	CTR_SEL_DVS_START3,
+};
+
+enum rk806_pin_dr_sel {
+	RK806_PIN_INPUT,
+	RK806_PIN_OUTPUT,
+};
+
+#define RK806_INT_POL_MSK		BIT(1)
+#define RK806_INT_POL_H			BIT(1)
+#define RK806_INT_POL_L			0
+
+#define RK806_SLAVE_RESTART_FUN_MSK	BIT(1)
+#define RK806_SLAVE_RESTART_FUN_EN	BIT(1)
+#define RK806_SLAVE_RESTART_FUN_OFF	0
+
+#define RK806_SYS_ENB2_2M_MSK		BIT(1)
+#define RK806_SYS_ENB2_2M_EN		BIT(1)
+#define RK806_SYS_ENB2_2M_OFF		0
+
+enum rk806_int_fun {
+	RK806_INT_ONLY,
+	RK806_INT_ADN_WKUP,
+};
+
+enum rk806_dvs_mode {
+	RK806_DVS_NOT_SUPPORT,
+	RK806_DVS_START1,
+	RK806_DVS_START2,
+	RK806_DVS_START3,
+	RK806_DVS_PWRCTRL1,
+	RK806_DVS_PWRCTRL2,
+	RK806_DVS_PWRCTRL3,
+	RK806_DVS_START_PWRCTR1,
+	RK806_DVS_START_PWRCTR2,
+	RK806_DVS_START_PWRCTR3,
+	RK806_DVS_END,
+};
+
 /* RK808 IRQ Definitions */
 #define RK808_IRQ_VOUT_LO	0
 #define RK808_IRQ_VB_LO		1
@@ -780,6 +1188,7 @@ enum {
 
 enum {
 	RK805_ID = 0x8050,
+	RK806_ID = 0x8060,
 	RK808_ID = 0x0000,
 	RK809_ID = 0x8090,
 	RK817_ID = 0x8170,
-- 
2.39.0


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

* [PATCHv6 08/11] mfd: rk8xx: add rk806 support
@ 2023-01-27 18:12   ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Add support for SPI connected rk806, which is used by the RK3588
evaluation boards. The PMIC is advertised to support I2C and SPI,
but the evaluation boards all use SPI. Thus only SPI support is
added here.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/mfd/Kconfig       |  14 ++
 drivers/mfd/Makefile      |   1 +
 drivers/mfd/rk8xx-core.c  |  69 ++++++-
 drivers/mfd/rk8xx-spi.c   | 129 ++++++++++++
 include/linux/mfd/rk808.h | 409 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 619 insertions(+), 3 deletions(-)
 create mode 100644 drivers/mfd/rk8xx-spi.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 692e38283bda..13582ea5cb44 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1222,6 +1222,20 @@ config MFD_RK8XX_I2C
 	  through I2C interface. The device supports multiple sub-devices
 	  including interrupts, RTC, LDO & DCDC regulators, and onkey.
 
+config MFD_RK8XX_SPI
+	tristate "Rockchip RK806 Power Management Chip"
+	depends on SPI && OF
+	select MFD_CORE
+	select REGMAP_SPI
+	select REGMAP_IRQ
+	select MFD_RK8XX
+	help
+	  If you say yes here you get support for the RK806 Power Management
+	  chip.
+	  This driver provides common support for accessing the device
+	  through an SPI interface. The device supports multiple sub-devices
+	  including interrupts, LDO & DCDC regulators, and power on-key.
+
 config MFD_RN5T618
 	tristate "Ricoh RN5T567/618 PMIC"
 	depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f65ef1bd0810..a88f27cd837b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -222,6 +222,7 @@ obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
 obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
 obj-$(CONFIG_MFD_RK8XX)		+= rk8xx-core.o
 obj-$(CONFIG_MFD_RK8XX_I2C)	+= rk8xx-i2c.o
+obj-$(CONFIG_MFD_RK8XX_SPI)	+= rk8xx-spi.o
 obj-$(CONFIG_MFD_RN5T618)	+= rn5t618.o
 obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
 obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
index 21c6484a951c..252030b9be4c 100644
--- a/drivers/mfd/rk8xx-core.c
+++ b/drivers/mfd/rk8xx-core.c
@@ -37,6 +37,11 @@ static const struct resource rk805_key_resources[] = {
 	DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
 };
 
+static struct resource rk806_pwrkey_resources[] = {
+	DEFINE_RES_IRQ(RK806_IRQ_PWRON_FALL),
+	DEFINE_RES_IRQ(RK806_IRQ_PWRON_RISE),
+};
+
 static const struct resource rk817_pwrkey_resources[] = {
 	DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
 	DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
@@ -64,6 +69,17 @@ static const struct mfd_cell rk805s[] = {
 	},
 };
 
+static const struct mfd_cell rk806s[] = {
+	{ .name = "rk805-pinctrl", .id = PLATFORM_DEVID_AUTO, },
+	{ .name = "rk808-regulator", .id = PLATFORM_DEVID_AUTO, },
+	{
+		.name = "rk805-pwrkey",
+		.resources = rk806_pwrkey_resources,
+		.num_resources = ARRAY_SIZE(rk806_pwrkey_resources),
+		.id = PLATFORM_DEVID_AUTO,
+	},
+};
+
 static const struct mfd_cell rk808s[] = {
 	{ .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
 	{ .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
@@ -122,6 +138,12 @@ static const struct rk808_reg_data rk805_pre_init_reg[] = {
 	{RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
 };
 
+static const struct rk808_reg_data rk806_pre_init_reg[] = {
+	{ RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
+	{ RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
+	{ RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
+};
+
 static const struct rk808_reg_data rk808_pre_init_reg[] = {
 	{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_150MA },
 	{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_200MA },
@@ -272,6 +294,27 @@ static const struct regmap_irq rk805_irqs[] = {
 	},
 };
 
+static const struct regmap_irq rk806_irqs[] = {
+	/* INT_STS0 IRQs */
+	REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),
+	REGMAP_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE),
+	REGMAP_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON),
+	REGMAP_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP),
+	REGMAP_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE),
+	REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),
+	REGMAP_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL),
+	REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),
+	/* INT_STS1 IRQs */
+	REGMAP_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0),
+	REGMAP_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1),
+	REGMAP_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2),
+	REGMAP_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR),
+	REGMAP_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO),
+	REGMAP_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO),
+	REGMAP_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO),
+	REGMAP_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT),
+};
+
 static const struct regmap_irq rk808_irqs[] = {
 	/* INT_STS */
 	[RK808_IRQ_VOUT_LO] = {
@@ -422,6 +465,18 @@ static struct regmap_irq_chip rk805_irq_chip = {
 	.init_ack_masked = true,
 };
 
+static struct regmap_irq_chip rk806_irq_chip = {
+	.name = "rk806",
+	.irqs = rk806_irqs,
+	.num_irqs = ARRAY_SIZE(rk806_irqs),
+	.num_regs = 2,
+	.irq_reg_stride = 2,
+	.mask_base = RK806_INT_MSK0,
+	.status_base = RK806_INT_STS0,
+	.ack_base = RK806_INT_STS0,
+	.init_ack_masked = true,
+};
+
 static const struct regmap_irq_chip rk808_irq_chip = {
 	.name = "rk808",
 	.irqs = rk808_irqs,
@@ -548,6 +603,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
 	struct rk808 *rk808;
 	const struct rk808_reg_data *pre_init_reg;
 	const struct mfd_cell *cells;
+	int dual_support = 0;
 	int nr_pre_init_regs;
 	int nr_cells;
 	int ret;
@@ -569,6 +625,14 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
 		cells = rk805s;
 		nr_cells = ARRAY_SIZE(rk805s);
 		break;
+	case RK806_ID:
+		rk808->regmap_irq_chip = &rk806_irq_chip;
+		pre_init_reg = rk806_pre_init_reg;
+		nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
+		cells = rk806s;
+		nr_cells = ARRAY_SIZE(rk806s);
+		dual_support = IRQF_SHARED;
+		break;
 	case RK808_ID:
 		rk808->regmap_irq_chip = &rk808_irq_chip;
 		pre_init_reg = rk808_pre_init_reg;
@@ -600,7 +664,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
 		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
 
 	ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
-				       IRQF_ONESHOT, -1,
+				       IRQF_ONESHOT | dual_support, -1,
 				       rk808->regmap_irq_chip, &rk808->irq_data);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
@@ -615,8 +679,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
 					     pre_init_reg[i].addr);
 	}
 
-	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
-			      cells, nr_cells, NULL, 0,
+	ret = devm_mfd_add_devices(dev, 0, cells, nr_cells, NULL, 0,
 			      regmap_irq_get_domain(rk808->irq_data));
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to add MFD devices\n");
diff --git a/drivers/mfd/rk8xx-spi.c b/drivers/mfd/rk8xx-spi.c
new file mode 100644
index 000000000000..3f6c5b1334f7
--- /dev/null
+++ b/drivers/mfd/rk8xx-spi.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip RK806 Core (SPI) driver
+ *
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2023 Collabora Ltd.
+ *
+ * Author: Xu Shengfei <xsf@rock-chips.com>
+ * Author: Sebastian Reichel <sebastian.reichel@collabora.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/rk808.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#define RK806_CMD		0
+#define RK806_REG_ADDR_L	1
+#define RK806_REG_ADDR_H	2
+#define RK806_CMD_WITH_SIZE(CMD, VALUE_BYTES) \
+	(RK806_CMD_ ## CMD | (VALUE_BYTES-1))
+
+static const struct regmap_range rk806_volatile_ranges[] = {
+	regmap_reg_range(RK806_POWER_EN0, RK806_POWER_EN5),
+	regmap_reg_range(RK806_DVS_START_CTRL, RK806_INT_MSK1),
+};
+
+static const struct regmap_access_table rk806_volatile_table = {
+	.yes_ranges = rk806_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(rk806_volatile_ranges),
+};
+
+static const struct regmap_config rk806_regmap_config_spi = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.cache_type = REGCACHE_RBTREE,
+	.volatile_table = &rk806_volatile_table,
+};
+
+static int rk806_spi_bus_write(void *context, const void *vdata, size_t count)
+{
+	struct device *dev = context;
+	struct spi_device *spi = to_spi_device(dev);
+	const char *data = vdata;
+	char buffer[3] = { 0 };
+	struct spi_transfer xfer[2] = { 0 };
+	/* count includes the register size */
+	size_t val_size = count - 1;
+
+	if (val_size < 1 || val_size > 128)
+		return -EINVAL;
+
+	buffer[RK806_CMD]	 = RK806_CMD_WITH_SIZE(WRITE, val_size);
+	buffer[RK806_REG_ADDR_L] = data[0];
+	buffer[RK806_REG_ADDR_H] = RK806_REG_H;
+
+	xfer[0].tx_buf = buffer;
+	xfer[0].len = sizeof(buffer);
+	xfer[1].tx_buf = data + 1;
+	xfer[1].len = count - 1;
+
+	return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
+}
+
+static int rk806_spi_bus_read(void *context, const void *vreg, size_t reg_size,
+			      void *val, size_t val_size)
+{
+	struct device *dev = context;
+	struct spi_device *spi = to_spi_device(dev);
+	const char *reg = vreg;
+	char txbuf[3] = { 0 };
+
+	if (reg_size != sizeof(char) || val_size < 1 || val_size > 128)
+		return -EINVAL;
+
+	txbuf[RK806_CMD]	= RK806_CMD_WITH_SIZE(READ, val_size);
+	txbuf[RK806_REG_ADDR_L]	= *reg;
+	txbuf[RK806_REG_ADDR_H]	= RK806_REG_H;
+
+	return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size);
+}
+
+static const struct regmap_bus rk806_regmap_bus_spi = {
+	.write = rk806_spi_bus_write,
+	.read = rk806_spi_bus_read,
+	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+static int rk8xx_spi_probe(struct spi_device *spi)
+{
+	struct regmap *regmap;
+
+	regmap = devm_regmap_init(&spi->dev, &rk806_regmap_bus_spi,
+				  &spi->dev, &rk806_regmap_config_spi);
+	if (IS_ERR(regmap))
+		return dev_err_probe(&spi->dev, PTR_ERR(regmap),
+				     "Failed to initialize register map\n");
+
+	return rk8xx_probe(&spi->dev, RK806_ID, spi->irq, regmap);
+}
+
+static const struct of_device_id rk8xx_spi_of_match[] = {
+	{ .compatible = "rockchip,rk806", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, rk8xx_spi_of_match);
+
+static const struct spi_device_id rk8xx_spi_id_table[] = {
+	{ "rk806", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, rk8xx_spi_id_table);
+
+static struct spi_driver rk8xx_spi_driver = {
+	.driver		= {
+		.name	= "rk8xx-spi",
+		.of_match_table = rk8xx_spi_of_match,
+	},
+	.probe		= rk8xx_spi_probe,
+	.id_table	= rk8xx_spi_id_table,
+};
+module_spi_driver(rk8xx_spi_driver);
+
+MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
+MODULE_DESCRIPTION("RK8xx SPI PMIC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index 4183427a80fe..78e167a92483 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -289,6 +289,414 @@ enum rk805_reg {
 #define RK805_INT_ALARM_EN		(1 << 3)
 #define RK805_INT_TIMER_EN		(1 << 2)
 
+/* RK806 */
+#define RK806_POWER_EN0			0x0
+#define RK806_POWER_EN1			0x1
+#define RK806_POWER_EN2			0x2
+#define RK806_POWER_EN3			0x3
+#define RK806_POWER_EN4			0x4
+#define RK806_POWER_EN5			0x5
+#define RK806_POWER_SLP_EN0		0x6
+#define RK806_POWER_SLP_EN1		0x7
+#define RK806_POWER_SLP_EN2		0x8
+#define RK806_POWER_DISCHRG_EN0		0x9
+#define RK806_POWER_DISCHRG_EN1		0xA
+#define RK806_POWER_DISCHRG_EN2		0xB
+#define RK806_BUCK_FB_CONFIG		0xC
+#define RK806_SLP_LP_CONFIG		0xD
+#define RK806_POWER_FPWM_EN0		0xE
+#define RK806_POWER_FPWM_EN1		0xF
+#define RK806_BUCK1_CONFIG		0x10
+#define RK806_BUCK2_CONFIG		0x11
+#define RK806_BUCK3_CONFIG		0x12
+#define RK806_BUCK4_CONFIG		0x13
+#define RK806_BUCK5_CONFIG		0x14
+#define RK806_BUCK6_CONFIG		0x15
+#define RK806_BUCK7_CONFIG		0x16
+#define RK806_BUCK8_CONFIG		0x17
+#define RK806_BUCK9_CONFIG		0x18
+#define RK806_BUCK10_CONFIG		0x19
+#define RK806_BUCK1_ON_VSEL		0x1A
+#define RK806_BUCK2_ON_VSEL		0x1B
+#define RK806_BUCK3_ON_VSEL		0x1C
+#define RK806_BUCK4_ON_VSEL		0x1D
+#define RK806_BUCK5_ON_VSEL		0x1E
+#define RK806_BUCK6_ON_VSEL		0x1F
+#define RK806_BUCK7_ON_VSEL		0x20
+#define RK806_BUCK8_ON_VSEL		0x21
+#define RK806_BUCK9_ON_VSEL		0x22
+#define RK806_BUCK10_ON_VSEL		0x23
+#define RK806_BUCK1_SLP_VSEL		0x24
+#define RK806_BUCK2_SLP_VSEL		0x25
+#define RK806_BUCK3_SLP_VSEL		0x26
+#define RK806_BUCK4_SLP_VSEL		0x27
+#define RK806_BUCK5_SLP_VSEL		0x28
+#define RK806_BUCK6_SLP_VSEL		0x29
+#define RK806_BUCK7_SLP_VSEL		0x2A
+#define RK806_BUCK8_SLP_VSEL		0x2B
+#define RK806_BUCK9_SLP_VSEL		0x2D
+#define RK806_BUCK10_SLP_VSEL		0x2E
+#define RK806_BUCK_DEBUG1		0x30
+#define RK806_BUCK_DEBUG2		0x31
+#define RK806_BUCK_DEBUG3		0x32
+#define RK806_BUCK_DEBUG4		0x33
+#define RK806_BUCK_DEBUG5		0x34
+#define RK806_BUCK_DEBUG6		0x35
+#define RK806_BUCK_DEBUG7		0x36
+#define RK806_BUCK_DEBUG8		0x37
+#define RK806_BUCK_DEBUG9		0x38
+#define RK806_BUCK_DEBUG10		0x39
+#define RK806_BUCK_DEBUG11		0x3A
+#define RK806_BUCK_DEBUG12		0x3B
+#define RK806_BUCK_DEBUG13		0x3C
+#define RK806_BUCK_DEBUG14		0x3D
+#define RK806_BUCK_DEBUG15		0x3E
+#define RK806_BUCK_DEBUG16		0x3F
+#define RK806_BUCK_DEBUG17		0x40
+#define RK806_BUCK_DEBUG18		0x41
+#define RK806_NLDO_IMAX			0x42
+#define RK806_NLDO1_ON_VSEL		0x43
+#define RK806_NLDO2_ON_VSEL		0x44
+#define RK806_NLDO3_ON_VSEL		0x45
+#define RK806_NLDO4_ON_VSEL		0x46
+#define RK806_NLDO5_ON_VSEL		0x47
+#define RK806_NLDO1_SLP_VSEL		0x48
+#define RK806_NLDO2_SLP_VSEL		0x49
+#define RK806_NLDO3_SLP_VSEL		0x4A
+#define RK806_NLDO4_SLP_VSEL		0x4B
+#define RK806_NLDO5_SLP_VSEL		0x4C
+#define RK806_PLDO_IMAX			0x4D
+#define RK806_PLDO1_ON_VSEL		0x4E
+#define RK806_PLDO2_ON_VSEL		0x4F
+#define RK806_PLDO3_ON_VSEL		0x50
+#define RK806_PLDO4_ON_VSEL		0x51
+#define RK806_PLDO5_ON_VSEL		0x52
+#define RK806_PLDO6_ON_VSEL		0x53
+#define RK806_PLDO1_SLP_VSEL		0x54
+#define RK806_PLDO2_SLP_VSEL		0x55
+#define RK806_PLDO3_SLP_VSEL		0x56
+#define RK806_PLDO4_SLP_VSEL		0x57
+#define RK806_PLDO5_SLP_VSEL		0x58
+#define RK806_PLDO6_SLP_VSEL		0x59
+#define RK806_CHIP_NAME			0x5A
+#define RK806_CHIP_VER			0x5B
+#define RK806_OTP_VER			0x5C
+#define RK806_SYS_STS			0x5D
+#define RK806_SYS_CFG0			0x5E
+#define RK806_SYS_CFG1			0x5F
+#define RK806_SYS_OPTION		0x61
+#define RK806_SLEEP_CONFIG0		0x62
+#define RK806_SLEEP_CONFIG1		0x63
+#define RK806_SLEEP_CTR_SEL0		0x64
+#define RK806_SLEEP_CTR_SEL1		0x65
+#define RK806_SLEEP_CTR_SEL2		0x66
+#define RK806_SLEEP_CTR_SEL3		0x67
+#define RK806_SLEEP_CTR_SEL4		0x68
+#define RK806_SLEEP_CTR_SEL5		0x69
+#define RK806_DVS_CTRL_SEL0		0x6A
+#define RK806_DVS_CTRL_SEL1		0x6B
+#define RK806_DVS_CTRL_SEL2		0x6C
+#define RK806_DVS_CTRL_SEL3		0x6D
+#define RK806_DVS_CTRL_SEL4		0x6E
+#define RK806_DVS_CTRL_SEL5		0x6F
+#define RK806_DVS_START_CTRL		0x70
+#define RK806_SLEEP_GPIO		0x71
+#define RK806_SYS_CFG3			0x72
+#define RK806_ON_SOURCE			0x74
+#define RK806_OFF_SOURCE		0x75
+#define RK806_PWRON_KEY			0x76
+#define RK806_INT_STS0			0x77
+#define RK806_INT_MSK0			0x78
+#define RK806_INT_STS1			0x79
+#define RK806_INT_MSK1			0x7A
+#define RK806_GPIO_INT_CONFIG		0x7B
+#define RK806_DATA_REG0			0x7C
+#define RK806_DATA_REG1			0x7D
+#define RK806_DATA_REG2			0x7E
+#define RK806_DATA_REG3			0x7F
+#define RK806_DATA_REG4			0x80
+#define RK806_DATA_REG5			0x81
+#define RK806_DATA_REG6			0x82
+#define RK806_DATA_REG7			0x83
+#define RK806_DATA_REG8			0x84
+#define RK806_DATA_REG9			0x85
+#define RK806_DATA_REG10		0x86
+#define RK806_DATA_REG11		0x87
+#define RK806_DATA_REG12		0x88
+#define RK806_DATA_REG13		0x89
+#define RK806_DATA_REG14		0x8A
+#define RK806_DATA_REG15		0x8B
+#define RK806_TM_REG			0x8C
+#define RK806_OTP_EN_REG		0x8D
+#define RK806_FUNC_OTP_EN_REG		0x8E
+#define RK806_TEST_REG1			0x8F
+#define RK806_TEST_REG2			0x90
+#define RK806_TEST_REG3			0x91
+#define RK806_TEST_REG4			0x92
+#define RK806_TEST_REG5			0x93
+#define RK806_BUCK_VSEL_OTP_REG0	0x94
+#define RK806_BUCK_VSEL_OTP_REG1	0x95
+#define RK806_BUCK_VSEL_OTP_REG2	0x96
+#define RK806_BUCK_VSEL_OTP_REG3	0x97
+#define RK806_BUCK_VSEL_OTP_REG4	0x98
+#define RK806_BUCK_VSEL_OTP_REG5	0x99
+#define RK806_BUCK_VSEL_OTP_REG6	0x9A
+#define RK806_BUCK_VSEL_OTP_REG7	0x9B
+#define RK806_BUCK_VSEL_OTP_REG8	0x9C
+#define RK806_BUCK_VSEL_OTP_REG9	0x9D
+#define RK806_NLDO1_VSEL_OTP_REG0	0x9E
+#define RK806_NLDO1_VSEL_OTP_REG1	0x9F
+#define RK806_NLDO1_VSEL_OTP_REG2	0xA0
+#define RK806_NLDO1_VSEL_OTP_REG3	0xA1
+#define RK806_NLDO1_VSEL_OTP_REG4	0xA2
+#define RK806_PLDO_VSEL_OTP_REG0	0xA3
+#define RK806_PLDO_VSEL_OTP_REG1	0xA4
+#define RK806_PLDO_VSEL_OTP_REG2	0xA5
+#define RK806_PLDO_VSEL_OTP_REG3	0xA6
+#define RK806_PLDO_VSEL_OTP_REG4	0xA7
+#define RK806_PLDO_VSEL_OTP_REG5	0xA8
+#define RK806_BUCK_EN_OTP_REG1		0xA9
+#define RK806_NLDO_EN_OTP_REG1		0xAA
+#define RK806_PLDO_EN_OTP_REG1		0xAB
+#define RK806_BUCK_FB_RES_OTP_REG1	0xAC
+#define RK806_OTP_RESEV_REG0		0xAD
+#define RK806_OTP_RESEV_REG1		0xAE
+#define RK806_OTP_RESEV_REG2		0xAF
+#define RK806_OTP_RESEV_REG3		0xB0
+#define RK806_OTP_RESEV_REG4		0xB1
+#define RK806_BUCK_SEQ_REG0		0xB2
+#define RK806_BUCK_SEQ_REG1		0xB3
+#define RK806_BUCK_SEQ_REG2		0xB4
+#define RK806_BUCK_SEQ_REG3		0xB5
+#define RK806_BUCK_SEQ_REG4		0xB6
+#define RK806_BUCK_SEQ_REG5		0xB7
+#define RK806_BUCK_SEQ_REG6		0xB8
+#define RK806_BUCK_SEQ_REG7		0xB9
+#define RK806_BUCK_SEQ_REG8		0xBA
+#define RK806_BUCK_SEQ_REG9		0xBB
+#define RK806_BUCK_SEQ_REG10		0xBC
+#define RK806_BUCK_SEQ_REG11		0xBD
+#define RK806_BUCK_SEQ_REG12		0xBE
+#define RK806_BUCK_SEQ_REG13		0xBF
+#define RK806_BUCK_SEQ_REG14		0xC0
+#define RK806_BUCK_SEQ_REG15		0xC1
+#define RK806_BUCK_SEQ_REG16		0xC2
+#define RK806_BUCK_SEQ_REG17		0xC3
+#define RK806_HK_TRIM_REG1		0xC4
+#define RK806_HK_TRIM_REG2		0xC5
+#define RK806_BUCK_REF_TRIM_REG1	0xC6
+#define RK806_BUCK_REF_TRIM_REG2	0xC7
+#define RK806_BUCK_REF_TRIM_REG3	0xC8
+#define RK806_BUCK_REF_TRIM_REG4	0xC9
+#define RK806_BUCK_REF_TRIM_REG5	0xCA
+#define RK806_BUCK_OSC_TRIM_REG1	0xCB
+#define RK806_BUCK_OSC_TRIM_REG2	0xCC
+#define RK806_BUCK_OSC_TRIM_REG3	0xCD
+#define RK806_BUCK_OSC_TRIM_REG4	0xCE
+#define RK806_BUCK_OSC_TRIM_REG5	0xCF
+#define RK806_BUCK_TRIM_ZCDIOS_REG1	0xD0
+#define RK806_BUCK_TRIM_ZCDIOS_REG2	0xD1
+#define RK806_NLDO_TRIM_REG1		0xD2
+#define RK806_NLDO_TRIM_REG2		0xD3
+#define RK806_NLDO_TRIM_REG3		0xD4
+#define RK806_PLDO_TRIM_REG1		0xD5
+#define RK806_PLDO_TRIM_REG2		0xD6
+#define RK806_PLDO_TRIM_REG3		0xD7
+#define RK806_TRIM_ICOMP_REG1		0xD8
+#define RK806_TRIM_ICOMP_REG2		0xD9
+#define RK806_EFUSE_CONTROL_REGH	0xDA
+#define RK806_FUSE_PROG_REG		0xDB
+#define RK806_MAIN_FSM_STS_REG		0xDD
+#define RK806_FSM_REG			0xDE
+#define RK806_TOP_RESEV_OFFR		0xEC
+#define RK806_TOP_RESEV_POR		0xED
+#define RK806_BUCK_VRSN_REG1		0xEE
+#define RK806_BUCK_VRSN_REG2		0xEF
+#define RK806_NLDO_RLOAD_SEL_REG1	0xF0
+#define RK806_PLDO_RLOAD_SEL_REG1	0xF1
+#define RK806_PLDO_RLOAD_SEL_REG2	0xF2
+#define RK806_BUCK_CMIN_MX_REG1		0xF3
+#define RK806_BUCK_CMIN_MX_REG2		0xF4
+#define RK806_BUCK_FREQ_SET_REG1	0xF5
+#define RK806_BUCK_FREQ_SET_REG2	0xF6
+#define RK806_BUCK_RS_MEABS_REG1	0xF7
+#define RK806_BUCK_RS_MEABS_REG2	0xF8
+#define RK806_BUCK_RS_ZDLEB_REG1	0xF9
+#define RK806_BUCK_RS_ZDLEB_REG2	0xFA
+#define RK806_BUCK_RSERVE_REG1		0xFB
+#define RK806_BUCK_RSERVE_REG2		0xFC
+#define RK806_BUCK_RSERVE_REG3		0xFD
+#define RK806_BUCK_RSERVE_REG4		0xFE
+#define RK806_BUCK_RSERVE_REG5		0xFF
+
+/* INT_STS Register field definitions */
+#define RK806_INT_STS_PWRON_FALL	BIT(0)
+#define RK806_INT_STS_PWRON_RISE	BIT(1)
+#define RK806_INT_STS_PWRON		BIT(2)
+#define RK806_INT_STS_PWRON_LP		BIT(3)
+#define RK806_INT_STS_HOTDIE		BIT(4)
+#define RK806_INT_STS_VDC_RISE		BIT(5)
+#define RK806_INT_STS_VDC_FALL		BIT(6)
+#define RK806_INT_STS_VB_LO		BIT(7)
+#define RK806_INT_STS_REV0		BIT(0)
+#define RK806_INT_STS_REV1		BIT(1)
+#define RK806_INT_STS_REV2		BIT(2)
+#define RK806_INT_STS_CRC_ERROR		BIT(3)
+#define RK806_INT_STS_SLP3_GPIO		BIT(4)
+#define RK806_INT_STS_SLP2_GPIO		BIT(5)
+#define RK806_INT_STS_SLP1_GPIO		BIT(6)
+#define RK806_INT_STS_WDT		BIT(7)
+
+/* SPI command */
+#define RK806_CMD_READ			0
+#define RK806_CMD_WRITE			BIT(7)
+#define RK806_CMD_CRC_EN		BIT(6)
+#define RK806_CMD_CRC_DIS		0
+#define RK806_CMD_LEN_MSK		0x0f
+#define RK806_REG_H			0x00
+
+#define VERSION_AB		0x01
+
+enum rk806_reg_id {
+	RK806_ID_DCDC1 = 0,
+	RK806_ID_DCDC2,
+	RK806_ID_DCDC3,
+	RK806_ID_DCDC4,
+	RK806_ID_DCDC5,
+	RK806_ID_DCDC6,
+	RK806_ID_DCDC7,
+	RK806_ID_DCDC8,
+	RK806_ID_DCDC9,
+	RK806_ID_DCDC10,
+
+	RK806_ID_NLDO1,
+	RK806_ID_NLDO2,
+	RK806_ID_NLDO3,
+	RK806_ID_NLDO4,
+	RK806_ID_NLDO5,
+
+	RK806_ID_PLDO1,
+	RK806_ID_PLDO2,
+	RK806_ID_PLDO3,
+	RK806_ID_PLDO4,
+	RK806_ID_PLDO5,
+	RK806_ID_PLDO6,
+	RK806_ID_END,
+};
+
+/* Define the RK806 IRQ numbers */
+enum rk806_irqs {
+	/* INT_STS0 registers */
+	RK806_IRQ_PWRON_FALL,
+	RK806_IRQ_PWRON_RISE,
+	RK806_IRQ_PWRON,
+	RK806_IRQ_PWRON_LP,
+	RK806_IRQ_HOTDIE,
+	RK806_IRQ_VDC_RISE,
+	RK806_IRQ_VDC_FALL,
+	RK806_IRQ_VB_LO,
+
+	/* INT_STS0 registers */
+	RK806_IRQ_REV0,
+	RK806_IRQ_REV1,
+	RK806_IRQ_REV2,
+	RK806_IRQ_CRC_ERROR,
+	RK806_IRQ_SLP3_GPIO,
+	RK806_IRQ_SLP2_GPIO,
+	RK806_IRQ_SLP1_GPIO,
+	RK806_IRQ_WDT,
+};
+
+/* VCC1 Low Voltage Threshold */
+enum rk806_lv_sel {
+	VB_LO_SEL_2800,
+	VB_LO_SEL_2900,
+	VB_LO_SEL_3000,
+	VB_LO_SEL_3100,
+	VB_LO_SEL_3200,
+	VB_LO_SEL_3300,
+	VB_LO_SEL_3400,
+	VB_LO_SEL_3500,
+};
+
+/* System Shutdown Voltage Select */
+enum rk806_uv_sel {
+	VB_UV_SEL_2700,
+	VB_UV_SEL_2800,
+	VB_UV_SEL_2900,
+	VB_UV_SEL_3000,
+	VB_UV_SEL_3100,
+	VB_UV_SEL_3200,
+	VB_UV_SEL_3300,
+	VB_UV_SEL_3400,
+};
+
+/* Pin Function */
+enum rk806_pwrctrl_fun {
+	PWRCTRL_NULL_FUN,
+	PWRCTRL_SLP_FUN,
+	PWRCTRL_POWOFF_FUN,
+	PWRCTRL_RST_FUN,
+	PWRCTRL_DVS_FUN,
+	PWRCTRL_GPIO_FUN,
+};
+
+/* Pin Polarity */
+enum rk806_pin_level {
+	POL_LOW,
+	POL_HIGH,
+};
+
+enum rk806_vsel_ctr_sel {
+	CTR_BY_NO_EFFECT,
+	CTR_BY_PWRCTRL1,
+	CTR_BY_PWRCTRL2,
+	CTR_BY_PWRCTRL3,
+};
+
+enum rk806_dvs_ctr_sel {
+	CTR_SEL_NO_EFFECT,
+	CTR_SEL_DVS_START1,
+	CTR_SEL_DVS_START2,
+	CTR_SEL_DVS_START3,
+};
+
+enum rk806_pin_dr_sel {
+	RK806_PIN_INPUT,
+	RK806_PIN_OUTPUT,
+};
+
+#define RK806_INT_POL_MSK		BIT(1)
+#define RK806_INT_POL_H			BIT(1)
+#define RK806_INT_POL_L			0
+
+#define RK806_SLAVE_RESTART_FUN_MSK	BIT(1)
+#define RK806_SLAVE_RESTART_FUN_EN	BIT(1)
+#define RK806_SLAVE_RESTART_FUN_OFF	0
+
+#define RK806_SYS_ENB2_2M_MSK		BIT(1)
+#define RK806_SYS_ENB2_2M_EN		BIT(1)
+#define RK806_SYS_ENB2_2M_OFF		0
+
+enum rk806_int_fun {
+	RK806_INT_ONLY,
+	RK806_INT_ADN_WKUP,
+};
+
+enum rk806_dvs_mode {
+	RK806_DVS_NOT_SUPPORT,
+	RK806_DVS_START1,
+	RK806_DVS_START2,
+	RK806_DVS_START3,
+	RK806_DVS_PWRCTRL1,
+	RK806_DVS_PWRCTRL2,
+	RK806_DVS_PWRCTRL3,
+	RK806_DVS_START_PWRCTR1,
+	RK806_DVS_START_PWRCTR2,
+	RK806_DVS_START_PWRCTR3,
+	RK806_DVS_END,
+};
+
 /* RK808 IRQ Definitions */
 #define RK808_IRQ_VOUT_LO	0
 #define RK808_IRQ_VB_LO		1
@@ -780,6 +1188,7 @@ enum {
 
 enum {
 	RK805_ID = 0x8050,
+	RK806_ID = 0x8060,
 	RK808_ID = 0x0000,
 	RK809_ID = 0x8090,
 	RK817_ID = 0x8170,
-- 
2.39.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCHv6 09/11] pinctrl: rk805: add rk806 pinctrl support
  2023-01-27 18:12 ` Sebastian Reichel
@ 2023-01-27 18:12   ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel, shengfei Xu

Add support for rk806 dvs pinctrl to the existing rk805
driver.

This has been implemented using shengfei Xu's rk806
specific driver from the vendor tree as reference.

Co-Developed-by: shengfei Xu <xsf@rock-chips.com>
Signed-off-by: shengfei Xu <xsf@rock-chips.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/pinctrl/pinctrl-rk805.c | 189 ++++++++++++++++++++++++++++----
 1 file changed, 168 insertions(+), 21 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rk805.c b/drivers/pinctrl/pinctrl-rk805.c
index 7c1f7408fb9a..2639a9ee82cd 100644
--- a/drivers/pinctrl/pinctrl-rk805.c
+++ b/drivers/pinctrl/pinctrl-rk805.c
@@ -1,10 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /*
- * Pinctrl driver for Rockchip RK805 PMIC
+ * Pinctrl driver for Rockchip RK805/RK806 PMIC
  *
  * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
  *
  * Author: Joseph Chen <chenjh@rock-chips.com>
+ * Author: Xu Shengfei <xsf@rock-chips.com>
  *
  * Based on the pinctrl-as3722 driver
  */
@@ -44,6 +46,7 @@ struct rk805_pin_group {
 
 /*
  * @reg: gpio setting register;
+ * @fun_reg: functions select register;
  * @fun_mask: functions select mask value, when set is gpio;
  * @dir_mask: input or output mask value, when set is output, otherwise input;
  * @val_mask: gpio set value, when set is level high, otherwise low;
@@ -56,6 +59,7 @@ struct rk805_pin_group {
  */
 struct rk805_pin_config {
 	u8 reg;
+	u8 fun_reg;
 	u8 fun_msk;
 	u8 dir_msk;
 	u8 val_msk;
@@ -80,22 +84,50 @@ enum rk805_pinmux_option {
 	RK805_PINMUX_GPIO,
 };
 
+enum rk806_pinmux_option {
+	RK806_PINMUX_FUN0 = 0,
+	RK806_PINMUX_FUN1,
+	RK806_PINMUX_FUN2,
+	RK806_PINMUX_FUN3,
+	RK806_PINMUX_FUN4,
+	RK806_PINMUX_FUN5,
+};
+
 enum {
 	RK805_GPIO0,
 	RK805_GPIO1,
 };
 
+enum {
+	RK806_GPIO_DVS1,
+	RK806_GPIO_DVS2,
+	RK806_GPIO_DVS3
+};
+
 static const char *const rk805_gpio_groups[] = {
 	"gpio0",
 	"gpio1",
 };
 
+static const char *const rk806_gpio_groups[] = {
+	"gpio_pwrctrl1",
+	"gpio_pwrctrl2",
+	"gpio_pwrctrl3",
+};
+
 /* RK805: 2 output only GPIOs */
 static const struct pinctrl_pin_desc rk805_pins_desc[] = {
 	PINCTRL_PIN(RK805_GPIO0, "gpio0"),
 	PINCTRL_PIN(RK805_GPIO1, "gpio1"),
 };
 
+/* RK806 */
+static const struct pinctrl_pin_desc rk806_pins_desc[] = {
+	PINCTRL_PIN(RK806_GPIO_DVS1, "gpio_pwrctrl1"),
+	PINCTRL_PIN(RK806_GPIO_DVS2, "gpio_pwrctrl2"),
+	PINCTRL_PIN(RK806_GPIO_DVS3, "gpio_pwrctrl3"),
+};
+
 static const struct rk805_pin_function rk805_pin_functions[] = {
 	{
 		.name = "gpio",
@@ -105,6 +137,45 @@ static const struct rk805_pin_function rk805_pin_functions[] = {
 	},
 };
 
+static const struct rk805_pin_function rk806_pin_functions[] = {
+	{
+		.name = "pin_fun0",
+		.groups = rk806_gpio_groups,
+		.ngroups = ARRAY_SIZE(rk806_gpio_groups),
+		.mux_option = RK806_PINMUX_FUN0,
+	},
+	{
+		.name = "pin_fun1",
+		.groups = rk806_gpio_groups,
+		.ngroups = ARRAY_SIZE(rk806_gpio_groups),
+		.mux_option = RK806_PINMUX_FUN1,
+	},
+	{
+		.name = "pin_fun2",
+		.groups = rk806_gpio_groups,
+		.ngroups = ARRAY_SIZE(rk806_gpio_groups),
+		.mux_option = RK806_PINMUX_FUN2,
+	},
+	{
+		.name = "pin_fun3",
+		.groups = rk806_gpio_groups,
+		.ngroups = ARRAY_SIZE(rk806_gpio_groups),
+		.mux_option = RK806_PINMUX_FUN3,
+	},
+	{
+		.name = "pin_fun4",
+		.groups = rk806_gpio_groups,
+		.ngroups = ARRAY_SIZE(rk806_gpio_groups),
+		.mux_option = RK806_PINMUX_FUN4,
+	},
+	{
+		.name = "pin_fun5",
+		.groups = rk806_gpio_groups,
+		.ngroups = ARRAY_SIZE(rk806_gpio_groups),
+		.mux_option = RK806_PINMUX_FUN5,
+	},
+};
+
 static const struct rk805_pin_group rk805_pin_groups[] = {
 	{
 		.name = "gpio0",
@@ -118,6 +189,24 @@ static const struct rk805_pin_group rk805_pin_groups[] = {
 	},
 };
 
+static const struct rk805_pin_group rk806_pin_groups[] = {
+	{
+		.name = "gpio_pwrctrl1",
+		.pins = { RK806_GPIO_DVS1 },
+		.npins = 1,
+	},
+	{
+		.name = "gpio_pwrctrl2",
+		.pins = { RK806_GPIO_DVS2 },
+		.npins = 1,
+	},
+	{
+		.name = "gpio_pwrctrl3",
+		.pins = { RK806_GPIO_DVS3 },
+		.npins = 1,
+	}
+};
+
 #define RK805_GPIO0_VAL_MSK	BIT(0)
 #define RK805_GPIO1_VAL_MSK	BIT(1)
 
@@ -132,6 +221,40 @@ static const struct rk805_pin_config rk805_gpio_cfgs[] = {
 	},
 };
 
+#define RK806_PWRCTRL1_DR	BIT(0)
+#define RK806_PWRCTRL2_DR	BIT(1)
+#define RK806_PWRCTRL3_DR	BIT(2)
+#define RK806_PWRCTRL1_DATA	BIT(4)
+#define RK806_PWRCTRL2_DATA	BIT(5)
+#define RK806_PWRCTRL3_DATA	BIT(6)
+#define RK806_PWRCTRL1_FUN	GENMASK(2, 0)
+#define RK806_PWRCTRL2_FUN	GENMASK(6, 4)
+#define RK806_PWRCTRL3_FUN	GENMASK(2, 0)
+
+static struct rk805_pin_config rk806_gpio_cfgs[] = {
+	{
+		.fun_reg = RK806_SLEEP_CONFIG0,
+		.fun_msk = RK806_PWRCTRL1_FUN,
+		.reg = RK806_SLEEP_GPIO,
+		.val_msk = RK806_PWRCTRL1_DATA,
+		.dir_msk = RK806_PWRCTRL1_DR,
+	},
+	{
+		.fun_reg = RK806_SLEEP_CONFIG0,
+		.fun_msk = RK806_PWRCTRL2_FUN,
+		.reg = RK806_SLEEP_GPIO,
+		.val_msk = RK806_PWRCTRL2_DATA,
+		.dir_msk = RK806_PWRCTRL2_DR,
+	},
+	{
+		.fun_reg = RK806_SLEEP_CONFIG1,
+		.fun_msk = RK806_PWRCTRL3_FUN,
+		.reg = RK806_SLEEP_GPIO,
+		.val_msk = RK806_PWRCTRL3_DATA,
+		.dir_msk = RK806_PWRCTRL3_DR,
+	}
+};
+
 /* generic gpio chip */
 static int rk805_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
@@ -289,19 +412,13 @@ static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
 	if (!pci->pin_cfg[offset].fun_msk)
 		return 0;
 
-	if (mux == RK805_PINMUX_GPIO) {
-		ret = regmap_update_bits(pci->rk808->regmap,
-					 pci->pin_cfg[offset].reg,
-					 pci->pin_cfg[offset].fun_msk,
-					 pci->pin_cfg[offset].fun_msk);
-		if (ret) {
-			dev_err(pci->dev, "set gpio%d GPIO failed\n", offset);
-			return ret;
-		}
-	} else {
-		dev_err(pci->dev, "Couldn't find function mux %d\n", mux);
-		return -EINVAL;
-	}
+	mux <<= ffs(pci->pin_cfg[offset].fun_msk) - 1;
+	ret = regmap_update_bits(pci->rk808->regmap,
+				 pci->pin_cfg[offset].fun_reg,
+				 pci->pin_cfg[offset].fun_msk, mux);
+
+	if (ret)
+		dev_err(pci->dev, "set gpio%d func%d failed\n", offset, mux);
 
 	return 0;
 }
@@ -317,6 +434,22 @@ static int rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
 	return _rk805_pinctrl_set_mux(pctldev, offset, mux);
 }
 
+static int rk805_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
+					     struct pinctrl_gpio_range *range,
+					     unsigned int offset)
+{
+	struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+
+	switch (pci->rk808->variant) {
+	case RK805_ID:
+		return _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO);
+	case RK806_ID:
+		return _rk805_pinctrl_set_mux(pctldev, offset, RK806_PINMUX_FUN5);
+	}
+
+	return -ENOTSUPP;
+}
+
 static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
 					struct pinctrl_gpio_range *range,
 					unsigned int offset, bool input)
@@ -324,13 +457,6 @@ static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
 	struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
 	int ret;
 
-	/* switch to gpio function */
-	ret = _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO);
-	if (ret) {
-		dev_err(pci->dev, "set gpio%d mux failed\n", offset);
-		return ret;
-	}
-
 	/* set direction */
 	if (!pci->pin_cfg[offset].dir_msk)
 		return 0;
@@ -352,6 +478,7 @@ static const struct pinmux_ops rk805_pinmux_ops = {
 	.get_function_name	= rk805_pinctrl_get_func_name,
 	.get_function_groups	= rk805_pinctrl_get_func_groups,
 	.set_mux		= rk805_pinctrl_set_mux,
+	.gpio_request_enable	= rk805_pinctrl_gpio_request_enable,
 	.gpio_set_direction	= rk805_pmx_gpio_set_direction,
 };
 
@@ -364,6 +491,7 @@ static int rk805_pinconf_get(struct pinctrl_dev *pctldev,
 
 	switch (param) {
 	case PIN_CONFIG_OUTPUT:
+	case PIN_CONFIG_INPUT_ENABLE:
 		arg = rk805_gpio_get(&pci->gpio_chip, pin);
 		break;
 	default:
@@ -393,6 +521,12 @@ static int rk805_pinconf_set(struct pinctrl_dev *pctldev,
 			rk805_gpio_set(&pci->gpio_chip, pin, arg);
 			rk805_pmx_gpio_set_direction(pctldev, NULL, pin, false);
 			break;
+		case PIN_CONFIG_INPUT_ENABLE:
+			if (pci->rk808->variant != RK805_ID && arg) {
+				rk805_pmx_gpio_set_direction(pctldev, NULL, pin, true);
+				break;
+			}
+			fallthrough;
 		default:
 			dev_err(pci->dev, "Properties not supported\n");
 			return -ENOTSUPP;
@@ -448,6 +582,18 @@ static int rk805_pinctrl_probe(struct platform_device *pdev)
 		pci->pin_cfg = rk805_gpio_cfgs;
 		pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs);
 		break;
+	case RK806_ID:
+		pci->pins = rk806_pins_desc;
+		pci->num_pins = ARRAY_SIZE(rk806_pins_desc);
+		pci->functions = rk806_pin_functions;
+		pci->num_functions = ARRAY_SIZE(rk806_pin_functions);
+		pci->groups = rk806_pin_groups;
+		pci->num_pin_groups = ARRAY_SIZE(rk806_pin_groups);
+		pci->pinctrl_desc.pins = rk806_pins_desc;
+		pci->pinctrl_desc.npins = ARRAY_SIZE(rk806_pins_desc);
+		pci->pin_cfg = rk806_gpio_cfgs;
+		pci->gpio_chip.ngpio = ARRAY_SIZE(rk806_gpio_cfgs);
+		break;
 	default:
 		dev_err(&pdev->dev, "unsupported RK805 ID %lu\n",
 			pci->rk808->variant);
@@ -488,5 +634,6 @@ static struct platform_driver rk805_pinctrl_driver = {
 module_platform_driver(rk805_pinctrl_driver);
 
 MODULE_DESCRIPTION("RK805 pin control and GPIO driver");
+MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
 MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>");
 MODULE_LICENSE("GPL v2");
-- 
2.39.0


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

* [PATCHv6 09/11] pinctrl: rk805: add rk806 pinctrl support
@ 2023-01-27 18:12   ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel, shengfei Xu

Add support for rk806 dvs pinctrl to the existing rk805
driver.

This has been implemented using shengfei Xu's rk806
specific driver from the vendor tree as reference.

Co-Developed-by: shengfei Xu <xsf@rock-chips.com>
Signed-off-by: shengfei Xu <xsf@rock-chips.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/pinctrl/pinctrl-rk805.c | 189 ++++++++++++++++++++++++++++----
 1 file changed, 168 insertions(+), 21 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rk805.c b/drivers/pinctrl/pinctrl-rk805.c
index 7c1f7408fb9a..2639a9ee82cd 100644
--- a/drivers/pinctrl/pinctrl-rk805.c
+++ b/drivers/pinctrl/pinctrl-rk805.c
@@ -1,10 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /*
- * Pinctrl driver for Rockchip RK805 PMIC
+ * Pinctrl driver for Rockchip RK805/RK806 PMIC
  *
  * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
  *
  * Author: Joseph Chen <chenjh@rock-chips.com>
+ * Author: Xu Shengfei <xsf@rock-chips.com>
  *
  * Based on the pinctrl-as3722 driver
  */
@@ -44,6 +46,7 @@ struct rk805_pin_group {
 
 /*
  * @reg: gpio setting register;
+ * @fun_reg: functions select register;
  * @fun_mask: functions select mask value, when set is gpio;
  * @dir_mask: input or output mask value, when set is output, otherwise input;
  * @val_mask: gpio set value, when set is level high, otherwise low;
@@ -56,6 +59,7 @@ struct rk805_pin_group {
  */
 struct rk805_pin_config {
 	u8 reg;
+	u8 fun_reg;
 	u8 fun_msk;
 	u8 dir_msk;
 	u8 val_msk;
@@ -80,22 +84,50 @@ enum rk805_pinmux_option {
 	RK805_PINMUX_GPIO,
 };
 
+enum rk806_pinmux_option {
+	RK806_PINMUX_FUN0 = 0,
+	RK806_PINMUX_FUN1,
+	RK806_PINMUX_FUN2,
+	RK806_PINMUX_FUN3,
+	RK806_PINMUX_FUN4,
+	RK806_PINMUX_FUN5,
+};
+
 enum {
 	RK805_GPIO0,
 	RK805_GPIO1,
 };
 
+enum {
+	RK806_GPIO_DVS1,
+	RK806_GPIO_DVS2,
+	RK806_GPIO_DVS3
+};
+
 static const char *const rk805_gpio_groups[] = {
 	"gpio0",
 	"gpio1",
 };
 
+static const char *const rk806_gpio_groups[] = {
+	"gpio_pwrctrl1",
+	"gpio_pwrctrl2",
+	"gpio_pwrctrl3",
+};
+
 /* RK805: 2 output only GPIOs */
 static const struct pinctrl_pin_desc rk805_pins_desc[] = {
 	PINCTRL_PIN(RK805_GPIO0, "gpio0"),
 	PINCTRL_PIN(RK805_GPIO1, "gpio1"),
 };
 
+/* RK806 */
+static const struct pinctrl_pin_desc rk806_pins_desc[] = {
+	PINCTRL_PIN(RK806_GPIO_DVS1, "gpio_pwrctrl1"),
+	PINCTRL_PIN(RK806_GPIO_DVS2, "gpio_pwrctrl2"),
+	PINCTRL_PIN(RK806_GPIO_DVS3, "gpio_pwrctrl3"),
+};
+
 static const struct rk805_pin_function rk805_pin_functions[] = {
 	{
 		.name = "gpio",
@@ -105,6 +137,45 @@ static const struct rk805_pin_function rk805_pin_functions[] = {
 	},
 };
 
+static const struct rk805_pin_function rk806_pin_functions[] = {
+	{
+		.name = "pin_fun0",
+		.groups = rk806_gpio_groups,
+		.ngroups = ARRAY_SIZE(rk806_gpio_groups),
+		.mux_option = RK806_PINMUX_FUN0,
+	},
+	{
+		.name = "pin_fun1",
+		.groups = rk806_gpio_groups,
+		.ngroups = ARRAY_SIZE(rk806_gpio_groups),
+		.mux_option = RK806_PINMUX_FUN1,
+	},
+	{
+		.name = "pin_fun2",
+		.groups = rk806_gpio_groups,
+		.ngroups = ARRAY_SIZE(rk806_gpio_groups),
+		.mux_option = RK806_PINMUX_FUN2,
+	},
+	{
+		.name = "pin_fun3",
+		.groups = rk806_gpio_groups,
+		.ngroups = ARRAY_SIZE(rk806_gpio_groups),
+		.mux_option = RK806_PINMUX_FUN3,
+	},
+	{
+		.name = "pin_fun4",
+		.groups = rk806_gpio_groups,
+		.ngroups = ARRAY_SIZE(rk806_gpio_groups),
+		.mux_option = RK806_PINMUX_FUN4,
+	},
+	{
+		.name = "pin_fun5",
+		.groups = rk806_gpio_groups,
+		.ngroups = ARRAY_SIZE(rk806_gpio_groups),
+		.mux_option = RK806_PINMUX_FUN5,
+	},
+};
+
 static const struct rk805_pin_group rk805_pin_groups[] = {
 	{
 		.name = "gpio0",
@@ -118,6 +189,24 @@ static const struct rk805_pin_group rk805_pin_groups[] = {
 	},
 };
 
+static const struct rk805_pin_group rk806_pin_groups[] = {
+	{
+		.name = "gpio_pwrctrl1",
+		.pins = { RK806_GPIO_DVS1 },
+		.npins = 1,
+	},
+	{
+		.name = "gpio_pwrctrl2",
+		.pins = { RK806_GPIO_DVS2 },
+		.npins = 1,
+	},
+	{
+		.name = "gpio_pwrctrl3",
+		.pins = { RK806_GPIO_DVS3 },
+		.npins = 1,
+	}
+};
+
 #define RK805_GPIO0_VAL_MSK	BIT(0)
 #define RK805_GPIO1_VAL_MSK	BIT(1)
 
@@ -132,6 +221,40 @@ static const struct rk805_pin_config rk805_gpio_cfgs[] = {
 	},
 };
 
+#define RK806_PWRCTRL1_DR	BIT(0)
+#define RK806_PWRCTRL2_DR	BIT(1)
+#define RK806_PWRCTRL3_DR	BIT(2)
+#define RK806_PWRCTRL1_DATA	BIT(4)
+#define RK806_PWRCTRL2_DATA	BIT(5)
+#define RK806_PWRCTRL3_DATA	BIT(6)
+#define RK806_PWRCTRL1_FUN	GENMASK(2, 0)
+#define RK806_PWRCTRL2_FUN	GENMASK(6, 4)
+#define RK806_PWRCTRL3_FUN	GENMASK(2, 0)
+
+static struct rk805_pin_config rk806_gpio_cfgs[] = {
+	{
+		.fun_reg = RK806_SLEEP_CONFIG0,
+		.fun_msk = RK806_PWRCTRL1_FUN,
+		.reg = RK806_SLEEP_GPIO,
+		.val_msk = RK806_PWRCTRL1_DATA,
+		.dir_msk = RK806_PWRCTRL1_DR,
+	},
+	{
+		.fun_reg = RK806_SLEEP_CONFIG0,
+		.fun_msk = RK806_PWRCTRL2_FUN,
+		.reg = RK806_SLEEP_GPIO,
+		.val_msk = RK806_PWRCTRL2_DATA,
+		.dir_msk = RK806_PWRCTRL2_DR,
+	},
+	{
+		.fun_reg = RK806_SLEEP_CONFIG1,
+		.fun_msk = RK806_PWRCTRL3_FUN,
+		.reg = RK806_SLEEP_GPIO,
+		.val_msk = RK806_PWRCTRL3_DATA,
+		.dir_msk = RK806_PWRCTRL3_DR,
+	}
+};
+
 /* generic gpio chip */
 static int rk805_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
@@ -289,19 +412,13 @@ static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
 	if (!pci->pin_cfg[offset].fun_msk)
 		return 0;
 
-	if (mux == RK805_PINMUX_GPIO) {
-		ret = regmap_update_bits(pci->rk808->regmap,
-					 pci->pin_cfg[offset].reg,
-					 pci->pin_cfg[offset].fun_msk,
-					 pci->pin_cfg[offset].fun_msk);
-		if (ret) {
-			dev_err(pci->dev, "set gpio%d GPIO failed\n", offset);
-			return ret;
-		}
-	} else {
-		dev_err(pci->dev, "Couldn't find function mux %d\n", mux);
-		return -EINVAL;
-	}
+	mux <<= ffs(pci->pin_cfg[offset].fun_msk) - 1;
+	ret = regmap_update_bits(pci->rk808->regmap,
+				 pci->pin_cfg[offset].fun_reg,
+				 pci->pin_cfg[offset].fun_msk, mux);
+
+	if (ret)
+		dev_err(pci->dev, "set gpio%d func%d failed\n", offset, mux);
 
 	return 0;
 }
@@ -317,6 +434,22 @@ static int rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
 	return _rk805_pinctrl_set_mux(pctldev, offset, mux);
 }
 
+static int rk805_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
+					     struct pinctrl_gpio_range *range,
+					     unsigned int offset)
+{
+	struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+
+	switch (pci->rk808->variant) {
+	case RK805_ID:
+		return _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO);
+	case RK806_ID:
+		return _rk805_pinctrl_set_mux(pctldev, offset, RK806_PINMUX_FUN5);
+	}
+
+	return -ENOTSUPP;
+}
+
 static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
 					struct pinctrl_gpio_range *range,
 					unsigned int offset, bool input)
@@ -324,13 +457,6 @@ static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
 	struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
 	int ret;
 
-	/* switch to gpio function */
-	ret = _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO);
-	if (ret) {
-		dev_err(pci->dev, "set gpio%d mux failed\n", offset);
-		return ret;
-	}
-
 	/* set direction */
 	if (!pci->pin_cfg[offset].dir_msk)
 		return 0;
@@ -352,6 +478,7 @@ static const struct pinmux_ops rk805_pinmux_ops = {
 	.get_function_name	= rk805_pinctrl_get_func_name,
 	.get_function_groups	= rk805_pinctrl_get_func_groups,
 	.set_mux		= rk805_pinctrl_set_mux,
+	.gpio_request_enable	= rk805_pinctrl_gpio_request_enable,
 	.gpio_set_direction	= rk805_pmx_gpio_set_direction,
 };
 
@@ -364,6 +491,7 @@ static int rk805_pinconf_get(struct pinctrl_dev *pctldev,
 
 	switch (param) {
 	case PIN_CONFIG_OUTPUT:
+	case PIN_CONFIG_INPUT_ENABLE:
 		arg = rk805_gpio_get(&pci->gpio_chip, pin);
 		break;
 	default:
@@ -393,6 +521,12 @@ static int rk805_pinconf_set(struct pinctrl_dev *pctldev,
 			rk805_gpio_set(&pci->gpio_chip, pin, arg);
 			rk805_pmx_gpio_set_direction(pctldev, NULL, pin, false);
 			break;
+		case PIN_CONFIG_INPUT_ENABLE:
+			if (pci->rk808->variant != RK805_ID && arg) {
+				rk805_pmx_gpio_set_direction(pctldev, NULL, pin, true);
+				break;
+			}
+			fallthrough;
 		default:
 			dev_err(pci->dev, "Properties not supported\n");
 			return -ENOTSUPP;
@@ -448,6 +582,18 @@ static int rk805_pinctrl_probe(struct platform_device *pdev)
 		pci->pin_cfg = rk805_gpio_cfgs;
 		pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs);
 		break;
+	case RK806_ID:
+		pci->pins = rk806_pins_desc;
+		pci->num_pins = ARRAY_SIZE(rk806_pins_desc);
+		pci->functions = rk806_pin_functions;
+		pci->num_functions = ARRAY_SIZE(rk806_pin_functions);
+		pci->groups = rk806_pin_groups;
+		pci->num_pin_groups = ARRAY_SIZE(rk806_pin_groups);
+		pci->pinctrl_desc.pins = rk806_pins_desc;
+		pci->pinctrl_desc.npins = ARRAY_SIZE(rk806_pins_desc);
+		pci->pin_cfg = rk806_gpio_cfgs;
+		pci->gpio_chip.ngpio = ARRAY_SIZE(rk806_gpio_cfgs);
+		break;
 	default:
 		dev_err(&pdev->dev, "unsupported RK805 ID %lu\n",
 			pci->rk808->variant);
@@ -488,5 +634,6 @@ static struct platform_driver rk805_pinctrl_driver = {
 module_platform_driver(rk805_pinctrl_driver);
 
 MODULE_DESCRIPTION("RK805 pin control and GPIO driver");
+MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
 MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>");
 MODULE_LICENSE("GPL v2");
-- 
2.39.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCHv6 10/11] regulator: expose regulator_find_closest_bigger
  2023-01-27 18:12 ` Sebastian Reichel
@ 2023-01-27 18:12   ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Expose and document the table lookup logic used by
regulator_set_ramp_delay_regmap, so that it can be
reused for devices that cannot be configured via
regulator_set_ramp_delay_regmap.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/regulator/helpers.c      | 22 ++++++++++++++++++----
 include/linux/regulator/driver.h |  2 ++
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c
index ad2237a95572..586f42e378ee 100644
--- a/drivers/regulator/helpers.c
+++ b/drivers/regulator/helpers.c
@@ -902,8 +902,21 @@ bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
 }
 EXPORT_SYMBOL_GPL(regulator_is_equal);
 
-static int find_closest_bigger(unsigned int target, const unsigned int *table,
-			       unsigned int num_sel, unsigned int *sel)
+/**
+ * regulator_find_closest_bigger - helper to find offset in ramp delay table
+ *
+ * @target: targeted ramp_delay
+ * @table: table with supported ramp delays
+ * @num_sel: number of entries in the table
+ * @sel: Pointer to store table offset
+ *
+ * This is the internal helper used by regulator_set_ramp_delay_regmap to
+ * map ramp delay to register value. It should only be used directly if
+ * regulator_set_ramp_delay_regmap cannot handle a specific device setup
+ * (e.g. because the value is split over multiple registers).
+ */
+int regulator_find_closest_bigger(unsigned int target, const unsigned int *table,
+				  unsigned int num_sel, unsigned int *sel)
 {
 	unsigned int s, tmp, max, maxsel = 0;
 	bool found = false;
@@ -933,6 +946,7 @@ static int find_closest_bigger(unsigned int target, const unsigned int *table,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(regulator_find_closest_bigger);
 
 /**
  * regulator_set_ramp_delay_regmap - set_ramp_delay() helper
@@ -951,8 +965,8 @@ int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay)
 	if (WARN_ON(!rdev->desc->n_ramp_values || !rdev->desc->ramp_delay_table))
 		return -EINVAL;
 
-	ret = find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
-				  rdev->desc->n_ramp_values, &sel);
+	ret = regulator_find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
+					    rdev->desc->n_ramp_values, &sel);
 
 	if (ret) {
 		dev_warn(rdev_get_dev(rdev),
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index d3b4a3d4514a..c6ef7d68eb9a 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -758,6 +758,8 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
 				       int min_uA, int max_uA);
 int regulator_get_current_limit_regmap(struct regulator_dev *rdev);
 void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
+int regulator_find_closest_bigger(unsigned int target, const unsigned int *table,
+				  unsigned int num_sel, unsigned int *sel);
 int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay);
 int regulator_sync_voltage_rdev(struct regulator_dev *rdev);
 
-- 
2.39.0


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

* [PATCHv6 10/11] regulator: expose regulator_find_closest_bigger
@ 2023-01-27 18:12   ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel

Expose and document the table lookup logic used by
regulator_set_ramp_delay_regmap, so that it can be
reused for devices that cannot be configured via
regulator_set_ramp_delay_regmap.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/regulator/helpers.c      | 22 ++++++++++++++++++----
 include/linux/regulator/driver.h |  2 ++
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c
index ad2237a95572..586f42e378ee 100644
--- a/drivers/regulator/helpers.c
+++ b/drivers/regulator/helpers.c
@@ -902,8 +902,21 @@ bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
 }
 EXPORT_SYMBOL_GPL(regulator_is_equal);
 
-static int find_closest_bigger(unsigned int target, const unsigned int *table,
-			       unsigned int num_sel, unsigned int *sel)
+/**
+ * regulator_find_closest_bigger - helper to find offset in ramp delay table
+ *
+ * @target: targeted ramp_delay
+ * @table: table with supported ramp delays
+ * @num_sel: number of entries in the table
+ * @sel: Pointer to store table offset
+ *
+ * This is the internal helper used by regulator_set_ramp_delay_regmap to
+ * map ramp delay to register value. It should only be used directly if
+ * regulator_set_ramp_delay_regmap cannot handle a specific device setup
+ * (e.g. because the value is split over multiple registers).
+ */
+int regulator_find_closest_bigger(unsigned int target, const unsigned int *table,
+				  unsigned int num_sel, unsigned int *sel)
 {
 	unsigned int s, tmp, max, maxsel = 0;
 	bool found = false;
@@ -933,6 +946,7 @@ static int find_closest_bigger(unsigned int target, const unsigned int *table,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(regulator_find_closest_bigger);
 
 /**
  * regulator_set_ramp_delay_regmap - set_ramp_delay() helper
@@ -951,8 +965,8 @@ int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay)
 	if (WARN_ON(!rdev->desc->n_ramp_values || !rdev->desc->ramp_delay_table))
 		return -EINVAL;
 
-	ret = find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
-				  rdev->desc->n_ramp_values, &sel);
+	ret = regulator_find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
+					    rdev->desc->n_ramp_values, &sel);
 
 	if (ret) {
 		dev_warn(rdev_get_dev(rdev),
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index d3b4a3d4514a..c6ef7d68eb9a 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -758,6 +758,8 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
 				       int min_uA, int max_uA);
 int regulator_get_current_limit_regmap(struct regulator_dev *rdev);
 void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
+int regulator_find_closest_bigger(unsigned int target, const unsigned int *table,
+				  unsigned int num_sel, unsigned int *sel);
 int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay);
 int regulator_sync_voltage_rdev(struct regulator_dev *rdev);
 
-- 
2.39.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCHv6 11/11] regulator: rk808: add rk806 support
  2023-01-27 18:12 ` Sebastian Reichel
@ 2023-01-27 18:12   ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel, shengfei Xu, Matti Vaittinen

Add rk806 support to the existing rk808 regulator
driver.

This has been implemented using shengfei Xu's rk806
specific driver from the vendor tree as reference.

Co-Developed-by: shengfei Xu <xsf@rock-chips.com>
Signed-off-by: shengfei Xu <xsf@rock-chips.com>
Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/regulator/rk808-regulator.c | 383 ++++++++++++++++++++++++++++
 1 file changed, 383 insertions(+)

diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index fa9fc1aa1ae3..3d534d411104 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -3,9 +3,11 @@
  * Regulator driver for Rockchip RK805/RK808/RK818
  *
  * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
  *
  * Author: Chris Zhong <zyw@rock-chips.com>
  * Author: Zhang Qing <zhangqing@rock-chips.com>
+ * Author: Xu Shengfei <xsf@rock-chips.com>
  *
  * Copyright (C) 2016 PHYTEC Messtechnik GmbH
  *
@@ -39,6 +41,13 @@
 #define RK818_LDO3_ON_VSEL_MASK		0xf
 #define RK818_BOOST_ON_VSEL_MASK	0xe0
 
+#define RK806_DCDC_SLP_REG_OFFSET	0x0A
+#define RK806_NLDO_SLP_REG_OFFSET	0x05
+#define RK806_PLDO_SLP_REG_OFFSET	0x06
+
+#define RK806_BUCK_SEL_CNT		0xff
+#define RK806_LDO_SEL_CNT		0xff
+
 /* Ramp rate definitions for buck1 / buck2 only */
 #define RK808_RAMP_RATE_OFFSET		3
 #define RK808_RAMP_RATE_MASK		(3 << RK808_RAMP_RATE_OFFSET)
@@ -117,6 +126,34 @@
 	RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, 0, 0, _etime, &rk805_reg_ops)
 
+#define RK806_REGULATOR(_name, _supply_name, _id, _ops,\
+			_n_voltages, _vr, _er, _lr, ctrl_bit,\
+			_rr, _rm, _rt)\
+[_id] = {\
+		.name = _name,\
+		.supply_name = _supply_name,\
+		.of_match = of_match_ptr(_name),\
+		.regulators_node = of_match_ptr("regulators"),\
+		.id = _id,\
+		.ops = &_ops,\
+		.type = REGULATOR_VOLTAGE,\
+		.n_voltages = _n_voltages,\
+		.linear_ranges = _lr,\
+		.n_linear_ranges = ARRAY_SIZE(_lr),\
+		.vsel_reg = _vr,\
+		.vsel_mask = 0xff,\
+		.enable_reg = _er,\
+		.enable_mask = ENABLE_MASK(ctrl_bit),\
+		.enable_val = ENABLE_MASK(ctrl_bit),\
+		.disable_val = DISABLE_VAL(ctrl_bit),\
+		.of_map_mode = rk8xx_regulator_of_map_mode,\
+		.ramp_reg = _rr,\
+		.ramp_mask = _rm,\
+		.ramp_delay_table = _rt, \
+		.n_ramp_values = ARRAY_SIZE(_rt), \
+		.owner = THIS_MODULE,\
+	}
+
 #define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, _etime)					\
 	RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg,	\
@@ -153,6 +190,17 @@
 	RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask,	\
 	0, 0, &rk808_switch_ops)
 
+struct rk8xx_register_bit {
+	u8 reg;
+	u8 bit;
+};
+
+#define RK8XX_REG_BIT(_reg, _bit)					\
+	{								\
+		.reg = _reg,						\
+		.bit = BIT(_bit),						\
+	}
+
 struct rk808_regulator_data {
 	struct gpio_desc *dvs_gpio[2];
 };
@@ -216,6 +264,133 @@ static const unsigned int rk817_buck1_4_ramp_table[] = {
 	3000, 6300, 12500, 25000
 };
 
+static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode)
+{
+	int rid = rdev_get_id(rdev);
+	int ctr_bit, reg;
+
+	reg = RK806_POWER_FPWM_EN0 + rid / 8;
+	ctr_bit = rid % 8;
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		return regmap_update_bits(rdev->regmap, reg,
+					  PWM_MODE_MSK << ctr_bit,
+					  FPWM_MODE << ctr_bit);
+	case REGULATOR_MODE_NORMAL:
+		return regmap_update_bits(rdev->regmap, reg,
+					  PWM_MODE_MSK << ctr_bit,
+					  AUTO_PWM_MODE << ctr_bit);
+	default:
+		dev_err(rdev_get_dev(rdev), "mode unsupported: %u\n", mode);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned int rk806_get_mode_dcdc(struct regulator_dev *rdev)
+{
+	int rid = rdev_get_id(rdev);
+	int ctr_bit, reg;
+	unsigned int val;
+	int err;
+
+	reg = RK806_POWER_FPWM_EN0 + rid / 8;
+	ctr_bit = rid % 8;
+
+	err = regmap_read(rdev->regmap, reg, &val);
+	if (err)
+		return err;
+
+	if ((val >> ctr_bit) & FPWM_MODE)
+		return REGULATOR_MODE_FAST;
+	else
+		return REGULATOR_MODE_NORMAL;
+}
+
+static const struct rk8xx_register_bit rk806_dcdc_rate2[] = {
+	RK8XX_REG_BIT(0xEB, 0),
+	RK8XX_REG_BIT(0xEB, 1),
+	RK8XX_REG_BIT(0xEB, 2),
+	RK8XX_REG_BIT(0xEB, 3),
+	RK8XX_REG_BIT(0xEB, 4),
+	RK8XX_REG_BIT(0xEB, 5),
+	RK8XX_REG_BIT(0xEB, 6),
+	RK8XX_REG_BIT(0xEB, 7),
+	RK8XX_REG_BIT(0xEA, 0),
+	RK8XX_REG_BIT(0xEA, 1),
+};
+
+static const unsigned int rk806_ramp_delay_table_dcdc[] = {
+	50000, 25000, 12500, 6250, 3125, 1560, 961, 390
+};
+
+static int rk806_set_ramp_delay_dcdc(struct regulator_dev *rdev, int ramp_delay)
+{
+	int rid = rdev_get_id(rdev);
+	int regval, ramp_value, ret;
+
+	ret = regulator_find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
+					    rdev->desc->n_ramp_values, &ramp_value);
+	if (ret) {
+		dev_warn(rdev_get_dev(rdev),
+			 "Can't set ramp-delay %u, setting %u\n", ramp_delay,
+			 rdev->desc->ramp_delay_table[ramp_value]);
+	}
+
+	regval = ramp_value << (ffs(rdev->desc->ramp_mask) - 1);
+
+	ret = regmap_update_bits(rdev->regmap, rdev->desc->ramp_reg,
+				 rdev->desc->ramp_mask, regval);
+	if (ret)
+		return ret;
+
+	/*
+	 * The above is effectively a copy of regulator_set_ramp_delay_regmap(),
+	 * but that only stores the lower 2 bits for rk806 DCDC ramp. The MSB must
+	 * be stored in a separate register, so this open codes the implementation
+	 * to have access to the ramp_value.
+	 */
+
+	regval = (ramp_value >> 2) & 0x1 ? rk806_dcdc_rate2[rid].bit : 0;
+	return regmap_update_bits(rdev->regmap, rk806_dcdc_rate2[rid].reg,
+				  rk806_dcdc_rate2[rid].bit,
+				  regval);
+}
+
+static const unsigned int rk806_ramp_delay_table_ldo[] = {
+	100000, 50000, 25000, 12500, 6280, 3120, 1900, 780
+};
+
+static int rk806_set_suspend_voltage_range(struct regulator_dev *rdev, int reg_offset, int uv)
+{
+	int sel = regulator_map_voltage_linear_range(rdev, uv, uv);
+	unsigned int reg;
+
+	if (sel < 0)
+		return -EINVAL;
+
+	reg = rdev->desc->vsel_reg + reg_offset;
+
+	return regmap_update_bits(rdev->regmap, reg, rdev->desc->vsel_mask, sel);
+}
+
+static int rk806_set_suspend_voltage_range_dcdc(struct regulator_dev *rdev, int uv)
+{
+	return rk806_set_suspend_voltage_range(rdev, RK806_DCDC_SLP_REG_OFFSET, uv);
+}
+
+static int rk806_set_suspend_voltage_range_nldo(struct regulator_dev *rdev, int uv)
+{
+	return rk806_set_suspend_voltage_range(rdev, RK806_NLDO_SLP_REG_OFFSET, uv);
+}
+
+static int rk806_set_suspend_voltage_range_pldo(struct regulator_dev *rdev, int uv)
+{
+	return rk806_set_suspend_voltage_range(rdev, RK806_PLDO_SLP_REG_OFFSET, uv);
+}
+
 static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
 {
 	struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
@@ -393,6 +568,45 @@ static int rk805_set_suspend_disable(struct regulator_dev *rdev)
 				  0);
 }
 
+static const struct rk8xx_register_bit rk806_suspend_bits[] = {
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 0),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 1),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 2),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 3),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 4),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 5),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 6),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 7),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 6),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 7),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 0),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 1),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 2),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 3),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 4),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 1),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 2),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 3),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 4),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 5),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 0),
+};
+
+static int rk806_set_suspend_enable(struct regulator_dev *rdev)
+{
+	int rid = rdev_get_id(rdev);
+	return regmap_update_bits(rdev->regmap, rk806_suspend_bits[rid].reg,
+				  rk806_suspend_bits[rid].bit,
+				  rk806_suspend_bits[rid].bit);
+}
+
+static int rk806_set_suspend_disable(struct regulator_dev *rdev)
+{
+	int rid = rdev_get_id(rdev);
+	return regmap_update_bits(rdev->regmap, rk806_suspend_bits[rid].reg,
+				  rk806_suspend_bits[rid].bit, 0);
+}
+
 static int rk808_set_suspend_enable(struct regulator_dev *rdev)
 {
 	unsigned int reg;
@@ -561,6 +775,64 @@ static const struct regulator_ops rk805_switch_ops = {
 	.set_suspend_disable    = rk805_set_suspend_disable,
 };
 
+static const struct regulator_ops rk806_ops_dcdc = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel        = regulator_set_voltage_sel_regmap,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+	.set_mode		= rk806_set_mode_dcdc,
+	.get_mode		= rk806_get_mode_dcdc,
+
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= rk8xx_is_enabled_wmsk_regmap,
+
+	.set_suspend_mode	= rk806_set_mode_dcdc,
+	.set_ramp_delay		= rk806_set_ramp_delay_dcdc,
+
+	.set_suspend_voltage	= rk806_set_suspend_voltage_range_dcdc,
+	.set_suspend_enable	= rk806_set_suspend_enable,
+	.set_suspend_disable	= rk806_set_suspend_disable,
+};
+
+static const struct regulator_ops rk806_ops_nldo = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel        = regulator_set_voltage_sel_regmap,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+
+	.set_ramp_delay		= regulator_set_ramp_delay_regmap,
+
+	.set_suspend_voltage	= rk806_set_suspend_voltage_range_nldo,
+	.set_suspend_enable	= rk806_set_suspend_enable,
+	.set_suspend_disable	= rk806_set_suspend_disable,
+};
+
+static const struct regulator_ops rk806_ops_pldo = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel        = regulator_set_voltage_sel_regmap,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+
+	.set_ramp_delay		= regulator_set_ramp_delay_regmap,
+
+	.set_suspend_voltage	= rk806_set_suspend_voltage_range_pldo,
+	.set_suspend_enable	= rk806_set_suspend_enable,
+	.set_suspend_disable	= rk806_set_suspend_disable,
+};
+
 static const struct regulator_ops rk808_buck1_2_ops = {
 	.list_voltage		= regulator_list_voltage_linear,
 	.map_voltage		= regulator_map_voltage_linear,
@@ -743,6 +1015,112 @@ static const struct regulator_desc rk805_reg[] = {
 		BIT(2), 400),
 };
 
+static const struct linear_range rk806_buck_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0, 160, 6250), /* 500mV ~ 1500mV */
+	REGULATOR_LINEAR_RANGE(1500000, 161, 237, 25000), /* 1500mV ~ 3400mV */
+	REGULATOR_LINEAR_RANGE(3400000, 238, 255, 0),
+};
+
+static const struct linear_range rk806_ldo_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0, 232, 12500), /* 500mV ~ 3400mV */
+	REGULATOR_LINEAR_RANGE(3400000, 233, 255, 0), /* 500mV ~ 3400mV */
+};
+
+static const struct regulator_desc rk806_reg[] = {
+	RK806_REGULATOR("dcdc-reg1", "vcc1", RK806_ID_DCDC1, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK1_ON_VSEL,
+			RK806_POWER_EN0, rk806_buck_voltage_ranges, 0,
+			RK806_BUCK1_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg2", "vcc2", RK806_ID_DCDC2, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK2_ON_VSEL,
+			RK806_POWER_EN0, rk806_buck_voltage_ranges, 1,
+			RK806_BUCK2_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg3", "vcc3", RK806_ID_DCDC3, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK3_ON_VSEL,
+			RK806_POWER_EN0, rk806_buck_voltage_ranges, 2,
+			RK806_BUCK3_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg4", "vcc4", RK806_ID_DCDC4, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK4_ON_VSEL,
+			RK806_POWER_EN0, rk806_buck_voltage_ranges, 3,
+			RK806_BUCK4_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+
+	RK806_REGULATOR("dcdc-reg5", "vcc5", RK806_ID_DCDC5, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK5_ON_VSEL,
+			RK806_POWER_EN1, rk806_buck_voltage_ranges, 0,
+			RK806_BUCK5_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg6", "vcc6", RK806_ID_DCDC6, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK6_ON_VSEL,
+			RK806_POWER_EN1, rk806_buck_voltage_ranges, 1,
+			RK806_BUCK6_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg7", "vcc7", RK806_ID_DCDC7, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK7_ON_VSEL,
+			RK806_POWER_EN1, rk806_buck_voltage_ranges, 2,
+			RK806_BUCK7_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg8", "vcc8", RK806_ID_DCDC8, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK8_ON_VSEL,
+			RK806_POWER_EN1, rk806_buck_voltage_ranges, 3,
+			RK806_BUCK8_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+
+	RK806_REGULATOR("dcdc-reg9", "vcc9", RK806_ID_DCDC9, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK9_ON_VSEL,
+			RK806_POWER_EN2, rk806_buck_voltage_ranges, 0,
+			RK806_BUCK9_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg10", "vcc10", RK806_ID_DCDC10, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK10_ON_VSEL,
+			RK806_POWER_EN2, rk806_buck_voltage_ranges, 1,
+			RK806_BUCK10_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+
+	RK806_REGULATOR("nldo-reg1", "vcc13", RK806_ID_NLDO1, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO1_ON_VSEL,
+			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 0,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("nldo-reg2", "vcc13", RK806_ID_NLDO2, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO2_ON_VSEL,
+			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 1,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("nldo-reg3", "vcc13", RK806_ID_NLDO3, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO3_ON_VSEL,
+			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 2,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("nldo-reg4", "vcc14", RK806_ID_NLDO4, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO4_ON_VSEL,
+			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 3,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+	RK806_REGULATOR("nldo-reg5", "vcc14", RK806_ID_NLDO5, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO5_ON_VSEL,
+			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 2,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+	RK806_REGULATOR("pldo-reg1", "vcc11", RK806_ID_PLDO1, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO1_ON_VSEL,
+			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 1,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("pldo-reg2", "vcc11", RK806_ID_PLDO2, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO2_ON_VSEL,
+			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 2,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("pldo-reg3", "vcc11", RK806_ID_PLDO3, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO3_ON_VSEL,
+			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 3,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+	RK806_REGULATOR("pldo-reg4", "vcc12", RK806_ID_PLDO4, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO4_ON_VSEL,
+			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 0,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("pldo-reg5", "vcc12", RK806_ID_PLDO5, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO5_ON_VSEL,
+			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 1,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+	RK806_REGULATOR("pldo-reg6", "vcca", RK806_ID_PLDO6, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO6_ON_VSEL,
+			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 0,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+};
+
+
 static const struct regulator_desc rk808_reg[] = {
 	{
 		.name = "DCDC_REG1",
@@ -1312,6 +1690,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
 		regulators = rk805_reg;
 		nregulators = RK805_NUM_REGULATORS;
 		break;
+	case RK806_ID:
+		regulators = rk806_reg;
+		nregulators = ARRAY_SIZE(rk806_reg);
+		break;
 	case RK808_ID:
 		regulators = rk808_reg;
 		nregulators = RK808_NUM_REGULATORS;
@@ -1365,5 +1747,6 @@ 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>");
+MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:rk808-regulator");
-- 
2.39.0


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

* [PATCHv6 11/11] regulator: rk808: add rk806 support
@ 2023-01-27 18:12   ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-27 18:12 UTC (permalink / raw)
  To: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones
  Cc: Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, Sebastian Reichel,
	kernel, shengfei Xu, Matti Vaittinen

Add rk806 support to the existing rk808 regulator
driver.

This has been implemented using shengfei Xu's rk806
specific driver from the vendor tree as reference.

Co-Developed-by: shengfei Xu <xsf@rock-chips.com>
Signed-off-by: shengfei Xu <xsf@rock-chips.com>
Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
 drivers/regulator/rk808-regulator.c | 383 ++++++++++++++++++++++++++++
 1 file changed, 383 insertions(+)

diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index fa9fc1aa1ae3..3d534d411104 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -3,9 +3,11 @@
  * Regulator driver for Rockchip RK805/RK808/RK818
  *
  * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
  *
  * Author: Chris Zhong <zyw@rock-chips.com>
  * Author: Zhang Qing <zhangqing@rock-chips.com>
+ * Author: Xu Shengfei <xsf@rock-chips.com>
  *
  * Copyright (C) 2016 PHYTEC Messtechnik GmbH
  *
@@ -39,6 +41,13 @@
 #define RK818_LDO3_ON_VSEL_MASK		0xf
 #define RK818_BOOST_ON_VSEL_MASK	0xe0
 
+#define RK806_DCDC_SLP_REG_OFFSET	0x0A
+#define RK806_NLDO_SLP_REG_OFFSET	0x05
+#define RK806_PLDO_SLP_REG_OFFSET	0x06
+
+#define RK806_BUCK_SEL_CNT		0xff
+#define RK806_LDO_SEL_CNT		0xff
+
 /* Ramp rate definitions for buck1 / buck2 only */
 #define RK808_RAMP_RATE_OFFSET		3
 #define RK808_RAMP_RATE_MASK		(3 << RK808_RAMP_RATE_OFFSET)
@@ -117,6 +126,34 @@
 	RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, 0, 0, _etime, &rk805_reg_ops)
 
+#define RK806_REGULATOR(_name, _supply_name, _id, _ops,\
+			_n_voltages, _vr, _er, _lr, ctrl_bit,\
+			_rr, _rm, _rt)\
+[_id] = {\
+		.name = _name,\
+		.supply_name = _supply_name,\
+		.of_match = of_match_ptr(_name),\
+		.regulators_node = of_match_ptr("regulators"),\
+		.id = _id,\
+		.ops = &_ops,\
+		.type = REGULATOR_VOLTAGE,\
+		.n_voltages = _n_voltages,\
+		.linear_ranges = _lr,\
+		.n_linear_ranges = ARRAY_SIZE(_lr),\
+		.vsel_reg = _vr,\
+		.vsel_mask = 0xff,\
+		.enable_reg = _er,\
+		.enable_mask = ENABLE_MASK(ctrl_bit),\
+		.enable_val = ENABLE_MASK(ctrl_bit),\
+		.disable_val = DISABLE_VAL(ctrl_bit),\
+		.of_map_mode = rk8xx_regulator_of_map_mode,\
+		.ramp_reg = _rr,\
+		.ramp_mask = _rm,\
+		.ramp_delay_table = _rt, \
+		.n_ramp_values = ARRAY_SIZE(_rt), \
+		.owner = THIS_MODULE,\
+	}
+
 #define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\
 	_vmask, _ereg, _emask, _etime)					\
 	RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg,	\
@@ -153,6 +190,17 @@
 	RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask,	\
 	0, 0, &rk808_switch_ops)
 
+struct rk8xx_register_bit {
+	u8 reg;
+	u8 bit;
+};
+
+#define RK8XX_REG_BIT(_reg, _bit)					\
+	{								\
+		.reg = _reg,						\
+		.bit = BIT(_bit),						\
+	}
+
 struct rk808_regulator_data {
 	struct gpio_desc *dvs_gpio[2];
 };
@@ -216,6 +264,133 @@ static const unsigned int rk817_buck1_4_ramp_table[] = {
 	3000, 6300, 12500, 25000
 };
 
+static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode)
+{
+	int rid = rdev_get_id(rdev);
+	int ctr_bit, reg;
+
+	reg = RK806_POWER_FPWM_EN0 + rid / 8;
+	ctr_bit = rid % 8;
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		return regmap_update_bits(rdev->regmap, reg,
+					  PWM_MODE_MSK << ctr_bit,
+					  FPWM_MODE << ctr_bit);
+	case REGULATOR_MODE_NORMAL:
+		return regmap_update_bits(rdev->regmap, reg,
+					  PWM_MODE_MSK << ctr_bit,
+					  AUTO_PWM_MODE << ctr_bit);
+	default:
+		dev_err(rdev_get_dev(rdev), "mode unsupported: %u\n", mode);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned int rk806_get_mode_dcdc(struct regulator_dev *rdev)
+{
+	int rid = rdev_get_id(rdev);
+	int ctr_bit, reg;
+	unsigned int val;
+	int err;
+
+	reg = RK806_POWER_FPWM_EN0 + rid / 8;
+	ctr_bit = rid % 8;
+
+	err = regmap_read(rdev->regmap, reg, &val);
+	if (err)
+		return err;
+
+	if ((val >> ctr_bit) & FPWM_MODE)
+		return REGULATOR_MODE_FAST;
+	else
+		return REGULATOR_MODE_NORMAL;
+}
+
+static const struct rk8xx_register_bit rk806_dcdc_rate2[] = {
+	RK8XX_REG_BIT(0xEB, 0),
+	RK8XX_REG_BIT(0xEB, 1),
+	RK8XX_REG_BIT(0xEB, 2),
+	RK8XX_REG_BIT(0xEB, 3),
+	RK8XX_REG_BIT(0xEB, 4),
+	RK8XX_REG_BIT(0xEB, 5),
+	RK8XX_REG_BIT(0xEB, 6),
+	RK8XX_REG_BIT(0xEB, 7),
+	RK8XX_REG_BIT(0xEA, 0),
+	RK8XX_REG_BIT(0xEA, 1),
+};
+
+static const unsigned int rk806_ramp_delay_table_dcdc[] = {
+	50000, 25000, 12500, 6250, 3125, 1560, 961, 390
+};
+
+static int rk806_set_ramp_delay_dcdc(struct regulator_dev *rdev, int ramp_delay)
+{
+	int rid = rdev_get_id(rdev);
+	int regval, ramp_value, ret;
+
+	ret = regulator_find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
+					    rdev->desc->n_ramp_values, &ramp_value);
+	if (ret) {
+		dev_warn(rdev_get_dev(rdev),
+			 "Can't set ramp-delay %u, setting %u\n", ramp_delay,
+			 rdev->desc->ramp_delay_table[ramp_value]);
+	}
+
+	regval = ramp_value << (ffs(rdev->desc->ramp_mask) - 1);
+
+	ret = regmap_update_bits(rdev->regmap, rdev->desc->ramp_reg,
+				 rdev->desc->ramp_mask, regval);
+	if (ret)
+		return ret;
+
+	/*
+	 * The above is effectively a copy of regulator_set_ramp_delay_regmap(),
+	 * but that only stores the lower 2 bits for rk806 DCDC ramp. The MSB must
+	 * be stored in a separate register, so this open codes the implementation
+	 * to have access to the ramp_value.
+	 */
+
+	regval = (ramp_value >> 2) & 0x1 ? rk806_dcdc_rate2[rid].bit : 0;
+	return regmap_update_bits(rdev->regmap, rk806_dcdc_rate2[rid].reg,
+				  rk806_dcdc_rate2[rid].bit,
+				  regval);
+}
+
+static const unsigned int rk806_ramp_delay_table_ldo[] = {
+	100000, 50000, 25000, 12500, 6280, 3120, 1900, 780
+};
+
+static int rk806_set_suspend_voltage_range(struct regulator_dev *rdev, int reg_offset, int uv)
+{
+	int sel = regulator_map_voltage_linear_range(rdev, uv, uv);
+	unsigned int reg;
+
+	if (sel < 0)
+		return -EINVAL;
+
+	reg = rdev->desc->vsel_reg + reg_offset;
+
+	return regmap_update_bits(rdev->regmap, reg, rdev->desc->vsel_mask, sel);
+}
+
+static int rk806_set_suspend_voltage_range_dcdc(struct regulator_dev *rdev, int uv)
+{
+	return rk806_set_suspend_voltage_range(rdev, RK806_DCDC_SLP_REG_OFFSET, uv);
+}
+
+static int rk806_set_suspend_voltage_range_nldo(struct regulator_dev *rdev, int uv)
+{
+	return rk806_set_suspend_voltage_range(rdev, RK806_NLDO_SLP_REG_OFFSET, uv);
+}
+
+static int rk806_set_suspend_voltage_range_pldo(struct regulator_dev *rdev, int uv)
+{
+	return rk806_set_suspend_voltage_range(rdev, RK806_PLDO_SLP_REG_OFFSET, uv);
+}
+
 static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
 {
 	struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
@@ -393,6 +568,45 @@ static int rk805_set_suspend_disable(struct regulator_dev *rdev)
 				  0);
 }
 
+static const struct rk8xx_register_bit rk806_suspend_bits[] = {
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 0),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 1),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 2),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 3),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 4),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 5),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 6),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 7),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 6),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 7),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 0),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 1),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 2),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 3),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 4),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 1),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 2),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 3),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 4),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 5),
+	RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 0),
+};
+
+static int rk806_set_suspend_enable(struct regulator_dev *rdev)
+{
+	int rid = rdev_get_id(rdev);
+	return regmap_update_bits(rdev->regmap, rk806_suspend_bits[rid].reg,
+				  rk806_suspend_bits[rid].bit,
+				  rk806_suspend_bits[rid].bit);
+}
+
+static int rk806_set_suspend_disable(struct regulator_dev *rdev)
+{
+	int rid = rdev_get_id(rdev);
+	return regmap_update_bits(rdev->regmap, rk806_suspend_bits[rid].reg,
+				  rk806_suspend_bits[rid].bit, 0);
+}
+
 static int rk808_set_suspend_enable(struct regulator_dev *rdev)
 {
 	unsigned int reg;
@@ -561,6 +775,64 @@ static const struct regulator_ops rk805_switch_ops = {
 	.set_suspend_disable    = rk805_set_suspend_disable,
 };
 
+static const struct regulator_ops rk806_ops_dcdc = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel        = regulator_set_voltage_sel_regmap,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+	.set_mode		= rk806_set_mode_dcdc,
+	.get_mode		= rk806_get_mode_dcdc,
+
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= rk8xx_is_enabled_wmsk_regmap,
+
+	.set_suspend_mode	= rk806_set_mode_dcdc,
+	.set_ramp_delay		= rk806_set_ramp_delay_dcdc,
+
+	.set_suspend_voltage	= rk806_set_suspend_voltage_range_dcdc,
+	.set_suspend_enable	= rk806_set_suspend_enable,
+	.set_suspend_disable	= rk806_set_suspend_disable,
+};
+
+static const struct regulator_ops rk806_ops_nldo = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel        = regulator_set_voltage_sel_regmap,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+
+	.set_ramp_delay		= regulator_set_ramp_delay_regmap,
+
+	.set_suspend_voltage	= rk806_set_suspend_voltage_range_nldo,
+	.set_suspend_enable	= rk806_set_suspend_enable,
+	.set_suspend_disable	= rk806_set_suspend_disable,
+};
+
+static const struct regulator_ops rk806_ops_pldo = {
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.map_voltage		= regulator_map_voltage_linear_range,
+
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel        = regulator_set_voltage_sel_regmap,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.is_enabled		= regulator_is_enabled_regmap,
+
+	.set_ramp_delay		= regulator_set_ramp_delay_regmap,
+
+	.set_suspend_voltage	= rk806_set_suspend_voltage_range_pldo,
+	.set_suspend_enable	= rk806_set_suspend_enable,
+	.set_suspend_disable	= rk806_set_suspend_disable,
+};
+
 static const struct regulator_ops rk808_buck1_2_ops = {
 	.list_voltage		= regulator_list_voltage_linear,
 	.map_voltage		= regulator_map_voltage_linear,
@@ -743,6 +1015,112 @@ static const struct regulator_desc rk805_reg[] = {
 		BIT(2), 400),
 };
 
+static const struct linear_range rk806_buck_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0, 160, 6250), /* 500mV ~ 1500mV */
+	REGULATOR_LINEAR_RANGE(1500000, 161, 237, 25000), /* 1500mV ~ 3400mV */
+	REGULATOR_LINEAR_RANGE(3400000, 238, 255, 0),
+};
+
+static const struct linear_range rk806_ldo_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(500000, 0, 232, 12500), /* 500mV ~ 3400mV */
+	REGULATOR_LINEAR_RANGE(3400000, 233, 255, 0), /* 500mV ~ 3400mV */
+};
+
+static const struct regulator_desc rk806_reg[] = {
+	RK806_REGULATOR("dcdc-reg1", "vcc1", RK806_ID_DCDC1, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK1_ON_VSEL,
+			RK806_POWER_EN0, rk806_buck_voltage_ranges, 0,
+			RK806_BUCK1_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg2", "vcc2", RK806_ID_DCDC2, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK2_ON_VSEL,
+			RK806_POWER_EN0, rk806_buck_voltage_ranges, 1,
+			RK806_BUCK2_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg3", "vcc3", RK806_ID_DCDC3, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK3_ON_VSEL,
+			RK806_POWER_EN0, rk806_buck_voltage_ranges, 2,
+			RK806_BUCK3_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg4", "vcc4", RK806_ID_DCDC4, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK4_ON_VSEL,
+			RK806_POWER_EN0, rk806_buck_voltage_ranges, 3,
+			RK806_BUCK4_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+
+	RK806_REGULATOR("dcdc-reg5", "vcc5", RK806_ID_DCDC5, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK5_ON_VSEL,
+			RK806_POWER_EN1, rk806_buck_voltage_ranges, 0,
+			RK806_BUCK5_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg6", "vcc6", RK806_ID_DCDC6, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK6_ON_VSEL,
+			RK806_POWER_EN1, rk806_buck_voltage_ranges, 1,
+			RK806_BUCK6_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg7", "vcc7", RK806_ID_DCDC7, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK7_ON_VSEL,
+			RK806_POWER_EN1, rk806_buck_voltage_ranges, 2,
+			RK806_BUCK7_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg8", "vcc8", RK806_ID_DCDC8, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK8_ON_VSEL,
+			RK806_POWER_EN1, rk806_buck_voltage_ranges, 3,
+			RK806_BUCK8_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+
+	RK806_REGULATOR("dcdc-reg9", "vcc9", RK806_ID_DCDC9, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK9_ON_VSEL,
+			RK806_POWER_EN2, rk806_buck_voltage_ranges, 0,
+			RK806_BUCK9_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+	RK806_REGULATOR("dcdc-reg10", "vcc10", RK806_ID_DCDC10, rk806_ops_dcdc,
+			RK806_BUCK_SEL_CNT, RK806_BUCK10_ON_VSEL,
+			RK806_POWER_EN2, rk806_buck_voltage_ranges, 1,
+			RK806_BUCK10_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
+
+	RK806_REGULATOR("nldo-reg1", "vcc13", RK806_ID_NLDO1, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO1_ON_VSEL,
+			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 0,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("nldo-reg2", "vcc13", RK806_ID_NLDO2, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO2_ON_VSEL,
+			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 1,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("nldo-reg3", "vcc13", RK806_ID_NLDO3, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO3_ON_VSEL,
+			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 2,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("nldo-reg4", "vcc14", RK806_ID_NLDO4, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO4_ON_VSEL,
+			RK806_POWER_EN3, rk806_ldo_voltage_ranges, 3,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+	RK806_REGULATOR("nldo-reg5", "vcc14", RK806_ID_NLDO5, rk806_ops_nldo,
+			RK806_LDO_SEL_CNT, RK806_NLDO5_ON_VSEL,
+			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 2,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+	RK806_REGULATOR("pldo-reg1", "vcc11", RK806_ID_PLDO1, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO1_ON_VSEL,
+			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 1,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("pldo-reg2", "vcc11", RK806_ID_PLDO2, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO2_ON_VSEL,
+			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 2,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("pldo-reg3", "vcc11", RK806_ID_PLDO3, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO3_ON_VSEL,
+			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 3,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+	RK806_REGULATOR("pldo-reg4", "vcc12", RK806_ID_PLDO4, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO4_ON_VSEL,
+			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 0,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+	RK806_REGULATOR("pldo-reg5", "vcc12", RK806_ID_PLDO5, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO5_ON_VSEL,
+			RK806_POWER_EN5, rk806_ldo_voltage_ranges, 1,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+
+	RK806_REGULATOR("pldo-reg6", "vcca", RK806_ID_PLDO6, rk806_ops_pldo,
+			RK806_LDO_SEL_CNT, RK806_PLDO6_ON_VSEL,
+			RK806_POWER_EN4, rk806_ldo_voltage_ranges, 0,
+			0xEA, 0x38, rk806_ramp_delay_table_ldo),
+};
+
+
 static const struct regulator_desc rk808_reg[] = {
 	{
 		.name = "DCDC_REG1",
@@ -1312,6 +1690,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
 		regulators = rk805_reg;
 		nregulators = RK805_NUM_REGULATORS;
 		break;
+	case RK806_ID:
+		regulators = rk806_reg;
+		nregulators = ARRAY_SIZE(rk806_reg);
+		break;
 	case RK808_ID:
 		regulators = rk808_reg;
 		nregulators = RK808_NUM_REGULATORS;
@@ -1365,5 +1747,6 @@ 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>");
+MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:rk808-regulator");
-- 
2.39.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCHv6 05/11] mfd: rk808: split into core and i2c
  2023-01-27 18:12   ` Sebastian Reichel
@ 2023-01-27 20:06     ` Alexandre Belloni
  -1 siblings, 0 replies; 48+ messages in thread
From: Alexandre Belloni @ 2023-01-27 20:06 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alessandro Zummo, linux-rockchip, devicetree,
	linux-kernel, kernel

On 27/01/2023 19:12:38+0100, Sebastian Reichel wrote:
> Split rk808 into a core and an i2c part in preperation for
> SPI support.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

For the RTC part:
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

> ---
>  drivers/clk/Kconfig                   |   2 +-
>  drivers/input/misc/Kconfig            |   2 +-
>  drivers/mfd/Kconfig                   |   7 +-
>  drivers/mfd/Makefile                  |   3 +-
>  drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
>  drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
>  drivers/pinctrl/Kconfig               |   2 +-
>  drivers/power/supply/Kconfig          |   2 +-
>  drivers/regulator/Kconfig             |   2 +-
>  drivers/rtc/Kconfig                   |   2 +-
>  include/linux/mfd/rk808.h             |   6 +
>  sound/soc/codecs/Kconfig              |   2 +-
>  12 files changed, 256 insertions(+), 183 deletions(-)
>  rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
>  create mode 100644 drivers/mfd/rk8xx-i2c.c
> 
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index d79905f3e174..8448d616b9aa 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -83,7 +83,7 @@ config COMMON_CLK_MAX9485
>  
>  config COMMON_CLK_RK808
>  	tristate "Clock driver for RK805/RK808/RK809/RK817/RK818"
> -	depends on MFD_RK808
> +	depends on MFD_RK8XX
>  	help
>  	  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.
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index 5c2d0c06d2a5..6a6978fc68fa 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -598,7 +598,7 @@ config INPUT_PWM_VIBRA
>  
>  config INPUT_RK805_PWRKEY
>  	tristate "Rockchip RK805 PMIC power key support"
> -	depends on MFD_RK808
> +	depends on MFD_RK8XX
>  	help
>  	  Select this option to enable power key driver for RK805.
>  
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 30db49f31866..692e38283bda 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1204,12 +1204,17 @@ config MFD_RC5T583
>  	  Additional drivers must be enabled in order to use the
>  	  different functionality of the device.
>  
> -config MFD_RK808
> +config MFD_RK8XX
> +	bool
> +	select MFD_CORE
> +
> +config MFD_RK8XX_I2C
>  	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip"
>  	depends on I2C && OF
>  	select MFD_CORE
>  	select REGMAP_I2C
>  	select REGMAP_IRQ
> +	select MFD_RK8XX
>  	help
>  	  If you say yes here you get support for the RK805, RK808, RK809,
>  	  RK817 and RK818 Power Management chips.
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 457471478a93..f65ef1bd0810 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -220,7 +220,8 @@ obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
>  obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
>  obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
>  obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
> -obj-$(CONFIG_MFD_RK808)		+= rk808.o
> +obj-$(CONFIG_MFD_RK8XX)		+= rk8xx-core.o
> +obj-$(CONFIG_MFD_RK8XX_I2C)	+= rk8xx-i2c.o
>  obj-$(CONFIG_MFD_RN5T618)	+= rn5t618.o
>  obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
>  obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
> diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk8xx-core.c
> similarity index 76%
> rename from drivers/mfd/rk808.c
> rename to drivers/mfd/rk8xx-core.c
> index 695a3fe6b9e0..c52f5fa1a4da 100644
> --- a/drivers/mfd/rk808.c
> +++ b/drivers/mfd/rk8xx-core.c
> @@ -1,18 +1,15 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * MFD core driver for Rockchip RK808/RK818
> + * MFD core driver for Rockchip RK8XX
>   *
>   * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
> + * Copyright (C) 2016 PHYTEC Messtechnik GmbH
>   *
>   * Author: Chris Zhong <zyw@rock-chips.com>
>   * Author: Zhang Qing <zhangqing@rock-chips.com>
> - *
> - * Copyright (C) 2016 PHYTEC Messtechnik GmbH
> - *
>   * Author: Wadim Egorov <w.egorov@phytec.de>
>   */
>  
> -#include <linux/i2c.h>
>  #include <linux/interrupt.h>
>  #include <linux/mfd/rk808.h>
>  #include <linux/mfd/core.h>
> @@ -27,92 +24,6 @@ struct rk808_reg_data {
>  	int value;
>  };
>  
> -static bool rk808_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 RK808_SECONDS_REG ... RK808_WEEKS_REG:
> -	case RK808_RTC_STATUS_REG:
> -	case RK808_VB_MON_REG:
> -	case RK808_THERMAL_REG:
> -	case RK808_DCDC_UV_STS_REG:
> -	case RK808_LDO_UV_STS_REG:
> -	case RK808_DCDC_PG_REG:
> -	case RK808_LDO_PG_REG:
> -	case RK808_DEVCTRL_REG:
> -	case RK808_INT_STS_REG1:
> -	case RK808_INT_STS_REG2:
> -		return true;
> -	}
> -
> -	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.
> -	 */
> -
> -	switch (reg) {
> -	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
> -	case RK817_RTC_STATUS_REG:
> -	case RK817_CODEC_DTOP_LPT_SRST:
> -	case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
> -	case RK817_PMIC_CHRG_STS:
> -	case RK817_PMIC_CHRG_OUT:
> -	case RK817_PMIC_CHRG_IN:
> -	case RK817_INT_STS_REG0:
> -	case RK817_INT_STS_REG1:
> -	case RK817_INT_STS_REG2:
> -	case RK817_SYS_STS:
> -		return true;
> -	}
> -
> -	return false;
> -}
> -
> -static const struct regmap_config rk818_regmap_config = {
> -	.reg_bits = 8,
> -	.val_bits = 8,
> -	.max_register = RK818_USB_CTRL_REG,
> -	.cache_type = REGCACHE_RBTREE,
> -	.volatile_reg = rk808_is_volatile_reg,
> -};
> -
> -static const struct regmap_config rk805_regmap_config = {
> -	.reg_bits = 8,
> -	.val_bits = 8,
> -	.max_register = RK805_OFF_SOURCE_REG,
> -	.cache_type = REGCACHE_RBTREE,
> -	.volatile_reg = rk808_is_volatile_reg,
> -};
> -
> -static const struct regmap_config rk808_regmap_config = {
> -	.reg_bits = 8,
> -	.val_bits = 8,
> -	.max_register = RK808_IO_POL_REG,
> -	.cache_type = REGCACHE_RBTREE,
> -	.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 const struct resource rtc_resources[] = {
>  	DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM),
>  };
> @@ -604,9 +515,9 @@ static int rk808_restart(struct sys_off_data *data)
>  	return NOTIFY_DONE;
>  }
>  
> -static void rk8xx_shutdown(struct i2c_client *client)
> +void rk8xx_shutdown(struct device *dev)
>  {
> -	struct rk808 *rk808 = i2c_get_clientdata(client);
> +	struct rk808 *rk808 = dev_get_drvdata(dev);
>  	int ret;
>  
>  	switch (rk808->variant) {
> @@ -627,61 +538,31 @@ static void rk8xx_shutdown(struct i2c_client *client)
>  		return;
>  	}
>  	if (ret)
> -		dev_warn(&client->dev,
> +		dev_warn(dev,
>  			 "Cannot switch to power down function\n");
>  }
> +EXPORT_SYMBOL_GPL(rk8xx_shutdown);
>  
> -static const struct of_device_id rk808_of_match[] = {
> -	{ .compatible = "rockchip,rk805" },
> -	{ .compatible = "rockchip,rk808" },
> -	{ .compatible = "rockchip,rk809" },
> -	{ .compatible = "rockchip,rk817" },
> -	{ .compatible = "rockchip,rk818" },
> -	{ },
> -};
> -MODULE_DEVICE_TABLE(of, rk808_of_match);
> -
> -static int rk808_probe(struct i2c_client *client)
> +int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap)
>  {
> -	struct device_node *np = client->dev.of_node;
>  	struct rk808 *rk808;
>  	const struct rk808_reg_data *pre_init_reg;
>  	const struct mfd_cell *cells;
>  	int nr_pre_init_regs;
>  	int nr_cells;
> -	int msb, lsb;
> -	unsigned char pmic_id_msb, pmic_id_lsb;
>  	int ret;
>  	int i;
>  
> -	rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
> +	rk808 = devm_kzalloc(dev, sizeof(*rk808), GFP_KERNEL);
>  	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;
> -	} else {
> -		pmic_id_msb = RK808_ID_MSB;
> -		pmic_id_lsb = RK808_ID_LSB;
> -	}
> -
> -	/* Read chip variant */
> -	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
> -	if (msb < 0)
> -		return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n");
> -
> -	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
> -	if (lsb < 0)
> -		return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n");
> -
> -	rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
> -	dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
> +	rk808->dev = dev;
> +	rk808->variant = variant;
> +	rk808->regmap = regmap;
> +	dev_set_drvdata(dev, rk808);
>  
>  	switch (rk808->variant) {
>  	case RK805_ID:
> -		rk808->regmap_cfg = &rk805_regmap_config;
>  		rk808->regmap_irq_chip = &rk805_irq_chip;
>  		pre_init_reg = rk805_pre_init_reg;
>  		nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
> @@ -689,7 +570,6 @@ static int rk808_probe(struct i2c_client *client)
>  		nr_cells = ARRAY_SIZE(rk805s);
>  		break;
>  	case RK808_ID:
> -		rk808->regmap_cfg = &rk808_regmap_config;
>  		rk808->regmap_irq_chip = &rk808_irq_chip;
>  		pre_init_reg = rk808_pre_init_reg;
>  		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
> @@ -697,7 +577,6 @@ static int rk808_probe(struct i2c_client *client)
>  		nr_cells = ARRAY_SIZE(rk808s);
>  		break;
>  	case RK818_ID:
> -		rk808->regmap_cfg = &rk818_regmap_config;
>  		rk808->regmap_irq_chip = &rk818_irq_chip;
>  		pre_init_reg = rk818_pre_init_reg;
>  		nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
> @@ -706,7 +585,6 @@ static int rk808_probe(struct i2c_client *client)
>  		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);
> @@ -714,27 +592,20 @@ static int rk808_probe(struct i2c_client *client)
>  		nr_cells = ARRAY_SIZE(rk817s);
>  		break;
>  	default:
> -		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
> -			rk808->variant);
> +		dev_err(dev, "Unsupported RK8XX ID %lu\n", rk808->variant);
>  		return -EINVAL;
>  	}
>  
> -	rk808->dev = &client->dev;
> -	i2c_set_clientdata(client, rk808);
> -
> -	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
> -	if (IS_ERR(rk808->regmap))
> -		return dev_err_probe(&client->dev, PTR_ERR(rk808->regmap),
> -				     "regmap initialization failed\n");
> +	dev_info(dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
>  
> -	if (!client->irq)
> -		return dev_err_probe(&client->dev, -EINVAL, "No interrupt support, no core IRQ\n");
> +	if (!irq)
> +		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
>  
> -	ret = devm_regmap_add_irq_chip(&client->dev, rk808->regmap, client->irq,
> +	ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
>  				       IRQF_ONESHOT, -1,
>  				       rk808->regmap_irq_chip, &rk808->irq_data);
>  	if (ret)
> -		return dev_err_probe(&client->dev, ret, "Failed to add irq_chip\n");
> +		return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
>  
>  	for (i = 0; i < nr_pre_init_regs; i++) {
>  		ret = regmap_update_bits(rk808->regmap,
> @@ -742,45 +613,46 @@ static int rk808_probe(struct i2c_client *client)
>  					pre_init_reg[i].mask,
>  					pre_init_reg[i].value);
>  		if (ret)
> -			return dev_err_probe(&client->dev, ret, "0x%x write err\n",
> +			return dev_err_probe(dev, ret, "0x%x write err\n",
>  					     pre_init_reg[i].addr);
>  	}
>  
> -	ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
> +	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
>  			      cells, nr_cells, NULL, 0,
>  			      regmap_irq_get_domain(rk808->irq_data));
>  	if (ret)
> -		return dev_err_probe(&client->dev, ret, "failed to add MFD devices\n");
> +		return dev_err_probe(dev, ret, "failed to add MFD devices\n");
>  
> -	if (of_property_read_bool(np, "rockchip,system-power-controller")) {
> -		ret = devm_register_sys_off_handler(&client->dev,
> +	if (device_property_read_bool(dev, "rockchip,system-power-controller")) {
> +		ret = devm_register_sys_off_handler(dev,
>  				    SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
>  				    &rk808_power_off, rk808);
>  		if (ret)
> -			return dev_err_probe(&client->dev, ret,
> +			return dev_err_probe(dev, ret,
>  					     "failed to register poweroff handler\n");
>  
>  		switch (rk808->variant) {
>  		case RK809_ID:
>  		case RK817_ID:
> -			ret = devm_register_sys_off_handler(&client->dev,
> +			ret = devm_register_sys_off_handler(dev,
>  							    SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
>  							    &rk808_restart, rk808);
>  			if (ret)
> -				dev_warn(&client->dev, "failed to register rst handler, %d\n", ret);
> +				dev_warn(dev, "failed to register rst handler, %d\n", ret);
>  			break;
>  		default:
> -			dev_dbg(&client->dev, "pmic controlled board reset not supported\n");
> +			dev_dbg(dev, "pmic controlled board reset not supported\n");
>  			break;
>  		}
>  	}
>  
>  	return 0;
>  }
> +EXPORT_SYMBOL_GPL(rk8xx_probe);
>  
> -static int __maybe_unused rk8xx_suspend(struct device *dev)
> +int rk8xx_suspend(struct device *dev)
>  {
> -	struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
> +	struct rk808 *rk808 = dev_get_drvdata(dev);
>  	int ret = 0;
>  
>  	switch (rk808->variant) {
> @@ -803,10 +675,11 @@ static int __maybe_unused rk8xx_suspend(struct device *dev)
>  
>  	return ret;
>  }
> +EXPORT_SYMBOL_GPL(rk8xx_suspend);
>  
> -static int __maybe_unused rk8xx_resume(struct device *dev)
> +int rk8xx_resume(struct device *dev)
>  {
> -	struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
> +	struct rk808 *rk808 = dev_get_drvdata(dev);
>  	int ret = 0;
>  
>  	switch (rk808->variant) {
> @@ -823,22 +696,10 @@ static int __maybe_unused rk8xx_resume(struct device *dev)
>  
>  	return ret;
>  }
> -static SIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume);
> -
> -static struct i2c_driver rk808_i2c_driver = {
> -	.driver = {
> -		.name = "rk808",
> -		.of_match_table = rk808_of_match,
> -		.pm = &rk8xx_pm_ops,
> -	},
> -	.probe_new = rk808_probe,
> -	.shutdown = rk8xx_shutdown,
> -};
> -
> -module_i2c_driver(rk808_i2c_driver);
> +EXPORT_SYMBOL_GPL(rk8xx_resume);
>  
>  MODULE_LICENSE("GPL");
>  MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
>  MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
>  MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
> -MODULE_DESCRIPTION("RK808/RK818 PMIC driver");
> +MODULE_DESCRIPTION("RK8xx PMIC core");
> diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c
> new file mode 100644
> index 000000000000..6d121b589fec
> --- /dev/null
> +++ b/drivers/mfd/rk8xx-i2c.c
> @@ -0,0 +1,200 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Rockchip RK808/RK818 Core (I2C) driver
> + *
> + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
> + * Copyright (C) 2016 PHYTEC Messtechnik GmbH
> + *
> + * Author: Chris Zhong <zyw@rock-chips.com>
> + * Author: Zhang Qing <zhangqing@rock-chips.com>
> + * Author: Wadim Egorov <w.egorov@phytec.de>
> + */
> +
> +#include <linux/i2c.h>
> +#include <linux/mfd/rk808.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/regmap.h>
> +
> +static bool rk808_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 RK808_SECONDS_REG ... RK808_WEEKS_REG:
> +	case RK808_RTC_STATUS_REG:
> +	case RK808_VB_MON_REG:
> +	case RK808_THERMAL_REG:
> +	case RK808_DCDC_UV_STS_REG:
> +	case RK808_LDO_UV_STS_REG:
> +	case RK808_DCDC_PG_REG:
> +	case RK808_LDO_PG_REG:
> +	case RK808_DEVCTRL_REG:
> +	case RK808_INT_STS_REG1:
> +	case RK808_INT_STS_REG2:
> +		return true;
> +	}
> +
> +	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.
> +	 */
> +
> +	switch (reg) {
> +	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
> +	case RK817_RTC_STATUS_REG:
> +	case RK817_CODEC_DTOP_LPT_SRST:
> +	case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
> +	case RK817_PMIC_CHRG_STS:
> +	case RK817_PMIC_CHRG_OUT:
> +	case RK817_PMIC_CHRG_IN:
> +	case RK817_INT_STS_REG0:
> +	case RK817_INT_STS_REG1:
> +	case RK817_INT_STS_REG2:
> +	case RK817_SYS_STS:
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +
> +static const struct regmap_config rk818_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = RK818_USB_CTRL_REG,
> +	.cache_type = REGCACHE_RBTREE,
> +	.volatile_reg = rk808_is_volatile_reg,
> +};
> +
> +static const struct regmap_config rk805_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = RK805_OFF_SOURCE_REG,
> +	.cache_type = REGCACHE_RBTREE,
> +	.volatile_reg = rk808_is_volatile_reg,
> +};
> +
> +static const struct regmap_config rk808_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = RK808_IO_POL_REG,
> +	.cache_type = REGCACHE_RBTREE,
> +	.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 int rk8xx_i2c_get_variant(struct i2c_client *client)
> +{
> +	u8 pmic_id_msb, pmic_id_lsb;
> +	int msb, lsb;
> +
> +	if (of_device_is_compatible(client->dev.of_node, "rockchip,rk817") ||
> +	    of_device_is_compatible(client->dev.of_node, "rockchip,rk809")) {
> +		pmic_id_msb = RK817_ID_MSB;
> +		pmic_id_lsb = RK817_ID_LSB;
> +	} else {
> +		pmic_id_msb = RK808_ID_MSB;
> +		pmic_id_lsb = RK808_ID_LSB;
> +	}
> +
> +	/* Read chip variant */
> +	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
> +	if (msb < 0)
> +		return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n");
> +
> +	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
> +	if (lsb < 0)
> +		return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n");
> +
> +	return ((msb << 8) | lsb) & RK8XX_ID_MSK;
> +}
> +
> +static int rk8xx_i2c_probe(struct i2c_client *client)
> +{
> +	const struct regmap_config *regmap_cfg;
> +	struct regmap *regmap;
> +	int variant;
> +
> +	variant = rk8xx_i2c_get_variant(client);
> +	if (variant < 0)
> +		return variant;
> +
> +	switch (variant) {
> +	case RK805_ID:
> +		regmap_cfg = &rk805_regmap_config;
> +		break;
> +	case RK808_ID:
> +		regmap_cfg = &rk808_regmap_config;
> +		break;
> +	case RK818_ID:
> +		regmap_cfg = &rk818_regmap_config;
> +		break;
> +	case RK809_ID:
> +	case RK817_ID:
> +		regmap_cfg = &rk817_regmap_config;
> +		break;
> +	default:
> +		return dev_err_probe(&client->dev, -EINVAL, "Unsupported RK8XX ID %x\n", variant);
> +	}
> +
> +	regmap = devm_regmap_init_i2c(client, regmap_cfg);
> +	if (IS_ERR(regmap))
> +		return dev_err_probe(&client->dev, PTR_ERR(regmap),
> +				     "regmap initialization failed\n");
> +
> +	return rk8xx_probe(&client->dev, variant, client->irq, regmap);
> +}
> +
> +static void rk8xx_i2c_shutdown(struct i2c_client *client)
> +{
> +	rk8xx_shutdown(&client->dev);
> +}
> +
> +static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume);
> +
> +static const struct of_device_id rk8xx_i2c_of_match[] = {
> +	{ .compatible = "rockchip,rk805" },
> +	{ .compatible = "rockchip,rk808" },
> +	{ .compatible = "rockchip,rk809" },
> +	{ .compatible = "rockchip,rk817" },
> +	{ .compatible = "rockchip,rk818" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match);
> +
> +static struct i2c_driver rk8xx_i2c_driver = {
> +	.driver = {
> +		.name = "rk8xx-i2c",
> +		.of_match_table = rk8xx_i2c_of_match,
> +		.pm = &rk8xx_i2c_pm_ops,
> +	},
> +	.probe_new = rk8xx_i2c_probe,
> +	.shutdown  = rk8xx_i2c_shutdown,
> +};
> +module_i2c_driver(rk8xx_i2c_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
> +MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
> +MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
> +MODULE_DESCRIPTION("RK8xx I2C PMIC driver");
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 7d5f5458c72e..b3cbce49a087 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -407,7 +407,7 @@ config PINCTRL_PISTACHIO
>  
>  config PINCTRL_RK805
>  	tristate "Pinctrl and GPIO driver for RK805 PMIC"
> -	depends on MFD_RK808
> +	depends on MFD_RK8XX
>  	select GPIOLIB
>  	select PINMUX
>  	select GENERIC_PINCONF
> diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
> index 0bbfe6a7ce4d..306a9b1f897e 100644
> --- a/drivers/power/supply/Kconfig
> +++ b/drivers/power/supply/Kconfig
> @@ -725,7 +725,7 @@ config CHARGER_BQ256XX
>  
>  config CHARGER_RK817
>  	tristate "Rockchip RK817 PMIC Battery Charger"
> -	depends on MFD_RK808
> +	depends on MFD_RK8XX
>  	help
>  	  Say Y to include support for Rockchip RK817 Battery Charger.
>  
> diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
> index 820c9a0788e5..90e79ec5b021 100644
> --- a/drivers/regulator/Kconfig
> +++ b/drivers/regulator/Kconfig
> @@ -1048,7 +1048,7 @@ config REGULATOR_RC5T583
>  
>  config REGULATOR_RK808
>  	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators"
> -	depends on MFD_RK808
> +	depends on MFD_RK8XX
>  	help
>  	  Select this option to enable the power regulator of ROCKCHIP
>  	  PMIC RK805,RK809&RK817,RK808 and RK818.
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 677d2601d305..313c14c4cb2d 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -395,7 +395,7 @@ config RTC_DRV_NCT3018Y
>  
>  config RTC_DRV_RK808
>  	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC"
> -	depends on MFD_RK808
> +	depends on MFD_RK8XX
>  	help
>  	  If you say yes here you will get support for the
>  	  RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC.
> diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
> index a89ddd9ba68e..4183427a80fe 100644
> --- a/include/linux/mfd/rk808.h
> +++ b/include/linux/mfd/rk808.h
> @@ -794,4 +794,10 @@ struct rk808 {
>  	const struct regmap_config	*regmap_cfg;
>  	const struct regmap_irq_chip	*regmap_irq_chip;
>  };
> +
> +void rk8xx_shutdown(struct device *dev);
> +int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap);
> +int rk8xx_suspend(struct device *dev);
> +int rk8xx_resume(struct device *dev);
> +
>  #endif /* __LINUX_REGULATOR_RK808_H */
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> index 0f9d71490075..7df9bb2c458f 100644
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -1211,7 +1211,7 @@ config SND_SOC_RK3328
>  
>  config SND_SOC_RK817
>  	tristate "Rockchip RK817 audio CODEC"
> -	depends on MFD_RK808 || COMPILE_TEST
> +	depends on MFD_RK8XX || COMPILE_TEST
>  
>  config SND_SOC_RL6231
>  	tristate
> -- 
> 2.39.0
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

* Re: [PATCHv6 05/11] mfd: rk808: split into core and i2c
@ 2023-01-27 20:06     ` Alexandre Belloni
  0 siblings, 0 replies; 48+ messages in thread
From: Alexandre Belloni @ 2023-01-27 20:06 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alessandro Zummo, linux-rockchip, devicetree,
	linux-kernel, kernel

On 27/01/2023 19:12:38+0100, Sebastian Reichel wrote:
> Split rk808 into a core and an i2c part in preperation for
> SPI support.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

For the RTC part:
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

> ---
>  drivers/clk/Kconfig                   |   2 +-
>  drivers/input/misc/Kconfig            |   2 +-
>  drivers/mfd/Kconfig                   |   7 +-
>  drivers/mfd/Makefile                  |   3 +-
>  drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
>  drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
>  drivers/pinctrl/Kconfig               |   2 +-
>  drivers/power/supply/Kconfig          |   2 +-
>  drivers/regulator/Kconfig             |   2 +-
>  drivers/rtc/Kconfig                   |   2 +-
>  include/linux/mfd/rk808.h             |   6 +
>  sound/soc/codecs/Kconfig              |   2 +-
>  12 files changed, 256 insertions(+), 183 deletions(-)
>  rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
>  create mode 100644 drivers/mfd/rk8xx-i2c.c
> 
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index d79905f3e174..8448d616b9aa 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -83,7 +83,7 @@ config COMMON_CLK_MAX9485
>  
>  config COMMON_CLK_RK808
>  	tristate "Clock driver for RK805/RK808/RK809/RK817/RK818"
> -	depends on MFD_RK808
> +	depends on MFD_RK8XX
>  	help
>  	  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.
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index 5c2d0c06d2a5..6a6978fc68fa 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -598,7 +598,7 @@ config INPUT_PWM_VIBRA
>  
>  config INPUT_RK805_PWRKEY
>  	tristate "Rockchip RK805 PMIC power key support"
> -	depends on MFD_RK808
> +	depends on MFD_RK8XX
>  	help
>  	  Select this option to enable power key driver for RK805.
>  
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 30db49f31866..692e38283bda 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1204,12 +1204,17 @@ config MFD_RC5T583
>  	  Additional drivers must be enabled in order to use the
>  	  different functionality of the device.
>  
> -config MFD_RK808
> +config MFD_RK8XX
> +	bool
> +	select MFD_CORE
> +
> +config MFD_RK8XX_I2C
>  	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip"
>  	depends on I2C && OF
>  	select MFD_CORE
>  	select REGMAP_I2C
>  	select REGMAP_IRQ
> +	select MFD_RK8XX
>  	help
>  	  If you say yes here you get support for the RK805, RK808, RK809,
>  	  RK817 and RK818 Power Management chips.
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 457471478a93..f65ef1bd0810 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -220,7 +220,8 @@ obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
>  obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
>  obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
>  obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
> -obj-$(CONFIG_MFD_RK808)		+= rk808.o
> +obj-$(CONFIG_MFD_RK8XX)		+= rk8xx-core.o
> +obj-$(CONFIG_MFD_RK8XX_I2C)	+= rk8xx-i2c.o
>  obj-$(CONFIG_MFD_RN5T618)	+= rn5t618.o
>  obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
>  obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
> diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk8xx-core.c
> similarity index 76%
> rename from drivers/mfd/rk808.c
> rename to drivers/mfd/rk8xx-core.c
> index 695a3fe6b9e0..c52f5fa1a4da 100644
> --- a/drivers/mfd/rk808.c
> +++ b/drivers/mfd/rk8xx-core.c
> @@ -1,18 +1,15 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * MFD core driver for Rockchip RK808/RK818
> + * MFD core driver for Rockchip RK8XX
>   *
>   * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
> + * Copyright (C) 2016 PHYTEC Messtechnik GmbH
>   *
>   * Author: Chris Zhong <zyw@rock-chips.com>
>   * Author: Zhang Qing <zhangqing@rock-chips.com>
> - *
> - * Copyright (C) 2016 PHYTEC Messtechnik GmbH
> - *
>   * Author: Wadim Egorov <w.egorov@phytec.de>
>   */
>  
> -#include <linux/i2c.h>
>  #include <linux/interrupt.h>
>  #include <linux/mfd/rk808.h>
>  #include <linux/mfd/core.h>
> @@ -27,92 +24,6 @@ struct rk808_reg_data {
>  	int value;
>  };
>  
> -static bool rk808_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 RK808_SECONDS_REG ... RK808_WEEKS_REG:
> -	case RK808_RTC_STATUS_REG:
> -	case RK808_VB_MON_REG:
> -	case RK808_THERMAL_REG:
> -	case RK808_DCDC_UV_STS_REG:
> -	case RK808_LDO_UV_STS_REG:
> -	case RK808_DCDC_PG_REG:
> -	case RK808_LDO_PG_REG:
> -	case RK808_DEVCTRL_REG:
> -	case RK808_INT_STS_REG1:
> -	case RK808_INT_STS_REG2:
> -		return true;
> -	}
> -
> -	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.
> -	 */
> -
> -	switch (reg) {
> -	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
> -	case RK817_RTC_STATUS_REG:
> -	case RK817_CODEC_DTOP_LPT_SRST:
> -	case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
> -	case RK817_PMIC_CHRG_STS:
> -	case RK817_PMIC_CHRG_OUT:
> -	case RK817_PMIC_CHRG_IN:
> -	case RK817_INT_STS_REG0:
> -	case RK817_INT_STS_REG1:
> -	case RK817_INT_STS_REG2:
> -	case RK817_SYS_STS:
> -		return true;
> -	}
> -
> -	return false;
> -}
> -
> -static const struct regmap_config rk818_regmap_config = {
> -	.reg_bits = 8,
> -	.val_bits = 8,
> -	.max_register = RK818_USB_CTRL_REG,
> -	.cache_type = REGCACHE_RBTREE,
> -	.volatile_reg = rk808_is_volatile_reg,
> -};
> -
> -static const struct regmap_config rk805_regmap_config = {
> -	.reg_bits = 8,
> -	.val_bits = 8,
> -	.max_register = RK805_OFF_SOURCE_REG,
> -	.cache_type = REGCACHE_RBTREE,
> -	.volatile_reg = rk808_is_volatile_reg,
> -};
> -
> -static const struct regmap_config rk808_regmap_config = {
> -	.reg_bits = 8,
> -	.val_bits = 8,
> -	.max_register = RK808_IO_POL_REG,
> -	.cache_type = REGCACHE_RBTREE,
> -	.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 const struct resource rtc_resources[] = {
>  	DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM),
>  };
> @@ -604,9 +515,9 @@ static int rk808_restart(struct sys_off_data *data)
>  	return NOTIFY_DONE;
>  }
>  
> -static void rk8xx_shutdown(struct i2c_client *client)
> +void rk8xx_shutdown(struct device *dev)
>  {
> -	struct rk808 *rk808 = i2c_get_clientdata(client);
> +	struct rk808 *rk808 = dev_get_drvdata(dev);
>  	int ret;
>  
>  	switch (rk808->variant) {
> @@ -627,61 +538,31 @@ static void rk8xx_shutdown(struct i2c_client *client)
>  		return;
>  	}
>  	if (ret)
> -		dev_warn(&client->dev,
> +		dev_warn(dev,
>  			 "Cannot switch to power down function\n");
>  }
> +EXPORT_SYMBOL_GPL(rk8xx_shutdown);
>  
> -static const struct of_device_id rk808_of_match[] = {
> -	{ .compatible = "rockchip,rk805" },
> -	{ .compatible = "rockchip,rk808" },
> -	{ .compatible = "rockchip,rk809" },
> -	{ .compatible = "rockchip,rk817" },
> -	{ .compatible = "rockchip,rk818" },
> -	{ },
> -};
> -MODULE_DEVICE_TABLE(of, rk808_of_match);
> -
> -static int rk808_probe(struct i2c_client *client)
> +int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap)
>  {
> -	struct device_node *np = client->dev.of_node;
>  	struct rk808 *rk808;
>  	const struct rk808_reg_data *pre_init_reg;
>  	const struct mfd_cell *cells;
>  	int nr_pre_init_regs;
>  	int nr_cells;
> -	int msb, lsb;
> -	unsigned char pmic_id_msb, pmic_id_lsb;
>  	int ret;
>  	int i;
>  
> -	rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
> +	rk808 = devm_kzalloc(dev, sizeof(*rk808), GFP_KERNEL);
>  	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;
> -	} else {
> -		pmic_id_msb = RK808_ID_MSB;
> -		pmic_id_lsb = RK808_ID_LSB;
> -	}
> -
> -	/* Read chip variant */
> -	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
> -	if (msb < 0)
> -		return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n");
> -
> -	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
> -	if (lsb < 0)
> -		return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n");
> -
> -	rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
> -	dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
> +	rk808->dev = dev;
> +	rk808->variant = variant;
> +	rk808->regmap = regmap;
> +	dev_set_drvdata(dev, rk808);
>  
>  	switch (rk808->variant) {
>  	case RK805_ID:
> -		rk808->regmap_cfg = &rk805_regmap_config;
>  		rk808->regmap_irq_chip = &rk805_irq_chip;
>  		pre_init_reg = rk805_pre_init_reg;
>  		nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
> @@ -689,7 +570,6 @@ static int rk808_probe(struct i2c_client *client)
>  		nr_cells = ARRAY_SIZE(rk805s);
>  		break;
>  	case RK808_ID:
> -		rk808->regmap_cfg = &rk808_regmap_config;
>  		rk808->regmap_irq_chip = &rk808_irq_chip;
>  		pre_init_reg = rk808_pre_init_reg;
>  		nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
> @@ -697,7 +577,6 @@ static int rk808_probe(struct i2c_client *client)
>  		nr_cells = ARRAY_SIZE(rk808s);
>  		break;
>  	case RK818_ID:
> -		rk808->regmap_cfg = &rk818_regmap_config;
>  		rk808->regmap_irq_chip = &rk818_irq_chip;
>  		pre_init_reg = rk818_pre_init_reg;
>  		nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
> @@ -706,7 +585,6 @@ static int rk808_probe(struct i2c_client *client)
>  		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);
> @@ -714,27 +592,20 @@ static int rk808_probe(struct i2c_client *client)
>  		nr_cells = ARRAY_SIZE(rk817s);
>  		break;
>  	default:
> -		dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
> -			rk808->variant);
> +		dev_err(dev, "Unsupported RK8XX ID %lu\n", rk808->variant);
>  		return -EINVAL;
>  	}
>  
> -	rk808->dev = &client->dev;
> -	i2c_set_clientdata(client, rk808);
> -
> -	rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
> -	if (IS_ERR(rk808->regmap))
> -		return dev_err_probe(&client->dev, PTR_ERR(rk808->regmap),
> -				     "regmap initialization failed\n");
> +	dev_info(dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
>  
> -	if (!client->irq)
> -		return dev_err_probe(&client->dev, -EINVAL, "No interrupt support, no core IRQ\n");
> +	if (!irq)
> +		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
>  
> -	ret = devm_regmap_add_irq_chip(&client->dev, rk808->regmap, client->irq,
> +	ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
>  				       IRQF_ONESHOT, -1,
>  				       rk808->regmap_irq_chip, &rk808->irq_data);
>  	if (ret)
> -		return dev_err_probe(&client->dev, ret, "Failed to add irq_chip\n");
> +		return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
>  
>  	for (i = 0; i < nr_pre_init_regs; i++) {
>  		ret = regmap_update_bits(rk808->regmap,
> @@ -742,45 +613,46 @@ static int rk808_probe(struct i2c_client *client)
>  					pre_init_reg[i].mask,
>  					pre_init_reg[i].value);
>  		if (ret)
> -			return dev_err_probe(&client->dev, ret, "0x%x write err\n",
> +			return dev_err_probe(dev, ret, "0x%x write err\n",
>  					     pre_init_reg[i].addr);
>  	}
>  
> -	ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
> +	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
>  			      cells, nr_cells, NULL, 0,
>  			      regmap_irq_get_domain(rk808->irq_data));
>  	if (ret)
> -		return dev_err_probe(&client->dev, ret, "failed to add MFD devices\n");
> +		return dev_err_probe(dev, ret, "failed to add MFD devices\n");
>  
> -	if (of_property_read_bool(np, "rockchip,system-power-controller")) {
> -		ret = devm_register_sys_off_handler(&client->dev,
> +	if (device_property_read_bool(dev, "rockchip,system-power-controller")) {
> +		ret = devm_register_sys_off_handler(dev,
>  				    SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
>  				    &rk808_power_off, rk808);
>  		if (ret)
> -			return dev_err_probe(&client->dev, ret,
> +			return dev_err_probe(dev, ret,
>  					     "failed to register poweroff handler\n");
>  
>  		switch (rk808->variant) {
>  		case RK809_ID:
>  		case RK817_ID:
> -			ret = devm_register_sys_off_handler(&client->dev,
> +			ret = devm_register_sys_off_handler(dev,
>  							    SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
>  							    &rk808_restart, rk808);
>  			if (ret)
> -				dev_warn(&client->dev, "failed to register rst handler, %d\n", ret);
> +				dev_warn(dev, "failed to register rst handler, %d\n", ret);
>  			break;
>  		default:
> -			dev_dbg(&client->dev, "pmic controlled board reset not supported\n");
> +			dev_dbg(dev, "pmic controlled board reset not supported\n");
>  			break;
>  		}
>  	}
>  
>  	return 0;
>  }
> +EXPORT_SYMBOL_GPL(rk8xx_probe);
>  
> -static int __maybe_unused rk8xx_suspend(struct device *dev)
> +int rk8xx_suspend(struct device *dev)
>  {
> -	struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
> +	struct rk808 *rk808 = dev_get_drvdata(dev);
>  	int ret = 0;
>  
>  	switch (rk808->variant) {
> @@ -803,10 +675,11 @@ static int __maybe_unused rk8xx_suspend(struct device *dev)
>  
>  	return ret;
>  }
> +EXPORT_SYMBOL_GPL(rk8xx_suspend);
>  
> -static int __maybe_unused rk8xx_resume(struct device *dev)
> +int rk8xx_resume(struct device *dev)
>  {
> -	struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
> +	struct rk808 *rk808 = dev_get_drvdata(dev);
>  	int ret = 0;
>  
>  	switch (rk808->variant) {
> @@ -823,22 +696,10 @@ static int __maybe_unused rk8xx_resume(struct device *dev)
>  
>  	return ret;
>  }
> -static SIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume);
> -
> -static struct i2c_driver rk808_i2c_driver = {
> -	.driver = {
> -		.name = "rk808",
> -		.of_match_table = rk808_of_match,
> -		.pm = &rk8xx_pm_ops,
> -	},
> -	.probe_new = rk808_probe,
> -	.shutdown = rk8xx_shutdown,
> -};
> -
> -module_i2c_driver(rk808_i2c_driver);
> +EXPORT_SYMBOL_GPL(rk8xx_resume);
>  
>  MODULE_LICENSE("GPL");
>  MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
>  MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
>  MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
> -MODULE_DESCRIPTION("RK808/RK818 PMIC driver");
> +MODULE_DESCRIPTION("RK8xx PMIC core");
> diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c
> new file mode 100644
> index 000000000000..6d121b589fec
> --- /dev/null
> +++ b/drivers/mfd/rk8xx-i2c.c
> @@ -0,0 +1,200 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Rockchip RK808/RK818 Core (I2C) driver
> + *
> + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
> + * Copyright (C) 2016 PHYTEC Messtechnik GmbH
> + *
> + * Author: Chris Zhong <zyw@rock-chips.com>
> + * Author: Zhang Qing <zhangqing@rock-chips.com>
> + * Author: Wadim Egorov <w.egorov@phytec.de>
> + */
> +
> +#include <linux/i2c.h>
> +#include <linux/mfd/rk808.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/regmap.h>
> +
> +static bool rk808_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 RK808_SECONDS_REG ... RK808_WEEKS_REG:
> +	case RK808_RTC_STATUS_REG:
> +	case RK808_VB_MON_REG:
> +	case RK808_THERMAL_REG:
> +	case RK808_DCDC_UV_STS_REG:
> +	case RK808_LDO_UV_STS_REG:
> +	case RK808_DCDC_PG_REG:
> +	case RK808_LDO_PG_REG:
> +	case RK808_DEVCTRL_REG:
> +	case RK808_INT_STS_REG1:
> +	case RK808_INT_STS_REG2:
> +		return true;
> +	}
> +
> +	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.
> +	 */
> +
> +	switch (reg) {
> +	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
> +	case RK817_RTC_STATUS_REG:
> +	case RK817_CODEC_DTOP_LPT_SRST:
> +	case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
> +	case RK817_PMIC_CHRG_STS:
> +	case RK817_PMIC_CHRG_OUT:
> +	case RK817_PMIC_CHRG_IN:
> +	case RK817_INT_STS_REG0:
> +	case RK817_INT_STS_REG1:
> +	case RK817_INT_STS_REG2:
> +	case RK817_SYS_STS:
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +
> +static const struct regmap_config rk818_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = RK818_USB_CTRL_REG,
> +	.cache_type = REGCACHE_RBTREE,
> +	.volatile_reg = rk808_is_volatile_reg,
> +};
> +
> +static const struct regmap_config rk805_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = RK805_OFF_SOURCE_REG,
> +	.cache_type = REGCACHE_RBTREE,
> +	.volatile_reg = rk808_is_volatile_reg,
> +};
> +
> +static const struct regmap_config rk808_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = RK808_IO_POL_REG,
> +	.cache_type = REGCACHE_RBTREE,
> +	.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 int rk8xx_i2c_get_variant(struct i2c_client *client)
> +{
> +	u8 pmic_id_msb, pmic_id_lsb;
> +	int msb, lsb;
> +
> +	if (of_device_is_compatible(client->dev.of_node, "rockchip,rk817") ||
> +	    of_device_is_compatible(client->dev.of_node, "rockchip,rk809")) {
> +		pmic_id_msb = RK817_ID_MSB;
> +		pmic_id_lsb = RK817_ID_LSB;
> +	} else {
> +		pmic_id_msb = RK808_ID_MSB;
> +		pmic_id_lsb = RK808_ID_LSB;
> +	}
> +
> +	/* Read chip variant */
> +	msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
> +	if (msb < 0)
> +		return dev_err_probe(&client->dev, msb, "failed to read the chip id MSB\n");
> +
> +	lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
> +	if (lsb < 0)
> +		return dev_err_probe(&client->dev, lsb, "failed to read the chip id LSB\n");
> +
> +	return ((msb << 8) | lsb) & RK8XX_ID_MSK;
> +}
> +
> +static int rk8xx_i2c_probe(struct i2c_client *client)
> +{
> +	const struct regmap_config *regmap_cfg;
> +	struct regmap *regmap;
> +	int variant;
> +
> +	variant = rk8xx_i2c_get_variant(client);
> +	if (variant < 0)
> +		return variant;
> +
> +	switch (variant) {
> +	case RK805_ID:
> +		regmap_cfg = &rk805_regmap_config;
> +		break;
> +	case RK808_ID:
> +		regmap_cfg = &rk808_regmap_config;
> +		break;
> +	case RK818_ID:
> +		regmap_cfg = &rk818_regmap_config;
> +		break;
> +	case RK809_ID:
> +	case RK817_ID:
> +		regmap_cfg = &rk817_regmap_config;
> +		break;
> +	default:
> +		return dev_err_probe(&client->dev, -EINVAL, "Unsupported RK8XX ID %x\n", variant);
> +	}
> +
> +	regmap = devm_regmap_init_i2c(client, regmap_cfg);
> +	if (IS_ERR(regmap))
> +		return dev_err_probe(&client->dev, PTR_ERR(regmap),
> +				     "regmap initialization failed\n");
> +
> +	return rk8xx_probe(&client->dev, variant, client->irq, regmap);
> +}
> +
> +static void rk8xx_i2c_shutdown(struct i2c_client *client)
> +{
> +	rk8xx_shutdown(&client->dev);
> +}
> +
> +static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume);
> +
> +static const struct of_device_id rk8xx_i2c_of_match[] = {
> +	{ .compatible = "rockchip,rk805" },
> +	{ .compatible = "rockchip,rk808" },
> +	{ .compatible = "rockchip,rk809" },
> +	{ .compatible = "rockchip,rk817" },
> +	{ .compatible = "rockchip,rk818" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match);
> +
> +static struct i2c_driver rk8xx_i2c_driver = {
> +	.driver = {
> +		.name = "rk8xx-i2c",
> +		.of_match_table = rk8xx_i2c_of_match,
> +		.pm = &rk8xx_i2c_pm_ops,
> +	},
> +	.probe_new = rk8xx_i2c_probe,
> +	.shutdown  = rk8xx_i2c_shutdown,
> +};
> +module_i2c_driver(rk8xx_i2c_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
> +MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
> +MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
> +MODULE_DESCRIPTION("RK8xx I2C PMIC driver");
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 7d5f5458c72e..b3cbce49a087 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -407,7 +407,7 @@ config PINCTRL_PISTACHIO
>  
>  config PINCTRL_RK805
>  	tristate "Pinctrl and GPIO driver for RK805 PMIC"
> -	depends on MFD_RK808
> +	depends on MFD_RK8XX
>  	select GPIOLIB
>  	select PINMUX
>  	select GENERIC_PINCONF
> diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
> index 0bbfe6a7ce4d..306a9b1f897e 100644
> --- a/drivers/power/supply/Kconfig
> +++ b/drivers/power/supply/Kconfig
> @@ -725,7 +725,7 @@ config CHARGER_BQ256XX
>  
>  config CHARGER_RK817
>  	tristate "Rockchip RK817 PMIC Battery Charger"
> -	depends on MFD_RK808
> +	depends on MFD_RK8XX
>  	help
>  	  Say Y to include support for Rockchip RK817 Battery Charger.
>  
> diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
> index 820c9a0788e5..90e79ec5b021 100644
> --- a/drivers/regulator/Kconfig
> +++ b/drivers/regulator/Kconfig
> @@ -1048,7 +1048,7 @@ config REGULATOR_RC5T583
>  
>  config REGULATOR_RK808
>  	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators"
> -	depends on MFD_RK808
> +	depends on MFD_RK8XX
>  	help
>  	  Select this option to enable the power regulator of ROCKCHIP
>  	  PMIC RK805,RK809&RK817,RK808 and RK818.
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 677d2601d305..313c14c4cb2d 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -395,7 +395,7 @@ config RTC_DRV_NCT3018Y
>  
>  config RTC_DRV_RK808
>  	tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC"
> -	depends on MFD_RK808
> +	depends on MFD_RK8XX
>  	help
>  	  If you say yes here you will get support for the
>  	  RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC.
> diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
> index a89ddd9ba68e..4183427a80fe 100644
> --- a/include/linux/mfd/rk808.h
> +++ b/include/linux/mfd/rk808.h
> @@ -794,4 +794,10 @@ struct rk808 {
>  	const struct regmap_config	*regmap_cfg;
>  	const struct regmap_irq_chip	*regmap_irq_chip;
>  };
> +
> +void rk8xx_shutdown(struct device *dev);
> +int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap);
> +int rk8xx_suspend(struct device *dev);
> +int rk8xx_resume(struct device *dev);
> +
>  #endif /* __LINUX_REGULATOR_RK808_H */
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> index 0f9d71490075..7df9bb2c458f 100644
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -1211,7 +1211,7 @@ config SND_SOC_RK3328
>  
>  config SND_SOC_RK817
>  	tristate "Rockchip RK817 audio CODEC"
> -	depends on MFD_RK808 || COMPILE_TEST
> +	depends on MFD_RK8XX || COMPILE_TEST
>  
>  config SND_SOC_RL6231
>  	tristate
> -- 
> 2.39.0
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCHv6 09/11] pinctrl: rk805: add rk806 pinctrl support
  2023-01-27 18:12   ` Sebastian Reichel
@ 2023-01-30 22:31     ` Linus Walleij
  -1 siblings, 0 replies; 48+ messages in thread
From: Linus Walleij @ 2023-01-30 22:31 UTC (permalink / raw)
  To: Sebastian Reichel, Heiko Stuebner
  Cc: Rob Herring, Krzysztof Kozlowski, Lee Jones, Michael Turquette,
	Stephen Boyd, Mark Brown, Liam Girdwood, Alexandre Belloni,
	Alessandro Zummo, linux-rockchip, devicetree, linux-kernel,
	kernel, shengfei Xu

On Fri, Jan 27, 2023 at 7:13 PM Sebastian Reichel
<sebastian.reichel@collabora.com> wrote:

> Add support for rk806 dvs pinctrl to the existing rk805
> driver.
>
> This has been implemented using shengfei Xu's rk806
> specific driver from the vendor tree as reference.
>
> Co-Developed-by: shengfei Xu <xsf@rock-chips.com>
> Signed-off-by: shengfei Xu <xsf@rock-chips.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

Is this something I can just apply? I haven't had Heiko's review
on it but it looks innocent enough.

Yours,
Linus Walleij

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

* Re: [PATCHv6 09/11] pinctrl: rk805: add rk806 pinctrl support
@ 2023-01-30 22:31     ` Linus Walleij
  0 siblings, 0 replies; 48+ messages in thread
From: Linus Walleij @ 2023-01-30 22:31 UTC (permalink / raw)
  To: Sebastian Reichel, Heiko Stuebner
  Cc: Rob Herring, Krzysztof Kozlowski, Lee Jones, Michael Turquette,
	Stephen Boyd, Mark Brown, Liam Girdwood, Alexandre Belloni,
	Alessandro Zummo, linux-rockchip, devicetree, linux-kernel,
	kernel, shengfei Xu

On Fri, Jan 27, 2023 at 7:13 PM Sebastian Reichel
<sebastian.reichel@collabora.com> wrote:

> Add support for rk806 dvs pinctrl to the existing rk805
> driver.
>
> This has been implemented using shengfei Xu's rk806
> specific driver from the vendor tree as reference.
>
> Co-Developed-by: shengfei Xu <xsf@rock-chips.com>
> Signed-off-by: shengfei Xu <xsf@rock-chips.com>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

Is this something I can just apply? I haven't had Heiko's review
on it but it looks innocent enough.

Yours,
Linus Walleij

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCHv6 09/11] pinctrl: rk805: add rk806 pinctrl support
  2023-01-30 22:31     ` Linus Walleij
@ 2023-01-30 23:36       ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-30 23:36 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones,
	Michael Turquette, Stephen Boyd, Mark Brown, Liam Girdwood,
	Alexandre Belloni, Alessandro Zummo, linux-rockchip, devicetree,
	linux-kernel, kernel, shengfei Xu

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

Hi Linus,

On Mon, Jan 30, 2023 at 11:31:51PM +0100, Linus Walleij wrote:
> On Fri, Jan 27, 2023 at 7:13 PM Sebastian Reichel
> <sebastian.reichel@collabora.com> wrote:
> 
> > Add support for rk806 dvs pinctrl to the existing rk805
> > driver.
> >
> > This has been implemented using shengfei Xu's rk806
> > specific driver from the vendor tree as reference.
> >
> > Co-Developed-by: shengfei Xu <xsf@rock-chips.com>
> > Signed-off-by: shengfei Xu <xsf@rock-chips.com>
> > Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> 
> Is this something I can just apply? I haven't had Heiko's review
> on it but it looks innocent enough.

No. This code depends on the RK806 register defines added to
include/linux/mfd/rk808.h in the previous patch. The series cannot
be applied per-subsystem and my suggestion is that Lee provides an
immutable branch once he is happy with the MFD patches.

Greetings,

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCHv6 09/11] pinctrl: rk805: add rk806 pinctrl support
@ 2023-01-30 23:36       ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-01-30 23:36 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski, Lee Jones,
	Michael Turquette, Stephen Boyd, Mark Brown, Liam Girdwood,
	Alexandre Belloni, Alessandro Zummo, linux-rockchip, devicetree,
	linux-kernel, kernel, shengfei Xu


[-- Attachment #1.1: Type: text/plain, Size: 1012 bytes --]

Hi Linus,

On Mon, Jan 30, 2023 at 11:31:51PM +0100, Linus Walleij wrote:
> On Fri, Jan 27, 2023 at 7:13 PM Sebastian Reichel
> <sebastian.reichel@collabora.com> wrote:
> 
> > Add support for rk806 dvs pinctrl to the existing rk805
> > driver.
> >
> > This has been implemented using shengfei Xu's rk806
> > specific driver from the vendor tree as reference.
> >
> > Co-Developed-by: shengfei Xu <xsf@rock-chips.com>
> > Signed-off-by: shengfei Xu <xsf@rock-chips.com>
> > Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> 
> Is this something I can just apply? I haven't had Heiko's review
> on it but it looks innocent enough.

No. This code depends on the RK806 register defines added to
include/linux/mfd/rk808.h in the previous patch. The series cannot
be applied per-subsystem and my suggestion is that Lee provides an
immutable branch once he is happy with the MFD patches.

Greetings,

-- Sebastian

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 170 bytes --]

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCHv6 05/11] mfd: rk808: split into core and i2c
  2023-01-27 18:12   ` Sebastian Reichel
@ 2023-02-04 13:52     ` Lee Jones
  -1 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-02-04 13:52 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

On Fri, 27 Jan 2023, Sebastian Reichel wrote:

> Split rk808 into a core and an i2c part in preperation for
> SPI support.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
>  drivers/clk/Kconfig                   |   2 +-
>  drivers/input/misc/Kconfig            |   2 +-
>  drivers/mfd/Kconfig                   |   7 +-
>  drivers/mfd/Makefile                  |   3 +-
>  drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
>  drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
>  drivers/pinctrl/Kconfig               |   2 +-
>  drivers/power/supply/Kconfig          |   2 +-
>  drivers/regulator/Kconfig             |   2 +-
>  drivers/rtc/Kconfig                   |   2 +-
>  include/linux/mfd/rk808.h             |   6 +
>  sound/soc/codecs/Kconfig              |   2 +-
>  12 files changed, 256 insertions(+), 183 deletions(-)
>  rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
>  create mode 100644 drivers/mfd/rk8xx-i2c.c

Looks like you completely ignored (no response / no action) my review of
v4.  This submission is therefore not getting one!  All comments can be
superimposed from v4.

-- 
Lee Jones [李琼斯]

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

* Re: [PATCHv6 05/11] mfd: rk808: split into core and i2c
@ 2023-02-04 13:52     ` Lee Jones
  0 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-02-04 13:52 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

On Fri, 27 Jan 2023, Sebastian Reichel wrote:

> Split rk808 into a core and an i2c part in preperation for
> SPI support.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
>  drivers/clk/Kconfig                   |   2 +-
>  drivers/input/misc/Kconfig            |   2 +-
>  drivers/mfd/Kconfig                   |   7 +-
>  drivers/mfd/Makefile                  |   3 +-
>  drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
>  drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
>  drivers/pinctrl/Kconfig               |   2 +-
>  drivers/power/supply/Kconfig          |   2 +-
>  drivers/regulator/Kconfig             |   2 +-
>  drivers/rtc/Kconfig                   |   2 +-
>  include/linux/mfd/rk808.h             |   6 +
>  sound/soc/codecs/Kconfig              |   2 +-
>  12 files changed, 256 insertions(+), 183 deletions(-)
>  rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
>  create mode 100644 drivers/mfd/rk8xx-i2c.c

Looks like you completely ignored (no response / no action) my review of
v4.  This submission is therefore not getting one!  All comments can be
superimposed from v4.

-- 
Lee Jones [李琼斯]

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCHv6 05/11] mfd: rk808: split into core and i2c
  2023-02-04 13:52     ` Lee Jones
@ 2023-02-04 14:01       ` Lee Jones
  -1 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-02-04 14:01 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

On Sat, 04 Feb 2023, Lee Jones wrote:

> On Fri, 27 Jan 2023, Sebastian Reichel wrote:
> 
> > Split rk808 into a core and an i2c part in preperation for
> > SPI support.
> > 
> > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > ---
> >  drivers/clk/Kconfig                   |   2 +-
> >  drivers/input/misc/Kconfig            |   2 +-
> >  drivers/mfd/Kconfig                   |   7 +-
> >  drivers/mfd/Makefile                  |   3 +-
> >  drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
> >  drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
> >  drivers/pinctrl/Kconfig               |   2 +-
> >  drivers/power/supply/Kconfig          |   2 +-
> >  drivers/regulator/Kconfig             |   2 +-
> >  drivers/rtc/Kconfig                   |   2 +-
> >  include/linux/mfd/rk808.h             |   6 +
> >  sound/soc/codecs/Kconfig              |   2 +-
> >  12 files changed, 256 insertions(+), 183 deletions(-)
> >  rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
> >  create mode 100644 drivers/mfd/rk8xx-i2c.c
> 
> Looks like you completely ignored (no response / no action) my review of
> v4.  This submission is therefore not getting one!  All comments can be
> superimposed from v4.

s/v4/v5/

-- 
Lee Jones [李琼斯]

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

* Re: [PATCHv6 05/11] mfd: rk808: split into core and i2c
@ 2023-02-04 14:01       ` Lee Jones
  0 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-02-04 14:01 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

On Sat, 04 Feb 2023, Lee Jones wrote:

> On Fri, 27 Jan 2023, Sebastian Reichel wrote:
> 
> > Split rk808 into a core and an i2c part in preperation for
> > SPI support.
> > 
> > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > ---
> >  drivers/clk/Kconfig                   |   2 +-
> >  drivers/input/misc/Kconfig            |   2 +-
> >  drivers/mfd/Kconfig                   |   7 +-
> >  drivers/mfd/Makefile                  |   3 +-
> >  drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
> >  drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
> >  drivers/pinctrl/Kconfig               |   2 +-
> >  drivers/power/supply/Kconfig          |   2 +-
> >  drivers/regulator/Kconfig             |   2 +-
> >  drivers/rtc/Kconfig                   |   2 +-
> >  include/linux/mfd/rk808.h             |   6 +
> >  sound/soc/codecs/Kconfig              |   2 +-
> >  12 files changed, 256 insertions(+), 183 deletions(-)
> >  rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
> >  create mode 100644 drivers/mfd/rk8xx-i2c.c
> 
> Looks like you completely ignored (no response / no action) my review of
> v4.  This submission is therefore not getting one!  All comments can be
> superimposed from v4.

s/v4/v5/

-- 
Lee Jones [李琼斯]

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCHv6 05/11] mfd: rk808: split into core and i2c
  2023-02-04 14:01       ` Lee Jones
@ 2023-02-05  1:06         ` Sebastian Reichel
  -1 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-02-05  1:06 UTC (permalink / raw)
  To: Lee Jones
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

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

Hi Lee,

On Sat, Feb 04, 2023 at 02:01:46PM +0000, Lee Jones wrote:
> On Sat, 04 Feb 2023, Lee Jones wrote:
> > On Fri, 27 Jan 2023, Sebastian Reichel wrote:
> > > Split rk808 into a core and an i2c part in preperation for
> > > SPI support.
> > > 
> > > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > > ---
> > >  drivers/clk/Kconfig                   |   2 +-
> > >  drivers/input/misc/Kconfig            |   2 +-
> > >  drivers/mfd/Kconfig                   |   7 +-
> > >  drivers/mfd/Makefile                  |   3 +-
> > >  drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
> > >  drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
> > >  drivers/pinctrl/Kconfig               |   2 +-
> > >  drivers/power/supply/Kconfig          |   2 +-
> > >  drivers/regulator/Kconfig             |   2 +-
> > >  drivers/rtc/Kconfig                   |   2 +-
> > >  include/linux/mfd/rk808.h             |   6 +
> > >  sound/soc/codecs/Kconfig              |   2 +-
> > >  12 files changed, 256 insertions(+), 183 deletions(-)
> > >  rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
> > >  create mode 100644 drivers/mfd/rk8xx-i2c.c
> > 
> > Looks like you completely ignored (no response / no action) my review of
> > v4.  This submission is therefore not getting one!  All comments can be
> > superimposed from v4.
> 
> s/v4/v5/

not sure what you are talking about. I dropped the PM wrappers and
added a new patch moving the driver to use OF match. There were no
other comments as far as I can tell. Did I miss a second mail with
more comments?

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCHv6 05/11] mfd: rk808: split into core and i2c
@ 2023-02-05  1:06         ` Sebastian Reichel
  0 siblings, 0 replies; 48+ messages in thread
From: Sebastian Reichel @ 2023-02-05  1:06 UTC (permalink / raw)
  To: Lee Jones
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel


[-- Attachment #1.1: Type: text/plain, Size: 1661 bytes --]

Hi Lee,

On Sat, Feb 04, 2023 at 02:01:46PM +0000, Lee Jones wrote:
> On Sat, 04 Feb 2023, Lee Jones wrote:
> > On Fri, 27 Jan 2023, Sebastian Reichel wrote:
> > > Split rk808 into a core and an i2c part in preperation for
> > > SPI support.
> > > 
> > > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > > ---
> > >  drivers/clk/Kconfig                   |   2 +-
> > >  drivers/input/misc/Kconfig            |   2 +-
> > >  drivers/mfd/Kconfig                   |   7 +-
> > >  drivers/mfd/Makefile                  |   3 +-
> > >  drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
> > >  drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
> > >  drivers/pinctrl/Kconfig               |   2 +-
> > >  drivers/power/supply/Kconfig          |   2 +-
> > >  drivers/regulator/Kconfig             |   2 +-
> > >  drivers/rtc/Kconfig                   |   2 +-
> > >  include/linux/mfd/rk808.h             |   6 +
> > >  sound/soc/codecs/Kconfig              |   2 +-
> > >  12 files changed, 256 insertions(+), 183 deletions(-)
> > >  rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
> > >  create mode 100644 drivers/mfd/rk8xx-i2c.c
> > 
> > Looks like you completely ignored (no response / no action) my review of
> > v4.  This submission is therefore not getting one!  All comments can be
> > superimposed from v4.
> 
> s/v4/v5/

not sure what you are talking about. I dropped the PM wrappers and
added a new patch moving the driver to use OF match. There were no
other comments as far as I can tell. Did I miss a second mail with
more comments?

-- Sebastian

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 170 bytes --]

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCHv6 05/11] mfd: rk808: split into core and i2c
  2023-02-05  1:06         ` Sebastian Reichel
@ 2023-02-06 18:47           ` Lee Jones
  -1 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-02-06 18:47 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

On Sun, 05 Feb 2023, Sebastian Reichel wrote:

> Hi Lee,
> 
> On Sat, Feb 04, 2023 at 02:01:46PM +0000, Lee Jones wrote:
> > On Sat, 04 Feb 2023, Lee Jones wrote:
> > > On Fri, 27 Jan 2023, Sebastian Reichel wrote:
> > > > Split rk808 into a core and an i2c part in preperation for
> > > > SPI support.
> > > > 
> > > > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > > > ---
> > > >  drivers/clk/Kconfig                   |   2 +-
> > > >  drivers/input/misc/Kconfig            |   2 +-
> > > >  drivers/mfd/Kconfig                   |   7 +-
> > > >  drivers/mfd/Makefile                  |   3 +-
> > > >  drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
> > > >  drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
> > > >  drivers/pinctrl/Kconfig               |   2 +-
> > > >  drivers/power/supply/Kconfig          |   2 +-
> > > >  drivers/regulator/Kconfig             |   2 +-
> > > >  drivers/rtc/Kconfig                   |   2 +-
> > > >  include/linux/mfd/rk808.h             |   6 +
> > > >  sound/soc/codecs/Kconfig              |   2 +-
> > > >  12 files changed, 256 insertions(+), 183 deletions(-)
> > > >  rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
> > > >  create mode 100644 drivers/mfd/rk8xx-i2c.c
> > > 
> > > Looks like you completely ignored (no response / no action) my review of
> > > v4.  This submission is therefore not getting one!  All comments can be
> > > superimposed from v4.
> > 
> > s/v4/v5/
> 
> not sure what you are talking about. I dropped the PM wrappers and
> added a new patch moving the driver to use OF match. There were no
> other comments as far as I can tell. Did I miss a second mail with
> more comments?

Ah, the driver was split *then* you implemented my suggestions.

That's not what I was expecting, but is also valid.

Very well, ignore my last - this set is back in my to-review queue.

-- 
Lee Jones [李琼斯]

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

* Re: [PATCHv6 05/11] mfd: rk808: split into core and i2c
@ 2023-02-06 18:47           ` Lee Jones
  0 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-02-06 18:47 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

On Sun, 05 Feb 2023, Sebastian Reichel wrote:

> Hi Lee,
> 
> On Sat, Feb 04, 2023 at 02:01:46PM +0000, Lee Jones wrote:
> > On Sat, 04 Feb 2023, Lee Jones wrote:
> > > On Fri, 27 Jan 2023, Sebastian Reichel wrote:
> > > > Split rk808 into a core and an i2c part in preperation for
> > > > SPI support.
> > > > 
> > > > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > > > ---
> > > >  drivers/clk/Kconfig                   |   2 +-
> > > >  drivers/input/misc/Kconfig            |   2 +-
> > > >  drivers/mfd/Kconfig                   |   7 +-
> > > >  drivers/mfd/Makefile                  |   3 +-
> > > >  drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
> > > >  drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
> > > >  drivers/pinctrl/Kconfig               |   2 +-
> > > >  drivers/power/supply/Kconfig          |   2 +-
> > > >  drivers/regulator/Kconfig             |   2 +-
> > > >  drivers/rtc/Kconfig                   |   2 +-
> > > >  include/linux/mfd/rk808.h             |   6 +
> > > >  sound/soc/codecs/Kconfig              |   2 +-
> > > >  12 files changed, 256 insertions(+), 183 deletions(-)
> > > >  rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
> > > >  create mode 100644 drivers/mfd/rk8xx-i2c.c
> > > 
> > > Looks like you completely ignored (no response / no action) my review of
> > > v4.  This submission is therefore not getting one!  All comments can be
> > > superimposed from v4.
> > 
> > s/v4/v5/
> 
> not sure what you are talking about. I dropped the PM wrappers and
> added a new patch moving the driver to use OF match. There were no
> other comments as far as I can tell. Did I miss a second mail with
> more comments?

Ah, the driver was split *then* you implemented my suggestions.

That's not what I was expecting, but is also valid.

Very well, ignore my last - this set is back in my to-review queue.

-- 
Lee Jones [李琼斯]

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCHv6 09/11] pinctrl: rk805: add rk806 pinctrl support
  2023-01-30 22:31     ` Linus Walleij
@ 2023-03-02 16:22       ` Lee Jones
  -1 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-03-02 16:22 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Sebastian Reichel, Heiko Stuebner, Rob Herring,
	Krzysztof Kozlowski, Michael Turquette, Stephen Boyd, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel, shengfei Xu

On Mon, 30 Jan 2023, Linus Walleij wrote:

> On Fri, Jan 27, 2023 at 7:13 PM Sebastian Reichel
> <sebastian.reichel@collabora.com> wrote:
> 
> > Add support for rk806 dvs pinctrl to the existing rk805
> > driver.
> >
> > This has been implemented using shengfei Xu's rk806
> > specific driver from the vendor tree as reference.
> >
> > Co-Developed-by: shengfei Xu <xsf@rock-chips.com>
> > Signed-off-by: shengfei Xu <xsf@rock-chips.com>
> > Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> 
> Is this something I can just apply? I haven't had Heiko's review
> on it but it looks innocent enough.

Ack please. :)

-- 
Lee Jones [李琼斯]

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

* Re: [PATCHv6 09/11] pinctrl: rk805: add rk806 pinctrl support
@ 2023-03-02 16:22       ` Lee Jones
  0 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-03-02 16:22 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Sebastian Reichel, Heiko Stuebner, Rob Herring,
	Krzysztof Kozlowski, Michael Turquette, Stephen Boyd, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel, shengfei Xu

On Mon, 30 Jan 2023, Linus Walleij wrote:

> On Fri, Jan 27, 2023 at 7:13 PM Sebastian Reichel
> <sebastian.reichel@collabora.com> wrote:
> 
> > Add support for rk806 dvs pinctrl to the existing rk805
> > driver.
> >
> > This has been implemented using shengfei Xu's rk806
> > specific driver from the vendor tree as reference.
> >
> > Co-Developed-by: shengfei Xu <xsf@rock-chips.com>
> > Signed-off-by: shengfei Xu <xsf@rock-chips.com>
> > Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> 
> Is this something I can just apply? I haven't had Heiko's review
> on it but it looks innocent enough.

Ack please. :)

-- 
Lee Jones [李琼斯]

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCHv6 05/11] mfd: rk808: split into core and i2c
  2023-01-27 18:12   ` Sebastian Reichel
@ 2023-03-02 16:24     ` Lee Jones
  -1 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-03-02 16:24 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

On Fri, 27 Jan 2023, Sebastian Reichel wrote:

> Split rk808 into a core and an i2c part in preperation for
> SPI support.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
>  drivers/clk/Kconfig                   |   2 +-
>  drivers/input/misc/Kconfig            |   2 +-
>  drivers/mfd/Kconfig                   |   7 +-
>  drivers/mfd/Makefile                  |   3 +-
>  drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
>  drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
>  drivers/pinctrl/Kconfig               |   2 +-
>  drivers/power/supply/Kconfig          |   2 +-
>  drivers/regulator/Kconfig             |   2 +-
>  drivers/rtc/Kconfig                   |   2 +-
>  include/linux/mfd/rk808.h             |   6 +
>  sound/soc/codecs/Kconfig              |   2 +-
>  12 files changed, 256 insertions(+), 183 deletions(-)
>  rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
>  create mode 100644 drivers/mfd/rk8xx-i2c.c

For my own reference (apply this as-is to your sign-off block):

Acked-for-MFD-by: Lee Jones <lee@kernel.org>

-- 
Lee Jones [李琼斯]

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

* Re: [PATCHv6 05/11] mfd: rk808: split into core and i2c
@ 2023-03-02 16:24     ` Lee Jones
  0 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-03-02 16:24 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

On Fri, 27 Jan 2023, Sebastian Reichel wrote:

> Split rk808 into a core and an i2c part in preperation for
> SPI support.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
>  drivers/clk/Kconfig                   |   2 +-
>  drivers/input/misc/Kconfig            |   2 +-
>  drivers/mfd/Kconfig                   |   7 +-
>  drivers/mfd/Makefile                  |   3 +-
>  drivers/mfd/{rk808.c => rk8xx-core.c} | 209 +++++---------------------
>  drivers/mfd/rk8xx-i2c.c               | 200 ++++++++++++++++++++++++
>  drivers/pinctrl/Kconfig               |   2 +-
>  drivers/power/supply/Kconfig          |   2 +-
>  drivers/regulator/Kconfig             |   2 +-
>  drivers/rtc/Kconfig                   |   2 +-
>  include/linux/mfd/rk808.h             |   6 +
>  sound/soc/codecs/Kconfig              |   2 +-
>  12 files changed, 256 insertions(+), 183 deletions(-)
>  rename drivers/mfd/{rk808.c => rk8xx-core.c} (76%)
>  create mode 100644 drivers/mfd/rk8xx-i2c.c

For my own reference (apply this as-is to your sign-off block):

Acked-for-MFD-by: Lee Jones <lee@kernel.org>

-- 
Lee Jones [李琼斯]

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCHv6 06/11] mfd: rk8xx-i2c: use device_get_match_data
  2023-01-27 18:12   ` Sebastian Reichel
@ 2023-03-02 16:50     ` Lee Jones
  -1 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-03-02 16:50 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

On Fri, 27 Jan 2023, Sebastian Reichel wrote:

> Simplify the device identification logic by supplying the relevant
> information via of_match_data. This also removes the dev_info()
> printing the chip version, since that's supplied by the match data
> now.
> 
> Due to lack of hardware this change is compile-tested only.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
>  drivers/mfd/rk8xx-core.c |  2 -
>  drivers/mfd/rk8xx-i2c.c  | 89 +++++++++++++++++-----------------------
>  2 files changed, 37 insertions(+), 54 deletions(-)

For my own reference (apply this as-is to your sign-off block):

Acked-for-MFD-by: Lee Jones <lee@kernel.org>

-- 
Lee Jones [李琼斯]

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

* Re: [PATCHv6 06/11] mfd: rk8xx-i2c: use device_get_match_data
@ 2023-03-02 16:50     ` Lee Jones
  0 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-03-02 16:50 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

On Fri, 27 Jan 2023, Sebastian Reichel wrote:

> Simplify the device identification logic by supplying the relevant
> information via of_match_data. This also removes the dev_info()
> printing the chip version, since that's supplied by the match data
> now.
> 
> Due to lack of hardware this change is compile-tested only.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
>  drivers/mfd/rk8xx-core.c |  2 -
>  drivers/mfd/rk8xx-i2c.c  | 89 +++++++++++++++++-----------------------
>  2 files changed, 37 insertions(+), 54 deletions(-)

For my own reference (apply this as-is to your sign-off block):

Acked-for-MFD-by: Lee Jones <lee@kernel.org>

-- 
Lee Jones [李琼斯]

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCHv6 08/11] mfd: rk8xx: add rk806 support
  2023-01-27 18:12   ` Sebastian Reichel
@ 2023-03-02 17:52     ` Lee Jones
  -1 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-03-02 17:52 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

On Fri, 27 Jan 2023, Sebastian Reichel wrote:

> Add support for SPI connected rk806, which is used by the RK3588
> evaluation boards. The PMIC is advertised to support I2C and SPI,
> but the evaluation boards all use SPI. Thus only SPI support is
> added here.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
>  drivers/mfd/Kconfig       |  14 ++
>  drivers/mfd/Makefile      |   1 +
>  drivers/mfd/rk8xx-core.c  |  69 ++++++-
>  drivers/mfd/rk8xx-spi.c   | 129 ++++++++++++
>  include/linux/mfd/rk808.h | 409 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 619 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/mfd/rk8xx-spi.c

Few nits, nothing bad ...

> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 692e38283bda..13582ea5cb44 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1222,6 +1222,20 @@ config MFD_RK8XX_I2C
>  	  through I2C interface. The device supports multiple sub-devices
>  	  including interrupts, RTC, LDO & DCDC regulators, and onkey.
>  
> +config MFD_RK8XX_SPI
> +	tristate "Rockchip RK806 Power Management Chip"
> +	depends on SPI && OF
> +	select MFD_CORE
> +	select REGMAP_SPI
> +	select REGMAP_IRQ
> +	select MFD_RK8XX
> +	help
> +	  If you say yes here you get support for the RK806 Power Management
> +	  chip.
> +	  This driver provides common support for accessing the device
> +	  through an SPI interface. The device supports multiple sub-devices
> +	  including interrupts, LDO & DCDC regulators, and power on-key.
> +
>  config MFD_RN5T618
>  	tristate "Ricoh RN5T567/618 PMIC"
>  	depends on I2C
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index f65ef1bd0810..a88f27cd837b 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -222,6 +222,7 @@ obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
>  obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
>  obj-$(CONFIG_MFD_RK8XX)		+= rk8xx-core.o
>  obj-$(CONFIG_MFD_RK8XX_I2C)	+= rk8xx-i2c.o
> +obj-$(CONFIG_MFD_RK8XX_SPI)	+= rk8xx-spi.o
>  obj-$(CONFIG_MFD_RN5T618)	+= rn5t618.o
>  obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
>  obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
> diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
> index 21c6484a951c..252030b9be4c 100644
> --- a/drivers/mfd/rk8xx-core.c
> +++ b/drivers/mfd/rk8xx-core.c
> @@ -37,6 +37,11 @@ static const struct resource rk805_key_resources[] = {
>  	DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
>  };
>  
> +static struct resource rk806_pwrkey_resources[] = {
> +	DEFINE_RES_IRQ(RK806_IRQ_PWRON_FALL),
> +	DEFINE_RES_IRQ(RK806_IRQ_PWRON_RISE),
> +};
> +
>  static const struct resource rk817_pwrkey_resources[] = {
>  	DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
>  	DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
> @@ -64,6 +69,17 @@ static const struct mfd_cell rk805s[] = {
>  	},
>  };
>  
> +static const struct mfd_cell rk806s[] = {
> +	{ .name = "rk805-pinctrl", .id = PLATFORM_DEVID_AUTO, },
> +	{ .name = "rk808-regulator", .id = PLATFORM_DEVID_AUTO, },
> +	{
> +		.name = "rk805-pwrkey",
> +		.resources = rk806_pwrkey_resources,
> +		.num_resources = ARRAY_SIZE(rk806_pwrkey_resources),
> +		.id = PLATFORM_DEVID_AUTO,
> +	},
> +};
> +
>  static const struct mfd_cell rk808s[] = {
>  	{ .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
>  	{ .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
> @@ -122,6 +138,12 @@ static const struct rk808_reg_data rk805_pre_init_reg[] = {
>  	{RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
>  };
>  
> +static const struct rk808_reg_data rk806_pre_init_reg[] = {
> +	{ RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
> +	{ RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
> +	{ RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
> +};
> +
>  static const struct rk808_reg_data rk808_pre_init_reg[] = {
>  	{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_150MA },
>  	{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_200MA },
> @@ -272,6 +294,27 @@ static const struct regmap_irq rk805_irqs[] = {
>  	},
>  };
>  
> +static const struct regmap_irq rk806_irqs[] = {
> +	/* INT_STS0 IRQs */
> +	REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),
> +	REGMAP_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE),
> +	REGMAP_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON),
> +	REGMAP_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP),
> +	REGMAP_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE),
> +	REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),
> +	REGMAP_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL),
> +	REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),
> +	/* INT_STS1 IRQs */
> +	REGMAP_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0),
> +	REGMAP_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1),
> +	REGMAP_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2),
> +	REGMAP_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR),
> +	REGMAP_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO),
> +	REGMAP_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO),
> +	REGMAP_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO),
> +	REGMAP_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT),
> +};
> +
>  static const struct regmap_irq rk808_irqs[] = {
>  	/* INT_STS */
>  	[RK808_IRQ_VOUT_LO] = {
> @@ -422,6 +465,18 @@ static struct regmap_irq_chip rk805_irq_chip = {
>  	.init_ack_masked = true,
>  };
>  
> +static struct regmap_irq_chip rk806_irq_chip = {
> +	.name = "rk806",
> +	.irqs = rk806_irqs,
> +	.num_irqs = ARRAY_SIZE(rk806_irqs),
> +	.num_regs = 2,
> +	.irq_reg_stride = 2,
> +	.mask_base = RK806_INT_MSK0,
> +	.status_base = RK806_INT_STS0,
> +	.ack_base = RK806_INT_STS0,
> +	.init_ack_masked = true,
> +};
> +
>  static const struct regmap_irq_chip rk808_irq_chip = {
>  	.name = "rk808",
>  	.irqs = rk808_irqs,
> @@ -548,6 +603,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
>  	struct rk808 *rk808;
>  	const struct rk808_reg_data *pre_init_reg;
>  	const struct mfd_cell *cells;
> +	int dual_support = 0;
>  	int nr_pre_init_regs;
>  	int nr_cells;
>  	int ret;
> @@ -569,6 +625,14 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
>  		cells = rk805s;
>  		nr_cells = ARRAY_SIZE(rk805s);
>  		break;
> +	case RK806_ID:
> +		rk808->regmap_irq_chip = &rk806_irq_chip;
> +		pre_init_reg = rk806_pre_init_reg;
> +		nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
> +		cells = rk806s;
> +		nr_cells = ARRAY_SIZE(rk806s);
> +		dual_support = IRQF_SHARED;
> +		break;
>  	case RK808_ID:
>  		rk808->regmap_irq_chip = &rk808_irq_chip;
>  		pre_init_reg = rk808_pre_init_reg;
> @@ -600,7 +664,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
>  		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
>  
>  	ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
> -				       IRQF_ONESHOT, -1,
> +				       IRQF_ONESHOT | dual_support, -1,
>  				       rk808->regmap_irq_chip, &rk808->irq_data);
>  	if (ret)
>  		return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
> @@ -615,8 +679,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
>  					     pre_init_reg[i].addr);
>  	}
>  
> -	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
> -			      cells, nr_cells, NULL, 0,
> +	ret = devm_mfd_add_devices(dev, 0, cells, nr_cells, NULL, 0,
>  			      regmap_irq_get_domain(rk808->irq_data));
>  	if (ret)
>  		return dev_err_probe(dev, ret, "failed to add MFD devices\n");
> diff --git a/drivers/mfd/rk8xx-spi.c b/drivers/mfd/rk8xx-spi.c
> new file mode 100644
> index 000000000000..3f6c5b1334f7
> --- /dev/null
> +++ b/drivers/mfd/rk8xx-spi.c
> @@ -0,0 +1,129 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Rockchip RK806 Core (SPI) driver
> + *
> + * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
> + * Copyright (c) 2023 Collabora Ltd.
> + *
> + * Author: Xu Shengfei <xsf@rock-chips.com>
> + * Author: Sebastian Reichel <sebastian.reichel@collabora.com>
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/rk808.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <linux/spi/spi.h>
> +
> +#define RK806_CMD		0
> +#define RK806_REG_ADDR_L	1
> +#define RK806_REG_ADDR_H	2
> +#define RK806_CMD_WITH_SIZE(CMD, VALUE_BYTES) \
> +	(RK806_CMD_ ## CMD | (VALUE_BYTES-1))

Nit: Spaces around the '-' please.

Spaces around the ## look odd to me too.

> +static const struct regmap_range rk80g6_volatile_ranges[] = {
> +	regmap_reg_range(RK806_POWER_EN0, RK806_POWER_EN5),
> +	regmap_reg_range(RK806_DVS_START_CTRL, RK806_INT_MSK1),
> +};
> +
> +static const struct regmap_access_table rk806_volatile_table = {
> +	.yes_ranges = rk806_volatile_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(rk806_volatile_ranges),
> +};
> +
> +static const struct regmap_config rk806_regmap_config_spi = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.cache_type = REGCACHE_RBTREE,
> +	.volatile_table = &rk806_volatile_table,
> +};
> +
> +static int rk806_spi_bus_write(void *context, const void *vdata, size_t count)
> +{
> +	struct device *dev = context;
> +	struct spi_device *spi = to_spi_device(dev);
> +	const char *data = vdata;
> +	char buffer[3] = { 0 };
> +	struct spi_transfer xfer[2] = { 0 };
> +	/* count includes the register size */
> +	size_t val_size = count - 1;
> +
> +	if (val_size < 1 || val_size > 128)
> +		return -EINVAL;
> +
> +	buffer[RK806_CMD]	 = RK806_CMD_WITH_SIZE(WRITE, val_size);
> +	buffer[RK806_REG_ADDR_L] = data[0];
> +	buffer[RK806_REG_ADDR_H] = RK806_REG_H;
> +
> +	xfer[0].tx_buf = buffer;
> +	xfer[0].len = sizeof(buffer);
> +	xfer[1].tx_buf = data + 1;

Why, what's at [0]?  Clearer with a define?

> +	xfer[1].len = count - 1;

Isn't this val_size?

> +	return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
> +}
> +
> +static int rk806_spi_bus_read(void *context, const void *vreg, size_t reg_size,
> +			      void *val, size_t val_size)
> +{
> +	struct device *dev = context;
> +	struct spi_device *spi = to_spi_device(dev);
> +	const char *reg = vreg;
> +	char txbuf[3] = { 0 };
> +
> +	if (reg_size != sizeof(char) || val_size < 1 || val_size > 128)

#define MAX_BUFFER_SIZE 128?

> +		return -EINVAL;
> +
> +	txbuf[RK806_CMD]	= RK806_CMD_WITH_SIZE(READ, val_size);
> +	txbuf[RK806_REG_ADDR_L]	= *reg;
> +	txbuf[RK806_REG_ADDR_H]	= RK806_REG_H;
> +
> +	return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size);
> +}
> +
> +static const struct regmap_bus rk806_regmap_bus_spi = {
> +	.write = rk806_spi_bus_write,
> +	.read = rk806_spi_bus_read,
> +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +};
> +
> +static int rk8xx_spi_probe(struct spi_device *spi)
> +{
> +	struct regmap *regmap;
> +
> +	regmap = devm_regmap_init(&spi->dev, &rk806_regmap_bus_spi,
> +				  &spi->dev, &rk806_regmap_config_spi);
> +	if (IS_ERR(regmap))
> +		return dev_err_probe(&spi->dev, PTR_ERR(regmap),
> +				     "Failed to initialize register map\n");

It's more widely known as regmap.

> +	return rk8xx_probe(&spi->dev, RK806_ID, spi->irq, regmap);
> +}
> +
> +static const struct of_device_id rk8xx_spi_of_match[] = {
> +	{ .compatible = "rockchip,rk806", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, rk8xx_spi_of_match);
> +
> +static const struct spi_device_id rk8xx_spi_id_table[] = {
> +	{ "rk806", 0 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(spi, rk8xx_spi_id_table);
> +
> +static struct spi_driver rk8xx_spi_driver = {
> +	.driver		= {
> +		.name	= "rk8xx-spi",
> +		.of_match_table = rk8xx_spi_of_match,
> +	},
> +	.probe		= rk8xx_spi_probe,
> +	.id_table	= rk8xx_spi_id_table,
> +};
> +module_spi_driver(rk8xx_spi_driver);
> +
> +MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
> +MODULE_DESCRIPTION("RK8xx SPI PMIC driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
> index 4183427a80fe..78e167a92483 100644
> --- a/include/linux/mfd/rk808.h
> +++ b/include/linux/mfd/rk808.h
> @@ -289,6 +289,414 @@ enum rk805_reg {
>  #define RK805_INT_ALARM_EN		(1 << 3)
>  #define RK805_INT_TIMER_EN		(1 << 2)
>  
> +/* RK806 */
> +#define RK806_POWER_EN0			0x0
> +#define RK806_POWER_EN1			0x1
> +#define RK806_POWER_EN2			0x2
> +#define RK806_POWER_EN3			0x3
> +#define RK806_POWER_EN4			0x4
> +#define RK806_POWER_EN5			0x5
> +#define RK806_POWER_SLP_EN0		0x6
> +#define RK806_POWER_SLP_EN1		0x7
> +#define RK806_POWER_SLP_EN2		0x8
> +#define RK806_POWER_DISCHRG_EN0		0x9
> +#define RK806_POWER_DISCHRG_EN1		0xA
> +#define RK806_POWER_DISCHRG_EN2		0xB
> +#define RK806_BUCK_FB_CONFIG		0xC
> +#define RK806_SLP_LP_CONFIG		0xD
> +#define RK806_POWER_FPWM_EN0		0xE
> +#define RK806_POWER_FPWM_EN1		0xF
> +#define RK806_BUCK1_CONFIG		0x10
> +#define RK806_BUCK2_CONFIG		0x11
> +#define RK806_BUCK3_CONFIG		0x12
> +#define RK806_BUCK4_CONFIG		0x13
> +#define RK806_BUCK5_CONFIG		0x14
> +#define RK806_BUCK6_CONFIG		0x15
> +#define RK806_BUCK7_CONFIG		0x16
> +#define RK806_BUCK8_CONFIG		0x17
> +#define RK806_BUCK9_CONFIG		0x18
> +#define RK806_BUCK10_CONFIG		0x19
> +#define RK806_BUCK1_ON_VSEL		0x1A
> +#define RK806_BUCK2_ON_VSEL		0x1B
> +#define RK806_BUCK3_ON_VSEL		0x1C
> +#define RK806_BUCK4_ON_VSEL		0x1D
> +#define RK806_BUCK5_ON_VSEL		0x1E
> +#define RK806_BUCK6_ON_VSEL		0x1F
> +#define RK806_BUCK7_ON_VSEL		0x20
> +#define RK806_BUCK8_ON_VSEL		0x21
> +#define RK806_BUCK9_ON_VSEL		0x22
> +#define RK806_BUCK10_ON_VSEL		0x23
> +#define RK806_BUCK1_SLP_VSEL		0x24
> +#define RK806_BUCK2_SLP_VSEL		0x25
> +#define RK806_BUCK3_SLP_VSEL		0x26
> +#define RK806_BUCK4_SLP_VSEL		0x27
> +#define RK806_BUCK5_SLP_VSEL		0x28
> +#define RK806_BUCK6_SLP_VSEL		0x29
> +#define RK806_BUCK7_SLP_VSEL		0x2A
> +#define RK806_BUCK8_SLP_VSEL		0x2B
> +#define RK806_BUCK9_SLP_VSEL		0x2D
> +#define RK806_BUCK10_SLP_VSEL		0x2E
> +#define RK806_BUCK_DEBUG1		0x30
> +#define RK806_BUCK_DEBUG2		0x31
> +#define RK806_BUCK_DEBUG3		0x32
> +#define RK806_BUCK_DEBUG4		0x33
> +#define RK806_BUCK_DEBUG5		0x34
> +#define RK806_BUCK_DEBUG6		0x35
> +#define RK806_BUCK_DEBUG7		0x36
> +#define RK806_BUCK_DEBUG8		0x37
> +#define RK806_BUCK_DEBUG9		0x38
> +#define RK806_BUCK_DEBUG10		0x39
> +#define RK806_BUCK_DEBUG11		0x3A
> +#define RK806_BUCK_DEBUG12		0x3B
> +#define RK806_BUCK_DEBUG13		0x3C
> +#define RK806_BUCK_DEBUG14		0x3D
> +#define RK806_BUCK_DEBUG15		0x3E
> +#define RK806_BUCK_DEBUG16		0x3F
> +#define RK806_BUCK_DEBUG17		0x40
> +#define RK806_BUCK_DEBUG18		0x41
> +#define RK806_NLDO_IMAX			0x42
> +#define RK806_NLDO1_ON_VSEL		0x43
> +#define RK806_NLDO2_ON_VSEL		0x44
> +#define RK806_NLDO3_ON_VSEL		0x45
> +#define RK806_NLDO4_ON_VSEL		0x46
> +#define RK806_NLDO5_ON_VSEL		0x47
> +#define RK806_NLDO1_SLP_VSEL		0x48
> +#define RK806_NLDO2_SLP_VSEL		0x49
> +#define RK806_NLDO3_SLP_VSEL		0x4A
> +#define RK806_NLDO4_SLP_VSEL		0x4B
> +#define RK806_NLDO5_SLP_VSEL		0x4C
> +#define RK806_PLDO_IMAX			0x4D
> +#define RK806_PLDO1_ON_VSEL		0x4E
> +#define RK806_PLDO2_ON_VSEL		0x4F
> +#define RK806_PLDO3_ON_VSEL		0x50
> +#define RK806_PLDO4_ON_VSEL		0x51
> +#define RK806_PLDO5_ON_VSEL		0x52
> +#define RK806_PLDO6_ON_VSEL		0x53
> +#define RK806_PLDO1_SLP_VSEL		0x54
> +#define RK806_PLDO2_SLP_VSEL		0x55
> +#define RK806_PLDO3_SLP_VSEL		0x56
> +#define RK806_PLDO4_SLP_VSEL		0x57
> +#define RK806_PLDO5_SLP_VSEL		0x58
> +#define RK806_PLDO6_SLP_VSEL		0x59
> +#define RK806_CHIP_NAME			0x5A
> +#define RK806_CHIP_VER			0x5B
> +#define RK806_OTP_VER			0x5C
> +#define RK806_SYS_STS			0x5D
> +#define RK806_SYS_CFG0			0x5E
> +#define RK806_SYS_CFG1			0x5F
> +#define RK806_SYS_OPTION		0x61
> +#define RK806_SLEEP_CONFIG0		0x62
> +#define RK806_SLEEP_CONFIG1		0x63
> +#define RK806_SLEEP_CTR_SEL0		0x64
> +#define RK806_SLEEP_CTR_SEL1		0x65
> +#define RK806_SLEEP_CTR_SEL2		0x66
> +#define RK806_SLEEP_CTR_SEL3		0x67
> +#define RK806_SLEEP_CTR_SEL4		0x68
> +#define RK806_SLEEP_CTR_SEL5		0x69
> +#define RK806_DVS_CTRL_SEL0		0x6A
> +#define RK806_DVS_CTRL_SEL1		0x6B
> +#define RK806_DVS_CTRL_SEL2		0x6C
> +#define RK806_DVS_CTRL_SEL3		0x6D
> +#define RK806_DVS_CTRL_SEL4		0x6E
> +#define RK806_DVS_CTRL_SEL5		0x6F
> +#define RK806_DVS_START_CTRL		0x70
> +#define RK806_SLEEP_GPIO		0x71
> +#define RK806_SYS_CFG3			0x72
> +#define RK806_ON_SOURCE			0x74
> +#define RK806_OFF_SOURCE		0x75
> +#define RK806_PWRON_KEY			0x76
> +#define RK806_INT_STS0			0x77
> +#define RK806_INT_MSK0			0x78
> +#define RK806_INT_STS1			0x79
> +#define RK806_INT_MSK1			0x7A
> +#define RK806_GPIO_INT_CONFIG		0x7B
> +#define RK806_DATA_REG0			0x7C
> +#define RK806_DATA_REG1			0x7D
> +#define RK806_DATA_REG2			0x7E
> +#define RK806_DATA_REG3			0x7F
> +#define RK806_DATA_REG4			0x80
> +#define RK806_DATA_REG5			0x81
> +#define RK806_DATA_REG6			0x82
> +#define RK806_DATA_REG7			0x83
> +#define RK806_DATA_REG8			0x84
> +#define RK806_DATA_REG9			0x85
> +#define RK806_DATA_REG10		0x86
> +#define RK806_DATA_REG11		0x87
> +#define RK806_DATA_REG12		0x88
> +#define RK806_DATA_REG13		0x89
> +#define RK806_DATA_REG14		0x8A
> +#define RK806_DATA_REG15		0x8B
> +#define RK806_TM_REG			0x8C
> +#define RK806_OTP_EN_REG		0x8D
> +#define RK806_FUNC_OTP_EN_REG		0x8E
> +#define RK806_TEST_REG1			0x8F
> +#define RK806_TEST_REG2			0x90
> +#define RK806_TEST_REG3			0x91
> +#define RK806_TEST_REG4			0x92
> +#define RK806_TEST_REG5			0x93
> +#define RK806_BUCK_VSEL_OTP_REG0	0x94
> +#define RK806_BUCK_VSEL_OTP_REG1	0x95
> +#define RK806_BUCK_VSEL_OTP_REG2	0x96
> +#define RK806_BUCK_VSEL_OTP_REG3	0x97
> +#define RK806_BUCK_VSEL_OTP_REG4	0x98
> +#define RK806_BUCK_VSEL_OTP_REG5	0x99
> +#define RK806_BUCK_VSEL_OTP_REG6	0x9A
> +#define RK806_BUCK_VSEL_OTP_REG7	0x9B
> +#define RK806_BUCK_VSEL_OTP_REG8	0x9C
> +#define RK806_BUCK_VSEL_OTP_REG9	0x9D
> +#define RK806_NLDO1_VSEL_OTP_REG0	0x9E
> +#define RK806_NLDO1_VSEL_OTP_REG1	0x9F
> +#define RK806_NLDO1_VSEL_OTP_REG2	0xA0
> +#define RK806_NLDO1_VSEL_OTP_REG3	0xA1
> +#define RK806_NLDO1_VSEL_OTP_REG4	0xA2
> +#define RK806_PLDO_VSEL_OTP_REG0	0xA3
> +#define RK806_PLDO_VSEL_OTP_REG1	0xA4
> +#define RK806_PLDO_VSEL_OTP_REG2	0xA5
> +#define RK806_PLDO_VSEL_OTP_REG3	0xA6
> +#define RK806_PLDO_VSEL_OTP_REG4	0xA7
> +#define RK806_PLDO_VSEL_OTP_REG5	0xA8
> +#define RK806_BUCK_EN_OTP_REG1		0xA9
> +#define RK806_NLDO_EN_OTP_REG1		0xAA
> +#define RK806_PLDO_EN_OTP_REG1		0xAB
> +#define RK806_BUCK_FB_RES_OTP_REG1	0xAC
> +#define RK806_OTP_RESEV_REG0		0xAD
> +#define RK806_OTP_RESEV_REG1		0xAE
> +#define RK806_OTP_RESEV_REG2		0xAF
> +#define RK806_OTP_RESEV_REG3		0xB0
> +#define RK806_OTP_RESEV_REG4		0xB1
> +#define RK806_BUCK_SEQ_REG0		0xB2
> +#define RK806_BUCK_SEQ_REG1		0xB3
> +#define RK806_BUCK_SEQ_REG2		0xB4
> +#define RK806_BUCK_SEQ_REG3		0xB5
> +#define RK806_BUCK_SEQ_REG4		0xB6
> +#define RK806_BUCK_SEQ_REG5		0xB7
> +#define RK806_BUCK_SEQ_REG6		0xB8
> +#define RK806_BUCK_SEQ_REG7		0xB9
> +#define RK806_BUCK_SEQ_REG8		0xBA
> +#define RK806_BUCK_SEQ_REG9		0xBB
> +#define RK806_BUCK_SEQ_REG10		0xBC
> +#define RK806_BUCK_SEQ_REG11		0xBD
> +#define RK806_BUCK_SEQ_REG12		0xBE
> +#define RK806_BUCK_SEQ_REG13		0xBF
> +#define RK806_BUCK_SEQ_REG14		0xC0
> +#define RK806_BUCK_SEQ_REG15		0xC1
> +#define RK806_BUCK_SEQ_REG16		0xC2
> +#define RK806_BUCK_SEQ_REG17		0xC3
> +#define RK806_HK_TRIM_REG1		0xC4
> +#define RK806_HK_TRIM_REG2		0xC5
> +#define RK806_BUCK_REF_TRIM_REG1	0xC6
> +#define RK806_BUCK_REF_TRIM_REG2	0xC7
> +#define RK806_BUCK_REF_TRIM_REG3	0xC8
> +#define RK806_BUCK_REF_TRIM_REG4	0xC9
> +#define RK806_BUCK_REF_TRIM_REG5	0xCA
> +#define RK806_BUCK_OSC_TRIM_REG1	0xCB
> +#define RK806_BUCK_OSC_TRIM_REG2	0xCC
> +#define RK806_BUCK_OSC_TRIM_REG3	0xCD
> +#define RK806_BUCK_OSC_TRIM_REG4	0xCE
> +#define RK806_BUCK_OSC_TRIM_REG5	0xCF
> +#define RK806_BUCK_TRIM_ZCDIOS_REG1	0xD0
> +#define RK806_BUCK_TRIM_ZCDIOS_REG2	0xD1
> +#define RK806_NLDO_TRIM_REG1		0xD2
> +#define RK806_NLDO_TRIM_REG2		0xD3
> +#define RK806_NLDO_TRIM_REG3		0xD4
> +#define RK806_PLDO_TRIM_REG1		0xD5
> +#define RK806_PLDO_TRIM_REG2		0xD6
> +#define RK806_PLDO_TRIM_REG3		0xD7
> +#define RK806_TRIM_ICOMP_REG1		0xD8
> +#define RK806_TRIM_ICOMP_REG2		0xD9
> +#define RK806_EFUSE_CONTROL_REGH	0xDA
> +#define RK806_FUSE_PROG_REG		0xDB
> +#define RK806_MAIN_FSM_STS_REG		0xDD
> +#define RK806_FSM_REG			0xDE
> +#define RK806_TOP_RESEV_OFFR		0xEC
> +#define RK806_TOP_RESEV_POR		0xED
> +#define RK806_BUCK_VRSN_REG1		0xEE
> +#define RK806_BUCK_VRSN_REG2		0xEF
> +#define RK806_NLDO_RLOAD_SEL_REG1	0xF0
> +#define RK806_PLDO_RLOAD_SEL_REG1	0xF1
> +#define RK806_PLDO_RLOAD_SEL_REG2	0xF2
> +#define RK806_BUCK_CMIN_MX_REG1		0xF3
> +#define RK806_BUCK_CMIN_MX_REG2		0xF4
> +#define RK806_BUCK_FREQ_SET_REG1	0xF5
> +#define RK806_BUCK_FREQ_SET_REG2	0xF6
> +#define RK806_BUCK_RS_MEABS_REG1	0xF7
> +#define RK806_BUCK_RS_MEABS_REG2	0xF8
> +#define RK806_BUCK_RS_ZDLEB_REG1	0xF9
> +#define RK806_BUCK_RS_ZDLEB_REG2	0xFA
> +#define RK806_BUCK_RSERVE_REG1		0xFB
> +#define RK806_BUCK_RSERVE_REG2		0xFC
> +#define RK806_BUCK_RSERVE_REG3		0xFD
> +#define RK806_BUCK_RSERVE_REG4		0xFE
> +#define RK806_BUCK_RSERVE_REG5		0xFF
> +
> +/* INT_STS Register field definitions */
> +#define RK806_INT_STS_PWRON_FALL	BIT(0)
> +#define RK806_INT_STS_PWRON_RISE	BIT(1)
> +#define RK806_INT_STS_PWRON		BIT(2)
> +#define RK806_INT_STS_PWRON_LP		BIT(3)
> +#define RK806_INT_STS_HOTDIE		BIT(4)
> +#define RK806_INT_STS_VDC_RISE		BIT(5)
> +#define RK806_INT_STS_VDC_FALL		BIT(6)
> +#define RK806_INT_STS_VB_LO		BIT(7)
> +#define RK806_INT_STS_REV0		BIT(0)
> +#define RK806_INT_STS_REV1		BIT(1)
> +#define RK806_INT_STS_REV2		BIT(2)
> +#define RK806_INT_STS_CRC_ERROR		BIT(3)
> +#define RK806_INT_STS_SLP3_GPIO		BIT(4)
> +#define RK806_INT_STS_SLP2_GPIO		BIT(5)
> +#define RK806_INT_STS_SLP1_GPIO		BIT(6)
> +#define RK806_INT_STS_WDT		BIT(7)
> +
> +/* SPI command */
> +#define RK806_CMD_READ			0
> +#define RK806_CMD_WRITE			BIT(7)
> +#define RK806_CMD_CRC_EN		BIT(6)
> +#define RK806_CMD_CRC_DIS		0
> +#define RK806_CMD_LEN_MSK		0x0f
> +#define RK806_REG_H			0x00
> +
> +#define VERSION_AB		0x01
> +
> +enum rk806_reg_id {
> +	RK806_ID_DCDC1 = 0,
> +	RK806_ID_DCDC2,
> +	RK806_ID_DCDC3,
> +	RK806_ID_DCDC4,
> +	RK806_ID_DCDC5,
> +	RK806_ID_DCDC6,
> +	RK806_ID_DCDC7,
> +	RK806_ID_DCDC8,
> +	RK806_ID_DCDC9,
> +	RK806_ID_DCDC10,
> +
> +	RK806_ID_NLDO1,
> +	RK806_ID_NLDO2,
> +	RK806_ID_NLDO3,
> +	RK806_ID_NLDO4,
> +	RK806_ID_NLDO5,
> +
> +	RK806_ID_PLDO1,
> +	RK806_ID_PLDO2,
> +	RK806_ID_PLDO3,
> +	RK806_ID_PLDO4,
> +	RK806_ID_PLDO5,
> +	RK806_ID_PLDO6,
> +	RK806_ID_END,
> +};
> +
> +/* Define the RK806 IRQ numbers */
> +enum rk806_irqs {
> +	/* INT_STS0 registers */
> +	RK806_IRQ_PWRON_FALL,
> +	RK806_IRQ_PWRON_RISE,
> +	RK806_IRQ_PWRON,
> +	RK806_IRQ_PWRON_LP,
> +	RK806_IRQ_HOTDIE,
> +	RK806_IRQ_VDC_RISE,
> +	RK806_IRQ_VDC_FALL,
> +	RK806_IRQ_VB_LO,
> +
> +	/* INT_STS0 registers */
> +	RK806_IRQ_REV0,
> +	RK806_IRQ_REV1,
> +	RK806_IRQ_REV2,
> +	RK806_IRQ_CRC_ERROR,
> +	RK806_IRQ_SLP3_GPIO,
> +	RK806_IRQ_SLP2_GPIO,
> +	RK806_IRQ_SLP1_GPIO,
> +	RK806_IRQ_WDT,
> +};
> +
> +/* VCC1 Low Voltage Threshold */
> +enum rk806_lv_sel {
> +	VB_LO_SEL_2800,
> +	VB_LO_SEL_2900,
> +	VB_LO_SEL_3000,
> +	VB_LO_SEL_3100,
> +	VB_LO_SEL_3200,
> +	VB_LO_SEL_3300,
> +	VB_LO_SEL_3400,
> +	VB_LO_SEL_3500,
> +};
> +
> +/* System Shutdown Voltage Select */
> +enum rk806_uv_sel {
> +	VB_UV_SEL_2700,
> +	VB_UV_SEL_2800,
> +	VB_UV_SEL_2900,
> +	VB_UV_SEL_3000,
> +	VB_UV_SEL_3100,
> +	VB_UV_SEL_3200,
> +	VB_UV_SEL_3300,
> +	VB_UV_SEL_3400,
> +};
> +
> +/* Pin Function */
> +enum rk806_pwrctrl_fun {
> +	PWRCTRL_NULL_FUN,
> +	PWRCTRL_SLP_FUN,
> +	PWRCTRL_POWOFF_FUN,
> +	PWRCTRL_RST_FUN,
> +	PWRCTRL_DVS_FUN,
> +	PWRCTRL_GPIO_FUN,
> +};
> +
> +/* Pin Polarity */
> +enum rk806_pin_level {
> +	POL_LOW,
> +	POL_HIGH,
> +};
> +
> +enum rk806_vsel_ctr_sel {
> +	CTR_BY_NO_EFFECT,
> +	CTR_BY_PWRCTRL1,
> +	CTR_BY_PWRCTRL2,
> +	CTR_BY_PWRCTRL3,
> +};
> +
> +enum rk806_dvs_ctr_sel {
> +	CTR_SEL_NO_EFFECT,
> +	CTR_SEL_DVS_START1,
> +	CTR_SEL_DVS_START2,
> +	CTR_SEL_DVS_START3,
> +};
> +
> +enum rk806_pin_dr_sel {
> +	RK806_PIN_INPUT,
> +	RK806_PIN_OUTPUT,
> +};
> +
> +#define RK806_INT_POL_MSK		BIT(1)
> +#define RK806_INT_POL_H			BIT(1)
> +#define RK806_INT_POL_L			0
> +
> +#define RK806_SLAVE_RESTART_FUN_MSK	BIT(1)
> +#define RK806_SLAVE_RESTART_FUN_EN	BIT(1)
> +#define RK806_SLAVE_RESTART_FUN_OFF	0
> +
> +#define RK806_SYS_ENB2_2M_MSK		BIT(1)
> +#define RK806_SYS_ENB2_2M_EN		BIT(1)
> +#define RK806_SYS_ENB2_2M_OFF		0
> +
> +enum rk806_int_fun {
> +	RK806_INT_ONLY,
> +	RK806_INT_ADN_WKUP,
> +};
> +
> +enum rk806_dvs_mode {
> +	RK806_DVS_NOT_SUPPORT,
> +	RK806_DVS_START1,
> +	RK806_DVS_START2,
> +	RK806_DVS_START3,
> +	RK806_DVS_PWRCTRL1,
> +	RK806_DVS_PWRCTRL2,
> +	RK806_DVS_PWRCTRL3,
> +	RK806_DVS_START_PWRCTR1,
> +	RK806_DVS_START_PWRCTR2,
> +	RK806_DVS_START_PWRCTR3,
> +	RK806_DVS_END,
> +};
> +
>  /* RK808 IRQ Definitions */
>  #define RK808_IRQ_VOUT_LO	0
>  #define RK808_IRQ_VB_LO		1
> @@ -780,6 +1188,7 @@ enum {
>  
>  enum {
>  	RK805_ID = 0x8050,
> +	RK806_ID = 0x8060,
>  	RK808_ID = 0x0000,
>  	RK809_ID = 0x8090,
>  	RK817_ID = 0x8170,
> -- 
> 2.39.0
> 

-- 
Lee Jones [李琼斯]

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

* Re: [PATCHv6 08/11] mfd: rk8xx: add rk806 support
@ 2023-03-02 17:52     ` Lee Jones
  0 siblings, 0 replies; 48+ messages in thread
From: Lee Jones @ 2023-03-02 17:52 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
	Michael Turquette, Stephen Boyd, Linus Walleij, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel

On Fri, 27 Jan 2023, Sebastian Reichel wrote:

> Add support for SPI connected rk806, which is used by the RK3588
> evaluation boards. The PMIC is advertised to support I2C and SPI,
> but the evaluation boards all use SPI. Thus only SPI support is
> added here.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> ---
>  drivers/mfd/Kconfig       |  14 ++
>  drivers/mfd/Makefile      |   1 +
>  drivers/mfd/rk8xx-core.c  |  69 ++++++-
>  drivers/mfd/rk8xx-spi.c   | 129 ++++++++++++
>  include/linux/mfd/rk808.h | 409 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 619 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/mfd/rk8xx-spi.c

Few nits, nothing bad ...

> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 692e38283bda..13582ea5cb44 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1222,6 +1222,20 @@ config MFD_RK8XX_I2C
>  	  through I2C interface. The device supports multiple sub-devices
>  	  including interrupts, RTC, LDO & DCDC regulators, and onkey.
>  
> +config MFD_RK8XX_SPI
> +	tristate "Rockchip RK806 Power Management Chip"
> +	depends on SPI && OF
> +	select MFD_CORE
> +	select REGMAP_SPI
> +	select REGMAP_IRQ
> +	select MFD_RK8XX
> +	help
> +	  If you say yes here you get support for the RK806 Power Management
> +	  chip.
> +	  This driver provides common support for accessing the device
> +	  through an SPI interface. The device supports multiple sub-devices
> +	  including interrupts, LDO & DCDC regulators, and power on-key.
> +
>  config MFD_RN5T618
>  	tristate "Ricoh RN5T567/618 PMIC"
>  	depends on I2C
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index f65ef1bd0810..a88f27cd837b 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -222,6 +222,7 @@ obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
>  obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
>  obj-$(CONFIG_MFD_RK8XX)		+= rk8xx-core.o
>  obj-$(CONFIG_MFD_RK8XX_I2C)	+= rk8xx-i2c.o
> +obj-$(CONFIG_MFD_RK8XX_SPI)	+= rk8xx-spi.o
>  obj-$(CONFIG_MFD_RN5T618)	+= rn5t618.o
>  obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
>  obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
> diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
> index 21c6484a951c..252030b9be4c 100644
> --- a/drivers/mfd/rk8xx-core.c
> +++ b/drivers/mfd/rk8xx-core.c
> @@ -37,6 +37,11 @@ static const struct resource rk805_key_resources[] = {
>  	DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
>  };
>  
> +static struct resource rk806_pwrkey_resources[] = {
> +	DEFINE_RES_IRQ(RK806_IRQ_PWRON_FALL),
> +	DEFINE_RES_IRQ(RK806_IRQ_PWRON_RISE),
> +};
> +
>  static const struct resource rk817_pwrkey_resources[] = {
>  	DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
>  	DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
> @@ -64,6 +69,17 @@ static const struct mfd_cell rk805s[] = {
>  	},
>  };
>  
> +static const struct mfd_cell rk806s[] = {
> +	{ .name = "rk805-pinctrl", .id = PLATFORM_DEVID_AUTO, },
> +	{ .name = "rk808-regulator", .id = PLATFORM_DEVID_AUTO, },
> +	{
> +		.name = "rk805-pwrkey",
> +		.resources = rk806_pwrkey_resources,
> +		.num_resources = ARRAY_SIZE(rk806_pwrkey_resources),
> +		.id = PLATFORM_DEVID_AUTO,
> +	},
> +};
> +
>  static const struct mfd_cell rk808s[] = {
>  	{ .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
>  	{ .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
> @@ -122,6 +138,12 @@ static const struct rk808_reg_data rk805_pre_init_reg[] = {
>  	{RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
>  };
>  
> +static const struct rk808_reg_data rk806_pre_init_reg[] = {
> +	{ RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
> +	{ RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
> +	{ RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
> +};
> +
>  static const struct rk808_reg_data rk808_pre_init_reg[] = {
>  	{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_150MA },
>  	{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_200MA },
> @@ -272,6 +294,27 @@ static const struct regmap_irq rk805_irqs[] = {
>  	},
>  };
>  
> +static const struct regmap_irq rk806_irqs[] = {
> +	/* INT_STS0 IRQs */
> +	REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),
> +	REGMAP_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE),
> +	REGMAP_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON),
> +	REGMAP_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP),
> +	REGMAP_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE),
> +	REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),
> +	REGMAP_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL),
> +	REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),
> +	/* INT_STS1 IRQs */
> +	REGMAP_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0),
> +	REGMAP_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1),
> +	REGMAP_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2),
> +	REGMAP_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR),
> +	REGMAP_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO),
> +	REGMAP_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO),
> +	REGMAP_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO),
> +	REGMAP_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT),
> +};
> +
>  static const struct regmap_irq rk808_irqs[] = {
>  	/* INT_STS */
>  	[RK808_IRQ_VOUT_LO] = {
> @@ -422,6 +465,18 @@ static struct regmap_irq_chip rk805_irq_chip = {
>  	.init_ack_masked = true,
>  };
>  
> +static struct regmap_irq_chip rk806_irq_chip = {
> +	.name = "rk806",
> +	.irqs = rk806_irqs,
> +	.num_irqs = ARRAY_SIZE(rk806_irqs),
> +	.num_regs = 2,
> +	.irq_reg_stride = 2,
> +	.mask_base = RK806_INT_MSK0,
> +	.status_base = RK806_INT_STS0,
> +	.ack_base = RK806_INT_STS0,
> +	.init_ack_masked = true,
> +};
> +
>  static const struct regmap_irq_chip rk808_irq_chip = {
>  	.name = "rk808",
>  	.irqs = rk808_irqs,
> @@ -548,6 +603,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
>  	struct rk808 *rk808;
>  	const struct rk808_reg_data *pre_init_reg;
>  	const struct mfd_cell *cells;
> +	int dual_support = 0;
>  	int nr_pre_init_regs;
>  	int nr_cells;
>  	int ret;
> @@ -569,6 +625,14 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
>  		cells = rk805s;
>  		nr_cells = ARRAY_SIZE(rk805s);
>  		break;
> +	case RK806_ID:
> +		rk808->regmap_irq_chip = &rk806_irq_chip;
> +		pre_init_reg = rk806_pre_init_reg;
> +		nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
> +		cells = rk806s;
> +		nr_cells = ARRAY_SIZE(rk806s);
> +		dual_support = IRQF_SHARED;
> +		break;
>  	case RK808_ID:
>  		rk808->regmap_irq_chip = &rk808_irq_chip;
>  		pre_init_reg = rk808_pre_init_reg;
> @@ -600,7 +664,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
>  		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
>  
>  	ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
> -				       IRQF_ONESHOT, -1,
> +				       IRQF_ONESHOT | dual_support, -1,
>  				       rk808->regmap_irq_chip, &rk808->irq_data);
>  	if (ret)
>  		return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
> @@ -615,8 +679,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
>  					     pre_init_reg[i].addr);
>  	}
>  
> -	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
> -			      cells, nr_cells, NULL, 0,
> +	ret = devm_mfd_add_devices(dev, 0, cells, nr_cells, NULL, 0,
>  			      regmap_irq_get_domain(rk808->irq_data));
>  	if (ret)
>  		return dev_err_probe(dev, ret, "failed to add MFD devices\n");
> diff --git a/drivers/mfd/rk8xx-spi.c b/drivers/mfd/rk8xx-spi.c
> new file mode 100644
> index 000000000000..3f6c5b1334f7
> --- /dev/null
> +++ b/drivers/mfd/rk8xx-spi.c
> @@ -0,0 +1,129 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Rockchip RK806 Core (SPI) driver
> + *
> + * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
> + * Copyright (c) 2023 Collabora Ltd.
> + *
> + * Author: Xu Shengfei <xsf@rock-chips.com>
> + * Author: Sebastian Reichel <sebastian.reichel@collabora.com>
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/rk808.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <linux/spi/spi.h>
> +
> +#define RK806_CMD		0
> +#define RK806_REG_ADDR_L	1
> +#define RK806_REG_ADDR_H	2
> +#define RK806_CMD_WITH_SIZE(CMD, VALUE_BYTES) \
> +	(RK806_CMD_ ## CMD | (VALUE_BYTES-1))

Nit: Spaces around the '-' please.

Spaces around the ## look odd to me too.

> +static const struct regmap_range rk80g6_volatile_ranges[] = {
> +	regmap_reg_range(RK806_POWER_EN0, RK806_POWER_EN5),
> +	regmap_reg_range(RK806_DVS_START_CTRL, RK806_INT_MSK1),
> +};
> +
> +static const struct regmap_access_table rk806_volatile_table = {
> +	.yes_ranges = rk806_volatile_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(rk806_volatile_ranges),
> +};
> +
> +static const struct regmap_config rk806_regmap_config_spi = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.cache_type = REGCACHE_RBTREE,
> +	.volatile_table = &rk806_volatile_table,
> +};
> +
> +static int rk806_spi_bus_write(void *context, const void *vdata, size_t count)
> +{
> +	struct device *dev = context;
> +	struct spi_device *spi = to_spi_device(dev);
> +	const char *data = vdata;
> +	char buffer[3] = { 0 };
> +	struct spi_transfer xfer[2] = { 0 };
> +	/* count includes the register size */
> +	size_t val_size = count - 1;
> +
> +	if (val_size < 1 || val_size > 128)
> +		return -EINVAL;
> +
> +	buffer[RK806_CMD]	 = RK806_CMD_WITH_SIZE(WRITE, val_size);
> +	buffer[RK806_REG_ADDR_L] = data[0];
> +	buffer[RK806_REG_ADDR_H] = RK806_REG_H;
> +
> +	xfer[0].tx_buf = buffer;
> +	xfer[0].len = sizeof(buffer);
> +	xfer[1].tx_buf = data + 1;

Why, what's at [0]?  Clearer with a define?

> +	xfer[1].len = count - 1;

Isn't this val_size?

> +	return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
> +}
> +
> +static int rk806_spi_bus_read(void *context, const void *vreg, size_t reg_size,
> +			      void *val, size_t val_size)
> +{
> +	struct device *dev = context;
> +	struct spi_device *spi = to_spi_device(dev);
> +	const char *reg = vreg;
> +	char txbuf[3] = { 0 };
> +
> +	if (reg_size != sizeof(char) || val_size < 1 || val_size > 128)

#define MAX_BUFFER_SIZE 128?

> +		return -EINVAL;
> +
> +	txbuf[RK806_CMD]	= RK806_CMD_WITH_SIZE(READ, val_size);
> +	txbuf[RK806_REG_ADDR_L]	= *reg;
> +	txbuf[RK806_REG_ADDR_H]	= RK806_REG_H;
> +
> +	return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size);
> +}
> +
> +static const struct regmap_bus rk806_regmap_bus_spi = {
> +	.write = rk806_spi_bus_write,
> +	.read = rk806_spi_bus_read,
> +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +};
> +
> +static int rk8xx_spi_probe(struct spi_device *spi)
> +{
> +	struct regmap *regmap;
> +
> +	regmap = devm_regmap_init(&spi->dev, &rk806_regmap_bus_spi,
> +				  &spi->dev, &rk806_regmap_config_spi);
> +	if (IS_ERR(regmap))
> +		return dev_err_probe(&spi->dev, PTR_ERR(regmap),
> +				     "Failed to initialize register map\n");

It's more widely known as regmap.

> +	return rk8xx_probe(&spi->dev, RK806_ID, spi->irq, regmap);
> +}
> +
> +static const struct of_device_id rk8xx_spi_of_match[] = {
> +	{ .compatible = "rockchip,rk806", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, rk8xx_spi_of_match);
> +
> +static const struct spi_device_id rk8xx_spi_id_table[] = {
> +	{ "rk806", 0 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(spi, rk8xx_spi_id_table);
> +
> +static struct spi_driver rk8xx_spi_driver = {
> +	.driver		= {
> +		.name	= "rk8xx-spi",
> +		.of_match_table = rk8xx_spi_of_match,
> +	},
> +	.probe		= rk8xx_spi_probe,
> +	.id_table	= rk8xx_spi_id_table,
> +};
> +module_spi_driver(rk8xx_spi_driver);
> +
> +MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
> +MODULE_DESCRIPTION("RK8xx SPI PMIC driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
> index 4183427a80fe..78e167a92483 100644
> --- a/include/linux/mfd/rk808.h
> +++ b/include/linux/mfd/rk808.h
> @@ -289,6 +289,414 @@ enum rk805_reg {
>  #define RK805_INT_ALARM_EN		(1 << 3)
>  #define RK805_INT_TIMER_EN		(1 << 2)
>  
> +/* RK806 */
> +#define RK806_POWER_EN0			0x0
> +#define RK806_POWER_EN1			0x1
> +#define RK806_POWER_EN2			0x2
> +#define RK806_POWER_EN3			0x3
> +#define RK806_POWER_EN4			0x4
> +#define RK806_POWER_EN5			0x5
> +#define RK806_POWER_SLP_EN0		0x6
> +#define RK806_POWER_SLP_EN1		0x7
> +#define RK806_POWER_SLP_EN2		0x8
> +#define RK806_POWER_DISCHRG_EN0		0x9
> +#define RK806_POWER_DISCHRG_EN1		0xA
> +#define RK806_POWER_DISCHRG_EN2		0xB
> +#define RK806_BUCK_FB_CONFIG		0xC
> +#define RK806_SLP_LP_CONFIG		0xD
> +#define RK806_POWER_FPWM_EN0		0xE
> +#define RK806_POWER_FPWM_EN1		0xF
> +#define RK806_BUCK1_CONFIG		0x10
> +#define RK806_BUCK2_CONFIG		0x11
> +#define RK806_BUCK3_CONFIG		0x12
> +#define RK806_BUCK4_CONFIG		0x13
> +#define RK806_BUCK5_CONFIG		0x14
> +#define RK806_BUCK6_CONFIG		0x15
> +#define RK806_BUCK7_CONFIG		0x16
> +#define RK806_BUCK8_CONFIG		0x17
> +#define RK806_BUCK9_CONFIG		0x18
> +#define RK806_BUCK10_CONFIG		0x19
> +#define RK806_BUCK1_ON_VSEL		0x1A
> +#define RK806_BUCK2_ON_VSEL		0x1B
> +#define RK806_BUCK3_ON_VSEL		0x1C
> +#define RK806_BUCK4_ON_VSEL		0x1D
> +#define RK806_BUCK5_ON_VSEL		0x1E
> +#define RK806_BUCK6_ON_VSEL		0x1F
> +#define RK806_BUCK7_ON_VSEL		0x20
> +#define RK806_BUCK8_ON_VSEL		0x21
> +#define RK806_BUCK9_ON_VSEL		0x22
> +#define RK806_BUCK10_ON_VSEL		0x23
> +#define RK806_BUCK1_SLP_VSEL		0x24
> +#define RK806_BUCK2_SLP_VSEL		0x25
> +#define RK806_BUCK3_SLP_VSEL		0x26
> +#define RK806_BUCK4_SLP_VSEL		0x27
> +#define RK806_BUCK5_SLP_VSEL		0x28
> +#define RK806_BUCK6_SLP_VSEL		0x29
> +#define RK806_BUCK7_SLP_VSEL		0x2A
> +#define RK806_BUCK8_SLP_VSEL		0x2B
> +#define RK806_BUCK9_SLP_VSEL		0x2D
> +#define RK806_BUCK10_SLP_VSEL		0x2E
> +#define RK806_BUCK_DEBUG1		0x30
> +#define RK806_BUCK_DEBUG2		0x31
> +#define RK806_BUCK_DEBUG3		0x32
> +#define RK806_BUCK_DEBUG4		0x33
> +#define RK806_BUCK_DEBUG5		0x34
> +#define RK806_BUCK_DEBUG6		0x35
> +#define RK806_BUCK_DEBUG7		0x36
> +#define RK806_BUCK_DEBUG8		0x37
> +#define RK806_BUCK_DEBUG9		0x38
> +#define RK806_BUCK_DEBUG10		0x39
> +#define RK806_BUCK_DEBUG11		0x3A
> +#define RK806_BUCK_DEBUG12		0x3B
> +#define RK806_BUCK_DEBUG13		0x3C
> +#define RK806_BUCK_DEBUG14		0x3D
> +#define RK806_BUCK_DEBUG15		0x3E
> +#define RK806_BUCK_DEBUG16		0x3F
> +#define RK806_BUCK_DEBUG17		0x40
> +#define RK806_BUCK_DEBUG18		0x41
> +#define RK806_NLDO_IMAX			0x42
> +#define RK806_NLDO1_ON_VSEL		0x43
> +#define RK806_NLDO2_ON_VSEL		0x44
> +#define RK806_NLDO3_ON_VSEL		0x45
> +#define RK806_NLDO4_ON_VSEL		0x46
> +#define RK806_NLDO5_ON_VSEL		0x47
> +#define RK806_NLDO1_SLP_VSEL		0x48
> +#define RK806_NLDO2_SLP_VSEL		0x49
> +#define RK806_NLDO3_SLP_VSEL		0x4A
> +#define RK806_NLDO4_SLP_VSEL		0x4B
> +#define RK806_NLDO5_SLP_VSEL		0x4C
> +#define RK806_PLDO_IMAX			0x4D
> +#define RK806_PLDO1_ON_VSEL		0x4E
> +#define RK806_PLDO2_ON_VSEL		0x4F
> +#define RK806_PLDO3_ON_VSEL		0x50
> +#define RK806_PLDO4_ON_VSEL		0x51
> +#define RK806_PLDO5_ON_VSEL		0x52
> +#define RK806_PLDO6_ON_VSEL		0x53
> +#define RK806_PLDO1_SLP_VSEL		0x54
> +#define RK806_PLDO2_SLP_VSEL		0x55
> +#define RK806_PLDO3_SLP_VSEL		0x56
> +#define RK806_PLDO4_SLP_VSEL		0x57
> +#define RK806_PLDO5_SLP_VSEL		0x58
> +#define RK806_PLDO6_SLP_VSEL		0x59
> +#define RK806_CHIP_NAME			0x5A
> +#define RK806_CHIP_VER			0x5B
> +#define RK806_OTP_VER			0x5C
> +#define RK806_SYS_STS			0x5D
> +#define RK806_SYS_CFG0			0x5E
> +#define RK806_SYS_CFG1			0x5F
> +#define RK806_SYS_OPTION		0x61
> +#define RK806_SLEEP_CONFIG0		0x62
> +#define RK806_SLEEP_CONFIG1		0x63
> +#define RK806_SLEEP_CTR_SEL0		0x64
> +#define RK806_SLEEP_CTR_SEL1		0x65
> +#define RK806_SLEEP_CTR_SEL2		0x66
> +#define RK806_SLEEP_CTR_SEL3		0x67
> +#define RK806_SLEEP_CTR_SEL4		0x68
> +#define RK806_SLEEP_CTR_SEL5		0x69
> +#define RK806_DVS_CTRL_SEL0		0x6A
> +#define RK806_DVS_CTRL_SEL1		0x6B
> +#define RK806_DVS_CTRL_SEL2		0x6C
> +#define RK806_DVS_CTRL_SEL3		0x6D
> +#define RK806_DVS_CTRL_SEL4		0x6E
> +#define RK806_DVS_CTRL_SEL5		0x6F
> +#define RK806_DVS_START_CTRL		0x70
> +#define RK806_SLEEP_GPIO		0x71
> +#define RK806_SYS_CFG3			0x72
> +#define RK806_ON_SOURCE			0x74
> +#define RK806_OFF_SOURCE		0x75
> +#define RK806_PWRON_KEY			0x76
> +#define RK806_INT_STS0			0x77
> +#define RK806_INT_MSK0			0x78
> +#define RK806_INT_STS1			0x79
> +#define RK806_INT_MSK1			0x7A
> +#define RK806_GPIO_INT_CONFIG		0x7B
> +#define RK806_DATA_REG0			0x7C
> +#define RK806_DATA_REG1			0x7D
> +#define RK806_DATA_REG2			0x7E
> +#define RK806_DATA_REG3			0x7F
> +#define RK806_DATA_REG4			0x80
> +#define RK806_DATA_REG5			0x81
> +#define RK806_DATA_REG6			0x82
> +#define RK806_DATA_REG7			0x83
> +#define RK806_DATA_REG8			0x84
> +#define RK806_DATA_REG9			0x85
> +#define RK806_DATA_REG10		0x86
> +#define RK806_DATA_REG11		0x87
> +#define RK806_DATA_REG12		0x88
> +#define RK806_DATA_REG13		0x89
> +#define RK806_DATA_REG14		0x8A
> +#define RK806_DATA_REG15		0x8B
> +#define RK806_TM_REG			0x8C
> +#define RK806_OTP_EN_REG		0x8D
> +#define RK806_FUNC_OTP_EN_REG		0x8E
> +#define RK806_TEST_REG1			0x8F
> +#define RK806_TEST_REG2			0x90
> +#define RK806_TEST_REG3			0x91
> +#define RK806_TEST_REG4			0x92
> +#define RK806_TEST_REG5			0x93
> +#define RK806_BUCK_VSEL_OTP_REG0	0x94
> +#define RK806_BUCK_VSEL_OTP_REG1	0x95
> +#define RK806_BUCK_VSEL_OTP_REG2	0x96
> +#define RK806_BUCK_VSEL_OTP_REG3	0x97
> +#define RK806_BUCK_VSEL_OTP_REG4	0x98
> +#define RK806_BUCK_VSEL_OTP_REG5	0x99
> +#define RK806_BUCK_VSEL_OTP_REG6	0x9A
> +#define RK806_BUCK_VSEL_OTP_REG7	0x9B
> +#define RK806_BUCK_VSEL_OTP_REG8	0x9C
> +#define RK806_BUCK_VSEL_OTP_REG9	0x9D
> +#define RK806_NLDO1_VSEL_OTP_REG0	0x9E
> +#define RK806_NLDO1_VSEL_OTP_REG1	0x9F
> +#define RK806_NLDO1_VSEL_OTP_REG2	0xA0
> +#define RK806_NLDO1_VSEL_OTP_REG3	0xA1
> +#define RK806_NLDO1_VSEL_OTP_REG4	0xA2
> +#define RK806_PLDO_VSEL_OTP_REG0	0xA3
> +#define RK806_PLDO_VSEL_OTP_REG1	0xA4
> +#define RK806_PLDO_VSEL_OTP_REG2	0xA5
> +#define RK806_PLDO_VSEL_OTP_REG3	0xA6
> +#define RK806_PLDO_VSEL_OTP_REG4	0xA7
> +#define RK806_PLDO_VSEL_OTP_REG5	0xA8
> +#define RK806_BUCK_EN_OTP_REG1		0xA9
> +#define RK806_NLDO_EN_OTP_REG1		0xAA
> +#define RK806_PLDO_EN_OTP_REG1		0xAB
> +#define RK806_BUCK_FB_RES_OTP_REG1	0xAC
> +#define RK806_OTP_RESEV_REG0		0xAD
> +#define RK806_OTP_RESEV_REG1		0xAE
> +#define RK806_OTP_RESEV_REG2		0xAF
> +#define RK806_OTP_RESEV_REG3		0xB0
> +#define RK806_OTP_RESEV_REG4		0xB1
> +#define RK806_BUCK_SEQ_REG0		0xB2
> +#define RK806_BUCK_SEQ_REG1		0xB3
> +#define RK806_BUCK_SEQ_REG2		0xB4
> +#define RK806_BUCK_SEQ_REG3		0xB5
> +#define RK806_BUCK_SEQ_REG4		0xB6
> +#define RK806_BUCK_SEQ_REG5		0xB7
> +#define RK806_BUCK_SEQ_REG6		0xB8
> +#define RK806_BUCK_SEQ_REG7		0xB9
> +#define RK806_BUCK_SEQ_REG8		0xBA
> +#define RK806_BUCK_SEQ_REG9		0xBB
> +#define RK806_BUCK_SEQ_REG10		0xBC
> +#define RK806_BUCK_SEQ_REG11		0xBD
> +#define RK806_BUCK_SEQ_REG12		0xBE
> +#define RK806_BUCK_SEQ_REG13		0xBF
> +#define RK806_BUCK_SEQ_REG14		0xC0
> +#define RK806_BUCK_SEQ_REG15		0xC1
> +#define RK806_BUCK_SEQ_REG16		0xC2
> +#define RK806_BUCK_SEQ_REG17		0xC3
> +#define RK806_HK_TRIM_REG1		0xC4
> +#define RK806_HK_TRIM_REG2		0xC5
> +#define RK806_BUCK_REF_TRIM_REG1	0xC6
> +#define RK806_BUCK_REF_TRIM_REG2	0xC7
> +#define RK806_BUCK_REF_TRIM_REG3	0xC8
> +#define RK806_BUCK_REF_TRIM_REG4	0xC9
> +#define RK806_BUCK_REF_TRIM_REG5	0xCA
> +#define RK806_BUCK_OSC_TRIM_REG1	0xCB
> +#define RK806_BUCK_OSC_TRIM_REG2	0xCC
> +#define RK806_BUCK_OSC_TRIM_REG3	0xCD
> +#define RK806_BUCK_OSC_TRIM_REG4	0xCE
> +#define RK806_BUCK_OSC_TRIM_REG5	0xCF
> +#define RK806_BUCK_TRIM_ZCDIOS_REG1	0xD0
> +#define RK806_BUCK_TRIM_ZCDIOS_REG2	0xD1
> +#define RK806_NLDO_TRIM_REG1		0xD2
> +#define RK806_NLDO_TRIM_REG2		0xD3
> +#define RK806_NLDO_TRIM_REG3		0xD4
> +#define RK806_PLDO_TRIM_REG1		0xD5
> +#define RK806_PLDO_TRIM_REG2		0xD6
> +#define RK806_PLDO_TRIM_REG3		0xD7
> +#define RK806_TRIM_ICOMP_REG1		0xD8
> +#define RK806_TRIM_ICOMP_REG2		0xD9
> +#define RK806_EFUSE_CONTROL_REGH	0xDA
> +#define RK806_FUSE_PROG_REG		0xDB
> +#define RK806_MAIN_FSM_STS_REG		0xDD
> +#define RK806_FSM_REG			0xDE
> +#define RK806_TOP_RESEV_OFFR		0xEC
> +#define RK806_TOP_RESEV_POR		0xED
> +#define RK806_BUCK_VRSN_REG1		0xEE
> +#define RK806_BUCK_VRSN_REG2		0xEF
> +#define RK806_NLDO_RLOAD_SEL_REG1	0xF0
> +#define RK806_PLDO_RLOAD_SEL_REG1	0xF1
> +#define RK806_PLDO_RLOAD_SEL_REG2	0xF2
> +#define RK806_BUCK_CMIN_MX_REG1		0xF3
> +#define RK806_BUCK_CMIN_MX_REG2		0xF4
> +#define RK806_BUCK_FREQ_SET_REG1	0xF5
> +#define RK806_BUCK_FREQ_SET_REG2	0xF6
> +#define RK806_BUCK_RS_MEABS_REG1	0xF7
> +#define RK806_BUCK_RS_MEABS_REG2	0xF8
> +#define RK806_BUCK_RS_ZDLEB_REG1	0xF9
> +#define RK806_BUCK_RS_ZDLEB_REG2	0xFA
> +#define RK806_BUCK_RSERVE_REG1		0xFB
> +#define RK806_BUCK_RSERVE_REG2		0xFC
> +#define RK806_BUCK_RSERVE_REG3		0xFD
> +#define RK806_BUCK_RSERVE_REG4		0xFE
> +#define RK806_BUCK_RSERVE_REG5		0xFF
> +
> +/* INT_STS Register field definitions */
> +#define RK806_INT_STS_PWRON_FALL	BIT(0)
> +#define RK806_INT_STS_PWRON_RISE	BIT(1)
> +#define RK806_INT_STS_PWRON		BIT(2)
> +#define RK806_INT_STS_PWRON_LP		BIT(3)
> +#define RK806_INT_STS_HOTDIE		BIT(4)
> +#define RK806_INT_STS_VDC_RISE		BIT(5)
> +#define RK806_INT_STS_VDC_FALL		BIT(6)
> +#define RK806_INT_STS_VB_LO		BIT(7)
> +#define RK806_INT_STS_REV0		BIT(0)
> +#define RK806_INT_STS_REV1		BIT(1)
> +#define RK806_INT_STS_REV2		BIT(2)
> +#define RK806_INT_STS_CRC_ERROR		BIT(3)
> +#define RK806_INT_STS_SLP3_GPIO		BIT(4)
> +#define RK806_INT_STS_SLP2_GPIO		BIT(5)
> +#define RK806_INT_STS_SLP1_GPIO		BIT(6)
> +#define RK806_INT_STS_WDT		BIT(7)
> +
> +/* SPI command */
> +#define RK806_CMD_READ			0
> +#define RK806_CMD_WRITE			BIT(7)
> +#define RK806_CMD_CRC_EN		BIT(6)
> +#define RK806_CMD_CRC_DIS		0
> +#define RK806_CMD_LEN_MSK		0x0f
> +#define RK806_REG_H			0x00
> +
> +#define VERSION_AB		0x01
> +
> +enum rk806_reg_id {
> +	RK806_ID_DCDC1 = 0,
> +	RK806_ID_DCDC2,
> +	RK806_ID_DCDC3,
> +	RK806_ID_DCDC4,
> +	RK806_ID_DCDC5,
> +	RK806_ID_DCDC6,
> +	RK806_ID_DCDC7,
> +	RK806_ID_DCDC8,
> +	RK806_ID_DCDC9,
> +	RK806_ID_DCDC10,
> +
> +	RK806_ID_NLDO1,
> +	RK806_ID_NLDO2,
> +	RK806_ID_NLDO3,
> +	RK806_ID_NLDO4,
> +	RK806_ID_NLDO5,
> +
> +	RK806_ID_PLDO1,
> +	RK806_ID_PLDO2,
> +	RK806_ID_PLDO3,
> +	RK806_ID_PLDO4,
> +	RK806_ID_PLDO5,
> +	RK806_ID_PLDO6,
> +	RK806_ID_END,
> +};
> +
> +/* Define the RK806 IRQ numbers */
> +enum rk806_irqs {
> +	/* INT_STS0 registers */
> +	RK806_IRQ_PWRON_FALL,
> +	RK806_IRQ_PWRON_RISE,
> +	RK806_IRQ_PWRON,
> +	RK806_IRQ_PWRON_LP,
> +	RK806_IRQ_HOTDIE,
> +	RK806_IRQ_VDC_RISE,
> +	RK806_IRQ_VDC_FALL,
> +	RK806_IRQ_VB_LO,
> +
> +	/* INT_STS0 registers */
> +	RK806_IRQ_REV0,
> +	RK806_IRQ_REV1,
> +	RK806_IRQ_REV2,
> +	RK806_IRQ_CRC_ERROR,
> +	RK806_IRQ_SLP3_GPIO,
> +	RK806_IRQ_SLP2_GPIO,
> +	RK806_IRQ_SLP1_GPIO,
> +	RK806_IRQ_WDT,
> +};
> +
> +/* VCC1 Low Voltage Threshold */
> +enum rk806_lv_sel {
> +	VB_LO_SEL_2800,
> +	VB_LO_SEL_2900,
> +	VB_LO_SEL_3000,
> +	VB_LO_SEL_3100,
> +	VB_LO_SEL_3200,
> +	VB_LO_SEL_3300,
> +	VB_LO_SEL_3400,
> +	VB_LO_SEL_3500,
> +};
> +
> +/* System Shutdown Voltage Select */
> +enum rk806_uv_sel {
> +	VB_UV_SEL_2700,
> +	VB_UV_SEL_2800,
> +	VB_UV_SEL_2900,
> +	VB_UV_SEL_3000,
> +	VB_UV_SEL_3100,
> +	VB_UV_SEL_3200,
> +	VB_UV_SEL_3300,
> +	VB_UV_SEL_3400,
> +};
> +
> +/* Pin Function */
> +enum rk806_pwrctrl_fun {
> +	PWRCTRL_NULL_FUN,
> +	PWRCTRL_SLP_FUN,
> +	PWRCTRL_POWOFF_FUN,
> +	PWRCTRL_RST_FUN,
> +	PWRCTRL_DVS_FUN,
> +	PWRCTRL_GPIO_FUN,
> +};
> +
> +/* Pin Polarity */
> +enum rk806_pin_level {
> +	POL_LOW,
> +	POL_HIGH,
> +};
> +
> +enum rk806_vsel_ctr_sel {
> +	CTR_BY_NO_EFFECT,
> +	CTR_BY_PWRCTRL1,
> +	CTR_BY_PWRCTRL2,
> +	CTR_BY_PWRCTRL3,
> +};
> +
> +enum rk806_dvs_ctr_sel {
> +	CTR_SEL_NO_EFFECT,
> +	CTR_SEL_DVS_START1,
> +	CTR_SEL_DVS_START2,
> +	CTR_SEL_DVS_START3,
> +};
> +
> +enum rk806_pin_dr_sel {
> +	RK806_PIN_INPUT,
> +	RK806_PIN_OUTPUT,
> +};
> +
> +#define RK806_INT_POL_MSK		BIT(1)
> +#define RK806_INT_POL_H			BIT(1)
> +#define RK806_INT_POL_L			0
> +
> +#define RK806_SLAVE_RESTART_FUN_MSK	BIT(1)
> +#define RK806_SLAVE_RESTART_FUN_EN	BIT(1)
> +#define RK806_SLAVE_RESTART_FUN_OFF	0
> +
> +#define RK806_SYS_ENB2_2M_MSK		BIT(1)
> +#define RK806_SYS_ENB2_2M_EN		BIT(1)
> +#define RK806_SYS_ENB2_2M_OFF		0
> +
> +enum rk806_int_fun {
> +	RK806_INT_ONLY,
> +	RK806_INT_ADN_WKUP,
> +};
> +
> +enum rk806_dvs_mode {
> +	RK806_DVS_NOT_SUPPORT,
> +	RK806_DVS_START1,
> +	RK806_DVS_START2,
> +	RK806_DVS_START3,
> +	RK806_DVS_PWRCTRL1,
> +	RK806_DVS_PWRCTRL2,
> +	RK806_DVS_PWRCTRL3,
> +	RK806_DVS_START_PWRCTR1,
> +	RK806_DVS_START_PWRCTR2,
> +	RK806_DVS_START_PWRCTR3,
> +	RK806_DVS_END,
> +};
> +
>  /* RK808 IRQ Definitions */
>  #define RK808_IRQ_VOUT_LO	0
>  #define RK808_IRQ_VB_LO		1
> @@ -780,6 +1188,7 @@ enum {
>  
>  enum {
>  	RK805_ID = 0x8050,
> +	RK806_ID = 0x8060,
>  	RK808_ID = 0x0000,
>  	RK809_ID = 0x8090,
>  	RK817_ID = 0x8170,
> -- 
> 2.39.0
> 

-- 
Lee Jones [李琼斯]

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCHv6 09/11] pinctrl: rk805: add rk806 pinctrl support
  2023-03-02 16:22       ` Lee Jones
@ 2023-03-06 12:37         ` Linus Walleij
  -1 siblings, 0 replies; 48+ messages in thread
From: Linus Walleij @ 2023-03-06 12:37 UTC (permalink / raw)
  To: Lee Jones
  Cc: Sebastian Reichel, Heiko Stuebner, Rob Herring,
	Krzysztof Kozlowski, Michael Turquette, Stephen Boyd, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel, shengfei Xu

On Thu, Mar 2, 2023 at 5:22 PM Lee Jones <lee@kernel.org> wrote:
> On Mon, 30 Jan 2023, Linus Walleij wrote:
> > On Fri, Jan 27, 2023 at 7:13 PM Sebastian Reichel
> > <sebastian.reichel@collabora.com> wrote:
> >
> > > Add support for rk806 dvs pinctrl to the existing rk805
> > > driver.
> > >
> > > This has been implemented using shengfei Xu's rk806
> > > specific driver from the vendor tree as reference.
> > >
> > > Co-Developed-by: shengfei Xu <xsf@rock-chips.com>
> > > Signed-off-by: shengfei Xu <xsf@rock-chips.com>
> > > Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> > > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> >
> > Is this something I can just apply? I haven't had Heiko's review
> > on it but it looks innocent enough.
>
> Ack please. :)

Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

* Re: [PATCHv6 09/11] pinctrl: rk805: add rk806 pinctrl support
@ 2023-03-06 12:37         ` Linus Walleij
  0 siblings, 0 replies; 48+ messages in thread
From: Linus Walleij @ 2023-03-06 12:37 UTC (permalink / raw)
  To: Lee Jones
  Cc: Sebastian Reichel, Heiko Stuebner, Rob Herring,
	Krzysztof Kozlowski, Michael Turquette, Stephen Boyd, Mark Brown,
	Liam Girdwood, Alexandre Belloni, Alessandro Zummo,
	linux-rockchip, devicetree, linux-kernel, kernel, shengfei Xu

On Thu, Mar 2, 2023 at 5:22 PM Lee Jones <lee@kernel.org> wrote:
> On Mon, 30 Jan 2023, Linus Walleij wrote:
> > On Fri, Jan 27, 2023 at 7:13 PM Sebastian Reichel
> > <sebastian.reichel@collabora.com> wrote:
> >
> > > Add support for rk806 dvs pinctrl to the existing rk805
> > > driver.
> > >
> > > This has been implemented using shengfei Xu's rk806
> > > specific driver from the vendor tree as reference.
> > >
> > > Co-Developed-by: shengfei Xu <xsf@rock-chips.com>
> > > Signed-off-by: shengfei Xu <xsf@rock-chips.com>
> > > Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> > > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> >
> > Is this something I can just apply? I haven't had Heiko's review
> > on it but it looks innocent enough.
>
> Ack please. :)

Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

end of thread, other threads:[~2023-03-06 12:38 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-27 18:12 [PATCHv6 00/11] Introduce RK806 Support Sebastian Reichel
2023-01-27 18:12 ` Sebastian Reichel
2023-01-27 18:12 ` [PATCHv6 01/11] clk: RK808: reduce 'struct rk808' usage Sebastian Reichel
2023-01-27 18:12   ` Sebastian Reichel
2023-01-27 18:12 ` [PATCHv6 02/11] mfd: rk808: convert to device managed resources Sebastian Reichel
2023-01-27 18:12   ` Sebastian Reichel
2023-01-27 18:12 ` [PATCHv6 03/11] mfd: rk808: use dev_err_probe Sebastian Reichel
2023-01-27 18:12   ` Sebastian Reichel
2023-01-27 18:12 ` [PATCHv6 04/11] mfd: rk808: replace 'struct i2c_client' with 'struct device' Sebastian Reichel
2023-01-27 18:12   ` Sebastian Reichel
2023-01-27 18:12 ` [PATCHv6 05/11] mfd: rk808: split into core and i2c Sebastian Reichel
2023-01-27 18:12   ` Sebastian Reichel
2023-01-27 20:06   ` Alexandre Belloni
2023-01-27 20:06     ` Alexandre Belloni
2023-02-04 13:52   ` Lee Jones
2023-02-04 13:52     ` Lee Jones
2023-02-04 14:01     ` Lee Jones
2023-02-04 14:01       ` Lee Jones
2023-02-05  1:06       ` Sebastian Reichel
2023-02-05  1:06         ` Sebastian Reichel
2023-02-06 18:47         ` Lee Jones
2023-02-06 18:47           ` Lee Jones
2023-03-02 16:24   ` Lee Jones
2023-03-02 16:24     ` Lee Jones
2023-01-27 18:12 ` [PATCHv6 06/11] mfd: rk8xx-i2c: use device_get_match_data Sebastian Reichel
2023-01-27 18:12   ` Sebastian Reichel
2023-03-02 16:50   ` Lee Jones
2023-03-02 16:50     ` Lee Jones
2023-01-27 18:12 ` [PATCHv6 07/11] dt-bindings: mfd: add rk806 binding Sebastian Reichel
2023-01-27 18:12   ` Sebastian Reichel
2023-01-27 18:12 ` [PATCHv6 08/11] mfd: rk8xx: add rk806 support Sebastian Reichel
2023-01-27 18:12   ` Sebastian Reichel
2023-03-02 17:52   ` Lee Jones
2023-03-02 17:52     ` Lee Jones
2023-01-27 18:12 ` [PATCHv6 09/11] pinctrl: rk805: add rk806 pinctrl support Sebastian Reichel
2023-01-27 18:12   ` Sebastian Reichel
2023-01-30 22:31   ` Linus Walleij
2023-01-30 22:31     ` Linus Walleij
2023-01-30 23:36     ` Sebastian Reichel
2023-01-30 23:36       ` Sebastian Reichel
2023-03-02 16:22     ` Lee Jones
2023-03-02 16:22       ` Lee Jones
2023-03-06 12:37       ` Linus Walleij
2023-03-06 12:37         ` Linus Walleij
2023-01-27 18:12 ` [PATCHv6 10/11] regulator: expose regulator_find_closest_bigger Sebastian Reichel
2023-01-27 18:12   ` Sebastian Reichel
2023-01-27 18:12 ` [PATCHv6 11/11] regulator: rk808: add rk806 support Sebastian Reichel
2023-01-27 18:12   ` Sebastian Reichel

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.