All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/12] sunxi: Migrate to DM_I2C
@ 2021-10-08  5:17 Samuel Holland
  2021-10-08  5:17 ` [PATCH v2 01/12] power: pmic: Consistently depend on DM_PMIC Samuel Holland
                   ` (12 more replies)
  0 siblings, 13 replies; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

This series does the initial work to migrate sunxi boards to DM_I2C.
Version 1 of this series bitrotted quite a bit, so there is some
reorganization in version 2.

First it takes care of the PMIC:
 - Patches 1-2 clean up the PMIC Kconfig, though they are not strictly
   necessary after 7abf178b, and are independent from the other patches.
 - Patch 3 then adds a DM_PMIC driver.
 - Patches 4-6 prepare to move the P2WI/RSB bus drivers to drivers/i2c.
 - Patches 7-8 move and add DM_I2C versions of those two drivers.
 - Patches 9-10 migrate the "pmic_bus" functions to use the DM_I2C bus
   and DM_PMIC driver when possible.
Then it takes care of the LCD panels:
 - Patch 11 converts those drivers to use DM_I2C.
Finally, patch 12 switches all sunxi boards over to DM_I2C.

I have build-tested each commit on all sunxi boards.

There is some remaining work to clean up uses of pmic_bus in U-Boot
proper and replace them with DM_PMIC functions:
 - drivers/gpio/axp_gpio.c - I have a series for this.
 - do_poweroff() in drivers/gpio/axp???.c - I have a series for this.
 - axp_get_sid() in drivers/power/axp221.c - Not sure what to do here.
 - axp_set_eldo() in drivers/video/sunxi/sunxi_display.c - This will
   need a DM_REGULATOR driver.

Changes in v2:
- Rebase to pick up 7abf178b ("power: Tidy up #undef of CONFIG_DM_PMIC")
- Rebase to pick up 7abf178b ("power: Tidy up #undef of CONFIG_DM_PMIC")
- Replace axp_pmic_bind() with `.bind = dm_scan_fdt_dev`
- New patch to account for I2C Kconfig changes
- Renamed Kconfig symbol to SYS_I2C_SUN6I_P2WI
- Moved entire P2WI driver source to drivers/i2c
- Renamed Kconfig symbol to SYS_I2C_SUN8I_RSB
- Moved entire RSB driver source to drivers/i2c
- Update IS_ENABLEDs in pmic_bus.c to match chages to previous patches

Samuel Holland (12):
  power: pmic: Consistently depend on DM_PMIC
  power: pmic: Consistently depend on SPL_DM_PMIC
  power: pmic: Add a driver for X-Powers AXP PMICs
  sunxi: Only initialize legacy I2C when enabled
  sunxi: Select SUN8I_RSB more carefully
  sunxi: pmic_bus: Fix Kconfig dependencies
  i2c: Add a DM_I2C driver for the sun6i P2WI controller
  i2c: Add a DM_I2C driver for the sun8i RSB controller
  sunxi: pmic_bus: Clean up preprocessor conditions
  sunxi: pmic_bus: Use the DM PMIC interface when possible
  sunxi: video: Convert panel I2C to use DM_I2C
  sunxi: Enable DM_I2C for all sunxi boards

 arch/arm/Kconfig                    |   1 +
 arch/arm/mach-sunxi/Kconfig         |  59 ++----
 arch/arm/mach-sunxi/Makefile        |   2 -
 arch/arm/mach-sunxi/board.c         |   2 +-
 arch/arm/mach-sunxi/p2wi.c          | 117 ------------
 arch/arm/mach-sunxi/pmic_bus.c      | 109 +++++------
 arch/arm/mach-sunxi/rsb.c           | 175 -----------------
 board/sunxi/board.c                 |  44 +----
 configs/Colombus_defconfig          |   6 -
 configs/UTOO_P66_defconfig          |   3 -
 drivers/i2c/Kconfig                 |  16 ++
 drivers/i2c/Makefile                |   2 +
 drivers/i2c/sun6i_p2wi.c            | 220 ++++++++++++++++++++++
 drivers/i2c/sun8i_rsb.c             | 281 ++++++++++++++++++++++++++++
 drivers/power/pmic/Kconfig          |  69 ++++---
 drivers/power/pmic/Makefile         |   1 +
 drivers/power/pmic/axp.c            |  38 ++++
 drivers/video/anx9804.c             | 103 +++++-----
 drivers/video/anx9804.h             |   5 +-
 drivers/video/sunxi/sunxi_display.c |  55 ++++--
 include/axp_pmic.h                  |  12 ++
 include/configs/sunxi-common.h      |  17 --
 22 files changed, 773 insertions(+), 564 deletions(-)
 delete mode 100644 arch/arm/mach-sunxi/p2wi.c
 delete mode 100644 arch/arm/mach-sunxi/rsb.c
 create mode 100644 drivers/i2c/sun6i_p2wi.c
 create mode 100644 drivers/i2c/sun8i_rsb.c
 create mode 100644 drivers/power/pmic/axp.c

-- 
2.32.0


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

* [PATCH v2 01/12] power: pmic: Consistently depend on DM_PMIC
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
@ 2021-10-08  5:17 ` Samuel Holland
  2021-10-08  5:17 ` [PATCH v2 02/12] power: pmic: Consistently depend on SPL_DM_PMIC Samuel Holland
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini, Igor Opaniuk

Kconfig symbols for two PMIC drivers (PMIC_AS3722 and DM_PMIC_MC34708)
were missing a dependency on DM_PMIC. To fix this inconsistency, and to
keep it from happening again, wrap the driver section with "if DM_PMIC"
instead of using a "depends on DM_PMIC" clause for each driver.

Reviewed-by: Igor Opaniuk <igor.opaniuk@foundries.io>
Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v2:
- Rebase to pick up 7abf178b ("power: Tidy up #undef of CONFIG_DM_PMIC")

 drivers/power/pmic/Kconfig | 46 ++++++++------------------------------
 1 file changed, 9 insertions(+), 37 deletions(-)

diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index cf2a9b2c17e..2472555a3ff 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -10,10 +10,12 @@ config DM_PMIC
 	- 'drivers/power/pmic/pmic-uclass.c'
 	- 'include/power/pmic.h'
 
+if DM_PMIC
+
 config SPL_DM_PMIC
 	bool "Enable Driver Model for PMIC drivers (UCLASS_PMIC) in SPL"
 	depends on SPL_DM
-	default y if DM_PMIC
+	default y
 	---help---
 	This config enables the driver-model PMIC support in SPL.
 	UCLASS_PMIC - designed to provide an I/O interface for PMIC devices.
@@ -25,7 +27,6 @@ config SPL_DM_PMIC
 
 config PMIC_CHILDREN
 	bool "Allow child devices for PMICs"
-	depends on DM_PMIC
 	default y
 	---help---
 	This allows PMICs to support child devices (such as regulators) in
@@ -35,7 +36,6 @@ config PMIC_CHILDREN
 
 config SPL_PMIC_CHILDREN
 	bool "Allow child devices for PMICs in SPL"
-	depends on DM_PMIC
 	default y
 	---help---
 	This allows PMICs to support child devices (such as regulators) in
@@ -46,7 +46,6 @@ config SPL_PMIC_CHILDREN
 
 config PMIC_AB8500
 	bool "Enable driver for ST-Ericsson AB8500 PMIC via PRCMU"
-	depends on DM_PMIC
 	select REGMAP
 	select SYSCON
 	help
@@ -56,7 +55,7 @@ config PMIC_AB8500
 
 config PMIC_ACT8846
 	bool "Enable support for the active-semi 8846 PMIC"
-	depends on DM_PMIC && DM_I2C
+	depends on DM_I2C
 	---help---
 	This PMIC includes 4 DC/DC step-down buck regulators and 8 low-dropout
 	regulators (LDOs). It also provides some GPIO, reset and battery
@@ -65,14 +64,13 @@ config PMIC_ACT8846
 
 config DM_PMIC_DA9063
 	bool "Enable Driver Model for the Dialog DA9063 PMIC"
-	depends on DM_PMIC
 	help
 	  This config enables implementation of driver-model pmic uclass features
 	  for PMIC DA9063. The driver implements read/write operations.
 
 config SPL_DM_PMIC_DA9063
 	bool "Enable Driver Model for the Dialog DA9063 PMIC in SPL"
-	depends on DM_PMIC && SPL
+	depends on SPL
 	help
 	  This config enables implementation of driver-model pmic uclass features
 	  for PMIC DA9063. The driver implements read/write operations.
@@ -87,14 +85,12 @@ config PMIC_AS3722
 
 config DM_PMIC_BD71837
  	bool "Enable Driver Model for PMIC BD71837"
- 	depends on DM_PMIC
  	help
 	  This config enables implementation of driver-model pmic uclass features
 	  for PMIC BD71837. The driver implements read/write operations.
 
 config SPL_DM_PMIC_BD71837
 	bool "Enable Driver Model for PMIC BD71837 in SPL stage"
-	depends on DM_PMIC
 	help
 	  This config enables implementation of driver-model pmic uclass
 	  features for PMIC BD71837. The driver implements read/write
@@ -102,7 +98,7 @@ config SPL_DM_PMIC_BD71837
 
 config DM_PMIC_FAN53555
 	bool "Enable support for OnSemi FAN53555"
-	depends on DM_PMIC && DM_REGULATOR && DM_I2C
+	depends on DM_REGULATOR && DM_I2C
 	select DM_REGULATOR_FAN53555
 	help
 	  This config enables implementation of driver-model PMIC
@@ -116,14 +112,12 @@ config DM_PMIC_FAN53555
 
 config DM_PMIC_MP5416
 	bool "Enable Driver Model for PMIC MP5416"
-	depends on DM_PMIC
 	help
 	  This config enables implementation of driver-model pmic uclass features
 	  for PMIC MP5416. The driver implements read/write operations.
 
 config SPL_DM_PMIC_MP5416
 	bool "Enable Driver Model for PMIC MP5416 in SPL stage"
-	depends on DM_PMIC
 	help
 	  This config enables implementation of driver-model pmic uclass
 	  features for PMIC MP5416. The driver implements read/write
@@ -131,56 +125,48 @@ config SPL_DM_PMIC_MP5416
 
 config DM_PMIC_PCA9450
 	bool "Enable Driver Model for PMIC PCA9450"
-	depends on DM_PMIC
 	help
 	  This config enables implementation of driver-model pmic uclass features
 	  for PMIC PCA9450. The driver implements read/write operations.
 
 config SPL_DM_PMIC_PCA9450
 	bool "Enable Driver Model for PMIC PCA9450"
-	depends on DM_PMIC
 	help
 	  This config enables implementation of driver-model pmic uclass features
 	  for PMIC PCA9450 in SPL. The driver implements read/write operations.
 
 config DM_PMIC_PFUZE100
 	bool "Enable Driver Model for PMIC PFUZE100"
-	depends on DM_PMIC
 	---help---
 	This config enables implementation of driver-model pmic uclass features
 	for PMIC PFUZE100. The driver implements read/write operations.
 
 config SPL_DM_PMIC_PFUZE100
 	bool "Enable Driver Model for PMIC PFUZE100 in SPL"
-	depends on DM_PMIC
 	---help---
 	This config enables implementation of driver-model pmic uclass features
 	for PMIC PFUZE100 in SPL. The driver implements read/write operations.
 
 config DM_PMIC_MAX77686
 	bool "Enable Driver Model for PMIC MAX77686"
-	depends on DM_PMIC
 	---help---
 	This config enables implementation of driver-model pmic uclass features
 	for PMIC MAX77686. The driver implements read/write operations.
 
 config DM_PMIC_MAX8998
 	bool "Enable Driver Model for PMIC MAX8998"
-	depends on DM_PMIC
 	---help---
 	This config enables implementation of driver-model pmic uclass features
 	for PMIC MAX8998. The driver implements read/write operations.
 
 config DM_PMIC_MC34708
 	bool "Enable Driver Model for PMIC MC34708"
-	depends on DM_PMIC
 	help
 	 This config enables implementation of driver-model pmic uclass features
 	 for PMIC MC34708. The driver implements read/write operations.
 
 config PMIC_MAX8997
 	bool "Enable Driver Model for PMIC MAX8997"
-	depends on DM_PMIC
 	---help---
 	This config enables implementation of driver-model pmic uclass features
 	for PMIC MAX8997. The driver implements read/write operations.
@@ -195,7 +181,6 @@ config PMIC_MAX8997
 
 config PMIC_PM8916
 	bool "Enable Driver Model for Qualcomm PM8916 PMIC"
-	depends on DM_PMIC
 	---help---
 	The PM8916 is a PMIC connected to one (or several) processors
 	with SPMI bus. It has 2 slaves with several peripherals:
@@ -211,7 +196,6 @@ config PMIC_PM8916
 
 config PMIC_RK8XX
 	bool "Enable support for Rockchip PMIC RK8XX"
-	depends on DM_PMIC
 	---help---
 	The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs,
 	an RTC and two low Rds (resistance (drain to source)) switches. It is
@@ -220,7 +204,6 @@ config PMIC_RK8XX
 
 config SPL_PMIC_RK8XX
 	bool "Enable support for Rockchip PMIC RK8XX"
-	depends on DM_PMIC
 	---help---
 	The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs,
 	an RTC and two low Rds (resistance (drain to source)) switches. It is
@@ -229,7 +212,6 @@ config SPL_PMIC_RK8XX
 
 config PMIC_S2MPS11
 	bool "Enable Driver Model for PMIC Samsung S2MPS11"
-	depends on DM_PMIC
 	---help---
 	The Samsung S2MPS11 PMIC provides:
 	 - 38 adjustable LDO regulators
@@ -243,7 +225,6 @@ config PMIC_S2MPS11
 
 config DM_PMIC_SANDBOX
 	bool "Enable Driver Model for emulated Sandbox PMIC"
-	depends on DM_PMIC
 	---help---
 	Enable the driver for Sandbox PMIC emulation. The emulated PMIC device
 	depends on two drivers:
@@ -268,7 +249,6 @@ config DM_PMIC_SANDBOX
 
 config PMIC_S5M8767
 	bool "Enable Driver Model for the Samsung S5M8767 PMIC"
-	depends on DM_PMIC
 	---help---
 	The S5M8767 PMIC provides a large array of LDOs and BUCKs for use
 	as a SoC power controller. It also provides 32KHz clock outputs. This
@@ -277,7 +257,6 @@ config PMIC_S5M8767
 
 config PMIC_RN5T567
 	bool "Enable driver for Ricoh RN5T567 PMIC"
-	depends on DM_PMIC
 	---help---
 	The RN5T567 is a PMIC with 4 step-down DC/DC converters, 5 LDO
 	regulators Real-Time Clock and 4 GPIOs. This driver provides
@@ -285,7 +264,6 @@ config PMIC_RN5T567
 
 config PMIC_TPS65090
 	bool "Enable driver for Texas Instruments TPS65090 PMIC"
-	depends on DM_PMIC
 	---help---
 	The TPS65090 is a PMIC containing several LDOs, DC to DC convertors,
 	FETs and a battery charger. This driver provides register access
@@ -294,21 +272,18 @@ config PMIC_TPS65090
 
 config PMIC_PALMAS
 	bool "Enable driver for Texas Instruments PALMAS PMIC"
-	depends on DM_PMIC
 	---help---
 	The PALMAS is a PMIC containing several LDOs, SMPS.
 	This driver binds the pmic children.
 
 config PMIC_LP873X
 	bool "Enable driver for Texas Instruments LP873X PMIC"
-	depends on DM_PMIC
 	---help---
 	The LP873X is a PMIC containing couple of LDOs and couple of SMPS.
 	This driver binds the pmic children.
 
 config PMIC_LP87565
 	bool "Enable driver for Texas Instruments LP87565 PMIC"
-	depends on DM_PMIC
 	---help---
 	The LP87565 is a PMIC containing a bunch of SMPS.
 	This driver binds the pmic children.
@@ -322,7 +297,6 @@ config POWER_MC34VR500
 
 config DM_PMIC_TPS65910
 	bool "Enable driver for Texas Instruments TPS65910 PMIC"
-	depends on DM_PMIC
 	---help---
 	The TPS65910 is a PMIC containing 3 buck DC-DC converters, one boost
 	DC-DC converter, 8 LDOs and a RTC. This driver binds the SMPS and LDO
@@ -330,7 +304,7 @@ config DM_PMIC_TPS65910
 
 config PMIC_STPMIC1
 	bool "Enable support for STMicroelectronics STPMIC1 PMIC"
-	depends on DM_PMIC && DM_I2C
+	depends on DM_I2C
 	select SYSRESET_CMD_POWEROFF if CMD_POWEROFF && !ARM_PSCI_FW
 	---help---
 	The STPMIC1 PMIC provides 4 BUCKs, 6 LDOs, 1 VREF and 2 power switches.
@@ -339,28 +313,26 @@ config PMIC_STPMIC1
 
 config SPL_PMIC_PALMAS
 	bool "Enable driver for Texas Instruments PALMAS PMIC"
-	depends on DM_PMIC
 	help
 	The PALMAS is a PMIC containing several LDOs, SMPS.
 	This driver binds the pmic children in SPL.
 
 config SPL_PMIC_LP873X
 	bool "Enable driver for Texas Instruments LP873X PMIC"
-	depends on DM_PMIC
 	help
 	The LP873X is a PMIC containing couple of LDOs and couple of SMPS.
 	This driver binds the pmic children in SPL.
 
 config SPL_PMIC_LP87565
 	bool "Enable driver for Texas Instruments LP87565 PMIC"
-	depends on DM_PMIC
 	help
 	The LP87565 is a PMIC containing a bunch of SMPS.
 	This driver binds the pmic children in SPL.
 
 config PMIC_TPS65941
 	bool "Enable driver for Texas Instruments TPS65941 PMIC"
-	depends on DM_PMIC
 	help
 	The TPS65941 is a PMIC containing a bunch of SMPS & LDOs.
 	This driver binds the pmic children.
+
+endif
-- 
2.32.0


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

* [PATCH v2 02/12] power: pmic: Consistently depend on SPL_DM_PMIC
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
  2021-10-08  5:17 ` [PATCH v2 01/12] power: pmic: Consistently depend on DM_PMIC Samuel Holland
@ 2021-10-08  5:17 ` Samuel Holland
  2021-10-12 10:46   ` Andre Przywara
  2021-10-08  5:17 ` [PATCH v2 03/12] power: pmic: Add a driver for X-Powers AXP PMICs Samuel Holland
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

Now that there is a separate symbol to enable DM_PMIC in SPL, update the
the SPL-specific driver symbols to depend on this new option.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v2:
- Rebase to pick up 7abf178b ("power: Tidy up #undef of CONFIG_DM_PMIC")

 drivers/power/pmic/Kconfig | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index 2472555a3ff..e8a04325f85 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -36,6 +36,7 @@ config PMIC_CHILDREN
 
 config SPL_PMIC_CHILDREN
 	bool "Allow child devices for PMICs in SPL"
+	depends on SPL_DM_PMIC
 	default y
 	---help---
 	This allows PMICs to support child devices (such as regulators) in
@@ -70,7 +71,7 @@ config DM_PMIC_DA9063
 
 config SPL_DM_PMIC_DA9063
 	bool "Enable Driver Model for the Dialog DA9063 PMIC in SPL"
-	depends on SPL
+	depends on SPL_DM_PMIC
 	help
 	  This config enables implementation of driver-model pmic uclass features
 	  for PMIC DA9063. The driver implements read/write operations.
@@ -91,6 +92,7 @@ config DM_PMIC_BD71837
 
 config SPL_DM_PMIC_BD71837
 	bool "Enable Driver Model for PMIC BD71837 in SPL stage"
+	depends on SPL_DM_PMIC
 	help
 	  This config enables implementation of driver-model pmic uclass
 	  features for PMIC BD71837. The driver implements read/write
@@ -118,6 +120,7 @@ config DM_PMIC_MP5416
 
 config SPL_DM_PMIC_MP5416
 	bool "Enable Driver Model for PMIC MP5416 in SPL stage"
+	depends on SPL_DM_PMIC
 	help
 	  This config enables implementation of driver-model pmic uclass
 	  features for PMIC MP5416. The driver implements read/write
@@ -131,6 +134,7 @@ config DM_PMIC_PCA9450
 
 config SPL_DM_PMIC_PCA9450
 	bool "Enable Driver Model for PMIC PCA9450"
+	depends on SPL_DM_PMIC
 	help
 	  This config enables implementation of driver-model pmic uclass features
 	  for PMIC PCA9450 in SPL. The driver implements read/write operations.
@@ -143,6 +147,7 @@ config DM_PMIC_PFUZE100
 
 config SPL_DM_PMIC_PFUZE100
 	bool "Enable Driver Model for PMIC PFUZE100 in SPL"
+	depends on SPL_DM_PMIC
 	---help---
 	This config enables implementation of driver-model pmic uclass features
 	for PMIC PFUZE100 in SPL. The driver implements read/write operations.
@@ -204,6 +209,7 @@ config PMIC_RK8XX
 
 config SPL_PMIC_RK8XX
 	bool "Enable support for Rockchip PMIC RK8XX"
+	depends on SPL_DM_PMIC
 	---help---
 	The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs,
 	an RTC and two low Rds (resistance (drain to source)) switches. It is
@@ -313,18 +319,21 @@ config PMIC_STPMIC1
 
 config SPL_PMIC_PALMAS
 	bool "Enable driver for Texas Instruments PALMAS PMIC"
+	depends on SPL_DM_PMIC
 	help
 	The PALMAS is a PMIC containing several LDOs, SMPS.
 	This driver binds the pmic children in SPL.
 
 config SPL_PMIC_LP873X
 	bool "Enable driver for Texas Instruments LP873X PMIC"
+	depends on SPL_DM_PMIC
 	help
 	The LP873X is a PMIC containing couple of LDOs and couple of SMPS.
 	This driver binds the pmic children in SPL.
 
 config SPL_PMIC_LP87565
 	bool "Enable driver for Texas Instruments LP87565 PMIC"
+	depends on SPL_DM_PMIC
 	help
 	The LP87565 is a PMIC containing a bunch of SMPS.
 	This driver binds the pmic children in SPL.
-- 
2.32.0


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

* [PATCH v2 03/12] power: pmic: Add a driver for X-Powers AXP PMICs
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
  2021-10-08  5:17 ` [PATCH v2 01/12] power: pmic: Consistently depend on DM_PMIC Samuel Holland
  2021-10-08  5:17 ` [PATCH v2 02/12] power: pmic: Consistently depend on SPL_DM_PMIC Samuel Holland
@ 2021-10-08  5:17 ` Samuel Holland
  2021-10-12 10:47   ` Andre Przywara
  2021-10-08  5:17 ` [PATCH v2 04/12] sunxi: Only initialize legacy I2C when enabled Samuel Holland
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

These PMICs provide some combination of battery charger, fuel gauge,
GPIOs, regulators, and VBUS routing. These functions are represented
as child nodes in the device tree. Add the minimal driver needed to
probe these child devices and provide the DM_PMIC ops.

Enable the driver by default for SoCs that normally pair with a PMIC.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v2:
- Replace axp_pmic_bind() with `.bind = dm_scan_fdt_dev`

 drivers/power/pmic/Kconfig  | 14 ++++++++++++++
 drivers/power/pmic/Makefile |  1 +
 drivers/power/pmic/axp.c    | 38 +++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+)
 create mode 100644 drivers/power/pmic/axp.c

diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index e8a04325f85..fcb517f1044 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -63,6 +63,20 @@ config PMIC_ACT8846
 	functions. It uses an I2C interface and is designed for use with
 	tablets and smartphones.
 
+config PMIC_AXP
+	bool "Enable Driver Model for X-Powers AXP PMICs"
+	depends on DM_I2C
+	help
+	  This config enables driver-model PMIC uclass features for
+	  X-Powers AXP152, AXP2xx, and AXP8xx PMICs.
+
+config SPL_PMIC_AXP
+	bool "Enable Driver Model for X-Powers AXP PMICs in SPL"
+	depends on SPL_DM_I2C && SPL_DM_PMIC
+	help
+	  This config enables driver-model PMIC uclass features in the SPL for
+	  X-Powers AXP152, AXP2xx, and AXP8xx PMICs.
+
 config DM_PMIC_DA9063
 	bool "Enable Driver Model for the Dialog DA9063 PMIC"
 	help
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
index 5250eac12f2..e1922df00f8 100644
--- a/drivers/power/pmic/Makefile
+++ b/drivers/power/pmic/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
 obj-$(CONFIG_PMIC_AB8500) += ab8500.o
 obj-$(CONFIG_PMIC_ACT8846) += act8846.o
 obj-$(CONFIG_PMIC_AS3722) += as3722.o as3722_gpio.o
+obj-$(CONFIG_$(SPL_)PMIC_AXP) += axp.o
 obj-$(CONFIG_PMIC_MAX8997) += max8997.o
 obj-$(CONFIG_PMIC_PM8916) += pm8916.o
 obj-$(CONFIG_$(SPL_TPL_)PMIC_RK8XX) += rk8xx.o
diff --git a/drivers/power/pmic/axp.c b/drivers/power/pmic/axp.c
new file mode 100644
index 00000000000..74c94bdb47b
--- /dev/null
+++ b/drivers/power/pmic/axp.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+
+static int axp_pmic_reg_count(struct udevice *dev)
+{
+	/* TODO: Get the specific value from driver data. */
+	return 0x100;
+}
+
+static struct dm_pmic_ops axp_pmic_ops = {
+	.reg_count	= axp_pmic_reg_count,
+	.read		= dm_i2c_read,
+	.write		= dm_i2c_write,
+};
+
+static const struct udevice_id axp_pmic_ids[] = {
+	{ .compatible = "x-powers,axp152" },
+	{ .compatible = "x-powers,axp202" },
+	{ .compatible = "x-powers,axp209" },
+	{ .compatible = "x-powers,axp221" },
+	{ .compatible = "x-powers,axp223" },
+	{ .compatible = "x-powers,axp803" },
+	{ .compatible = "x-powers,axp806" },
+	{ .compatible = "x-powers,axp809" },
+	{ .compatible = "x-powers,axp813" },
+	{ }
+};
+
+U_BOOT_DRIVER(axp_pmic) = {
+	.name		= "axp_pmic",
+	.id		= UCLASS_PMIC,
+	.of_match	= axp_pmic_ids,
+	.bind		= dm_scan_fdt_dev,
+	.ops		= &axp_pmic_ops,
+};
-- 
2.32.0


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

* [PATCH v2 04/12] sunxi: Only initialize legacy I2C when enabled
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
                   ` (2 preceding siblings ...)
  2021-10-08  5:17 ` [PATCH v2 03/12] power: pmic: Add a driver for X-Powers AXP PMICs Samuel Holland
@ 2021-10-08  5:17 ` Samuel Holland
  2021-10-12 10:47   ` Andre Przywara
  2021-10-08  5:17 ` [PATCH v2 05/12] sunxi: Select SUN8I_RSB more carefully Samuel Holland
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

CONFIG_SPL_I2C is the wrong symbol to use here. It is the top-level
Kconfig symbol (not specific to either legacy or DM I2C), whereas the
i2c_init() function is specific to legacy I2C. This change fixes a
build failure when enabling SPL_I2C but not SPL_SYS_I2C_LEGACY.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
Actually, I think this commit raises a larger issue:

For some reason, SPL_SYS_I2C_LEGACY does not depend on SPL_I2C. When
SPL_SYS_I2C_LEGACY was added in commit 55dabcc8f245 ("Convert
CONFIG_SYS_I2C_LEGACY to Kconfig and add CONFIG_[ST]PL_SYS_I2C_LEGACY"),
SPL_I2C wasn't added to the board configs.

But since commit 537892065ac1 ("Makefile: Move drivers/i2c/ into
drivers/Makefile"), drivers/i2c is only compiled if SPL_I2C is enabled.

So the combination of these two commits appears to have accidentally
removed I2C support from SPL for many boards.

The impact here is that checking CONFIG_IS_ENABLED(SYS_I2C_LEGACY) is
not always enough, even though it should be. Because if CONFIG_SPL_I2C=n
then i2c_init is undefined because drivers/i2c/i2c_core.c is not built.

Changes in v2:
- New patch to account for I2C Kconfig changes

 arch/arm/mach-sunxi/board.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index d9b04f75fc4..b74ad4074df 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -339,7 +339,7 @@ void board_init_f(ulong dummy)
 	spl_init();
 	preloader_console_init();
 
-#ifdef CONFIG_SPL_I2C
+#if CONFIG_IS_ENABLED(I2C) && CONFIG_IS_ENABLED(SYS_I2C_LEGACY)
 	/* Needed early by sunxi_board_init if PMU is enabled */
 	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
 #endif
-- 
2.32.0


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

* [PATCH v2 05/12] sunxi: Select SUN8I_RSB more carefully
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
                   ` (3 preceding siblings ...)
  2021-10-08  5:17 ` [PATCH v2 04/12] sunxi: Only initialize legacy I2C when enabled Samuel Holland
@ 2021-10-08  5:17 ` Samuel Holland
  2021-10-12 10:47   ` Andre Przywara
  2021-10-08  5:17 ` [PATCH v2 06/12] sunxi: pmic_bus: Fix Kconfig dependencies Samuel Holland
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

SUN8I_RSB should not be selected by MACH_SUN8I, because the hardware
is not present in half of those SoCs (H3/H5, R40, and V3s). Move the
selection to the SoCs where the hardware actually exists.

Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v2:
- No changes

 arch/arm/mach-sunxi/Kconfig | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 1d4a4fdd0c5..677d4554173 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -260,6 +260,7 @@ config MACH_SUN8I_A23
 	select ARCH_SUPPORT_PSCI
 	select DRAM_SUN8I_A23
 	select PHY_SUN4I_USB
+	select SUN8I_RSB
 	select SUNXI_GEN_SUN6I
 	select SUPPORT_SPL
 	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
@@ -273,6 +274,7 @@ config MACH_SUN8I_A33
 	select ARCH_SUPPORT_PSCI
 	select DRAM_SUN8I_A33
 	select PHY_SUN4I_USB
+	select SUN8I_RSB
 	select SUNXI_GEN_SUN6I
 	select SUPPORT_SPL
 	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
@@ -283,6 +285,7 @@ config MACH_SUN8I_A83T
 	select CPU_V7A
 	select DRAM_SUN8I_A83T
 	select PHY_SUN4I_USB
+	select SUN8I_RSB
 	select SUNXI_GEN_SUN6I
 	select MMC_SUNXI_HAS_NEW_MODE
 	select MMC_SUNXI_HAS_MODE_SWITCH
@@ -377,7 +380,6 @@ endchoice
 # The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 || A33"
 config MACH_SUN8I
 	bool
-	select SUN8I_RSB
 	select SUN6I_PRCM
 	default y if MACH_SUN8I_A23
 	default y if MACH_SUN8I_A33
-- 
2.32.0


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

* [PATCH v2 06/12] sunxi: pmic_bus: Fix Kconfig dependencies
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
                   ` (4 preceding siblings ...)
  2021-10-08  5:17 ` [PATCH v2 05/12] sunxi: Select SUN8I_RSB more carefully Samuel Holland
@ 2021-10-08  5:17 ` Samuel Holland
  2021-10-08  5:17 ` [PATCH v2 07/12] i2c: Add a DM_I2C driver for the sun6i P2WI controller Samuel Holland
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

AXP_PMIC_BUS enables communication with a specific AXP PMIC at a
PMIC-dependent I2C/P2WI/RSB bus address. It is automatically selected
as a dependency of the PMIC driver. It should not be selectable by the
user when no PMIC is chosen.

AXP_GPIO uses the pmic_bus functions, and also depends on a specific
PMIC header to pick up register definitions.

Both of these changes have no impact on any existing configs, since
the code does not compile if the dependencies are not met.

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v2:
- No changes

 arch/arm/mach-sunxi/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 677d4554173..4d8f0e17d40 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -106,7 +106,7 @@ config SUN6I_PRCM
 	  in A31 SoC.
 
 config AXP_PMIC_BUS
-	bool "Sunxi AXP PMIC bus access helpers"
+	bool
 	help
 	  Select this PMIC bus access helpers for Sunxi platform PRCM or other
 	  AXP family PMIC devices.
@@ -809,6 +809,7 @@ endif
 
 config AXP_GPIO
 	bool "Enable support for gpio-s on axp PMICs"
+	depends on AXP_PMIC_BUS
 	---help---
 	Say Y here to enable support for the gpio pins of the axp PMIC ICs.
 
-- 
2.32.0


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

* [PATCH v2 07/12] i2c: Add a DM_I2C driver for the sun6i P2WI controller
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
                   ` (5 preceding siblings ...)
  2021-10-08  5:17 ` [PATCH v2 06/12] sunxi: pmic_bus: Fix Kconfig dependencies Samuel Holland
@ 2021-10-08  5:17 ` Samuel Holland
  2021-10-12 10:49   ` Andre Przywara
  2021-10-08  5:17 ` [PATCH v2 08/12] i2c: Add a DM_I2C driver for the sun8i RSB controller Samuel Holland
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

This bus controller is used to communicate with an X-Powers AXP PMIC.
Currently, various drivers access PMIC registers through a platform-
specific non-DM "pmic_bus" interface, which depends on the legacy I2C
framework. In order to convert those drivers to use DM_PMIC, this bus
needs a DM_I2C driver.

Refactor the p2wi functions to take the base address as a parameter,
and implement both the existing interface (which is still needed in
SPL) and the DM_I2C interface on top of them.

The register for switching between I2C/P2WI/RSB mode is the same across
all PMIC variants. Move that to the common header, so it can be used by
both interface implementations.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v2:
- Renamed Kconfig symbol to SYS_I2C_SUN6I_P2WI
- Moved entire P2WI driver source to drivers/i2c

 arch/arm/mach-sunxi/Kconfig    |  14 +--
 arch/arm/mach-sunxi/Makefile   |   1 -
 arch/arm/mach-sunxi/p2wi.c     | 117 ------------------
 arch/arm/mach-sunxi/pmic_bus.c |   7 +-
 drivers/i2c/Kconfig            |   8 ++
 drivers/i2c/Makefile           |   1 +
 drivers/i2c/sun6i_p2wi.c       | 220 +++++++++++++++++++++++++++++++++
 include/axp_pmic.h             |   6 +
 8 files changed, 240 insertions(+), 134 deletions(-)
 delete mode 100644 arch/arm/mach-sunxi/p2wi.c
 create mode 100644 drivers/i2c/sun6i_p2wi.c

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 4d8f0e17d40..ae3b7974f09 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -88,17 +88,6 @@ config DRAM_SUN50I_H616_UNKNOWN_FEATURE
 	  feature.
 endif
 
-config SUN6I_P2WI
-	bool "Allwinner sun6i internal P2WI controller"
-	help
-	  If you say yes to this option, support will be included for the
-	  P2WI (Push/Pull 2 Wire Interface) controller embedded in some sunxi
-	  SOCs.
-	  The P2WI looks like an SMBus controller (which supports only byte
-	  accesses), except that it only supports one slave device.
-	  This interface is used to connect to specific PMIC devices (like the
-	  AXP221).
-
 config SUN6I_PRCM
 	bool
 	help
@@ -232,10 +221,11 @@ config MACH_SUN6I
 	select ARCH_SUPPORT_PSCI
 	select DRAM_SUN6I
 	select PHY_SUN4I_USB
-	select SUN6I_P2WI
+	select SPL_I2C
 	select SUN6I_PRCM
 	select SUNXI_GEN_SUN6I
 	select SUPPORT_SPL
+	select SYS_I2C_SUN6I_P2WI
 	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
 
 config MACH_SUN7I
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index 3f081d92f37..c9312bb3934 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -11,7 +11,6 @@ obj-y	+= clock.o
 obj-y	+= cpu_info.o
 obj-y	+= dram_helpers.o
 obj-y	+= pinmux.o
-obj-$(CONFIG_SUN6I_P2WI)	+= p2wi.o
 obj-$(CONFIG_SUN6I_PRCM)	+= prcm.o
 obj-$(CONFIG_AXP_PMIC_BUS)	+= pmic_bus.o
 obj-$(CONFIG_SUN8I_RSB)		+= rsb.o
diff --git a/arch/arm/mach-sunxi/p2wi.c b/arch/arm/mach-sunxi/p2wi.c
deleted file mode 100644
index 7c5c12254ea..00000000000
--- a/arch/arm/mach-sunxi/p2wi.c
+++ /dev/null
@@ -1,117 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Sunxi A31 Power Management Unit
- *
- * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
- * http://linux-sunxi.org
- *
- * Based on sun6i sources and earlier U-Boot Allwinner A10 SPL work
- *
- * (C) Copyright 2006-2013
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- * Berg Xing <bergxing@allwinnertech.com>
- * Tom Cubie <tangliang@allwinnertech.com>
- */
-
-#include <common.h>
-#include <errno.h>
-#include <time.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/gpio.h>
-#include <asm/arch/p2wi.h>
-#include <asm/arch/prcm.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/sys_proto.h>
-
-void p2wi_init(void)
-{
-	struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE;
-
-	/* Enable p2wi and PIO clk, and de-assert their resets */
-	prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_P2WI);
-
-	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN6I_GPL0_R_P2WI_SCK);
-	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN6I_GPL1_R_P2WI_SDA);
-
-	/* Reset p2wi controller and set clock to CLKIN(12)/8 = 1.5 MHz */
-	writel(P2WI_CTRL_RESET, &p2wi->ctrl);
-	sdelay(0x100);
-	writel(P2WI_CC_SDA_OUT_DELAY(1) | P2WI_CC_CLK_DIV(8),
-	       &p2wi->cc);
-}
-
-int p2wi_change_to_p2wi_mode(u8 slave_addr, u8 ctrl_reg, u8 init_data)
-{
-	struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE;
-	unsigned long tmo = timer_get_us() + 1000000;
-
-	writel(P2WI_PM_DEV_ADDR(slave_addr) |
-	       P2WI_PM_CTRL_ADDR(ctrl_reg) |
-	       P2WI_PM_INIT_DATA(init_data) |
-	       P2WI_PM_INIT_SEND,
-	       &p2wi->pm);
-
-	while ((readl(&p2wi->pm) & P2WI_PM_INIT_SEND)) {
-		if (timer_get_us() > tmo)
-			return -ETIME;
-	}
-
-	return 0;
-}
-
-static int p2wi_await_trans(void)
-{
-	struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE;
-	unsigned long tmo = timer_get_us() + 1000000;
-	int ret;
-	u8 reg;
-
-	while (1) {
-		reg = readl(&p2wi->status);
-		if (reg & P2WI_STAT_TRANS_ERR) {
-			ret = -EIO;
-			break;
-		}
-		if (reg & P2WI_STAT_TRANS_DONE) {
-			ret = 0;
-			break;
-		}
-		if (timer_get_us() > tmo) {
-			ret = -ETIME;
-			break;
-		}
-	}
-	writel(reg, &p2wi->status); /* Clear status bits */
-	return ret;
-}
-
-int p2wi_read(const u8 addr, u8 *data)
-{
-	struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE;
-	int ret;
-
-	writel(P2WI_DATADDR_BYTE_1(addr), &p2wi->dataddr0);
-	writel(P2WI_DATA_NUM_BYTES(1) |
-	       P2WI_DATA_NUM_BYTES_READ, &p2wi->numbytes);
-	writel(P2WI_STAT_TRANS_DONE, &p2wi->status);
-	writel(P2WI_CTRL_TRANS_START, &p2wi->ctrl);
-
-	ret = p2wi_await_trans();
-
-	*data = readl(&p2wi->data0) & P2WI_DATA_BYTE_1_MASK;
-	return ret;
-}
-
-int p2wi_write(const u8 addr, u8 data)
-{
-	struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE;
-
-	writel(P2WI_DATADDR_BYTE_1(addr), &p2wi->dataddr0);
-	writel(P2WI_DATA_BYTE_1(data), &p2wi->data0);
-	writel(P2WI_DATA_NUM_BYTES(1), &p2wi->numbytes);
-	writel(P2WI_STAT_TRANS_DONE, &p2wi->status);
-	writel(P2WI_CTRL_TRANS_START, &p2wi->ctrl);
-
-	return p2wi_await_trans();
-}
diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c
index 0394ce85644..673a05fdd16 100644
--- a/arch/arm/mach-sunxi/pmic_bus.c
+++ b/arch/arm/mach-sunxi/pmic_bus.c
@@ -8,6 +8,7 @@
  * axp223 uses the rsb bus, these functions abstract this.
  */
 
+#include <axp_pmic.h>
 #include <common.h>
 #include <asm/arch/p2wi.h>
 #include <asm/arch/rsb.h>
@@ -21,8 +22,6 @@
 #define AXP305_I2C_ADDR			0x36
 
 #define AXP221_CHIP_ADDR		0x68
-#define AXP221_CTRL_ADDR		0x3e
-#define AXP221_INIT_DATA		0x3e
 
 /* AXP818 device and runtime addresses are same as AXP223 */
 #define AXP223_DEVICE_ADDR		0x3a3
@@ -40,8 +39,8 @@ int pmic_bus_init(void)
 #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER
 # ifdef CONFIG_MACH_SUN6I
 	p2wi_init();
-	ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR,
-				       AXP221_INIT_DATA);
+	ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP_PMIC_MODE_REG,
+				       AXP_PMIC_MODE_P2WI);
 # elif defined CONFIG_MACH_SUN8I_R40
 	/* Nothing. R40 uses the AXP221s in I2C mode */
 	ret = 0;
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 57cac4483f0..0adf143abfd 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -575,6 +575,14 @@ config SYS_I2C_STM32F7
 	   _ Optional clock stretching
 	   _ Software reset
 
+config SYS_I2C_SUN6I_P2WI
+	bool "Allwinner sun6i P2WI controller"
+	depends on ARCH_SUNXI
+	help
+	  Support for the P2WI (Push/Pull 2 Wire Interface) controller embedded
+	  in the Allwinner A31 and A31s SOCs. This interface is used to connect
+	  to specific devices like the X-Powers AXP221 PMIC.
+
 config SYS_I2C_SYNQUACER
 	bool "Socionext SynQuacer I2C controller"
 	depends on ARCH_SYNQUACER && DM_I2C
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 67841bf3e02..0a2cc641930 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o
 obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
 obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
 obj-$(CONFIG_SYS_I2C_STM32F7) += stm32f7_i2c.o
+obj-$(CONFIG_SYS_I2C_SUN6I_P2WI) += sun6i_p2wi.o
 obj-$(CONFIG_SYS_I2C_SYNQUACER) += synquacer_i2c.o
 obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
 obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o
diff --git a/drivers/i2c/sun6i_p2wi.c b/drivers/i2c/sun6i_p2wi.c
new file mode 100644
index 00000000000..c9e1b3fcd5f
--- /dev/null
+++ b/drivers/i2c/sun6i_p2wi.c
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Sunxi A31 Power Management Unit
+ *
+ * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
+ * http://linux-sunxi.org
+ *
+ * Based on sun6i sources and earlier U-Boot Allwinner A10 SPL work
+ *
+ * (C) Copyright 2006-2013
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Berg Xing <bergxing@allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ */
+
+#include <axp_pmic.h>
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <i2c.h>
+#include <time.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/p2wi.h>
+#include <asm/arch/prcm.h>
+#include <asm/arch/sys_proto.h>
+
+static int sun6i_p2wi_await_trans(struct sunxi_p2wi_reg *base)
+{
+	unsigned long tmo = timer_get_us() + 1000000;
+	int ret;
+	u8 reg;
+
+	while (1) {
+		reg = readl(&base->status);
+		if (reg & P2WI_STAT_TRANS_ERR) {
+			ret = -EIO;
+			break;
+		}
+		if (reg & P2WI_STAT_TRANS_DONE) {
+			ret = 0;
+			break;
+		}
+		if (timer_get_us() > tmo) {
+			ret = -ETIME;
+			break;
+		}
+	}
+	writel(reg, &base->status); /* Clear status bits */
+
+	return ret;
+}
+
+static int sun6i_p2wi_read(struct sunxi_p2wi_reg *base, const u8 addr, u8 *data)
+{
+	int ret;
+
+	writel(P2WI_DATADDR_BYTE_1(addr), &base->dataddr0);
+	writel(P2WI_DATA_NUM_BYTES(1) |
+	       P2WI_DATA_NUM_BYTES_READ, &base->numbytes);
+	writel(P2WI_STAT_TRANS_DONE, &base->status);
+	writel(P2WI_CTRL_TRANS_START, &base->ctrl);
+
+	ret = sun6i_p2wi_await_trans(base);
+
+	*data = readl(&base->data0) & P2WI_DATA_BYTE_1_MASK;
+
+	return ret;
+}
+
+static int sun6i_p2wi_write(struct sunxi_p2wi_reg *base, const u8 addr, u8 data)
+{
+	writel(P2WI_DATADDR_BYTE_1(addr), &base->dataddr0);
+	writel(P2WI_DATA_BYTE_1(data), &base->data0);
+	writel(P2WI_DATA_NUM_BYTES(1), &base->numbytes);
+	writel(P2WI_STAT_TRANS_DONE, &base->status);
+	writel(P2WI_CTRL_TRANS_START, &base->ctrl);
+
+	return sun6i_p2wi_await_trans(base);
+}
+
+static int sun6i_p2wi_change_to_p2wi_mode(struct sunxi_p2wi_reg *base,
+					  u8 slave_addr, u8 ctrl_reg,
+					  u8 init_data)
+{
+	unsigned long tmo = timer_get_us() + 1000000;
+
+	writel(P2WI_PM_DEV_ADDR(slave_addr) |
+	       P2WI_PM_CTRL_ADDR(ctrl_reg) |
+	       P2WI_PM_INIT_DATA(init_data) |
+	       P2WI_PM_INIT_SEND,
+	       &base->pm);
+
+	while ((readl(&base->pm) & P2WI_PM_INIT_SEND)) {
+		if (timer_get_us() > tmo)
+			return -ETIME;
+	}
+
+	return 0;
+}
+
+static void sun6i_p2wi_init(struct sunxi_p2wi_reg *base)
+{
+	/* Enable p2wi and PIO clk, and de-assert their resets */
+	prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_P2WI);
+
+	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN6I_GPL0_R_P2WI_SCK);
+	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN6I_GPL1_R_P2WI_SDA);
+
+	/* Reset p2wi controller and set clock to CLKIN(12)/8 = 1.5 MHz */
+	writel(P2WI_CTRL_RESET, &base->ctrl);
+	sdelay(0x100);
+	writel(P2WI_CC_SDA_OUT_DELAY(1) | P2WI_CC_CLK_DIV(8),
+	       &base->cc);
+}
+
+#if IS_ENABLED(CONFIG_AXP_PMIC_BUS)
+int p2wi_read(const u8 addr, u8 *data)
+{
+	struct sunxi_p2wi_reg *base = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE;
+
+	return sun6i_p2wi_read(base, addr, data);
+}
+
+int p2wi_write(const u8 addr, u8 data)
+{
+	struct sunxi_p2wi_reg *base = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE;
+
+	return sun6i_p2wi_write(base, addr, data);
+}
+
+int p2wi_change_to_p2wi_mode(u8 slave_addr, u8 ctrl_reg, u8 init_data)
+{
+	struct sunxi_p2wi_reg *base = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE;
+
+	return sun6i_p2wi_change_to_p2wi_mode(base, slave_addr, ctrl_reg,
+					      init_data);
+}
+
+void p2wi_init(void)
+{
+	struct sunxi_p2wi_reg *base = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE;
+
+	sun6i_p2wi_init(base);
+}
+#endif
+
+#if CONFIG_IS_ENABLED(DM_I2C)
+struct sun6i_p2wi_priv {
+	struct sunxi_p2wi_reg *base;
+};
+
+static int sun6i_p2wi_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
+{
+	struct sun6i_p2wi_priv *priv = dev_get_priv(bus);
+
+	/* The hardware only supports SMBus-style transfers. */
+	if (nmsgs == 2 && msg[1].flags == I2C_M_RD && msg[1].len == 1)
+		return sun6i_p2wi_read(priv->base,
+				       msg[0].buf[0], &msg[1].buf[0]);
+
+	if (nmsgs == 1 && msg[0].len == 2)
+		return sun6i_p2wi_write(priv->base,
+					msg[0].buf[0], msg[0].buf[1]);
+
+	return -EINVAL;
+}
+
+static int sun6i_p2wi_probe_chip(struct udevice *bus, uint chip_addr,
+				 uint chip_flags)
+{
+	struct sun6i_p2wi_priv *priv = dev_get_priv(bus);
+
+	return sun6i_p2wi_change_to_p2wi_mode(priv->base, chip_addr,
+					      AXP_PMIC_MODE_REG,
+					      AXP_PMIC_MODE_P2WI);
+}
+
+static int sun6i_p2wi_probe(struct udevice *bus)
+{
+	struct sun6i_p2wi_priv *priv = dev_get_priv(bus);
+
+	priv->base = dev_read_addr_ptr(bus);
+
+	sun6i_p2wi_init(priv->base);
+
+	return 0;
+}
+
+static int sun6i_p2wi_child_pre_probe(struct udevice *child)
+{
+	struct dm_i2c_chip *chip = dev_get_parent_plat(child);
+
+	/* Ensure each transfer is for a single register. */
+	chip->flags |= DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS;
+
+	return 0;
+}
+
+static const struct dm_i2c_ops sun6i_p2wi_ops = {
+	.xfer		= sun6i_p2wi_xfer,
+	.probe_chip	= sun6i_p2wi_probe_chip,
+};
+
+static const struct udevice_id sun6i_p2wi_ids[] = {
+	{ .compatible = "allwinner,sun6i-a31-p2wi" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(sun6i_p2wi) = {
+	.name			= "sun6i_p2wi",
+	.id			= UCLASS_I2C,
+	.of_match		= sun6i_p2wi_ids,
+	.probe			= sun6i_p2wi_probe,
+	.child_pre_probe	= sun6i_p2wi_child_pre_probe,
+	.priv_auto		= sizeof(struct sun6i_p2wi_priv),
+	.ops			= &sun6i_p2wi_ops,
+};
+#endif /* CONFIG_IS_ENABLED(DM_I2C) */
diff --git a/include/axp_pmic.h b/include/axp_pmic.h
index 405044c3a32..0db3e143eda 100644
--- a/include/axp_pmic.h
+++ b/include/axp_pmic.h
@@ -6,6 +6,8 @@
  */
 #ifndef _AXP_PMIC_H_
 
+#include <stdbool.h>
+
 #ifdef CONFIG_AXP152_POWER
 #include <axp152.h>
 #endif
@@ -25,6 +27,10 @@
 #include <axp818.h>
 #endif
 
+#define AXP_PMIC_MODE_REG		0x3e
+#define AXP_PMIC_MODE_I2C		0x00
+#define AXP_PMIC_MODE_P2WI		0x3e
+
 int axp_set_dcdc1(unsigned int mvolt);
 int axp_set_dcdc2(unsigned int mvolt);
 int axp_set_dcdc3(unsigned int mvolt);
-- 
2.32.0


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

* [PATCH v2 08/12] i2c: Add a DM_I2C driver for the sun8i RSB controller
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
                   ` (6 preceding siblings ...)
  2021-10-08  5:17 ` [PATCH v2 07/12] i2c: Add a DM_I2C driver for the sun6i P2WI controller Samuel Holland
@ 2021-10-08  5:17 ` Samuel Holland
  2021-10-12 10:49   ` Andre Przywara
  2021-10-08  5:17 ` [PATCH v2 09/12] sunxi: pmic_bus: Clean up preprocessor conditions Samuel Holland
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

This bus controller is used to communicate with an X-Powers AXP PMIC.
Currently, various drivers access PMIC registers through a platform-
specific non-DM "pmic_bus" interface, which depends on the legacy I2C
framework. In order to convert those drivers to use DM_PMIC, this bus
needs a DM_I2C driver.

Refactor the rsb functions to take the base address as a parameter,
and implement both the existing interface (which is still needed in
SPL) and the DM_I2C interface on top of them.

The register for switching between I2C/P2WI/RSB mode is the same across
all PMIC variants, so move that to the common header.

There are only a couple of pairs of hardware/runtime addresses used
across all PMIC variants. So far the code expected only the "primary"
pair, but some PMICs like the AXP305 and AXP805 use the secondary pair,
so add support for that to the DM driver as well.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v2:
- Renamed Kconfig symbol to SYS_I2C_SUN8I_RSB
- Moved entire RSB driver source to drivers/i2c

 arch/arm/mach-sunxi/Kconfig    |  20 +--
 arch/arm/mach-sunxi/Makefile   |   1 -
 arch/arm/mach-sunxi/pmic_bus.c |  11 +-
 arch/arm/mach-sunxi/rsb.c      | 175 --------------------
 drivers/i2c/Kconfig            |   8 +
 drivers/i2c/Makefile           |   1 +
 drivers/i2c/sun8i_rsb.c        | 281 +++++++++++++++++++++++++++++++++
 include/axp_pmic.h             |   6 +
 8 files changed, 308 insertions(+), 195 deletions(-)
 delete mode 100644 arch/arm/mach-sunxi/rsb.c
 create mode 100644 drivers/i2c/sun8i_rsb.c

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index ae3b7974f09..df160c9a775 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -100,14 +100,6 @@ config AXP_PMIC_BUS
 	  Select this PMIC bus access helpers for Sunxi platform PRCM or other
 	  AXP family PMIC devices.
 
-config SUN8I_RSB
-	bool "Allwinner sunXi Reduced Serial Bus Driver"
-	help
-	  Say y here to enable support for Allwinner's Reduced Serial Bus
-	  (RSB) support. This controller is responsible for communicating
-	  with various RSB based devices, such as AXP223, AXP8XX PMICs,
-	  and AC100/AC200 ICs.
-
 config SUNXI_SRAM_ADDRESS
 	hex
 	default 0x10000 if MACH_SUN9I || MACH_SUN50I || MACH_SUN50I_H5
@@ -250,9 +242,10 @@ config MACH_SUN8I_A23
 	select ARCH_SUPPORT_PSCI
 	select DRAM_SUN8I_A23
 	select PHY_SUN4I_USB
-	select SUN8I_RSB
+	select SPL_I2C
 	select SUNXI_GEN_SUN6I
 	select SUPPORT_SPL
+	select SYS_I2C_SUN8I_RSB
 	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
 	imply CONS_INDEX_5 if !DM_SERIAL
 
@@ -264,9 +257,10 @@ config MACH_SUN8I_A33
 	select ARCH_SUPPORT_PSCI
 	select DRAM_SUN8I_A33
 	select PHY_SUN4I_USB
-	select SUN8I_RSB
+	select SPL_I2C
 	select SUNXI_GEN_SUN6I
 	select SUPPORT_SPL
+	select SYS_I2C_SUN8I_RSB
 	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
 	imply CONS_INDEX_5 if !DM_SERIAL
 
@@ -275,11 +269,12 @@ config MACH_SUN8I_A83T
 	select CPU_V7A
 	select DRAM_SUN8I_A83T
 	select PHY_SUN4I_USB
-	select SUN8I_RSB
+	select SPL_I2C
 	select SUNXI_GEN_SUN6I
 	select MMC_SUNXI_HAS_NEW_MODE
 	select MMC_SUNXI_HAS_MODE_SWITCH
 	select SUPPORT_SPL
+	select SYS_I2C_SUN8I_RSB
 
 config MACH_SUN8I_H3
 	bool "sun8i (Allwinner H3)"
@@ -320,10 +315,11 @@ config MACH_SUN9I
 	bool "sun9i (Allwinner A80)"
 	select CPU_V7A
 	select DRAM_SUN9I
+	select SPL_I2C
 	select SUN6I_PRCM
 	select SUNXI_GEN_SUN6I
-	select SUN8I_RSB
 	select SUPPORT_SPL
+	select SYS_I2C_SUN8I_RSB
 
 config MACH_SUN50I
 	bool "sun50i (Allwinner A64)"
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index c9312bb3934..5d3fd70f749 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -13,7 +13,6 @@ obj-y	+= dram_helpers.o
 obj-y	+= pinmux.o
 obj-$(CONFIG_SUN6I_PRCM)	+= prcm.o
 obj-$(CONFIG_AXP_PMIC_BUS)	+= pmic_bus.o
-obj-$(CONFIG_SUN8I_RSB)		+= rsb.o
 obj-$(CONFIG_MACH_SUN4I)	+= clock_sun4i.o
 obj-$(CONFIG_MACH_SUN5I)	+= clock_sun4i.o
 obj-$(CONFIG_MACH_SUN6I)	+= clock_sun6i.o
diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c
index 673a05fdd16..827797249ea 100644
--- a/arch/arm/mach-sunxi/pmic_bus.c
+++ b/arch/arm/mach-sunxi/pmic_bus.c
@@ -23,10 +23,6 @@
 
 #define AXP221_CHIP_ADDR		0x68
 
-/* AXP818 device and runtime addresses are same as AXP223 */
-#define AXP223_DEVICE_ADDR		0x3a3
-#define AXP223_RUNTIME_ADDR		0x2d
-
 int pmic_bus_init(void)
 {
 	/* This cannot be 0 because it is used in SPL before BSS is ready */
@@ -49,7 +45,8 @@ int pmic_bus_init(void)
 	if (ret)
 		return ret;
 
-	ret = rsb_set_device_address(AXP223_DEVICE_ADDR, AXP223_RUNTIME_ADDR);
+	ret = rsb_set_device_address(AXP_PMIC_PRI_DEVICE_ADDR,
+				     AXP_PMIC_PRI_RUNTIME_ADDR);
 # endif
 	if (ret)
 		return ret;
@@ -73,7 +70,7 @@ int pmic_bus_read(u8 reg, u8 *data)
 # elif defined CONFIG_MACH_SUN8I_R40
 	return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1);
 # else
-	return rsb_read(AXP223_RUNTIME_ADDR, reg, data);
+	return rsb_read(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
 # endif
 #endif
 }
@@ -92,7 +89,7 @@ int pmic_bus_write(u8 reg, u8 data)
 # elif defined CONFIG_MACH_SUN8I_R40
 	return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1);
 # else
-	return rsb_write(AXP223_RUNTIME_ADDR, reg, data);
+	return rsb_write(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
 # endif
 #endif
 }
diff --git a/arch/arm/mach-sunxi/rsb.c b/arch/arm/mach-sunxi/rsb.c
deleted file mode 100644
index 01bb09b7478..00000000000
--- a/arch/arm/mach-sunxi/rsb.c
+++ /dev/null
@@ -1,175 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
- *
- * Based on allwinner u-boot sources rsb code which is:
- * (C) Copyright 2007-2013
- * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
- * lixiang <lixiang@allwinnertech.com>
- */
-
-#include <common.h>
-#include <errno.h>
-#include <time.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/gpio.h>
-#include <asm/arch/prcm.h>
-#include <asm/arch/rsb.h>
-
-static int rsb_set_device_mode(void);
-
-static void rsb_cfg_io(void)
-{
-#ifdef CONFIG_MACH_SUN8I
-	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB);
-	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB);
-	sunxi_gpio_set_pull(SUNXI_GPL(0), 1);
-	sunxi_gpio_set_pull(SUNXI_GPL(1), 1);
-	sunxi_gpio_set_drv(SUNXI_GPL(0), 2);
-	sunxi_gpio_set_drv(SUNXI_GPL(1), 2);
-#elif defined CONFIG_MACH_SUN9I
-	sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN_R_RSB);
-	sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN_R_RSB);
-	sunxi_gpio_set_pull(SUNXI_GPN(0), 1);
-	sunxi_gpio_set_pull(SUNXI_GPN(1), 1);
-	sunxi_gpio_set_drv(SUNXI_GPN(0), 2);
-	sunxi_gpio_set_drv(SUNXI_GPN(1), 2);
-#else
-#error unsupported MACH_SUNXI
-#endif
-}
-
-static void rsb_set_clk(void)
-{
-	struct sunxi_rsb_reg * const rsb =
-		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
-	u32 div = 0;
-	u32 cd_odly = 0;
-
-	/* Source is Hosc24M, set RSB clk to 3Mhz */
-	div = 24000000 / 3000000 / 2 - 1;
-	cd_odly = div >> 1;
-	if (!cd_odly)
-		cd_odly = 1;
-
-	writel((cd_odly << 8) | div, &rsb->ccr);
-}
-
-int rsb_init(void)
-{
-	struct sunxi_rsb_reg * const rsb =
-		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
-
-	/* Enable RSB and PIO clk, and de-assert their resets */
-	prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_RSB);
-
-	/* Setup external pins */
-	rsb_cfg_io();
-
-	writel(RSB_CTRL_SOFT_RST, &rsb->ctrl);
-	rsb_set_clk();
-
-	return rsb_set_device_mode();
-}
-
-static int rsb_await_trans(void)
-{
-	struct sunxi_rsb_reg * const rsb =
-		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
-	unsigned long tmo = timer_get_us() + 1000000;
-	u32 stat;
-	int ret;
-
-	while (1) {
-		stat = readl(&rsb->stat);
-		if (stat & RSB_STAT_LBSY_INT) {
-			ret = -EBUSY;
-			break;
-		}
-		if (stat & RSB_STAT_TERR_INT) {
-			ret = -EIO;
-			break;
-		}
-		if (stat & RSB_STAT_TOVER_INT) {
-			ret = 0;
-			break;
-		}
-		if (timer_get_us() > tmo) {
-			ret = -ETIME;
-			break;
-		}
-	}
-	writel(stat, &rsb->stat); /* Clear status bits */
-
-	return ret;
-}
-
-static int rsb_set_device_mode(void)
-{
-	struct sunxi_rsb_reg * const rsb =
-		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
-	unsigned long tmo = timer_get_us() + 1000000;
-
-	writel(RSB_DMCR_DEVICE_MODE_START | RSB_DMCR_DEVICE_MODE_DATA,
-	       &rsb->dmcr);
-
-	while (readl(&rsb->dmcr) & RSB_DMCR_DEVICE_MODE_START) {
-		if (timer_get_us() > tmo)
-			return -ETIME;
-	}
-
-	return rsb_await_trans();
-}
-
-static int rsb_do_trans(void)
-{
-	struct sunxi_rsb_reg * const rsb =
-		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
-
-	setbits_le32(&rsb->ctrl, RSB_CTRL_START_TRANS);
-	return rsb_await_trans();
-}
-
-int rsb_set_device_address(u16 device_addr, u16 runtime_addr)
-{
-	struct sunxi_rsb_reg * const rsb =
-		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
-
-	writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr) |
-	       RSB_DEVADDR_DEVICE_ADDR(device_addr), &rsb->devaddr);
-	writel(RSB_CMD_SET_RTSADDR, &rsb->cmd);
-
-	return rsb_do_trans();
-}
-
-int rsb_write(const u16 runtime_device_addr, const u8 reg_addr, u8 data)
-{
-	struct sunxi_rsb_reg * const rsb =
-		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
-
-	writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_device_addr), &rsb->devaddr);
-	writel(reg_addr, &rsb->addr);
-	writel(data, &rsb->data);
-	writel(RSB_CMD_BYTE_WRITE, &rsb->cmd);
-
-	return rsb_do_trans();
-}
-
-int rsb_read(const u16 runtime_device_addr, const u8 reg_addr, u8 *data)
-{
-	struct sunxi_rsb_reg * const rsb =
-		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
-	int ret;
-
-	writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_device_addr), &rsb->devaddr);
-	writel(reg_addr, &rsb->addr);
-	writel(RSB_CMD_BYTE_READ, &rsb->cmd);
-
-	ret = rsb_do_trans();
-	if (ret)
-		return ret;
-
-	*data = readl(&rsb->data) & 0xff;
-
-	return 0;
-}
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 0adf143abfd..66bd6fe2f34 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -583,6 +583,14 @@ config SYS_I2C_SUN6I_P2WI
 	  in the Allwinner A31 and A31s SOCs. This interface is used to connect
 	  to specific devices like the X-Powers AXP221 PMIC.
 
+config SYS_I2C_SUN8I_RSB
+	bool "Allwinner sun8i Reduced Serial Bus controller"
+	depends on ARCH_SUNXI
+	help
+	  Support for Allwinner's Reduced Serial Bus (RSB) controller. This
+	  controller is responsible for communicating with various RSB based
+	  devices, such as X-Powers AXPxxx PMICs and AC100/AC200 CODEC ICs.
+
 config SYS_I2C_SYNQUACER
 	bool "Socionext SynQuacer I2C controller"
 	depends on ARCH_SYNQUACER && DM_I2C
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 0a2cc641930..916427452a5 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
 obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
 obj-$(CONFIG_SYS_I2C_STM32F7) += stm32f7_i2c.o
 obj-$(CONFIG_SYS_I2C_SUN6I_P2WI) += sun6i_p2wi.o
+obj-$(CONFIG_SYS_I2C_SUN8I_RSB) += sun8i_rsb.o
 obj-$(CONFIG_SYS_I2C_SYNQUACER) += synquacer_i2c.o
 obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
 obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o
diff --git a/drivers/i2c/sun8i_rsb.c b/drivers/i2c/sun8i_rsb.c
new file mode 100644
index 00000000000..716b245a003
--- /dev/null
+++ b/drivers/i2c/sun8i_rsb.c
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ *
+ * Based on allwinner u-boot sources rsb code which is:
+ * (C) Copyright 2007-2013
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * lixiang <lixiang@allwinnertech.com>
+ */
+
+#include <axp_pmic.h>
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <i2c.h>
+#include <time.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/prcm.h>
+#include <asm/arch/rsb.h>
+
+static int sun8i_rsb_await_trans(struct sunxi_rsb_reg *base)
+{
+	unsigned long tmo = timer_get_us() + 1000000;
+	u32 stat;
+	int ret;
+
+	while (1) {
+		stat = readl(&base->stat);
+		if (stat & RSB_STAT_LBSY_INT) {
+			ret = -EBUSY;
+			break;
+		}
+		if (stat & RSB_STAT_TERR_INT) {
+			ret = -EIO;
+			break;
+		}
+		if (stat & RSB_STAT_TOVER_INT) {
+			ret = 0;
+			break;
+		}
+		if (timer_get_us() > tmo) {
+			ret = -ETIME;
+			break;
+		}
+	}
+	writel(stat, &base->stat); /* Clear status bits */
+
+	return ret;
+}
+
+static int sun8i_rsb_do_trans(struct sunxi_rsb_reg *base)
+{
+	setbits_le32(&base->ctrl, RSB_CTRL_START_TRANS);
+
+	return sun8i_rsb_await_trans(base);
+}
+
+static int sun8i_rsb_read(struct sunxi_rsb_reg *base, u16 runtime_addr,
+			  u8 reg_addr, u8 *data)
+{
+	int ret;
+
+	writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr), &base->devaddr);
+	writel(reg_addr, &base->addr);
+	writel(RSB_CMD_BYTE_READ, &base->cmd);
+
+	ret = sun8i_rsb_do_trans(base);
+	if (ret)
+		return ret;
+
+	*data = readl(&base->data) & 0xff;
+
+	return 0;
+}
+
+static int sun8i_rsb_write(struct sunxi_rsb_reg *base, u16 runtime_addr,
+			   u8 reg_addr, u8 data)
+{
+	writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr), &base->devaddr);
+	writel(reg_addr, &base->addr);
+	writel(data, &base->data);
+	writel(RSB_CMD_BYTE_WRITE, &base->cmd);
+
+	return sun8i_rsb_do_trans(base);
+}
+
+static int sun8i_rsb_set_device_address(struct sunxi_rsb_reg *base,
+					u16 device_addr, u16 runtime_addr)
+{
+	writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr) |
+	       RSB_DEVADDR_DEVICE_ADDR(device_addr), &base->devaddr);
+	writel(RSB_CMD_SET_RTSADDR, &base->cmd);
+
+	return sun8i_rsb_do_trans(base);
+}
+
+static void sun8i_rsb_cfg_io(void)
+{
+#ifdef CONFIG_MACH_SUN8I
+	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB);
+	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB);
+	sunxi_gpio_set_pull(SUNXI_GPL(0), 1);
+	sunxi_gpio_set_pull(SUNXI_GPL(1), 1);
+	sunxi_gpio_set_drv(SUNXI_GPL(0), 2);
+	sunxi_gpio_set_drv(SUNXI_GPL(1), 2);
+#elif defined CONFIG_MACH_SUN9I
+	sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN_R_RSB);
+	sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN_R_RSB);
+	sunxi_gpio_set_pull(SUNXI_GPN(0), 1);
+	sunxi_gpio_set_pull(SUNXI_GPN(1), 1);
+	sunxi_gpio_set_drv(SUNXI_GPN(0), 2);
+	sunxi_gpio_set_drv(SUNXI_GPN(1), 2);
+#else
+#error unsupported MACH_SUNXI
+#endif
+}
+
+static void sun8i_rsb_set_clk(struct sunxi_rsb_reg *base)
+{
+	u32 div = 0;
+	u32 cd_odly = 0;
+
+	/* Source is Hosc24M, set RSB clk to 3Mhz */
+	div = 24000000 / 3000000 / 2 - 1;
+	cd_odly = div >> 1;
+	if (!cd_odly)
+		cd_odly = 1;
+
+	writel((cd_odly << 8) | div, &base->ccr);
+}
+
+static int sun8i_rsb_set_device_mode(struct sunxi_rsb_reg *base)
+{
+	unsigned long tmo = timer_get_us() + 1000000;
+
+	writel(RSB_DMCR_DEVICE_MODE_START | RSB_DMCR_DEVICE_MODE_DATA,
+	       &base->dmcr);
+
+	while (readl(&base->dmcr) & RSB_DMCR_DEVICE_MODE_START) {
+		if (timer_get_us() > tmo)
+			return -ETIME;
+	}
+
+	return sun8i_rsb_await_trans(base);
+}
+
+static int sun8i_rsb_init(struct sunxi_rsb_reg *base)
+{
+	/* Enable RSB and PIO clk, and de-assert their resets */
+	prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_RSB);
+
+	/* Setup external pins */
+	sun8i_rsb_cfg_io();
+
+	writel(RSB_CTRL_SOFT_RST, &base->ctrl);
+	sun8i_rsb_set_clk(base);
+
+	return sun8i_rsb_set_device_mode(base);
+}
+
+#if IS_ENABLED(CONFIG_AXP_PMIC_BUS)
+int rsb_read(const u16 runtime_addr, const u8 reg_addr, u8 *data)
+{
+	struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
+
+	return sun8i_rsb_read(base, runtime_addr, reg_addr, data);
+}
+
+int rsb_write(const u16 runtime_addr, const u8 reg_addr, u8 data)
+{
+	struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
+
+	return sun8i_rsb_write(base, runtime_addr, reg_addr, data);
+}
+
+int rsb_set_device_address(u16 device_addr, u16 runtime_addr)
+{
+	struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
+
+	return sun8i_rsb_set_device_address(base, device_addr, runtime_addr);
+}
+
+int rsb_init(void)
+{
+	struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
+
+	return sun8i_rsb_init(base);
+}
+#endif
+
+#if CONFIG_IS_ENABLED(DM_I2C)
+struct sun8i_rsb_priv {
+	struct sunxi_rsb_reg *base;
+};
+
+/*
+ * The mapping from hardware address to runtime address is fixed, and shared
+ * among all RSB drivers. See the comment in drivers/bus/sunxi-rsb.c in Linux.
+ */
+static int sun8i_rsb_get_runtime_address(u16 device_addr)
+{
+	if (device_addr == AXP_PMIC_PRI_DEVICE_ADDR)
+		return AXP_PMIC_PRI_RUNTIME_ADDR;
+	if (device_addr == AXP_PMIC_SEC_DEVICE_ADDR)
+		return AXP_PMIC_SEC_RUNTIME_ADDR;
+
+	return -ENXIO;
+}
+
+static int sun8i_rsb_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
+{
+	int runtime_addr = sun8i_rsb_get_runtime_address(msg->addr);
+	struct sun8i_rsb_priv *priv = dev_get_priv(bus);
+
+	if (runtime_addr < 0)
+		return runtime_addr;
+
+	/* The hardware only supports SMBus-style transfers. */
+	if (nmsgs == 2 && msg[1].flags == I2C_M_RD && msg[1].len == 1)
+		return sun8i_rsb_read(priv->base, runtime_addr,
+				      msg[0].buf[0], &msg[1].buf[0]);
+
+	if (nmsgs == 1 && msg[0].len == 2)
+		return sun8i_rsb_write(priv->base, runtime_addr,
+				       msg[0].buf[0], msg[0].buf[1]);
+
+	return -EINVAL;
+}
+
+static int sun8i_rsb_probe_chip(struct udevice *bus, uint chip_addr,
+				uint chip_flags)
+{
+	int runtime_addr = sun8i_rsb_get_runtime_address(chip_addr);
+	struct sun8i_rsb_priv *priv = dev_get_priv(bus);
+
+	if (runtime_addr < 0)
+		return runtime_addr;
+
+	return sun8i_rsb_set_device_address(priv->base, chip_addr, runtime_addr);
+}
+
+static int sun8i_rsb_probe(struct udevice *bus)
+{
+	struct sun8i_rsb_priv *priv = dev_get_priv(bus);
+
+	priv->base = dev_read_addr_ptr(bus);
+
+	return sun8i_rsb_init(priv->base);
+}
+
+static int sun8i_rsb_child_pre_probe(struct udevice *child)
+{
+	struct dm_i2c_chip *chip = dev_get_parent_plat(child);
+
+	/* Ensure each transfer is for a single register. */
+	chip->flags |= DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS;
+
+	return 0;
+}
+
+static const struct dm_i2c_ops sun8i_rsb_ops = {
+	.xfer		= sun8i_rsb_xfer,
+	.probe_chip	= sun8i_rsb_probe_chip,
+};
+
+static const struct udevice_id sun8i_rsb_ids[] = {
+	{ .compatible = "allwinner,sun8i-a23-rsb" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(sun8i_rsb) = {
+	.name			= "sun8i_rsb",
+	.id			= UCLASS_I2C,
+	.of_match		= sun8i_rsb_ids,
+	.probe			= sun8i_rsb_probe,
+	.child_pre_probe	= sun8i_rsb_child_pre_probe,
+	.priv_auto		= sizeof(struct sun8i_rsb_priv),
+	.ops			= &sun8i_rsb_ops,
+};
+#endif /* CONFIG_IS_ENABLED(DM_I2C) */
diff --git a/include/axp_pmic.h b/include/axp_pmic.h
index 0db3e143eda..46a017d2efa 100644
--- a/include/axp_pmic.h
+++ b/include/axp_pmic.h
@@ -30,6 +30,12 @@
 #define AXP_PMIC_MODE_REG		0x3e
 #define AXP_PMIC_MODE_I2C		0x00
 #define AXP_PMIC_MODE_P2WI		0x3e
+#define AXP_PMIC_MODE_RSB		0x7c
+
+#define AXP_PMIC_PRI_DEVICE_ADDR	0x3a3
+#define AXP_PMIC_PRI_RUNTIME_ADDR	0x2d
+#define AXP_PMIC_SEC_DEVICE_ADDR	0x745
+#define AXP_PMIC_SEC_RUNTIME_ADDR	0x3a
 
 int axp_set_dcdc1(unsigned int mvolt);
 int axp_set_dcdc2(unsigned int mvolt);
-- 
2.32.0


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

* [PATCH v2 09/12] sunxi: pmic_bus: Clean up preprocessor conditions
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
                   ` (7 preceding siblings ...)
  2021-10-08  5:17 ` [PATCH v2 08/12] i2c: Add a DM_I2C driver for the sun8i RSB controller Samuel Holland
@ 2021-10-08  5:17 ` Samuel Holland
  2021-10-12 10:49   ` Andre Przywara
  2021-10-08  5:17 ` [PATCH v2 10/12] sunxi: pmic_bus: Use the DM PMIC interface when possible Samuel Holland
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

Instead of using the SoC symbols to decide the bus type, use whichever
bus driver is actually enabled. This allows collapsing all of the AXP2xx
and AXP8xx variants into one "else" case. It also has the advantage of
falling back to I2C when the other bus drivers are disabled; this works
because all of the PMICs support I2C in addition to other interfaces.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v2:
- Update IS_ENABLEDs in pmic_bus.c to match chages to previous patches

 arch/arm/mach-sunxi/pmic_bus.c | 90 +++++++++++++++-------------------
 1 file changed, 39 insertions(+), 51 deletions(-)

diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c
index 827797249ea..20ded436cd2 100644
--- a/arch/arm/mach-sunxi/pmic_bus.c
+++ b/arch/arm/mach-sunxi/pmic_bus.c
@@ -23,75 +23,63 @@
 
 #define AXP221_CHIP_ADDR		0x68
 
+static int pmic_i2c_address(void)
+{
+	if (IS_ENABLED(CONFIG_AXP152_POWER))
+		return AXP152_I2C_ADDR;
+	if (IS_ENABLED(CONFIG_AXP305_POWER))
+		return AXP305_I2C_ADDR;
+
+	/* Other AXP2xx and AXP8xx variants */
+	return AXP209_I2C_ADDR;
+}
+
 int pmic_bus_init(void)
 {
 	/* This cannot be 0 because it is used in SPL before BSS is ready */
 	static int needs_init = 1;
-	__maybe_unused int ret;
+	int ret = 0;
 
 	if (!needs_init)
 		return 0;
 
-#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER
-# ifdef CONFIG_MACH_SUN6I
-	p2wi_init();
-	ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP_PMIC_MODE_REG,
-				       AXP_PMIC_MODE_P2WI);
-# elif defined CONFIG_MACH_SUN8I_R40
-	/* Nothing. R40 uses the AXP221s in I2C mode */
-	ret = 0;
-# else
-	ret = rsb_init();
-	if (ret)
-		return ret;
+	if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI)) {
+		p2wi_init();
+		ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR,
+					       AXP_PMIC_MODE_REG,
+					       AXP_PMIC_MODE_P2WI);
+	} else if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB)) {
+		ret = rsb_init();
+		if (ret)
+			return ret;
 
-	ret = rsb_set_device_address(AXP_PMIC_PRI_DEVICE_ADDR,
-				     AXP_PMIC_PRI_RUNTIME_ADDR);
-# endif
-	if (ret)
-		return ret;
-#endif
+		ret = rsb_set_device_address(AXP_PMIC_PRI_DEVICE_ADDR,
+					     AXP_PMIC_PRI_RUNTIME_ADDR);
+	}
+
+	needs_init = ret;
 
-	needs_init = 0;
-	return 0;
+	return ret;
 }
 
 int pmic_bus_read(u8 reg, u8 *data)
 {
-#ifdef CONFIG_AXP152_POWER
-	return i2c_read(AXP152_I2C_ADDR, reg, 1, data, 1);
-#elif defined CONFIG_AXP209_POWER
-	return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1);
-#elif defined CONFIG_AXP305_POWER
-	return i2c_read(AXP305_I2C_ADDR, reg, 1, data, 1);
-#elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER
-# ifdef CONFIG_MACH_SUN6I
-	return p2wi_read(reg, data);
-# elif defined CONFIG_MACH_SUN8I_R40
-	return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1);
-# else
-	return rsb_read(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
-# endif
-#endif
+	if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI))
+		return p2wi_read(reg, data);
+	if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB))
+		return rsb_read(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
+
+	return i2c_read(pmic_i2c_address(), reg, 1, data, 1);
 }
 
 int pmic_bus_write(u8 reg, u8 data)
 {
-#ifdef CONFIG_AXP152_POWER
-	return i2c_write(AXP152_I2C_ADDR, reg, 1, &data, 1);
-#elif defined CONFIG_AXP209_POWER
-	return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1);
-#elif defined CONFIG_AXP305_POWER
-	return i2c_write(AXP305_I2C_ADDR, reg, 1, &data, 1);
-#elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER
-# ifdef CONFIG_MACH_SUN6I
-	return p2wi_write(reg, data);
-# elif defined CONFIG_MACH_SUN8I_R40
-	return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1);
-# else
-	return rsb_write(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
-# endif
-#endif
+	if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI))
+		return p2wi_write(reg, data);
+	if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB))
+		return rsb_write(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
+
+	return i2c_write(pmic_i2c_address(), reg, 1, &data, 1);
 }
 
 int pmic_bus_setbits(u8 reg, u8 bits)
-- 
2.32.0


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

* [PATCH v2 10/12] sunxi: pmic_bus: Use the DM PMIC interface when possible
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
                   ` (8 preceding siblings ...)
  2021-10-08  5:17 ` [PATCH v2 09/12] sunxi: pmic_bus: Clean up preprocessor conditions Samuel Holland
@ 2021-10-08  5:17 ` Samuel Holland
  2021-10-12 10:49   ` Andre Przywara
  2021-10-08  5:17 ` [PATCH v2 11/12] sunxi: video: Convert panel I2C to use DM_I2C Samuel Holland
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

The pmic_bus functions are used in both SPL (for regulator setup) and
U-Boot proper (for regulator setup, SID access, GPIO, and poweroff).

Currently, pmic_bus conflicts with DM_I2C because it uses the legacy I2C
interface. This commit makes pmic_bus dual-compatible with either the
legacy I2C functions or the newly-added PMIC_AXP driver (which uses
DM_I2C). In turn, this allows platforms to start transitioning to DM_I2C
in U-Boot proper, without breaking boards that still depend on the
legacy I2C interface for other reasons.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v2:
- No changes

 arch/arm/mach-sunxi/Kconfig    |  2 ++
 arch/arm/mach-sunxi/pmic_bus.c | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index df160c9a775..cfd95b09498 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -96,6 +96,8 @@ config SUN6I_PRCM
 
 config AXP_PMIC_BUS
 	bool
+	select DM_PMIC if DM_I2C
+	select PMIC_AXP if DM_I2C
 	help
 	  Select this PMIC bus access helpers for Sunxi platform PRCM or other
 	  AXP family PMIC devices.
diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c
index 20ded436cd2..c0908406370 100644
--- a/arch/arm/mach-sunxi/pmic_bus.c
+++ b/arch/arm/mach-sunxi/pmic_bus.c
@@ -10,9 +10,11 @@
 
 #include <axp_pmic.h>
 #include <common.h>
+#include <dm.h>
 #include <asm/arch/p2wi.h>
 #include <asm/arch/rsb.h>
 #include <i2c.h>
+#include <power/pmic.h>
 #include <asm/arch/pmic_bus.h>
 
 #define AXP152_I2C_ADDR			0x30
@@ -23,6 +25,9 @@
 
 #define AXP221_CHIP_ADDR		0x68
 
+#if CONFIG_IS_ENABLED(PMIC_AXP)
+static struct udevice *pmic;
+#else
 static int pmic_i2c_address(void)
 {
 	if (IS_ENABLED(CONFIG_AXP152_POWER))
@@ -33,6 +38,7 @@ static int pmic_i2c_address(void)
 	/* Other AXP2xx and AXP8xx variants */
 	return AXP209_I2C_ADDR;
 }
+#endif
 
 int pmic_bus_init(void)
 {
@@ -43,6 +49,10 @@ int pmic_bus_init(void)
 	if (!needs_init)
 		return 0;
 
+#if CONFIG_IS_ENABLED(PMIC_AXP)
+	ret = uclass_get_device_by_driver(UCLASS_PMIC, DM_DRIVER_GET(axp_pmic),
+					  &pmic);
+#else
 	if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI)) {
 		p2wi_init();
 		ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR,
@@ -56,6 +66,7 @@ int pmic_bus_init(void)
 		ret = rsb_set_device_address(AXP_PMIC_PRI_DEVICE_ADDR,
 					     AXP_PMIC_PRI_RUNTIME_ADDR);
 	}
+#endif
 
 	needs_init = ret;
 
@@ -64,22 +75,30 @@ int pmic_bus_init(void)
 
 int pmic_bus_read(u8 reg, u8 *data)
 {
+#if CONFIG_IS_ENABLED(PMIC_AXP)
+	return pmic_read(pmic, reg, data, 1);
+#else
 	if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI))
 		return p2wi_read(reg, data);
 	if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB))
 		return rsb_read(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
 
 	return i2c_read(pmic_i2c_address(), reg, 1, data, 1);
+#endif
 }
 
 int pmic_bus_write(u8 reg, u8 data)
 {
+#if CONFIG_IS_ENABLED(PMIC_AXP)
+	return pmic_write(pmic, reg, &data, 1);
+#else
 	if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI))
 		return p2wi_write(reg, data);
 	if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB))
 		return rsb_write(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
 
 	return i2c_write(pmic_i2c_address(), reg, 1, &data, 1);
+#endif
 }
 
 int pmic_bus_setbits(u8 reg, u8 bits)
-- 
2.32.0


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

* [PATCH v2 11/12] sunxi: video: Convert panel I2C to use DM_I2C
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
                   ` (9 preceding siblings ...)
  2021-10-08  5:17 ` [PATCH v2 10/12] sunxi: pmic_bus: Use the DM PMIC interface when possible Samuel Holland
@ 2021-10-08  5:17 ` Samuel Holland
  2021-10-08  5:17 ` [PATCH v2 12/12] sunxi: Enable DM_I2C for all sunxi boards Samuel Holland
  2021-10-12 11:24 ` [PATCH v2 00/12] sunxi: Migrate to DM_I2C Andre Przywara
  12 siblings, 0 replies; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

Two displays supported by the sunxi display driver (each one used by a
single board) require initialization over I2C. Both previously used
i2c_soft; replace this with the i2c-gpio instance that already exists in
those boards' device trees (sun5i-a13-utoo-p66 and sun6i-a31-colombus).

Since the i2c-gpio nodes are not referenced by any other node in the
device trees (the device trees have no panel node), the I2C bus is
selected by its node name.

This panel initialization code was the only i2c_soft user, so the
i2c_soft GPIO setup code can be removed now as well.

Reviewed-by: Heiko Schocher <hs@denx.de>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v2:
- No changes

 arch/arm/mach-sunxi/Kconfig         |  21 ++----
 board/sunxi/board.c                 |  44 +-----------
 configs/Colombus_defconfig          |   6 --
 configs/UTOO_P66_defconfig          |   3 -
 drivers/video/anx9804.c             | 103 ++++++++++++++--------------
 drivers/video/anx9804.h             |   5 +-
 drivers/video/sunxi/sunxi_display.c |  55 ++++++++++-----
 include/configs/sunxi-common.h      |  17 -----
 8 files changed, 100 insertions(+), 154 deletions(-)

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index cfd95b09498..99928821673 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -923,27 +923,18 @@ config VIDEO_LCD_BL_PWM_ACTIVE_LOW
 config VIDEO_LCD_PANEL_I2C
 	bool "LCD panel needs to be configured via i2c"
 	depends on VIDEO_SUNXI
-	select CMD_I2C
+	select DM_I2C
+	select DM_I2C_GPIO
 	---help---
 	Say y here if the LCD panel needs to be configured via i2c. This
 	will add a bitbang i2c controller using gpios to talk to the LCD.
 
-config VIDEO_LCD_PANEL_I2C_SDA
-	string "LCD panel i2c interface SDA pin"
-	depends on VIDEO_LCD_PANEL_I2C
-	default "PG12"
-	---help---
-	Set the SDA pin for the LCD i2c interface. This takes a string in the
-	format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
-
-config VIDEO_LCD_PANEL_I2C_SCL
-	string "LCD panel i2c interface SCL pin"
+config VIDEO_LCD_PANEL_I2C_NAME
+	string "LCD panel i2c interface node name"
 	depends on VIDEO_LCD_PANEL_I2C
-	default "PG10"
+	default "i2c@0"
 	---help---
-	Set the SCL pin for the LCD i2c interface. This takes a string in the
-	format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
-
+	Set the device tree node name for the LCD i2c interface.
 
 # Note only one of these may be selected at a time! But hidden choices are
 # not supported by Kconfig
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 2b7d655678d..dabe6734b81 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -47,47 +47,6 @@
 #include <sy8106a.h>
 #include <asm/setup.h>
 
-#if defined(CONFIG_VIDEO_LCD_PANEL_I2C)
-/* So that we can use pin names in Kconfig and sunxi_name_to_gpio() */
-int soft_i2c_gpio_sda;
-int soft_i2c_gpio_scl;
-
-static int soft_i2c_board_init(void)
-{
-	int ret;
-
-	soft_i2c_gpio_sda = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SDA);
-	if (soft_i2c_gpio_sda < 0) {
-		printf("Error invalid soft i2c sda pin: '%s', err %d\n",
-		       CONFIG_VIDEO_LCD_PANEL_I2C_SDA, soft_i2c_gpio_sda);
-		return soft_i2c_gpio_sda;
-	}
-	ret = gpio_request(soft_i2c_gpio_sda, "soft-i2c-sda");
-	if (ret) {
-		printf("Error requesting soft i2c sda pin: '%s', err %d\n",
-		       CONFIG_VIDEO_LCD_PANEL_I2C_SDA, ret);
-		return ret;
-	}
-
-	soft_i2c_gpio_scl = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SCL);
-	if (soft_i2c_gpio_scl < 0) {
-		printf("Error invalid soft i2c scl pin: '%s', err %d\n",
-		       CONFIG_VIDEO_LCD_PANEL_I2C_SCL, soft_i2c_gpio_scl);
-		return soft_i2c_gpio_scl;
-	}
-	ret = gpio_request(soft_i2c_gpio_scl, "soft-i2c-scl");
-	if (ret) {
-		printf("Error requesting soft i2c scl pin: '%s', err %d\n",
-		       CONFIG_VIDEO_LCD_PANEL_I2C_SCL, ret);
-		return ret;
-	}
-
-	return 0;
-}
-#else
-static int soft_i2c_board_init(void) { return 0; }
-#endif
-
 DECLARE_GLOBAL_DATA_PTR;
 
 void i2c_init_board(void)
@@ -312,8 +271,7 @@ int board_init(void)
 #endif
 #endif	/* CONFIG_DM_MMC */
 
-	/* Uses dm gpio code so do this here and not in i2c_init_board() */
-	return soft_i2c_board_init();
+	return 0;
 }
 
 /*
diff --git a/configs/Colombus_defconfig b/configs/Colombus_defconfig
index 31541f898d4..270bd7d351a 100644
--- a/configs/Colombus_defconfig
+++ b/configs/Colombus_defconfig
@@ -13,15 +13,9 @@ CONFIG_VIDEO_LCD_DCLK_PHASE=0
 CONFIG_VIDEO_LCD_POWER="PH27"
 CONFIG_VIDEO_LCD_BL_EN="PM1"
 CONFIG_VIDEO_LCD_BL_PWM="PH13"
-CONFIG_VIDEO_LCD_PANEL_I2C_SDA="PA23"
-CONFIG_VIDEO_LCD_PANEL_I2C_SCL="PA24"
 CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-CONFIG_SYS_I2C_LEGACY=y
 CONFIG_SPL_SYS_I2C_LEGACY=y
-CONFIG_SYS_I2C_SOFT=y
-CONFIG_SYS_I2C_SOFT_SPEED=50000
-CONFIG_SYS_I2C_SOFT_SLAVE=0x00
 CONFIG_SYS_I2C_MVTWSI=y
 CONFIG_SYS_I2C_SLAVE=0x7f
 CONFIG_SYS_I2C_SPEED=400000
diff --git a/configs/UTOO_P66_defconfig b/configs/UTOO_P66_defconfig
index b5728073086..b021b0a8865 100644
--- a/configs/UTOO_P66_defconfig
+++ b/configs/UTOO_P66_defconfig
@@ -21,9 +21,6 @@ CONFIG_VIDEO_LCD_BL_PWM="PB2"
 CONFIG_VIDEO_LCD_TL059WV5C0=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL_I2C=y
-CONFIG_SYS_I2C_SOFT=y
-CONFIG_SYS_I2C_SOFT_SPEED=50000
-CONFIG_SYS_I2C_SOFT_SLAVE=0x00
 CONFIG_SYS_I2C_MVTWSI=y
 CONFIG_SYS_I2C_SLAVE=0x7f
 CONFIG_SYS_I2C_SPEED=400000
diff --git a/drivers/video/anx9804.c b/drivers/video/anx9804.c
index 3037ff39b41..52b5988ba5f 100644
--- a/drivers/video/anx9804.c
+++ b/drivers/video/anx9804.c
@@ -21,18 +21,23 @@
  * This function will init an anx9804 parallel lcd to dp bridge chip
  * using the passed in parameters.
  *
- * @i2c_bus:	Number of the i2c bus to which the anx9804 is connected.
+ * @i2c_bus:	Device of the i2c bus to which the anx9804 is connected.
  * @lanes:	Number of displayport lanes to use
  * @data_rate:	Register value for the bandwidth reg 0x06: 1.62G, 0x0a: 2.7G
  * @bpp:	Bits per pixel, must be 18 or 24
  */
-void anx9804_init(unsigned int i2c_bus, u8 lanes, u8 data_rate, int bpp)
+void anx9804_init(struct udevice *i2c_bus, u8 lanes, u8 data_rate, int bpp)
 {
-	unsigned int orig_i2c_bus = i2c_get_bus_num();
-	u8 c, colordepth;
-	int i;
+	struct udevice *chip0, *chip1;
+	int c, colordepth, i, ret;
 
-	i2c_set_bus_num(i2c_bus);
+	ret = i2c_get_chip(i2c_bus, 0x38, 1, &chip0);
+	if (ret)
+		return;
+
+	ret = i2c_get_chip(i2c_bus, 0x39, 1, &chip1);
+	if (ret)
+		return;
 
 	if (bpp == 18)
 		colordepth = 0x00; /* 6 bit */
@@ -40,24 +45,23 @@ void anx9804_init(unsigned int i2c_bus, u8 lanes, u8 data_rate, int bpp)
 		colordepth = 0x10; /* 8 bit */
 
 	/* Reset */
-	i2c_reg_write(0x39, ANX9804_RST_CTRL_REG, 1);
+	dm_i2c_reg_write(chip1, ANX9804_RST_CTRL_REG, 1);
 	mdelay(100);
-	i2c_reg_write(0x39, ANX9804_RST_CTRL_REG, 0);
+	dm_i2c_reg_write(chip1, ANX9804_RST_CTRL_REG, 0);
 
 	/* Write 0 to the powerdown reg (powerup everything) */
-	i2c_reg_write(0x39, ANX9804_POWERD_CTRL_REG, 0);
+	dm_i2c_reg_write(chip1, ANX9804_POWERD_CTRL_REG, 0);
 
-	c = i2c_reg_read(0x39, ANX9804_DEV_IDH_REG);
+	c = dm_i2c_reg_read(chip1, ANX9804_DEV_IDH_REG);
 	if (c != 0x98) {
 		printf("Error anx9804 chipid mismatch\n");
-		i2c_set_bus_num(orig_i2c_bus);
 		return;
 	}
 
 	for (i = 0; i < 100; i++) {
-		c = i2c_reg_read(0x38, ANX9804_SYS_CTRL2_REG);
-		i2c_reg_write(0x38, ANX9804_SYS_CTRL2_REG, c);
-		c = i2c_reg_read(0x38, ANX9804_SYS_CTRL2_REG);
+		c = dm_i2c_reg_read(chip0, ANX9804_SYS_CTRL2_REG);
+		dm_i2c_reg_write(chip0, ANX9804_SYS_CTRL2_REG, c);
+		c = dm_i2c_reg_read(chip0, ANX9804_SYS_CTRL2_REG);
 		if ((c & ANX9804_SYS_CTRL2_CHA_STA) == 0)
 			break;
 
@@ -66,51 +70,51 @@ void anx9804_init(unsigned int i2c_bus, u8 lanes, u8 data_rate, int bpp)
 	if (i == 100)
 		printf("Error anx9804 clock is not stable\n");
 
-	i2c_reg_write(0x39, ANX9804_VID_CTRL2_REG, colordepth);
+	dm_i2c_reg_write(chip1, ANX9804_VID_CTRL2_REG, colordepth);
 
 	/* Set a bunch of analog related register values */
-	i2c_reg_write(0x38, ANX9804_PLL_CTRL_REG, 0x07);
-	i2c_reg_write(0x39, ANX9804_PLL_FILTER_CTRL3, 0x19);
-	i2c_reg_write(0x39, ANX9804_PLL_CTRL3, 0xd9);
-	i2c_reg_write(0x39, ANX9804_RST_CTRL2_REG, ANX9804_RST_CTRL2_AC_MODE);
-	i2c_reg_write(0x39, ANX9804_ANALOG_DEBUG_REG1, 0xf0);
-	i2c_reg_write(0x39, ANX9804_ANALOG_DEBUG_REG3, 0x99);
-	i2c_reg_write(0x39, ANX9804_PLL_FILTER_CTRL1, 0x7b);
-	i2c_reg_write(0x38, ANX9804_LINK_DEBUG_REG, 0x30);
-	i2c_reg_write(0x39, ANX9804_PLL_FILTER_CTRL, 0x06);
+	dm_i2c_reg_write(chip0, ANX9804_PLL_CTRL_REG, 0x07);
+	dm_i2c_reg_write(chip1, ANX9804_PLL_FILTER_CTRL3, 0x19);
+	dm_i2c_reg_write(chip1, ANX9804_PLL_CTRL3, 0xd9);
+	dm_i2c_reg_write(chip1, ANX9804_RST_CTRL2_REG, ANX9804_RST_CTRL2_AC_MODE);
+	dm_i2c_reg_write(chip1, ANX9804_ANALOG_DEBUG_REG1, 0xf0);
+	dm_i2c_reg_write(chip1, ANX9804_ANALOG_DEBUG_REG3, 0x99);
+	dm_i2c_reg_write(chip1, ANX9804_PLL_FILTER_CTRL1, 0x7b);
+	dm_i2c_reg_write(chip0, ANX9804_LINK_DEBUG_REG, 0x30);
+	dm_i2c_reg_write(chip1, ANX9804_PLL_FILTER_CTRL, 0x06);
 
 	/* Force HPD */
-	i2c_reg_write(0x38, ANX9804_SYS_CTRL3_REG,
-		      ANX9804_SYS_CTRL3_F_HPD | ANX9804_SYS_CTRL3_HPD_CTRL);
+	dm_i2c_reg_write(chip0, ANX9804_SYS_CTRL3_REG,
+			 ANX9804_SYS_CTRL3_F_HPD | ANX9804_SYS_CTRL3_HPD_CTRL);
 
 	/* Power up and configure lanes */
-	i2c_reg_write(0x38, ANX9804_ANALOG_POWER_DOWN_REG, 0x00);
-	i2c_reg_write(0x38, ANX9804_TRAINING_LANE0_SET_REG, 0x00);
-	i2c_reg_write(0x38, ANX9804_TRAINING_LANE1_SET_REG, 0x00);
-	i2c_reg_write(0x38, ANX9804_TRAINING_LANE2_SET_REG, 0x00);
-	i2c_reg_write(0x38, ANX9804_TRAINING_LANE3_SET_REG, 0x00);
+	dm_i2c_reg_write(chip0, ANX9804_ANALOG_POWER_DOWN_REG, 0x00);
+	dm_i2c_reg_write(chip0, ANX9804_TRAINING_LANE0_SET_REG, 0x00);
+	dm_i2c_reg_write(chip0, ANX9804_TRAINING_LANE1_SET_REG, 0x00);
+	dm_i2c_reg_write(chip0, ANX9804_TRAINING_LANE2_SET_REG, 0x00);
+	dm_i2c_reg_write(chip0, ANX9804_TRAINING_LANE3_SET_REG, 0x00);
 
 	/* Reset AUX CH */
-	i2c_reg_write(0x39, ANX9804_RST_CTRL2_REG,
-		      ANX9804_RST_CTRL2_AC_MODE | ANX9804_RST_CTRL2_AUX);
-	i2c_reg_write(0x39, ANX9804_RST_CTRL2_REG,
-		      ANX9804_RST_CTRL2_AC_MODE);
+	dm_i2c_reg_write(chip1, ANX9804_RST_CTRL2_REG,
+			 ANX9804_RST_CTRL2_AC_MODE | ANX9804_RST_CTRL2_AUX);
+	dm_i2c_reg_write(chip1, ANX9804_RST_CTRL2_REG,
+			 ANX9804_RST_CTRL2_AC_MODE);
 
 	/* Powerdown audio and some other unused bits */
-	i2c_reg_write(0x39, ANX9804_POWERD_CTRL_REG, ANX9804_POWERD_AUDIO);
-	i2c_reg_write(0x38, ANX9804_HDCP_CONTROL_0_REG, 0x00);
-	i2c_reg_write(0x38, 0xa7, 0x00);
+	dm_i2c_reg_write(chip1, ANX9804_POWERD_CTRL_REG, ANX9804_POWERD_AUDIO);
+	dm_i2c_reg_write(chip0, ANX9804_HDCP_CONTROL_0_REG, 0x00);
+	dm_i2c_reg_write(chip0, 0xa7, 0x00);
 
 	/* Set data-rate / lanes */
-	i2c_reg_write(0x38, ANX9804_LINK_BW_SET_REG, data_rate);
-	i2c_reg_write(0x38, ANX9804_LANE_COUNT_SET_REG, lanes);
+	dm_i2c_reg_write(chip0, ANX9804_LINK_BW_SET_REG, data_rate);
+	dm_i2c_reg_write(chip0, ANX9804_LANE_COUNT_SET_REG, lanes);
 
 	/* Link training */
-	i2c_reg_write(0x38, ANX9804_LINK_TRAINING_CTRL_REG,
-		      ANX9804_LINK_TRAINING_CTRL_EN);
+	dm_i2c_reg_write(chip0, ANX9804_LINK_TRAINING_CTRL_REG,
+			 ANX9804_LINK_TRAINING_CTRL_EN);
 	mdelay(5);
 	for (i = 0; i < 100; i++) {
-		c = i2c_reg_read(0x38, ANX9804_LINK_TRAINING_CTRL_REG);
+		c = dm_i2c_reg_read(chip0, ANX9804_LINK_TRAINING_CTRL_REG);
 		if ((c & 0x01) == 0)
 			break;
 
@@ -118,17 +122,14 @@ void anx9804_init(unsigned int i2c_bus, u8 lanes, u8 data_rate, int bpp)
 	}
 	if(i == 100) {
 		printf("Error anx9804 link training timeout\n");
-		i2c_set_bus_num(orig_i2c_bus);
 		return;
 	}
 
 	/* Enable */
-	i2c_reg_write(0x39, ANX9804_VID_CTRL1_REG,
-		      ANX9804_VID_CTRL1_VID_EN | ANX9804_VID_CTRL1_EDGE);
+	dm_i2c_reg_write(chip1, ANX9804_VID_CTRL1_REG,
+			 ANX9804_VID_CTRL1_VID_EN | ANX9804_VID_CTRL1_EDGE);
 	/* Force stream valid */
-	i2c_reg_write(0x38, ANX9804_SYS_CTRL3_REG,
-		      ANX9804_SYS_CTRL3_F_HPD | ANX9804_SYS_CTRL3_HPD_CTRL |
-		      ANX9804_SYS_CTRL3_F_VALID | ANX9804_SYS_CTRL3_VALID_CTRL);
-
-	i2c_set_bus_num(orig_i2c_bus);
+	dm_i2c_reg_write(chip0, ANX9804_SYS_CTRL3_REG,
+			 ANX9804_SYS_CTRL3_F_HPD | ANX9804_SYS_CTRL3_HPD_CTRL |
+			 ANX9804_SYS_CTRL3_F_VALID | ANX9804_SYS_CTRL3_VALID_CTRL);
 }
diff --git a/drivers/video/anx9804.h b/drivers/video/anx9804.h
index c0fe3b393b4..ea6c9f2d558 100644
--- a/drivers/video/anx9804.h
+++ b/drivers/video/anx9804.h
@@ -16,9 +16,10 @@
 #define ANX9804_DATA_RATE_2700M				0x0a
 
 #ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804
-void anx9804_init(unsigned int i2c_bus, u8 lanes, u8 data_rate, int bpp);
+void anx9804_init(struct udevice *i2c_bus, u8 lanes, u8 data_rate, int bpp);
 #else
-static inline void anx9804_init(unsigned int i2c_bus, u8 lanes, u8 data_rate,
+static inline void anx9804_init(struct udevice *i2c_bus, u8 lanes, u8 data_rate,
 				int bpp) {}
 #endif
+
 #endif
diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c
index 4361a58cd7e..6d3914c2aeb 100644
--- a/drivers/video/sunxi/sunxi_display.c
+++ b/drivers/video/sunxi/sunxi_display.c
@@ -902,6 +902,42 @@ static int sunxi_ssd2828_init(const struct ctfb_res_modes *mode)
 }
 #endif /* CONFIG_VIDEO_LCD_SSD2828 */
 
+#ifdef CONFIG_VIDEO_LCD_PANEL_I2C
+static void sunxi_panel_i2c_init(struct sunxi_display_priv *sunxi_display)
+{
+	const char *name = CONFIG_VIDEO_LCD_PANEL_I2C_NAME;
+	struct udevice *i2c_bus;
+	int ret;
+
+	ret = uclass_get_device_by_name(UCLASS_I2C, name, &i2c_bus);
+	if (ret)
+		return;
+
+	if (IS_ENABLED(CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804)) {
+		/*
+		 * The anx9804 needs 1.8V from eldo3, we do this here
+		 * and not via CONFIG_AXP_ELDO3_VOLT from board_init()
+		 * to avoid turning this on when using hdmi output.
+		 */
+		axp_set_eldo(3, 1800);
+		anx9804_init(i2c_bus, 4,
+			     ANX9804_DATA_RATE_1620M,
+			     sunxi_display->depth);
+	}
+	if (IS_ENABLED(CONFIG_VIDEO_LCD_TL059WV5C0)) {
+		struct udevice *chip;
+
+		ret = i2c_get_chip(i2c_bus, 0x5c, 1, &chip);
+		if (ret)
+			return;
+
+		dm_i2c_reg_write(chip, 0x04, 0x42); /* Turn on the LCD */
+	}
+}
+#else
+static void sunxi_panel_i2c_init(struct sunxi_display_priv *sunxi_display) {}
+#endif
+
 static void sunxi_engines_init(void)
 {
 	sunxi_composer_init();
@@ -936,27 +972,12 @@ static void sunxi_mode_set(struct sunxi_display_priv *sunxi_display,
 		break;
 	case sunxi_monitor_lcd:
 		sunxi_lcdc_panel_enable();
-		if (IS_ENABLED(CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804)) {
-			/*
-			 * The anx9804 needs 1.8V from eldo3, we do this here
-			 * and not via CONFIG_AXP_ELDO3_VOLT from board_init()
-			 * to avoid turning this on when using hdmi output.
-			 */
-			axp_set_eldo(3, 1800);
-			anx9804_init(CONFIG_VIDEO_LCD_I2C_BUS, 4,
-				     ANX9804_DATA_RATE_1620M,
-				     sunxi_display->depth);
-		}
 		if (IS_ENABLED(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM)) {
 			mdelay(50); /* Wait for lcd controller power on */
 			hitachi_tx18d42vm_init();
 		}
-		if (IS_ENABLED(CONFIG_VIDEO_LCD_TL059WV5C0)) {
-			unsigned int orig_i2c_bus = i2c_get_bus_num();
-			i2c_set_bus_num(CONFIG_VIDEO_LCD_I2C_BUS);
-			i2c_reg_write(0x5c, 0x04, 0x42); /* Turn on the LCD */
-			i2c_set_bus_num(orig_i2c_bus);
-		}
+		if (IS_ENABLED(CONFIG_VIDEO_LCD_PANEL_I2C))
+			sunxi_panel_i2c_init(sunxi_display);
 		sunxi_composer_mode_set(mode, address, monitor);
 		sunxi_lcdc_tcon0_mode_set(sunxi_display, mode, false);
 		sunxi_composer_enable();
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 5d8b6052e4f..c576d65efaf 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -160,23 +160,6 @@
 #define CONFIG_SPL_PAD_TO		32768		/* decimal for 'dd' */
 #endif
 
-
-/* I2C */
-#if defined(CONFIG_VIDEO_LCD_PANEL_I2C)
-/* We use pin names in Kconfig and sunxi_name_to_gpio() */
-#define CONFIG_SOFT_I2C_GPIO_SDA	soft_i2c_gpio_sda
-#define CONFIG_SOFT_I2C_GPIO_SCL	soft_i2c_gpio_scl
-#ifndef __ASSEMBLY__
-extern int soft_i2c_gpio_sda;
-extern int soft_i2c_gpio_scl;
-#endif
-#define CONFIG_VIDEO_LCD_I2C_BUS	0 /* The lcd panel soft i2c is bus 0 */
-#define CONFIG_SYS_SPD_BUS_NUM		1 /* And the axp209 i2c bus is bus 1 */
-#else
-#define CONFIG_SYS_SPD_BUS_NUM		0 /* The axp209 i2c bus is bus 0 */
-#define CONFIG_VIDEO_LCD_I2C_BUS	-1 /* NA, but necessary to compile */
-#endif
-
 /* Ethernet support */
 
 #ifdef CONFIG_USB_EHCI_HCD
-- 
2.32.0


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

* [PATCH v2 12/12] sunxi: Enable DM_I2C for all sunxi boards
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
                   ` (10 preceding siblings ...)
  2021-10-08  5:17 ` [PATCH v2 11/12] sunxi: video: Convert panel I2C to use DM_I2C Samuel Holland
@ 2021-10-08  5:17 ` Samuel Holland
  2021-10-12 11:24 ` [PATCH v2 00/12] sunxi: Migrate to DM_I2C Andre Przywara
  12 siblings, 0 replies; 22+ messages in thread
From: Samuel Holland @ 2021-10-08  5:17 UTC (permalink / raw)
  To: u-boot, Jagan Teki, Andre Przywara
  Cc: Jaehoon Chung, Heiko Schocher, Samuel Holland,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

Now that the last users of legacy I2C (outside of SPL) have been
resolved, we can enable DM_I2C at the sunxi architecture level.

Reviewed-by: Heiko Schocher <hs@denx.de>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v2:
- No changes

 arch/arm/Kconfig            | 1 +
 arch/arm/mach-sunxi/Kconfig | 3 ---
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ebb19272708..d8c041a8773 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1028,6 +1028,7 @@ config ARCH_SUNXI
 	select DM
 	select DM_ETH
 	select DM_GPIO
+	select DM_I2C if I2C
 	select DM_KEYBOARD
 	select DM_MMC if MMC
 	select DM_SCSI if SCSI
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 99928821673..9047a88c9da 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -165,7 +165,6 @@ endif
 
 config MACH_SUNXI_H3_H5
 	bool
-	select DM_I2C
 	select PHY_SUN4I_USB
 	select SUNXI_DE2
 	select SUNXI_DRAM_DW
@@ -327,7 +326,6 @@ config MACH_SUN50I
 	bool "sun50i (Allwinner A64)"
 	select ARM64
 	select SPI
-	select DM_I2C
 	select DM_SPI if SPI
 	select DM_SPI_FLASH
 	select PHY_SUN4I_USB
@@ -923,7 +921,6 @@ config VIDEO_LCD_BL_PWM_ACTIVE_LOW
 config VIDEO_LCD_PANEL_I2C
 	bool "LCD panel needs to be configured via i2c"
 	depends on VIDEO_SUNXI
-	select DM_I2C
 	select DM_I2C_GPIO
 	---help---
 	Say y here if the LCD panel needs to be configured via i2c. This
-- 
2.32.0


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

* Re: [PATCH v2 02/12] power: pmic: Consistently depend on SPL_DM_PMIC
  2021-10-08  5:17 ` [PATCH v2 02/12] power: pmic: Consistently depend on SPL_DM_PMIC Samuel Holland
@ 2021-10-12 10:46   ` Andre Przywara
  0 siblings, 0 replies; 22+ messages in thread
From: Andre Przywara @ 2021-10-12 10:46 UTC (permalink / raw)
  To: Samuel Holland
  Cc: u-boot, Jagan Teki, Jaehoon Chung, Heiko Schocher,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

On Fri,  8 Oct 2021 00:17:15 -0500
Samuel Holland <samuel@sholland.org> wrote:

Hi,

> Now that there is a separate symbol to enable DM_PMIC in SPL, update the
> the SPL-specific driver symbols to depend on this new option.

Yes, confirmed that this covers all SPL DM_PMIC drivers. Also checked that
those who didn't have DM in their Kconfig symbol name, are indeed DM style
drivers.

> Signed-off-by: Samuel Holland <samuel@sholland.org>

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
> 
> Changes in v2:
> - Rebase to pick up 7abf178b ("power: Tidy up #undef of CONFIG_DM_PMIC")
> 
>  drivers/power/pmic/Kconfig | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
> index 2472555a3ff..e8a04325f85 100644
> --- a/drivers/power/pmic/Kconfig
> +++ b/drivers/power/pmic/Kconfig
> @@ -36,6 +36,7 @@ config PMIC_CHILDREN
>  
>  config SPL_PMIC_CHILDREN
>  	bool "Allow child devices for PMICs in SPL"
> +	depends on SPL_DM_PMIC
>  	default y
>  	---help---
>  	This allows PMICs to support child devices (such as regulators)
> in @@ -70,7 +71,7 @@ config DM_PMIC_DA9063
>  
>  config SPL_DM_PMIC_DA9063
>  	bool "Enable Driver Model for the Dialog DA9063 PMIC in SPL"
> -	depends on SPL
> +	depends on SPL_DM_PMIC
>  	help
>  	  This config enables implementation of driver-model pmic
> uclass features for PMIC DA9063. The driver implements read/write
> operations. @@ -91,6 +92,7 @@ config DM_PMIC_BD71837
>  
>  config SPL_DM_PMIC_BD71837
>  	bool "Enable Driver Model for PMIC BD71837 in SPL stage"
> +	depends on SPL_DM_PMIC
>  	help
>  	  This config enables implementation of driver-model pmic uclass
>  	  features for PMIC BD71837. The driver implements read/write
> @@ -118,6 +120,7 @@ config DM_PMIC_MP5416
>  
>  config SPL_DM_PMIC_MP5416
>  	bool "Enable Driver Model for PMIC MP5416 in SPL stage"
> +	depends on SPL_DM_PMIC
>  	help
>  	  This config enables implementation of driver-model pmic uclass
>  	  features for PMIC MP5416. The driver implements read/write
> @@ -131,6 +134,7 @@ config DM_PMIC_PCA9450
>  
>  config SPL_DM_PMIC_PCA9450
>  	bool "Enable Driver Model for PMIC PCA9450"
> +	depends on SPL_DM_PMIC
>  	help
>  	  This config enables implementation of driver-model pmic
> uclass features for PMIC PCA9450 in SPL. The driver implements
> read/write operations. @@ -143,6 +147,7 @@ config DM_PMIC_PFUZE100
>  
>  config SPL_DM_PMIC_PFUZE100
>  	bool "Enable Driver Model for PMIC PFUZE100 in SPL"
> +	depends on SPL_DM_PMIC
>  	---help---
>  	This config enables implementation of driver-model pmic uclass
> features for PMIC PFUZE100 in SPL. The driver implements read/write
> operations. @@ -204,6 +209,7 @@ config PMIC_RK8XX
>  
>  config SPL_PMIC_RK8XX
>  	bool "Enable support for Rockchip PMIC RK8XX"
> +	depends on SPL_DM_PMIC
>  	---help---
>  	The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8
> LDOs, an RTC and two low Rds (resistance (drain to source)) switches. It
> is @@ -313,18 +319,21 @@ config PMIC_STPMIC1
>  
>  config SPL_PMIC_PALMAS
>  	bool "Enable driver for Texas Instruments PALMAS PMIC"
> +	depends on SPL_DM_PMIC
>  	help
>  	The PALMAS is a PMIC containing several LDOs, SMPS.
>  	This driver binds the pmic children in SPL.
>  
>  config SPL_PMIC_LP873X
>  	bool "Enable driver for Texas Instruments LP873X PMIC"
> +	depends on SPL_DM_PMIC
>  	help
>  	The LP873X is a PMIC containing couple of LDOs and couple of
> SMPS. This driver binds the pmic children in SPL.
>  
>  config SPL_PMIC_LP87565
>  	bool "Enable driver for Texas Instruments LP87565 PMIC"
> +	depends on SPL_DM_PMIC
>  	help
>  	The LP87565 is a PMIC containing a bunch of SMPS.
>  	This driver binds the pmic children in SPL.


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

* Re: [PATCH v2 03/12] power: pmic: Add a driver for X-Powers AXP PMICs
  2021-10-08  5:17 ` [PATCH v2 03/12] power: pmic: Add a driver for X-Powers AXP PMICs Samuel Holland
@ 2021-10-12 10:47   ` Andre Przywara
  0 siblings, 0 replies; 22+ messages in thread
From: Andre Przywara @ 2021-10-12 10:47 UTC (permalink / raw)
  To: Samuel Holland
  Cc: u-boot, Jagan Teki, Jaehoon Chung, Heiko Schocher,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

On Fri,  8 Oct 2021 00:17:16 -0500
Samuel Holland <samuel@sholland.org> wrote:

> These PMICs provide some combination of battery charger, fuel gauge,
> GPIOs, regulators, and VBUS routing. These functions are represented
> as child nodes in the device tree. Add the minimal driver needed to
> probe these child devices and provide the DM_PMIC ops.
> 
> Enable the driver by default for SoCs that normally pair with a PMIC.

Looks indeed like a minimal I2C passthrough DM driver.

> Signed-off-by: Samuel Holland <samuel@sholland.org>

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
> 
> Changes in v2:
> - Replace axp_pmic_bind() with `.bind = dm_scan_fdt_dev`
> 
>  drivers/power/pmic/Kconfig  | 14 ++++++++++++++
>  drivers/power/pmic/Makefile |  1 +
>  drivers/power/pmic/axp.c    | 38 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 53 insertions(+)
>  create mode 100644 drivers/power/pmic/axp.c
> 
> diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
> index e8a04325f85..fcb517f1044 100644
> --- a/drivers/power/pmic/Kconfig
> +++ b/drivers/power/pmic/Kconfig
> @@ -63,6 +63,20 @@ config PMIC_ACT8846
>  	functions. It uses an I2C interface and is designed for use with
>  	tablets and smartphones.
>  
> +config PMIC_AXP
> +	bool "Enable Driver Model for X-Powers AXP PMICs"
> +	depends on DM_I2C
> +	help
> +	  This config enables driver-model PMIC uclass features for
> +	  X-Powers AXP152, AXP2xx, and AXP8xx PMICs.
> +
> +config SPL_PMIC_AXP
> +	bool "Enable Driver Model for X-Powers AXP PMICs in SPL"
> +	depends on SPL_DM_I2C && SPL_DM_PMIC
> +	help
> +	  This config enables driver-model PMIC uclass features in the SPL for
> +	  X-Powers AXP152, AXP2xx, and AXP8xx PMICs.
> +
>  config DM_PMIC_DA9063
>  	bool "Enable Driver Model for the Dialog DA9063 PMIC"
>  	help
> diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
> index 5250eac12f2..e1922df00f8 100644
> --- a/drivers/power/pmic/Makefile
> +++ b/drivers/power/pmic/Makefile
> @@ -18,6 +18,7 @@ obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
>  obj-$(CONFIG_PMIC_AB8500) += ab8500.o
>  obj-$(CONFIG_PMIC_ACT8846) += act8846.o
>  obj-$(CONFIG_PMIC_AS3722) += as3722.o as3722_gpio.o
> +obj-$(CONFIG_$(SPL_)PMIC_AXP) += axp.o
>  obj-$(CONFIG_PMIC_MAX8997) += max8997.o
>  obj-$(CONFIG_PMIC_PM8916) += pm8916.o
>  obj-$(CONFIG_$(SPL_TPL_)PMIC_RK8XX) += rk8xx.o
> diff --git a/drivers/power/pmic/axp.c b/drivers/power/pmic/axp.c
> new file mode 100644
> index 00000000000..74c94bdb47b
> --- /dev/null
> +++ b/drivers/power/pmic/axp.c
> @@ -0,0 +1,38 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include <dm.h>
> +#include <i2c.h>
> +#include <power/pmic.h>
> +
> +static int axp_pmic_reg_count(struct udevice *dev)
> +{
> +	/* TODO: Get the specific value from driver data. */
> +	return 0x100;
> +}
> +
> +static struct dm_pmic_ops axp_pmic_ops = {
> +	.reg_count	= axp_pmic_reg_count,
> +	.read		= dm_i2c_read,
> +	.write		= dm_i2c_write,
> +};
> +
> +static const struct udevice_id axp_pmic_ids[] = {
> +	{ .compatible = "x-powers,axp152" },
> +	{ .compatible = "x-powers,axp202" },
> +	{ .compatible = "x-powers,axp209" },
> +	{ .compatible = "x-powers,axp221" },
> +	{ .compatible = "x-powers,axp223" },
> +	{ .compatible = "x-powers,axp803" },
> +	{ .compatible = "x-powers,axp806" },
> +	{ .compatible = "x-powers,axp809" },
> +	{ .compatible = "x-powers,axp813" },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(axp_pmic) = {
> +	.name		= "axp_pmic",
> +	.id		= UCLASS_PMIC,
> +	.of_match	= axp_pmic_ids,
> +	.bind		= dm_scan_fdt_dev,
> +	.ops		= &axp_pmic_ops,
> +};


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

* Re: [PATCH v2 04/12] sunxi: Only initialize legacy I2C when enabled
  2021-10-08  5:17 ` [PATCH v2 04/12] sunxi: Only initialize legacy I2C when enabled Samuel Holland
@ 2021-10-12 10:47   ` Andre Przywara
  0 siblings, 0 replies; 22+ messages in thread
From: Andre Przywara @ 2021-10-12 10:47 UTC (permalink / raw)
  To: Samuel Holland
  Cc: u-boot, Jagan Teki, Jaehoon Chung, Heiko Schocher,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

On Fri,  8 Oct 2021 00:17:17 -0500
Samuel Holland <samuel@sholland.org> wrote:

> CONFIG_SPL_I2C is the wrong symbol to use here. It is the top-level
> Kconfig symbol (not specific to either legacy or DM I2C), whereas the
> i2c_init() function is specific to legacy I2C. This change fixes a
> build failure when enabling SPL_I2C but not SPL_SYS_I2C_LEGACY.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>

I don't have the brain capacity right now to comment on the issue below,
but just for the sake of this patch:

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
> Actually, I think this commit raises a larger issue:
> 
> For some reason, SPL_SYS_I2C_LEGACY does not depend on SPL_I2C. When
> SPL_SYS_I2C_LEGACY was added in commit 55dabcc8f245 ("Convert
> CONFIG_SYS_I2C_LEGACY to Kconfig and add CONFIG_[ST]PL_SYS_I2C_LEGACY"),
> SPL_I2C wasn't added to the board configs.
> 
> But since commit 537892065ac1 ("Makefile: Move drivers/i2c/ into
> drivers/Makefile"), drivers/i2c is only compiled if SPL_I2C is enabled.
> 
> So the combination of these two commits appears to have accidentally
> removed I2C support from SPL for many boards.
> 
> The impact here is that checking CONFIG_IS_ENABLED(SYS_I2C_LEGACY) is
> not always enough, even though it should be. Because if CONFIG_SPL_I2C=n
> then i2c_init is undefined because drivers/i2c/i2c_core.c is not built.
> 
> Changes in v2:
> - New patch to account for I2C Kconfig changes
> 
>  arch/arm/mach-sunxi/board.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
> index d9b04f75fc4..b74ad4074df 100644
> --- a/arch/arm/mach-sunxi/board.c
> +++ b/arch/arm/mach-sunxi/board.c
> @@ -339,7 +339,7 @@ void board_init_f(ulong dummy)
>  	spl_init();
>  	preloader_console_init();
>  
> -#ifdef CONFIG_SPL_I2C
> +#if CONFIG_IS_ENABLED(I2C) && CONFIG_IS_ENABLED(SYS_I2C_LEGACY)
>  	/* Needed early by sunxi_board_init if PMU is enabled */
>  	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
>  #endif


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

* Re: [PATCH v2 05/12] sunxi: Select SUN8I_RSB more carefully
  2021-10-08  5:17 ` [PATCH v2 05/12] sunxi: Select SUN8I_RSB more carefully Samuel Holland
@ 2021-10-12 10:47   ` Andre Przywara
  0 siblings, 0 replies; 22+ messages in thread
From: Andre Przywara @ 2021-10-12 10:47 UTC (permalink / raw)
  To: Samuel Holland
  Cc: u-boot, Jagan Teki, Jaehoon Chung, Heiko Schocher,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

On Fri,  8 Oct 2021 00:17:18 -0500
Samuel Holland <samuel@sholland.org> wrote:

> SUN8I_RSB should not be selected by MACH_SUN8I, because the hardware
> is not present in half of those SoCs (H3/H5, R40, and V3s). Move the
> selection to the SoCs where the hardware actually exists.
> 
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
> Signed-off-by: Samuel Holland <samuel@sholland.org>

For the records, as per our IRC discussion, I removed the blanket select
from MACH_SUN9I, and added it to the defconfig of the two affected boards.
This fixes the compiler warnings for Sunchip_CX-A99.

Cheers,
Andre.

> ---
> 
> Changes in v2:
> - No changes
> 
>  arch/arm/mach-sunxi/Kconfig | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index 1d4a4fdd0c5..677d4554173 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -260,6 +260,7 @@ config MACH_SUN8I_A23
>  	select ARCH_SUPPORT_PSCI
>  	select DRAM_SUN8I_A23
>  	select PHY_SUN4I_USB
> +	select SUN8I_RSB
>  	select SUNXI_GEN_SUN6I
>  	select SUPPORT_SPL
>  	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
> @@ -273,6 +274,7 @@ config MACH_SUN8I_A33
>  	select ARCH_SUPPORT_PSCI
>  	select DRAM_SUN8I_A33
>  	select PHY_SUN4I_USB
> +	select SUN8I_RSB
>  	select SUNXI_GEN_SUN6I
>  	select SUPPORT_SPL
>  	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
> @@ -283,6 +285,7 @@ config MACH_SUN8I_A83T
>  	select CPU_V7A
>  	select DRAM_SUN8I_A83T
>  	select PHY_SUN4I_USB
> +	select SUN8I_RSB
>  	select SUNXI_GEN_SUN6I
>  	select MMC_SUNXI_HAS_NEW_MODE
>  	select MMC_SUNXI_HAS_MODE_SWITCH
> @@ -377,7 +380,6 @@ endchoice
>  # The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 ||
> A33" config MACH_SUN8I
>  	bool
> -	select SUN8I_RSB
>  	select SUN6I_PRCM
>  	default y if MACH_SUN8I_A23
>  	default y if MACH_SUN8I_A33


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

* Re: [PATCH v2 07/12] i2c: Add a DM_I2C driver for the sun6i P2WI controller
  2021-10-08  5:17 ` [PATCH v2 07/12] i2c: Add a DM_I2C driver for the sun6i P2WI controller Samuel Holland
@ 2021-10-12 10:49   ` Andre Przywara
  0 siblings, 0 replies; 22+ messages in thread
From: Andre Przywara @ 2021-10-12 10:49 UTC (permalink / raw)
  To: Samuel Holland
  Cc: u-boot, Jagan Teki, Jaehoon Chung, Heiko Schocher,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

On Fri,  8 Oct 2021 00:17:20 -0500
Samuel Holland <samuel@sholland.org> wrote:

> This bus controller is used to communicate with an X-Powers AXP PMIC.
> Currently, various drivers access PMIC registers through a platform-
> specific non-DM "pmic_bus" interface, which depends on the legacy I2C
> framework. In order to convert those drivers to use DM_PMIC, this bus
> needs a DM_I2C driver.
> 
> Refactor the p2wi functions to take the base address as a parameter,
> and implement both the existing interface (which is still needed in
> SPL) and the DM_I2C interface on top of them.

I compared the old and new file (with some tweaks), and can indeed confirm
that it's a conversion that preserves the actual functionality.
The new DM wrappers look good as well.

> The register for switching between I2C/P2WI/RSB mode is the same across
> all PMIC variants. Move that to the common header, so it can be used by
> both interface implementations.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Thanks!
Andre

> ---
> 
> Changes in v2:
> - Renamed Kconfig symbol to SYS_I2C_SUN6I_P2WI
> - Moved entire P2WI driver source to drivers/i2c
> 
>  arch/arm/mach-sunxi/Kconfig    |  14 +--
>  arch/arm/mach-sunxi/Makefile   |   1 -
>  arch/arm/mach-sunxi/p2wi.c     | 117 ------------------
>  arch/arm/mach-sunxi/pmic_bus.c |   7 +-
>  drivers/i2c/Kconfig            |   8 ++
>  drivers/i2c/Makefile           |   1 +
>  drivers/i2c/sun6i_p2wi.c       | 220 +++++++++++++++++++++++++++++++++
>  include/axp_pmic.h             |   6 +
>  8 files changed, 240 insertions(+), 134 deletions(-)
>  delete mode 100644 arch/arm/mach-sunxi/p2wi.c
>  create mode 100644 drivers/i2c/sun6i_p2wi.c
> 
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index 4d8f0e17d40..ae3b7974f09 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -88,17 +88,6 @@ config DRAM_SUN50I_H616_UNKNOWN_FEATURE
>  	  feature.
>  endif
>  
> -config SUN6I_P2WI
> -	bool "Allwinner sun6i internal P2WI controller"
> -	help
> -	  If you say yes to this option, support will be included for
> the
> -	  P2WI (Push/Pull 2 Wire Interface) controller embedded in some
> sunxi
> -	  SOCs.
> -	  The P2WI looks like an SMBus controller (which supports only
> byte
> -	  accesses), except that it only supports one slave device.
> -	  This interface is used to connect to specific PMIC devices
> (like the
> -	  AXP221).
> -
>  config SUN6I_PRCM
>  	bool
>  	help
> @@ -232,10 +221,11 @@ config MACH_SUN6I
>  	select ARCH_SUPPORT_PSCI
>  	select DRAM_SUN6I
>  	select PHY_SUN4I_USB
> -	select SUN6I_P2WI
> +	select SPL_I2C
>  	select SUN6I_PRCM
>  	select SUNXI_GEN_SUN6I
>  	select SUPPORT_SPL
> +	select SYS_I2C_SUN6I_P2WI
>  	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
>  
>  config MACH_SUN7I
> diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
> index 3f081d92f37..c9312bb3934 100644
> --- a/arch/arm/mach-sunxi/Makefile
> +++ b/arch/arm/mach-sunxi/Makefile
> @@ -11,7 +11,6 @@ obj-y	+= clock.o
>  obj-y	+= cpu_info.o
>  obj-y	+= dram_helpers.o
>  obj-y	+= pinmux.o
> -obj-$(CONFIG_SUN6I_P2WI)	+= p2wi.o
>  obj-$(CONFIG_SUN6I_PRCM)	+= prcm.o
>  obj-$(CONFIG_AXP_PMIC_BUS)	+= pmic_bus.o
>  obj-$(CONFIG_SUN8I_RSB)		+= rsb.o
> diff --git a/arch/arm/mach-sunxi/p2wi.c b/arch/arm/mach-sunxi/p2wi.c
> deleted file mode 100644
> index 7c5c12254ea..00000000000
> --- a/arch/arm/mach-sunxi/p2wi.c
> +++ /dev/null
> @@ -1,117 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0+
> -/*
> - * Sunxi A31 Power Management Unit
> - *
> - * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
> - * http://linux-sunxi.org
> - *
> - * Based on sun6i sources and earlier U-Boot Allwinner A10 SPL work
> - *
> - * (C) Copyright 2006-2013
> - * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> - * Berg Xing <bergxing@allwinnertech.com>
> - * Tom Cubie <tangliang@allwinnertech.com>
> - */
> -
> -#include <common.h>
> -#include <errno.h>
> -#include <time.h>
> -#include <asm/io.h>
> -#include <asm/arch/cpu.h>
> -#include <asm/arch/gpio.h>
> -#include <asm/arch/p2wi.h>
> -#include <asm/arch/prcm.h>
> -#include <asm/arch/clock.h>
> -#include <asm/arch/sys_proto.h>
> -
> -void p2wi_init(void)
> -{
> -	struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg
> *)SUN6I_P2WI_BASE; -
> -	/* Enable p2wi and PIO clk, and de-assert their resets */
> -	prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_P2WI);
> -
> -	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN6I_GPL0_R_P2WI_SCK);
> -	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN6I_GPL1_R_P2WI_SDA);
> -
> -	/* Reset p2wi controller and set clock to CLKIN(12)/8 = 1.5 MHz
> */
> -	writel(P2WI_CTRL_RESET, &p2wi->ctrl);
> -	sdelay(0x100);
> -	writel(P2WI_CC_SDA_OUT_DELAY(1) | P2WI_CC_CLK_DIV(8),
> -	       &p2wi->cc);
> -}
> -
> -int p2wi_change_to_p2wi_mode(u8 slave_addr, u8 ctrl_reg, u8 init_data)
> -{
> -	struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg
> *)SUN6I_P2WI_BASE;
> -	unsigned long tmo = timer_get_us() + 1000000;
> -
> -	writel(P2WI_PM_DEV_ADDR(slave_addr) |
> -	       P2WI_PM_CTRL_ADDR(ctrl_reg) |
> -	       P2WI_PM_INIT_DATA(init_data) |
> -	       P2WI_PM_INIT_SEND,
> -	       &p2wi->pm);
> -
> -	while ((readl(&p2wi->pm) & P2WI_PM_INIT_SEND)) {
> -		if (timer_get_us() > tmo)
> -			return -ETIME;
> -	}
> -
> -	return 0;
> -}
> -
> -static int p2wi_await_trans(void)
> -{
> -	struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg
> *)SUN6I_P2WI_BASE;
> -	unsigned long tmo = timer_get_us() + 1000000;
> -	int ret;
> -	u8 reg;
> -
> -	while (1) {
> -		reg = readl(&p2wi->status);
> -		if (reg & P2WI_STAT_TRANS_ERR) {
> -			ret = -EIO;
> -			break;
> -		}
> -		if (reg & P2WI_STAT_TRANS_DONE) {
> -			ret = 0;
> -			break;
> -		}
> -		if (timer_get_us() > tmo) {
> -			ret = -ETIME;
> -			break;
> -		}
> -	}
> -	writel(reg, &p2wi->status); /* Clear status bits */
> -	return ret;
> -}
> -
> -int p2wi_read(const u8 addr, u8 *data)
> -{
> -	struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg
> *)SUN6I_P2WI_BASE;
> -	int ret;
> -
> -	writel(P2WI_DATADDR_BYTE_1(addr), &p2wi->dataddr0);
> -	writel(P2WI_DATA_NUM_BYTES(1) |
> -	       P2WI_DATA_NUM_BYTES_READ, &p2wi->numbytes);
> -	writel(P2WI_STAT_TRANS_DONE, &p2wi->status);
> -	writel(P2WI_CTRL_TRANS_START, &p2wi->ctrl);
> -
> -	ret = p2wi_await_trans();
> -
> -	*data = readl(&p2wi->data0) & P2WI_DATA_BYTE_1_MASK;
> -	return ret;
> -}
> -
> -int p2wi_write(const u8 addr, u8 data)
> -{
> -	struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg
> *)SUN6I_P2WI_BASE; -
> -	writel(P2WI_DATADDR_BYTE_1(addr), &p2wi->dataddr0);
> -	writel(P2WI_DATA_BYTE_1(data), &p2wi->data0);
> -	writel(P2WI_DATA_NUM_BYTES(1), &p2wi->numbytes);
> -	writel(P2WI_STAT_TRANS_DONE, &p2wi->status);
> -	writel(P2WI_CTRL_TRANS_START, &p2wi->ctrl);
> -
> -	return p2wi_await_trans();
> -}
> diff --git a/arch/arm/mach-sunxi/pmic_bus.c
> b/arch/arm/mach-sunxi/pmic_bus.c index 0394ce85644..673a05fdd16 100644
> --- a/arch/arm/mach-sunxi/pmic_bus.c
> +++ b/arch/arm/mach-sunxi/pmic_bus.c
> @@ -8,6 +8,7 @@
>   * axp223 uses the rsb bus, these functions abstract this.
>   */
>  
> +#include <axp_pmic.h>
>  #include <common.h>
>  #include <asm/arch/p2wi.h>
>  #include <asm/arch/rsb.h>
> @@ -21,8 +22,6 @@
>  #define AXP305_I2C_ADDR			0x36
>  
>  #define AXP221_CHIP_ADDR		0x68
> -#define AXP221_CTRL_ADDR		0x3e
> -#define AXP221_INIT_DATA		0x3e
>  
>  /* AXP818 device and runtime addresses are same as AXP223 */
>  #define AXP223_DEVICE_ADDR		0x3a3
> @@ -40,8 +39,8 @@ int pmic_bus_init(void)
>  #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER ||
> defined CONFIG_AXP818_POWER # ifdef CONFIG_MACH_SUN6I
>  	p2wi_init();
> -	ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR,
> AXP221_CTRL_ADDR,
> -				       AXP221_INIT_DATA);
> +	ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR,
> AXP_PMIC_MODE_REG,
> +				       AXP_PMIC_MODE_P2WI);
>  # elif defined CONFIG_MACH_SUN8I_R40
>  	/* Nothing. R40 uses the AXP221s in I2C mode */
>  	ret = 0;
> diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
> index 57cac4483f0..0adf143abfd 100644
> --- a/drivers/i2c/Kconfig
> +++ b/drivers/i2c/Kconfig
> @@ -575,6 +575,14 @@ config SYS_I2C_STM32F7
>  	   _ Optional clock stretching
>  	   _ Software reset
>  
> +config SYS_I2C_SUN6I_P2WI
> +	bool "Allwinner sun6i P2WI controller"
> +	depends on ARCH_SUNXI
> +	help
> +	  Support for the P2WI (Push/Pull 2 Wire Interface) controller
> embedded
> +	  in the Allwinner A31 and A31s SOCs. This interface is used to
> connect
> +	  to specific devices like the X-Powers AXP221 PMIC.
> +
>  config SYS_I2C_SYNQUACER
>  	bool "Socionext SynQuacer I2C controller"
>  	depends on ARCH_SYNQUACER && DM_I2C
> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> index 67841bf3e02..0a2cc641930 100644
> --- a/drivers/i2c/Makefile
> +++ b/drivers/i2c/Makefile
> @@ -43,6 +43,7 @@ obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o
> i2c-emul-uclass.o obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
>  obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
>  obj-$(CONFIG_SYS_I2C_STM32F7) += stm32f7_i2c.o
> +obj-$(CONFIG_SYS_I2C_SUN6I_P2WI) += sun6i_p2wi.o
>  obj-$(CONFIG_SYS_I2C_SYNQUACER) += synquacer_i2c.o
>  obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
>  obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o
> diff --git a/drivers/i2c/sun6i_p2wi.c b/drivers/i2c/sun6i_p2wi.c
> new file mode 100644
> index 00000000000..c9e1b3fcd5f
> --- /dev/null
> +++ b/drivers/i2c/sun6i_p2wi.c
> @@ -0,0 +1,220 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Sunxi A31 Power Management Unit
> + *
> + * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
> + * http://linux-sunxi.org
> + *
> + * Based on sun6i sources and earlier U-Boot Allwinner A10 SPL work
> + *
> + * (C) Copyright 2006-2013
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Berg Xing <bergxing@allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + */
> +
> +#include <axp_pmic.h>
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <i2c.h>
> +#include <time.h>
> +#include <asm/io.h>
> +#include <asm/arch/cpu.h>
> +#include <asm/arch/gpio.h>
> +#include <asm/arch/p2wi.h>
> +#include <asm/arch/prcm.h>
> +#include <asm/arch/sys_proto.h>
> +
> +static int sun6i_p2wi_await_trans(struct sunxi_p2wi_reg *base)
> +{
> +	unsigned long tmo = timer_get_us() + 1000000;
> +	int ret;
> +	u8 reg;
> +
> +	while (1) {
> +		reg = readl(&base->status);
> +		if (reg & P2WI_STAT_TRANS_ERR) {
> +			ret = -EIO;
> +			break;
> +		}
> +		if (reg & P2WI_STAT_TRANS_DONE) {
> +			ret = 0;
> +			break;
> +		}
> +		if (timer_get_us() > tmo) {
> +			ret = -ETIME;
> +			break;
> +		}
> +	}
> +	writel(reg, &base->status); /* Clear status bits */
> +
> +	return ret;
> +}
> +
> +static int sun6i_p2wi_read(struct sunxi_p2wi_reg *base, const u8 addr,
> u8 *data) +{
> +	int ret;
> +
> +	writel(P2WI_DATADDR_BYTE_1(addr), &base->dataddr0);
> +	writel(P2WI_DATA_NUM_BYTES(1) |
> +	       P2WI_DATA_NUM_BYTES_READ, &base->numbytes);
> +	writel(P2WI_STAT_TRANS_DONE, &base->status);
> +	writel(P2WI_CTRL_TRANS_START, &base->ctrl);
> +
> +	ret = sun6i_p2wi_await_trans(base);
> +
> +	*data = readl(&base->data0) & P2WI_DATA_BYTE_1_MASK;
> +
> +	return ret;
> +}
> +
> +static int sun6i_p2wi_write(struct sunxi_p2wi_reg *base, const u8 addr,
> u8 data) +{
> +	writel(P2WI_DATADDR_BYTE_1(addr), &base->dataddr0);
> +	writel(P2WI_DATA_BYTE_1(data), &base->data0);
> +	writel(P2WI_DATA_NUM_BYTES(1), &base->numbytes);
> +	writel(P2WI_STAT_TRANS_DONE, &base->status);
> +	writel(P2WI_CTRL_TRANS_START, &base->ctrl);
> +
> +	return sun6i_p2wi_await_trans(base);
> +}
> +
> +static int sun6i_p2wi_change_to_p2wi_mode(struct sunxi_p2wi_reg *base,
> +					  u8 slave_addr, u8 ctrl_reg,
> +					  u8 init_data)
> +{
> +	unsigned long tmo = timer_get_us() + 1000000;
> +
> +	writel(P2WI_PM_DEV_ADDR(slave_addr) |
> +	       P2WI_PM_CTRL_ADDR(ctrl_reg) |
> +	       P2WI_PM_INIT_DATA(init_data) |
> +	       P2WI_PM_INIT_SEND,
> +	       &base->pm);
> +
> +	while ((readl(&base->pm) & P2WI_PM_INIT_SEND)) {
> +		if (timer_get_us() > tmo)
> +			return -ETIME;
> +	}
> +
> +	return 0;
> +}
> +
> +static void sun6i_p2wi_init(struct sunxi_p2wi_reg *base)
> +{
> +	/* Enable p2wi and PIO clk, and de-assert their resets */
> +	prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_P2WI);
> +
> +	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN6I_GPL0_R_P2WI_SCK);
> +	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN6I_GPL1_R_P2WI_SDA);
> +
> +	/* Reset p2wi controller and set clock to CLKIN(12)/8 = 1.5 MHz
> */
> +	writel(P2WI_CTRL_RESET, &base->ctrl);
> +	sdelay(0x100);
> +	writel(P2WI_CC_SDA_OUT_DELAY(1) | P2WI_CC_CLK_DIV(8),
> +	       &base->cc);
> +}
> +
> +#if IS_ENABLED(CONFIG_AXP_PMIC_BUS)
> +int p2wi_read(const u8 addr, u8 *data)
> +{
> +	struct sunxi_p2wi_reg *base = (struct sunxi_p2wi_reg
> *)SUN6I_P2WI_BASE; +
> +	return sun6i_p2wi_read(base, addr, data);
> +}
> +
> +int p2wi_write(const u8 addr, u8 data)
> +{
> +	struct sunxi_p2wi_reg *base = (struct sunxi_p2wi_reg
> *)SUN6I_P2WI_BASE; +
> +	return sun6i_p2wi_write(base, addr, data);
> +}
> +
> +int p2wi_change_to_p2wi_mode(u8 slave_addr, u8 ctrl_reg, u8 init_data)
> +{
> +	struct sunxi_p2wi_reg *base = (struct sunxi_p2wi_reg
> *)SUN6I_P2WI_BASE; +
> +	return sun6i_p2wi_change_to_p2wi_mode(base, slave_addr,
> ctrl_reg,
> +					      init_data);
> +}
> +
> +void p2wi_init(void)
> +{
> +	struct sunxi_p2wi_reg *base = (struct sunxi_p2wi_reg
> *)SUN6I_P2WI_BASE; +
> +	sun6i_p2wi_init(base);
> +}
> +#endif
> +
> +#if CONFIG_IS_ENABLED(DM_I2C)
> +struct sun6i_p2wi_priv {
> +	struct sunxi_p2wi_reg *base;
> +};
> +
> +static int sun6i_p2wi_xfer(struct udevice *bus, struct i2c_msg *msg,
> int nmsgs) +{
> +	struct sun6i_p2wi_priv *priv = dev_get_priv(bus);
> +
> +	/* The hardware only supports SMBus-style transfers. */
> +	if (nmsgs == 2 && msg[1].flags == I2C_M_RD && msg[1].len == 1)
> +		return sun6i_p2wi_read(priv->base,
> +				       msg[0].buf[0], &msg[1].buf[0]);
> +
> +	if (nmsgs == 1 && msg[0].len == 2)
> +		return sun6i_p2wi_write(priv->base,
> +					msg[0].buf[0], msg[0].buf[1]);
> +
> +	return -EINVAL;
> +}
> +
> +static int sun6i_p2wi_probe_chip(struct udevice *bus, uint chip_addr,
> +				 uint chip_flags)
> +{
> +	struct sun6i_p2wi_priv *priv = dev_get_priv(bus);
> +
> +	return sun6i_p2wi_change_to_p2wi_mode(priv->base, chip_addr,
> +					      AXP_PMIC_MODE_REG,
> +					      AXP_PMIC_MODE_P2WI);
> +}
> +
> +static int sun6i_p2wi_probe(struct udevice *bus)
> +{
> +	struct sun6i_p2wi_priv *priv = dev_get_priv(bus);
> +
> +	priv->base = dev_read_addr_ptr(bus);
> +
> +	sun6i_p2wi_init(priv->base);
> +
> +	return 0;
> +}
> +
> +static int sun6i_p2wi_child_pre_probe(struct udevice *child)
> +{
> +	struct dm_i2c_chip *chip = dev_get_parent_plat(child);
> +
> +	/* Ensure each transfer is for a single register. */
> +	chip->flags |= DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS;
> +
> +	return 0;
> +}
> +
> +static const struct dm_i2c_ops sun6i_p2wi_ops = {
> +	.xfer		= sun6i_p2wi_xfer,
> +	.probe_chip	= sun6i_p2wi_probe_chip,
> +};
> +
> +static const struct udevice_id sun6i_p2wi_ids[] = {
> +	{ .compatible = "allwinner,sun6i-a31-p2wi" },
> +	{ /* sentinel */ }
> +};
> +
> +U_BOOT_DRIVER(sun6i_p2wi) = {
> +	.name			= "sun6i_p2wi",
> +	.id			= UCLASS_I2C,
> +	.of_match		= sun6i_p2wi_ids,
> +	.probe			= sun6i_p2wi_probe,
> +	.child_pre_probe	= sun6i_p2wi_child_pre_probe,
> +	.priv_auto		= sizeof(struct sun6i_p2wi_priv),
> +	.ops			= &sun6i_p2wi_ops,
> +};
> +#endif /* CONFIG_IS_ENABLED(DM_I2C) */
> diff --git a/include/axp_pmic.h b/include/axp_pmic.h
> index 405044c3a32..0db3e143eda 100644
> --- a/include/axp_pmic.h
> +++ b/include/axp_pmic.h
> @@ -6,6 +6,8 @@
>   */
>  #ifndef _AXP_PMIC_H_
>  
> +#include <stdbool.h>
> +
>  #ifdef CONFIG_AXP152_POWER
>  #include <axp152.h>
>  #endif
> @@ -25,6 +27,10 @@
>  #include <axp818.h>
>  #endif
>  
> +#define AXP_PMIC_MODE_REG		0x3e
> +#define AXP_PMIC_MODE_I2C		0x00
> +#define AXP_PMIC_MODE_P2WI		0x3e
> +
>  int axp_set_dcdc1(unsigned int mvolt);
>  int axp_set_dcdc2(unsigned int mvolt);
>  int axp_set_dcdc3(unsigned int mvolt);


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

* Re: [PATCH v2 08/12] i2c: Add a DM_I2C driver for the sun8i RSB controller
  2021-10-08  5:17 ` [PATCH v2 08/12] i2c: Add a DM_I2C driver for the sun8i RSB controller Samuel Holland
@ 2021-10-12 10:49   ` Andre Przywara
  0 siblings, 0 replies; 22+ messages in thread
From: Andre Przywara @ 2021-10-12 10:49 UTC (permalink / raw)
  To: Samuel Holland
  Cc: u-boot, Jagan Teki, Jaehoon Chung, Heiko Schocher,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

On Fri,  8 Oct 2021 00:17:21 -0500
Samuel Holland <samuel@sholland.org> wrote:

> This bus controller is used to communicate with an X-Powers AXP PMIC.
> Currently, various drivers access PMIC registers through a platform-
> specific non-DM "pmic_bus" interface, which depends on the legacy I2C
> framework. In order to convert those drivers to use DM_PMIC, this bus
> needs a DM_I2C driver.
> 
> Refactor the rsb functions to take the base address as a parameter,
> and implement both the existing interface (which is still needed in
> SPL) and the DM_I2C interface on top of them.

I diff'ed the (slightly tweaked) old version and the new file, and can
indeed confirm that it's a conversion that preserves the actual
functionality. The new DM wrappers look good as well.

> The register for switching between I2C/P2WI/RSB mode is the same across
> all PMIC variants, so move that to the common header.
> 
> There are only a couple of pairs of hardware/runtime addresses used
> across all PMIC variants. So far the code expected only the "primary"
> pair, but some PMICs like the AXP305 and AXP805 use the secondary pair,
> so add support for that to the DM driver as well.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
> 
> Changes in v2:
> - Renamed Kconfig symbol to SYS_I2C_SUN8I_RSB
> - Moved entire RSB driver source to drivers/i2c
> 
>  arch/arm/mach-sunxi/Kconfig    |  20 +--
>  arch/arm/mach-sunxi/Makefile   |   1 -
>  arch/arm/mach-sunxi/pmic_bus.c |  11 +-
>  arch/arm/mach-sunxi/rsb.c      | 175 --------------------
>  drivers/i2c/Kconfig            |   8 +
>  drivers/i2c/Makefile           |   1 +
>  drivers/i2c/sun8i_rsb.c        | 281 +++++++++++++++++++++++++++++++++
>  include/axp_pmic.h             |   6 +
>  8 files changed, 308 insertions(+), 195 deletions(-)
>  delete mode 100644 arch/arm/mach-sunxi/rsb.c
>  create mode 100644 drivers/i2c/sun8i_rsb.c
> 
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index ae3b7974f09..df160c9a775 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -100,14 +100,6 @@ config AXP_PMIC_BUS
>  	  Select this PMIC bus access helpers for Sunxi platform PRCM or other
>  	  AXP family PMIC devices.
>  
> -config SUN8I_RSB
> -	bool "Allwinner sunXi Reduced Serial Bus Driver"
> -	help
> -	  Say y here to enable support for Allwinner's Reduced Serial Bus
> -	  (RSB) support. This controller is responsible for communicating
> -	  with various RSB based devices, such as AXP223, AXP8XX PMICs,
> -	  and AC100/AC200 ICs.
> -
>  config SUNXI_SRAM_ADDRESS
>  	hex
>  	default 0x10000 if MACH_SUN9I || MACH_SUN50I || MACH_SUN50I_H5
> @@ -250,9 +242,10 @@ config MACH_SUN8I_A23
>  	select ARCH_SUPPORT_PSCI
>  	select DRAM_SUN8I_A23
>  	select PHY_SUN4I_USB
> -	select SUN8I_RSB
> +	select SPL_I2C
>  	select SUNXI_GEN_SUN6I
>  	select SUPPORT_SPL
> +	select SYS_I2C_SUN8I_RSB
>  	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
>  	imply CONS_INDEX_5 if !DM_SERIAL
>  
> @@ -264,9 +257,10 @@ config MACH_SUN8I_A33
>  	select ARCH_SUPPORT_PSCI
>  	select DRAM_SUN8I_A33
>  	select PHY_SUN4I_USB
> -	select SUN8I_RSB
> +	select SPL_I2C
>  	select SUNXI_GEN_SUN6I
>  	select SUPPORT_SPL
> +	select SYS_I2C_SUN8I_RSB
>  	select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
>  	imply CONS_INDEX_5 if !DM_SERIAL
>  
> @@ -275,11 +269,12 @@ config MACH_SUN8I_A83T
>  	select CPU_V7A
>  	select DRAM_SUN8I_A83T
>  	select PHY_SUN4I_USB
> -	select SUN8I_RSB
> +	select SPL_I2C
>  	select SUNXI_GEN_SUN6I
>  	select MMC_SUNXI_HAS_NEW_MODE
>  	select MMC_SUNXI_HAS_MODE_SWITCH
>  	select SUPPORT_SPL
> +	select SYS_I2C_SUN8I_RSB
>  
>  config MACH_SUN8I_H3
>  	bool "sun8i (Allwinner H3)"
> @@ -320,10 +315,11 @@ config MACH_SUN9I
>  	bool "sun9i (Allwinner A80)"
>  	select CPU_V7A
>  	select DRAM_SUN9I
> +	select SPL_I2C
>  	select SUN6I_PRCM
>  	select SUNXI_GEN_SUN6I
> -	select SUN8I_RSB
>  	select SUPPORT_SPL
> +	select SYS_I2C_SUN8I_RSB
>  
>  config MACH_SUN50I
>  	bool "sun50i (Allwinner A64)"
> diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
> index c9312bb3934..5d3fd70f749 100644
> --- a/arch/arm/mach-sunxi/Makefile
> +++ b/arch/arm/mach-sunxi/Makefile
> @@ -13,7 +13,6 @@ obj-y	+= dram_helpers.o
>  obj-y	+= pinmux.o
>  obj-$(CONFIG_SUN6I_PRCM)	+= prcm.o
>  obj-$(CONFIG_AXP_PMIC_BUS)	+= pmic_bus.o
> -obj-$(CONFIG_SUN8I_RSB)		+= rsb.o
>  obj-$(CONFIG_MACH_SUN4I)	+= clock_sun4i.o
>  obj-$(CONFIG_MACH_SUN5I)	+= clock_sun4i.o
>  obj-$(CONFIG_MACH_SUN6I)	+= clock_sun6i.o
> diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c
> index 673a05fdd16..827797249ea 100644
> --- a/arch/arm/mach-sunxi/pmic_bus.c
> +++ b/arch/arm/mach-sunxi/pmic_bus.c
> @@ -23,10 +23,6 @@
>  
>  #define AXP221_CHIP_ADDR		0x68
>  
> -/* AXP818 device and runtime addresses are same as AXP223 */
> -#define AXP223_DEVICE_ADDR		0x3a3
> -#define AXP223_RUNTIME_ADDR		0x2d
> -
>  int pmic_bus_init(void)
>  {
>  	/* This cannot be 0 because it is used in SPL before BSS is ready */
> @@ -49,7 +45,8 @@ int pmic_bus_init(void)
>  	if (ret)
>  		return ret;
>  
> -	ret = rsb_set_device_address(AXP223_DEVICE_ADDR, AXP223_RUNTIME_ADDR);
> +	ret = rsb_set_device_address(AXP_PMIC_PRI_DEVICE_ADDR,
> +				     AXP_PMIC_PRI_RUNTIME_ADDR);
>  # endif
>  	if (ret)
>  		return ret;
> @@ -73,7 +70,7 @@ int pmic_bus_read(u8 reg, u8 *data)
>  # elif defined CONFIG_MACH_SUN8I_R40
>  	return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1);
>  # else
> -	return rsb_read(AXP223_RUNTIME_ADDR, reg, data);
> +	return rsb_read(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
>  # endif
>  #endif
>  }
> @@ -92,7 +89,7 @@ int pmic_bus_write(u8 reg, u8 data)
>  # elif defined CONFIG_MACH_SUN8I_R40
>  	return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1);
>  # else
> -	return rsb_write(AXP223_RUNTIME_ADDR, reg, data);
> +	return rsb_write(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
>  # endif
>  #endif
>  }
> diff --git a/arch/arm/mach-sunxi/rsb.c b/arch/arm/mach-sunxi/rsb.c
> deleted file mode 100644
> index 01bb09b7478..00000000000
> --- a/arch/arm/mach-sunxi/rsb.c
> +++ /dev/null
> @@ -1,175 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0+
> -/*
> - * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
> - *
> - * Based on allwinner u-boot sources rsb code which is:
> - * (C) Copyright 2007-2013
> - * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> - * lixiang <lixiang@allwinnertech.com>
> - */
> -
> -#include <common.h>
> -#include <errno.h>
> -#include <time.h>
> -#include <asm/arch/cpu.h>
> -#include <asm/arch/gpio.h>
> -#include <asm/arch/prcm.h>
> -#include <asm/arch/rsb.h>
> -
> -static int rsb_set_device_mode(void);
> -
> -static void rsb_cfg_io(void)
> -{
> -#ifdef CONFIG_MACH_SUN8I
> -	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB);
> -	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB);
> -	sunxi_gpio_set_pull(SUNXI_GPL(0), 1);
> -	sunxi_gpio_set_pull(SUNXI_GPL(1), 1);
> -	sunxi_gpio_set_drv(SUNXI_GPL(0), 2);
> -	sunxi_gpio_set_drv(SUNXI_GPL(1), 2);
> -#elif defined CONFIG_MACH_SUN9I
> -	sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN_R_RSB);
> -	sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN_R_RSB);
> -	sunxi_gpio_set_pull(SUNXI_GPN(0), 1);
> -	sunxi_gpio_set_pull(SUNXI_GPN(1), 1);
> -	sunxi_gpio_set_drv(SUNXI_GPN(0), 2);
> -	sunxi_gpio_set_drv(SUNXI_GPN(1), 2);
> -#else
> -#error unsupported MACH_SUNXI
> -#endif
> -}
> -
> -static void rsb_set_clk(void)
> -{
> -	struct sunxi_rsb_reg * const rsb =
> -		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
> -	u32 div = 0;
> -	u32 cd_odly = 0;
> -
> -	/* Source is Hosc24M, set RSB clk to 3Mhz */
> -	div = 24000000 / 3000000 / 2 - 1;
> -	cd_odly = div >> 1;
> -	if (!cd_odly)
> -		cd_odly = 1;
> -
> -	writel((cd_odly << 8) | div, &rsb->ccr);
> -}
> -
> -int rsb_init(void)
> -{
> -	struct sunxi_rsb_reg * const rsb =
> -		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
> -
> -	/* Enable RSB and PIO clk, and de-assert their resets */
> -	prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_RSB);
> -
> -	/* Setup external pins */
> -	rsb_cfg_io();
> -
> -	writel(RSB_CTRL_SOFT_RST, &rsb->ctrl);
> -	rsb_set_clk();
> -
> -	return rsb_set_device_mode();
> -}
> -
> -static int rsb_await_trans(void)
> -{
> -	struct sunxi_rsb_reg * const rsb =
> -		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
> -	unsigned long tmo = timer_get_us() + 1000000;
> -	u32 stat;
> -	int ret;
> -
> -	while (1) {
> -		stat = readl(&rsb->stat);
> -		if (stat & RSB_STAT_LBSY_INT) {
> -			ret = -EBUSY;
> -			break;
> -		}
> -		if (stat & RSB_STAT_TERR_INT) {
> -			ret = -EIO;
> -			break;
> -		}
> -		if (stat & RSB_STAT_TOVER_INT) {
> -			ret = 0;
> -			break;
> -		}
> -		if (timer_get_us() > tmo) {
> -			ret = -ETIME;
> -			break;
> -		}
> -	}
> -	writel(stat, &rsb->stat); /* Clear status bits */
> -
> -	return ret;
> -}
> -
> -static int rsb_set_device_mode(void)
> -{
> -	struct sunxi_rsb_reg * const rsb =
> -		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
> -	unsigned long tmo = timer_get_us() + 1000000;
> -
> -	writel(RSB_DMCR_DEVICE_MODE_START | RSB_DMCR_DEVICE_MODE_DATA,
> -	       &rsb->dmcr);
> -
> -	while (readl(&rsb->dmcr) & RSB_DMCR_DEVICE_MODE_START) {
> -		if (timer_get_us() > tmo)
> -			return -ETIME;
> -	}
> -
> -	return rsb_await_trans();
> -}
> -
> -static int rsb_do_trans(void)
> -{
> -	struct sunxi_rsb_reg * const rsb =
> -		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
> -
> -	setbits_le32(&rsb->ctrl, RSB_CTRL_START_TRANS);
> -	return rsb_await_trans();
> -}
> -
> -int rsb_set_device_address(u16 device_addr, u16 runtime_addr)
> -{
> -	struct sunxi_rsb_reg * const rsb =
> -		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
> -
> -	writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr) |
> -	       RSB_DEVADDR_DEVICE_ADDR(device_addr), &rsb->devaddr);
> -	writel(RSB_CMD_SET_RTSADDR, &rsb->cmd);
> -
> -	return rsb_do_trans();
> -}
> -
> -int rsb_write(const u16 runtime_device_addr, const u8 reg_addr, u8 data)
> -{
> -	struct sunxi_rsb_reg * const rsb =
> -		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
> -
> -	writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_device_addr), &rsb->devaddr);
> -	writel(reg_addr, &rsb->addr);
> -	writel(data, &rsb->data);
> -	writel(RSB_CMD_BYTE_WRITE, &rsb->cmd);
> -
> -	return rsb_do_trans();
> -}
> -
> -int rsb_read(const u16 runtime_device_addr, const u8 reg_addr, u8 *data)
> -{
> -	struct sunxi_rsb_reg * const rsb =
> -		(struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
> -	int ret;
> -
> -	writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_device_addr), &rsb->devaddr);
> -	writel(reg_addr, &rsb->addr);
> -	writel(RSB_CMD_BYTE_READ, &rsb->cmd);
> -
> -	ret = rsb_do_trans();
> -	if (ret)
> -		return ret;
> -
> -	*data = readl(&rsb->data) & 0xff;
> -
> -	return 0;
> -}
> diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
> index 0adf143abfd..66bd6fe2f34 100644
> --- a/drivers/i2c/Kconfig
> +++ b/drivers/i2c/Kconfig
> @@ -583,6 +583,14 @@ config SYS_I2C_SUN6I_P2WI
>  	  in the Allwinner A31 and A31s SOCs. This interface is used to connect
>  	  to specific devices like the X-Powers AXP221 PMIC.
>  
> +config SYS_I2C_SUN8I_RSB
> +	bool "Allwinner sun8i Reduced Serial Bus controller"
> +	depends on ARCH_SUNXI
> +	help
> +	  Support for Allwinner's Reduced Serial Bus (RSB) controller. This
> +	  controller is responsible for communicating with various RSB based
> +	  devices, such as X-Powers AXPxxx PMICs and AC100/AC200 CODEC ICs.
> +
>  config SYS_I2C_SYNQUACER
>  	bool "Socionext SynQuacer I2C controller"
>  	depends on ARCH_SYNQUACER && DM_I2C
> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> index 0a2cc641930..916427452a5 100644
> --- a/drivers/i2c/Makefile
> +++ b/drivers/i2c/Makefile
> @@ -44,6 +44,7 @@ obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
>  obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
>  obj-$(CONFIG_SYS_I2C_STM32F7) += stm32f7_i2c.o
>  obj-$(CONFIG_SYS_I2C_SUN6I_P2WI) += sun6i_p2wi.o
> +obj-$(CONFIG_SYS_I2C_SUN8I_RSB) += sun8i_rsb.o
>  obj-$(CONFIG_SYS_I2C_SYNQUACER) += synquacer_i2c.o
>  obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
>  obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o
> diff --git a/drivers/i2c/sun8i_rsb.c b/drivers/i2c/sun8i_rsb.c
> new file mode 100644
> index 00000000000..716b245a003
> --- /dev/null
> +++ b/drivers/i2c/sun8i_rsb.c
> @@ -0,0 +1,281 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
> + *
> + * Based on allwinner u-boot sources rsb code which is:
> + * (C) Copyright 2007-2013
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * lixiang <lixiang@allwinnertech.com>
> + */
> +
> +#include <axp_pmic.h>
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <i2c.h>
> +#include <time.h>
> +#include <asm/arch/cpu.h>
> +#include <asm/arch/gpio.h>
> +#include <asm/arch/prcm.h>
> +#include <asm/arch/rsb.h>
> +
> +static int sun8i_rsb_await_trans(struct sunxi_rsb_reg *base)
> +{
> +	unsigned long tmo = timer_get_us() + 1000000;
> +	u32 stat;
> +	int ret;
> +
> +	while (1) {
> +		stat = readl(&base->stat);
> +		if (stat & RSB_STAT_LBSY_INT) {
> +			ret = -EBUSY;
> +			break;
> +		}
> +		if (stat & RSB_STAT_TERR_INT) {
> +			ret = -EIO;
> +			break;
> +		}
> +		if (stat & RSB_STAT_TOVER_INT) {
> +			ret = 0;
> +			break;
> +		}
> +		if (timer_get_us() > tmo) {
> +			ret = -ETIME;
> +			break;
> +		}
> +	}
> +	writel(stat, &base->stat); /* Clear status bits */
> +
> +	return ret;
> +}
> +
> +static int sun8i_rsb_do_trans(struct sunxi_rsb_reg *base)
> +{
> +	setbits_le32(&base->ctrl, RSB_CTRL_START_TRANS);
> +
> +	return sun8i_rsb_await_trans(base);
> +}
> +
> +static int sun8i_rsb_read(struct sunxi_rsb_reg *base, u16 runtime_addr,
> +			  u8 reg_addr, u8 *data)
> +{
> +	int ret;
> +
> +	writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr), &base->devaddr);
> +	writel(reg_addr, &base->addr);
> +	writel(RSB_CMD_BYTE_READ, &base->cmd);
> +
> +	ret = sun8i_rsb_do_trans(base);
> +	if (ret)
> +		return ret;
> +
> +	*data = readl(&base->data) & 0xff;
> +
> +	return 0;
> +}
> +
> +static int sun8i_rsb_write(struct sunxi_rsb_reg *base, u16 runtime_addr,
> +			   u8 reg_addr, u8 data)
> +{
> +	writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr), &base->devaddr);
> +	writel(reg_addr, &base->addr);
> +	writel(data, &base->data);
> +	writel(RSB_CMD_BYTE_WRITE, &base->cmd);
> +
> +	return sun8i_rsb_do_trans(base);
> +}
> +
> +static int sun8i_rsb_set_device_address(struct sunxi_rsb_reg *base,
> +					u16 device_addr, u16 runtime_addr)
> +{
> +	writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr) |
> +	       RSB_DEVADDR_DEVICE_ADDR(device_addr), &base->devaddr);
> +	writel(RSB_CMD_SET_RTSADDR, &base->cmd);
> +
> +	return sun8i_rsb_do_trans(base);
> +}
> +
> +static void sun8i_rsb_cfg_io(void)
> +{
> +#ifdef CONFIG_MACH_SUN8I
> +	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB);
> +	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB);
> +	sunxi_gpio_set_pull(SUNXI_GPL(0), 1);
> +	sunxi_gpio_set_pull(SUNXI_GPL(1), 1);
> +	sunxi_gpio_set_drv(SUNXI_GPL(0), 2);
> +	sunxi_gpio_set_drv(SUNXI_GPL(1), 2);
> +#elif defined CONFIG_MACH_SUN9I
> +	sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN_R_RSB);
> +	sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN_R_RSB);
> +	sunxi_gpio_set_pull(SUNXI_GPN(0), 1);
> +	sunxi_gpio_set_pull(SUNXI_GPN(1), 1);
> +	sunxi_gpio_set_drv(SUNXI_GPN(0), 2);
> +	sunxi_gpio_set_drv(SUNXI_GPN(1), 2);
> +#else
> +#error unsupported MACH_SUNXI
> +#endif
> +}
> +
> +static void sun8i_rsb_set_clk(struct sunxi_rsb_reg *base)
> +{
> +	u32 div = 0;
> +	u32 cd_odly = 0;
> +
> +	/* Source is Hosc24M, set RSB clk to 3Mhz */
> +	div = 24000000 / 3000000 / 2 - 1;
> +	cd_odly = div >> 1;
> +	if (!cd_odly)
> +		cd_odly = 1;
> +
> +	writel((cd_odly << 8) | div, &base->ccr);
> +}
> +
> +static int sun8i_rsb_set_device_mode(struct sunxi_rsb_reg *base)
> +{
> +	unsigned long tmo = timer_get_us() + 1000000;
> +
> +	writel(RSB_DMCR_DEVICE_MODE_START | RSB_DMCR_DEVICE_MODE_DATA,
> +	       &base->dmcr);
> +
> +	while (readl(&base->dmcr) & RSB_DMCR_DEVICE_MODE_START) {
> +		if (timer_get_us() > tmo)
> +			return -ETIME;
> +	}
> +
> +	return sun8i_rsb_await_trans(base);
> +}
> +
> +static int sun8i_rsb_init(struct sunxi_rsb_reg *base)
> +{
> +	/* Enable RSB and PIO clk, and de-assert their resets */
> +	prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_RSB);
> +
> +	/* Setup external pins */
> +	sun8i_rsb_cfg_io();
> +
> +	writel(RSB_CTRL_SOFT_RST, &base->ctrl);
> +	sun8i_rsb_set_clk(base);
> +
> +	return sun8i_rsb_set_device_mode(base);
> +}
> +
> +#if IS_ENABLED(CONFIG_AXP_PMIC_BUS)
> +int rsb_read(const u16 runtime_addr, const u8 reg_addr, u8 *data)
> +{
> +	struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
> +
> +	return sun8i_rsb_read(base, runtime_addr, reg_addr, data);
> +}
> +
> +int rsb_write(const u16 runtime_addr, const u8 reg_addr, u8 data)
> +{
> +	struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
> +
> +	return sun8i_rsb_write(base, runtime_addr, reg_addr, data);
> +}
> +
> +int rsb_set_device_address(u16 device_addr, u16 runtime_addr)
> +{
> +	struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
> +
> +	return sun8i_rsb_set_device_address(base, device_addr, runtime_addr);
> +}
> +
> +int rsb_init(void)
> +{
> +	struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE;
> +
> +	return sun8i_rsb_init(base);
> +}
> +#endif
> +
> +#if CONFIG_IS_ENABLED(DM_I2C)
> +struct sun8i_rsb_priv {
> +	struct sunxi_rsb_reg *base;
> +};
> +
> +/*
> + * The mapping from hardware address to runtime address is fixed, and shared
> + * among all RSB drivers. See the comment in drivers/bus/sunxi-rsb.c in Linux.
> + */
> +static int sun8i_rsb_get_runtime_address(u16 device_addr)
> +{
> +	if (device_addr == AXP_PMIC_PRI_DEVICE_ADDR)
> +		return AXP_PMIC_PRI_RUNTIME_ADDR;
> +	if (device_addr == AXP_PMIC_SEC_DEVICE_ADDR)
> +		return AXP_PMIC_SEC_RUNTIME_ADDR;
> +
> +	return -ENXIO;
> +}
> +
> +static int sun8i_rsb_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
> +{
> +	int runtime_addr = sun8i_rsb_get_runtime_address(msg->addr);
> +	struct sun8i_rsb_priv *priv = dev_get_priv(bus);
> +
> +	if (runtime_addr < 0)
> +		return runtime_addr;
> +
> +	/* The hardware only supports SMBus-style transfers. */
> +	if (nmsgs == 2 && msg[1].flags == I2C_M_RD && msg[1].len == 1)
> +		return sun8i_rsb_read(priv->base, runtime_addr,
> +				      msg[0].buf[0], &msg[1].buf[0]);
> +
> +	if (nmsgs == 1 && msg[0].len == 2)
> +		return sun8i_rsb_write(priv->base, runtime_addr,
> +				       msg[0].buf[0], msg[0].buf[1]);
> +
> +	return -EINVAL;
> +}
> +
> +static int sun8i_rsb_probe_chip(struct udevice *bus, uint chip_addr,
> +				uint chip_flags)
> +{
> +	int runtime_addr = sun8i_rsb_get_runtime_address(chip_addr);
> +	struct sun8i_rsb_priv *priv = dev_get_priv(bus);
> +
> +	if (runtime_addr < 0)
> +		return runtime_addr;
> +
> +	return sun8i_rsb_set_device_address(priv->base, chip_addr, runtime_addr);
> +}
> +
> +static int sun8i_rsb_probe(struct udevice *bus)
> +{
> +	struct sun8i_rsb_priv *priv = dev_get_priv(bus);
> +
> +	priv->base = dev_read_addr_ptr(bus);
> +
> +	return sun8i_rsb_init(priv->base);
> +}
> +
> +static int sun8i_rsb_child_pre_probe(struct udevice *child)
> +{
> +	struct dm_i2c_chip *chip = dev_get_parent_plat(child);
> +
> +	/* Ensure each transfer is for a single register. */
> +	chip->flags |= DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS;
> +
> +	return 0;
> +}
> +
> +static const struct dm_i2c_ops sun8i_rsb_ops = {
> +	.xfer		= sun8i_rsb_xfer,
> +	.probe_chip	= sun8i_rsb_probe_chip,
> +};
> +
> +static const struct udevice_id sun8i_rsb_ids[] = {
> +	{ .compatible = "allwinner,sun8i-a23-rsb" },
> +	{ /* sentinel */ }
> +};
> +
> +U_BOOT_DRIVER(sun8i_rsb) = {
> +	.name			= "sun8i_rsb",
> +	.id			= UCLASS_I2C,
> +	.of_match		= sun8i_rsb_ids,
> +	.probe			= sun8i_rsb_probe,
> +	.child_pre_probe	= sun8i_rsb_child_pre_probe,
> +	.priv_auto		= sizeof(struct sun8i_rsb_priv),
> +	.ops			= &sun8i_rsb_ops,
> +};
> +#endif /* CONFIG_IS_ENABLED(DM_I2C) */
> diff --git a/include/axp_pmic.h b/include/axp_pmic.h
> index 0db3e143eda..46a017d2efa 100644
> --- a/include/axp_pmic.h
> +++ b/include/axp_pmic.h
> @@ -30,6 +30,12 @@
>  #define AXP_PMIC_MODE_REG		0x3e
>  #define AXP_PMIC_MODE_I2C		0x00
>  #define AXP_PMIC_MODE_P2WI		0x3e
> +#define AXP_PMIC_MODE_RSB		0x7c
> +
> +#define AXP_PMIC_PRI_DEVICE_ADDR	0x3a3
> +#define AXP_PMIC_PRI_RUNTIME_ADDR	0x2d
> +#define AXP_PMIC_SEC_DEVICE_ADDR	0x745
> +#define AXP_PMIC_SEC_RUNTIME_ADDR	0x3a
>  
>  int axp_set_dcdc1(unsigned int mvolt);
>  int axp_set_dcdc2(unsigned int mvolt);


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

* Re: [PATCH v2 09/12] sunxi: pmic_bus: Clean up preprocessor conditions
  2021-10-08  5:17 ` [PATCH v2 09/12] sunxi: pmic_bus: Clean up preprocessor conditions Samuel Holland
@ 2021-10-12 10:49   ` Andre Przywara
  0 siblings, 0 replies; 22+ messages in thread
From: Andre Przywara @ 2021-10-12 10:49 UTC (permalink / raw)
  To: Samuel Holland
  Cc: u-boot, Jagan Teki, Jaehoon Chung, Heiko Schocher,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

On Fri,  8 Oct 2021 00:17:22 -0500
Samuel Holland <samuel@sholland.org> wrote:

> Instead of using the SoC symbols to decide the bus type, use whichever
> bus driver is actually enabled. This allows collapsing all of the AXP2xx
> and AXP8xx variants into one "else" case. It also has the advantage of
> falling back to I2C when the other bus drivers are disabled; this works
> because all of the PMICs support I2C in addition to other interfaces.

Many many thanks for cleaning up this #ifdef mess! I couldn't be bothered
to double check all variants (did I mention that it's a mess?), but I
glanced over it, and it looks alright.

> Signed-off-by: Samuel Holland <samuel@sholland.org>

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
> 
> Changes in v2:
> - Update IS_ENABLEDs in pmic_bus.c to match chages to previous patches
> 
>  arch/arm/mach-sunxi/pmic_bus.c | 90 +++++++++++++++-------------------
>  1 file changed, 39 insertions(+), 51 deletions(-)
> 
> diff --git a/arch/arm/mach-sunxi/pmic_bus.c
> b/arch/arm/mach-sunxi/pmic_bus.c index 827797249ea..20ded436cd2 100644
> --- a/arch/arm/mach-sunxi/pmic_bus.c
> +++ b/arch/arm/mach-sunxi/pmic_bus.c
> @@ -23,75 +23,63 @@
>  
>  #define AXP221_CHIP_ADDR		0x68
>  
> +static int pmic_i2c_address(void)
> +{
> +	if (IS_ENABLED(CONFIG_AXP152_POWER))
> +		return AXP152_I2C_ADDR;
> +	if (IS_ENABLED(CONFIG_AXP305_POWER))
> +		return AXP305_I2C_ADDR;
> +
> +	/* Other AXP2xx and AXP8xx variants */
> +	return AXP209_I2C_ADDR;
> +}
> +
>  int pmic_bus_init(void)
>  {
>  	/* This cannot be 0 because it is used in SPL before BSS is
> ready */ static int needs_init = 1;
> -	__maybe_unused int ret;
> +	int ret = 0;
>  
>  	if (!needs_init)
>  		return 0;
>  
> -#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER ||
> defined CONFIG_AXP818_POWER -# ifdef CONFIG_MACH_SUN6I
> -	p2wi_init();
> -	ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR,
> AXP_PMIC_MODE_REG,
> -				       AXP_PMIC_MODE_P2WI);
> -# elif defined CONFIG_MACH_SUN8I_R40
> -	/* Nothing. R40 uses the AXP221s in I2C mode */
> -	ret = 0;
> -# else
> -	ret = rsb_init();
> -	if (ret)
> -		return ret;
> +	if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI)) {
> +		p2wi_init();
> +		ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR,
> +					       AXP_PMIC_MODE_REG,
> +					       AXP_PMIC_MODE_P2WI);
> +	} else if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB)) {
> +		ret = rsb_init();
> +		if (ret)
> +			return ret;
>  
> -	ret = rsb_set_device_address(AXP_PMIC_PRI_DEVICE_ADDR,
> -				     AXP_PMIC_PRI_RUNTIME_ADDR);
> -# endif
> -	if (ret)
> -		return ret;
> -#endif
> +		ret = rsb_set_device_address(AXP_PMIC_PRI_DEVICE_ADDR,
> +					     AXP_PMIC_PRI_RUNTIME_ADDR);
> +	}
> +
> +	needs_init = ret;
>  
> -	needs_init = 0;
> -	return 0;
> +	return ret;
>  }
>  
>  int pmic_bus_read(u8 reg, u8 *data)
>  {
> -#ifdef CONFIG_AXP152_POWER
> -	return i2c_read(AXP152_I2C_ADDR, reg, 1, data, 1);
> -#elif defined CONFIG_AXP209_POWER
> -	return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1);
> -#elif defined CONFIG_AXP305_POWER
> -	return i2c_read(AXP305_I2C_ADDR, reg, 1, data, 1);
> -#elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER ||
> defined CONFIG_AXP818_POWER -# ifdef CONFIG_MACH_SUN6I
> -	return p2wi_read(reg, data);
> -# elif defined CONFIG_MACH_SUN8I_R40
> -	return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1);
> -# else
> -	return rsb_read(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
> -# endif
> -#endif
> +	if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI))
> +		return p2wi_read(reg, data);
> +	if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB))
> +		return rsb_read(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
> +
> +	return i2c_read(pmic_i2c_address(), reg, 1, data, 1);
>  }
>  
>  int pmic_bus_write(u8 reg, u8 data)
>  {
> -#ifdef CONFIG_AXP152_POWER
> -	return i2c_write(AXP152_I2C_ADDR, reg, 1, &data, 1);
> -#elif defined CONFIG_AXP209_POWER
> -	return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1);
> -#elif defined CONFIG_AXP305_POWER
> -	return i2c_write(AXP305_I2C_ADDR, reg, 1, &data, 1);
> -#elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER ||
> defined CONFIG_AXP818_POWER -# ifdef CONFIG_MACH_SUN6I
> -	return p2wi_write(reg, data);
> -# elif defined CONFIG_MACH_SUN8I_R40
> -	return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1);
> -# else
> -	return rsb_write(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
> -# endif
> -#endif
> +	if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI))
> +		return p2wi_write(reg, data);
> +	if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB))
> +		return rsb_write(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
> +
> +	return i2c_write(pmic_i2c_address(), reg, 1, &data, 1);
>  }
>  
>  int pmic_bus_setbits(u8 reg, u8 bits)


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

* Re: [PATCH v2 10/12] sunxi: pmic_bus: Use the DM PMIC interface when possible
  2021-10-08  5:17 ` [PATCH v2 10/12] sunxi: pmic_bus: Use the DM PMIC interface when possible Samuel Holland
@ 2021-10-12 10:49   ` Andre Przywara
  0 siblings, 0 replies; 22+ messages in thread
From: Andre Przywara @ 2021-10-12 10:49 UTC (permalink / raw)
  To: Samuel Holland
  Cc: u-boot, Jagan Teki, Jaehoon Chung, Heiko Schocher,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

On Fri,  8 Oct 2021 00:17:23 -0500
Samuel Holland <samuel@sholland.org> wrote:

Hi,

> The pmic_bus functions are used in both SPL (for regulator setup) and
> U-Boot proper (for regulator setup, SID access, GPIO, and poweroff).
> 
> Currently, pmic_bus conflicts with DM_I2C because it uses the legacy I2C
> interface. This commit makes pmic_bus dual-compatible with either the
> legacy I2C functions or the newly-added PMIC_AXP driver (which uses
> DM_I2C). In turn, this allows platforms to start transitioning to DM_I2C
> in U-Boot proper, without breaking boards that still depend on the
> legacy I2C interface for other reasons.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
> 
> Changes in v2:
> - No changes
> 
>  arch/arm/mach-sunxi/Kconfig    |  2 ++
>  arch/arm/mach-sunxi/pmic_bus.c | 19 +++++++++++++++++++
>  2 files changed, 21 insertions(+)
> 
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index df160c9a775..cfd95b09498 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -96,6 +96,8 @@ config SUN6I_PRCM
>  
>  config AXP_PMIC_BUS
>  	bool
> +	select DM_PMIC if DM_I2C
> +	select PMIC_AXP if DM_I2C
>  	help
>  	  Select this PMIC bus access helpers for Sunxi platform PRCM or other
>  	  AXP family PMIC devices.
> diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c
> index 20ded436cd2..c0908406370 100644
> --- a/arch/arm/mach-sunxi/pmic_bus.c
> +++ b/arch/arm/mach-sunxi/pmic_bus.c
> @@ -10,9 +10,11 @@
>  
>  #include <axp_pmic.h>
>  #include <common.h>
> +#include <dm.h>
>  #include <asm/arch/p2wi.h>
>  #include <asm/arch/rsb.h>
>  #include <i2c.h>
> +#include <power/pmic.h>
>  #include <asm/arch/pmic_bus.h>
>  
>  #define AXP152_I2C_ADDR			0x30
> @@ -23,6 +25,9 @@
>  
>  #define AXP221_CHIP_ADDR		0x68
>  
> +#if CONFIG_IS_ENABLED(PMIC_AXP)
> +static struct udevice *pmic;
> +#else
>  static int pmic_i2c_address(void)
>  {
>  	if (IS_ENABLED(CONFIG_AXP152_POWER))
> @@ -33,6 +38,7 @@ static int pmic_i2c_address(void)
>  	/* Other AXP2xx and AXP8xx variants */
>  	return AXP209_I2C_ADDR;
>  }
> +#endif
>  
>  int pmic_bus_init(void)
>  {
> @@ -43,6 +49,10 @@ int pmic_bus_init(void)
>  	if (!needs_init)
>  		return 0;
>  
> +#if CONFIG_IS_ENABLED(PMIC_AXP)
> +	ret = uclass_get_device_by_driver(UCLASS_PMIC, DM_DRIVER_GET(axp_pmic),
> +					  &pmic);
> +#else
>  	if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI)) {
>  		p2wi_init();
>  		ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR,
> @@ -56,6 +66,7 @@ int pmic_bus_init(void)
>  		ret = rsb_set_device_address(AXP_PMIC_PRI_DEVICE_ADDR,
>  					     AXP_PMIC_PRI_RUNTIME_ADDR);
>  	}
> +#endif
>  
>  	needs_init = ret;
>  
> @@ -64,22 +75,30 @@ int pmic_bus_init(void)
>  
>  int pmic_bus_read(u8 reg, u8 *data)
>  {
> +#if CONFIG_IS_ENABLED(PMIC_AXP)
> +	return pmic_read(pmic, reg, data, 1);
> +#else
>  	if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI))
>  		return p2wi_read(reg, data);
>  	if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB))
>  		return rsb_read(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
>  
>  	return i2c_read(pmic_i2c_address(), reg, 1, data, 1);
> +#endif
>  }
>  
>  int pmic_bus_write(u8 reg, u8 data)
>  {
> +#if CONFIG_IS_ENABLED(PMIC_AXP)
> +	return pmic_write(pmic, reg, &data, 1);
> +#else
>  	if (IS_ENABLED(CONFIG_SYS_I2C_SUN6I_P2WI))
>  		return p2wi_write(reg, data);
>  	if (IS_ENABLED(CONFIG_SYS_I2C_SUN8I_RSB))
>  		return rsb_write(AXP_PMIC_PRI_RUNTIME_ADDR, reg, data);
>  
>  	return i2c_write(pmic_i2c_address(), reg, 1, &data, 1);
> +#endif
>  }
>  
>  int pmic_bus_setbits(u8 reg, u8 bits)


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

* Re: [PATCH v2 00/12] sunxi: Migrate to DM_I2C
  2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
                   ` (11 preceding siblings ...)
  2021-10-08  5:17 ` [PATCH v2 12/12] sunxi: Enable DM_I2C for all sunxi boards Samuel Holland
@ 2021-10-12 11:24 ` Andre Przywara
  12 siblings, 0 replies; 22+ messages in thread
From: Andre Przywara @ 2021-10-12 11:24 UTC (permalink / raw)
  To: Samuel Holland
  Cc: u-boot, Jagan Teki, Jaehoon Chung, Heiko Schocher,
	Anatolij Gustschin, Arnaud Ferraris, Bharat Gooty, Igor Opaniuk,
	Jernej Skrabec, Minkyu Kang, Rayagonda Kokatanur, Simon Glass,
	Stephan Gerhold, Tim Harvey, Tom Rini

On Fri,  8 Oct 2021 00:17:13 -0500
Samuel Holland <samuel@sholland.org> wrote:

Hi Samuel,

> This series does the initial work to migrate sunxi boards to DM_I2C.
> Version 1 of this series bitrotted quite a bit, so there is some
> reorganization in version 2.
> 
> First it takes care of the PMIC:
>  - Patches 1-2 clean up the PMIC Kconfig, though they are not strictly
>    necessary after 7abf178b, and are independent from the other patches.
>  - Patch 3 then adds a DM_PMIC driver.
>  - Patches 4-6 prepare to move the P2WI/RSB bus drivers to drivers/i2c.
>  - Patches 7-8 move and add DM_I2C versions of those two drivers.
>  - Patches 9-10 migrate the "pmic_bus" functions to use the DM_I2C bus
>    and DM_PMIC driver when possible.
> Then it takes care of the LCD panels:
>  - Patch 11 converts those drivers to use DM_I2C.
> Finally, patch 12 switches all sunxi boards over to DM_I2C.
> 
> I have build-tested each commit on all sunxi boards.

I am fine with this, and this removes the deprecation warnings for many
older boards, so I applied it to sunxi/master and will send a PR for this.
This looks like it has the potential to break boards, but I guess we will
never find out without applying it and waiting for bug reports.

Thanks!
Andre

> 
> There is some remaining work to clean up uses of pmic_bus in U-Boot
> proper and replace them with DM_PMIC functions:
>  - drivers/gpio/axp_gpio.c - I have a series for this.
>  - do_poweroff() in drivers/gpio/axp???.c - I have a series for this.
>  - axp_get_sid() in drivers/power/axp221.c - Not sure what to do here.
>  - axp_set_eldo() in drivers/video/sunxi/sunxi_display.c - This will
>    need a DM_REGULATOR driver.
> 
> Changes in v2:
> - Rebase to pick up 7abf178b ("power: Tidy up #undef of CONFIG_DM_PMIC")
> - Rebase to pick up 7abf178b ("power: Tidy up #undef of CONFIG_DM_PMIC")
> - Replace axp_pmic_bind() with `.bind = dm_scan_fdt_dev`
> - New patch to account for I2C Kconfig changes
> - Renamed Kconfig symbol to SYS_I2C_SUN6I_P2WI
> - Moved entire P2WI driver source to drivers/i2c
> - Renamed Kconfig symbol to SYS_I2C_SUN8I_RSB
> - Moved entire RSB driver source to drivers/i2c
> - Update IS_ENABLEDs in pmic_bus.c to match chages to previous patches
> 
> Samuel Holland (12):
>   power: pmic: Consistently depend on DM_PMIC
>   power: pmic: Consistently depend on SPL_DM_PMIC
>   power: pmic: Add a driver for X-Powers AXP PMICs
>   sunxi: Only initialize legacy I2C when enabled
>   sunxi: Select SUN8I_RSB more carefully
>   sunxi: pmic_bus: Fix Kconfig dependencies
>   i2c: Add a DM_I2C driver for the sun6i P2WI controller
>   i2c: Add a DM_I2C driver for the sun8i RSB controller
>   sunxi: pmic_bus: Clean up preprocessor conditions
>   sunxi: pmic_bus: Use the DM PMIC interface when possible
>   sunxi: video: Convert panel I2C to use DM_I2C
>   sunxi: Enable DM_I2C for all sunxi boards
> 
>  arch/arm/Kconfig                    |   1 +
>  arch/arm/mach-sunxi/Kconfig         |  59 ++----
>  arch/arm/mach-sunxi/Makefile        |   2 -
>  arch/arm/mach-sunxi/board.c         |   2 +-
>  arch/arm/mach-sunxi/p2wi.c          | 117 ------------
>  arch/arm/mach-sunxi/pmic_bus.c      | 109 +++++------
>  arch/arm/mach-sunxi/rsb.c           | 175 -----------------
>  board/sunxi/board.c                 |  44 +----
>  configs/Colombus_defconfig          |   6 -
>  configs/UTOO_P66_defconfig          |   3 -
>  drivers/i2c/Kconfig                 |  16 ++
>  drivers/i2c/Makefile                |   2 +
>  drivers/i2c/sun6i_p2wi.c            | 220 ++++++++++++++++++++++
>  drivers/i2c/sun8i_rsb.c             | 281 ++++++++++++++++++++++++++++
>  drivers/power/pmic/Kconfig          |  69 ++++---
>  drivers/power/pmic/Makefile         |   1 +
>  drivers/power/pmic/axp.c            |  38 ++++
>  drivers/video/anx9804.c             | 103 +++++-----
>  drivers/video/anx9804.h             |   5 +-
>  drivers/video/sunxi/sunxi_display.c |  55 ++++--
>  include/axp_pmic.h                  |  12 ++
>  include/configs/sunxi-common.h      |  17 --
>  22 files changed, 773 insertions(+), 564 deletions(-)
>  delete mode 100644 arch/arm/mach-sunxi/p2wi.c
>  delete mode 100644 arch/arm/mach-sunxi/rsb.c
>  create mode 100644 drivers/i2c/sun6i_p2wi.c
>  create mode 100644 drivers/i2c/sun8i_rsb.c
>  create mode 100644 drivers/power/pmic/axp.c
> 


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

end of thread, other threads:[~2021-10-12 11:24 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-08  5:17 [PATCH v2 00/12] sunxi: Migrate to DM_I2C Samuel Holland
2021-10-08  5:17 ` [PATCH v2 01/12] power: pmic: Consistently depend on DM_PMIC Samuel Holland
2021-10-08  5:17 ` [PATCH v2 02/12] power: pmic: Consistently depend on SPL_DM_PMIC Samuel Holland
2021-10-12 10:46   ` Andre Przywara
2021-10-08  5:17 ` [PATCH v2 03/12] power: pmic: Add a driver for X-Powers AXP PMICs Samuel Holland
2021-10-12 10:47   ` Andre Przywara
2021-10-08  5:17 ` [PATCH v2 04/12] sunxi: Only initialize legacy I2C when enabled Samuel Holland
2021-10-12 10:47   ` Andre Przywara
2021-10-08  5:17 ` [PATCH v2 05/12] sunxi: Select SUN8I_RSB more carefully Samuel Holland
2021-10-12 10:47   ` Andre Przywara
2021-10-08  5:17 ` [PATCH v2 06/12] sunxi: pmic_bus: Fix Kconfig dependencies Samuel Holland
2021-10-08  5:17 ` [PATCH v2 07/12] i2c: Add a DM_I2C driver for the sun6i P2WI controller Samuel Holland
2021-10-12 10:49   ` Andre Przywara
2021-10-08  5:17 ` [PATCH v2 08/12] i2c: Add a DM_I2C driver for the sun8i RSB controller Samuel Holland
2021-10-12 10:49   ` Andre Przywara
2021-10-08  5:17 ` [PATCH v2 09/12] sunxi: pmic_bus: Clean up preprocessor conditions Samuel Holland
2021-10-12 10:49   ` Andre Przywara
2021-10-08  5:17 ` [PATCH v2 10/12] sunxi: pmic_bus: Use the DM PMIC interface when possible Samuel Holland
2021-10-12 10:49   ` Andre Przywara
2021-10-08  5:17 ` [PATCH v2 11/12] sunxi: video: Convert panel I2C to use DM_I2C Samuel Holland
2021-10-08  5:17 ` [PATCH v2 12/12] sunxi: Enable DM_I2C for all sunxi boards Samuel Holland
2021-10-12 11:24 ` [PATCH v2 00/12] sunxi: Migrate to DM_I2C Andre Przywara

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.