public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Chris Morgan <macroalpha82@gmail.com>
To: u-boot@lists.denx.de
Cc: jonas@kwiboo.se, trini@konsulko.com, kever.yang@rock-chips.com,
	philipp.tomsich@vrull.eu, sjg@chromium.org, dsimic@manjaro.org,
	quentin.schulz@cherry.de, Chris Morgan <macromorgan@hotmail.com>
Subject: [PATCH V2 2/4] board: rockchip: Add vdd_cpu reg fixup for RGXX3 Series
Date: Thu, 19 Sep 2024 09:00:20 -0500	[thread overview]
Message-ID: <20240919140022.511067-3-macroalpha82@gmail.com> (raw)
In-Reply-To: <20240919140022.511067-1-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan@hotmail.com>

Some of the Powkiddy devices switched to using a different vendor for
the vdd_cpu regulator. Unfortunately the device does not have a new
revision to denote this, so users have no way of knowing in advance.

Add code to detect if a device is present at addresses 0x1c or 0x40 on
the i2c0 bus and update the devicetree if needed.

Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
 board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 147 +++++++++++++++++++++
 1 file changed, 147 insertions(+)

diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c
index 224019f9ba3..c1d1826fd14 100644
--- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c
+++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c
@@ -43,6 +43,7 @@ struct rg3xx_model {
 	const char *board_name;
 	const char *fdtfile;
 	const bool detect_panel;
+	const bool detect_regulator;
 	const bool uart_con;
 };
 
@@ -69,6 +70,7 @@ static const struct rg3xx_model rg3xx_model_details[] = {
 		/* Device is identical to RG353P. */
 		.fdtfile = DTB_DIR "rk3566-anbernic-rg353p.dtb",
 		.detect_panel = 1,
+		.detect_regulator = 0,
 		.uart_con = 1,
 	},
 	[RG353P] = {
@@ -77,6 +79,7 @@ static const struct rg3xx_model rg3xx_model_details[] = {
 		.board_name = "Anbernic RG353P",
 		.fdtfile = DTB_DIR "rk3566-anbernic-rg353p.dtb",
 		.detect_panel = 1,
+		.detect_regulator = 0,
 		.uart_con = 1,
 	},
 	[RG353V] = {
@@ -85,6 +88,7 @@ static const struct rg3xx_model rg3xx_model_details[] = {
 		.board_name = "Anbernic RG353V",
 		.fdtfile = DTB_DIR "rk3566-anbernic-rg353v.dtb",
 		.detect_panel = 1,
+		.detect_regulator = 0,
 		.uart_con = 1,
 	},
 	[RG503] = {
@@ -93,6 +97,7 @@ static const struct rg3xx_model rg3xx_model_details[] = {
 		.board_name = "Anbernic RG503",
 		.fdtfile = DTB_DIR "rk3566-anbernic-rg503.dtb",
 		.detect_panel = 0,
+		.detect_regulator = 0,
 		.uart_con = 1,
 	},
 	[RGB30] = {
@@ -101,6 +106,7 @@ static const struct rg3xx_model rg3xx_model_details[] = {
 		.board_name = "Powkiddy RGB30",
 		.fdtfile = DTB_DIR "rk3566-powkiddy-rgb30.dtb",
 		.detect_panel = 0,
+		.detect_regulator = 1,
 		.uart_con = 0,
 	},
 	[RK2023] = {
@@ -109,6 +115,7 @@ static const struct rg3xx_model rg3xx_model_details[] = {
 		.board_name = "Powkiddy RK2023",
 		.fdtfile = DTB_DIR "rk3566-powkiddy-rk2023.dtb",
 		.detect_panel = 0,
+		.detect_regulator = 1,
 		.uart_con = 0,
 	},
 	[RGARCD] = {
@@ -117,6 +124,7 @@ static const struct rg3xx_model rg3xx_model_details[] = {
 		.board_name = "Anbernic RG ARC-D",
 		.fdtfile = DTB_DIR "rk3566-anbernic-rg-arc-d.dtb",
 		.detect_panel = 0,
+		.detect_regulator = 0,
 		.uart_con = 1,
 	},
 	[RGB10MAX3] = {
@@ -125,6 +133,7 @@ static const struct rg3xx_model rg3xx_model_details[] = {
 		.board_name = "Powkiddy RGB10MAX3",
 		.fdtfile = DTB_DIR "rk3566-powkiddy-rgb10max3.dtb",
 		.detect_panel = 0,
+		.detect_regulator = 1,
 		.uart_con = 0,
 	},
 	/* Devices with duplicate ADC value */
@@ -134,6 +143,7 @@ static const struct rg3xx_model rg3xx_model_details[] = {
 		.board_name = "Anbernic RG353PS",
 		.fdtfile = DTB_DIR "rk3566-anbernic-rg353ps.dtb",
 		.detect_panel = 1,
+		.detect_regulator = 0,
 		.uart_con = 1,
 	},
 	[RG353VS] = {
@@ -142,6 +152,7 @@ static const struct rg3xx_model rg3xx_model_details[] = {
 		.board_name = "Anbernic RG353VS",
 		.fdtfile = DTB_DIR "rk3566-anbernic-rg353vs.dtb",
 		.detect_panel = 1,
+		.detect_regulator = 0,
 		.uart_con = 1,
 	},
 	[RGARCS] = {
@@ -150,6 +161,7 @@ static const struct rg3xx_model rg3xx_model_details[] = {
 		.board_name = "Anbernic RG ARC-S",
 		.fdtfile = DTB_DIR "rk3566-anbernic-rg-arc-s.dtb",
 		.detect_panel = 0,
+		.detect_regulator = 0,
 		.uart_con = 1,
 	},
 };
@@ -172,6 +184,22 @@ static const struct rg353_panel rg353_panel_details[] = {
 	},
 };
 
+struct powkiddy_regulators {
+	const u8 addr;
+	const char *regulator_compat;
+};
+
+static const struct powkiddy_regulators regulator_details[] = {
+	{
+		.addr = 0x1c,
+		.regulator_compat = "tcs,tcs4525",
+	},
+	{
+		.addr = 0x40,
+		.regulator_compat = "fcs,fan53555",
+	},
+};
+
 /*
  * Start LED very early so user knows device is on. Set color
  * to red.
@@ -361,6 +389,44 @@ int rgxx3_detect_display(void)
 	return 0;
 }
 
+/*
+ * Some of the Powkiddy devices switched the CPU regulator, but users
+ * are not able to determine this by looking at their hardware.
+ * Attempt to auto-detect this situation and fixup the device-tree.
+ */
+int rgxx3_detect_regulator(void)
+{
+	struct udevice *bus;
+	struct udevice *chip;
+	u8 val;
+	int ret;
+
+	/* Get the correct i2c bus (i2c0). */
+	ret = uclass_get_device_by_name(UCLASS_I2C,
+					"i2c@fdd40000", &bus);
+	if (ret)
+		return ret;
+
+	/*
+	 * Check for all vdd_cpu regulators and read an arbitrary
+	 * register to confirm it's present.
+	 */
+	for (int i = 0; i < ARRAY_SIZE(regulator_details); i++) {
+		ret = i2c_get_chip(bus, regulator_details[i].addr,
+				   1, &chip);
+		if (ret)
+			return ret;
+
+		ret = dm_i2c_read(chip, 0, &val, 1);
+		if (!ret) {
+			env_set("vdd_cpu", regulator_details[i].regulator_compat);
+			break;
+		}
+	}
+
+	return 0;
+}
+
 int rgxx3_read_board_id(void)
 {
 	u32 adc_info;
@@ -485,6 +551,16 @@ int rk_board_late_init(void)
 			printf("Failed to detect panel type\n");
 	}
 
+	/*
+	 * Skip vdd_cpu regulator detection if not needed. Warn but
+	 * don't fail for errors in auto-detection of regulator.
+	 */
+	if (rg3xx_model_details[gd->board_type].detect_regulator) {
+		ret = rgxx3_detect_regulator();
+		if (ret)
+			printf("Unable to detect vdd_cpu regulator\n");
+	}
+
 end:
 	/* Turn off red LED and turn on orange LED. */
 	writel(GPIO_WRITEMASK(GPIO_C7 | GPIO_C6 | GPIO_C5) | GPIO_C6,
@@ -547,6 +623,71 @@ int rgxx3_panel_fixup(void *blob)
 	return 0;
 }
 
+int rgxx3_regulator_fixup(void *blob)
+{
+	const struct powkiddy_regulators *vdd_cpu = NULL;
+	int node, ret, i;
+	char path[] = "/i2c@fdd40000/regulator@00";
+	char name[] = "regulator@00";
+	char *env;
+
+	env = env_get("vdd_cpu");
+	if (!env) {
+		printf("Can't get vdd_cpu env\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Find the device we have in our tree, which may or may not
+	 * be present.
+	 */
+	for (i = 0; i < ARRAY_SIZE(regulator_details); i++) {
+		sprintf(path, "/i2c@fdd40000/regulator@%02x",
+			regulator_details[i].addr);
+		node = fdt_path_offset(blob, path);
+		if (node > 0)
+			break;
+
+		printf("Unable to find vdd_cpu\n");
+		return -ENODEV;
+	}
+
+	node = fdt_path_offset(blob, path);
+	if (!(node > 0)) {
+		printf("Can't find the vdd_cpu node\n");
+		return -ENODEV;
+	}
+
+	ret = fdt_node_check_compatible(blob, node, env);
+	if (ret < 0)
+		return -ENODEV;
+
+	/* vdd_cpu regulators match, return 0. */
+	if (!ret)
+		return 0;
+
+	/* Regulators don't match, search by first compatible value. */
+	for (i = 0; i < ARRAY_SIZE(regulator_details); i++) {
+		if (!strcmp(env, regulator_details[i].regulator_compat)) {
+			vdd_cpu = &regulator_details[i];
+			break;
+		}
+	}
+
+	if (!vdd_cpu) {
+		printf("Unable to identify vdd_cpu by compat string\n");
+		return -ENODEV;
+	}
+
+	/* Set the compatible and reg with the auto-detected values */
+	fdt_setprop_string(blob, node, "compatible", vdd_cpu->regulator_compat);
+	fdt_setprop_u32(blob, node, "reg", vdd_cpu->addr);
+	sprintf(name, "regulator@%02x", vdd_cpu->addr);
+	fdt_set_name(blob, node, name);
+
+	return 0;
+}
+
 int ft_board_setup(void *blob, struct bd_info *bd)
 {
 	int ret;
@@ -562,6 +703,12 @@ int ft_board_setup(void *blob, struct bd_info *bd)
 			printf("Unable to update panel compat\n");
 	}
 
+	if (rg3xx_model_details[gd->board_type].detect_regulator) {
+		ret = rgxx3_regulator_fixup(blob);
+		if (ret)
+			printf("Unable to update vdd_cpu compat\n");
+	}
+
 	return 0;
 }
 
-- 
2.34.1


  parent reply	other threads:[~2024-09-19 14:03 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-19 14:00 [PATCH V2 0/4] Anbernic RGxx3 Bootloader Fixes Chris Morgan
2024-09-19 14:00 ` [PATCH V2 1/4] board: rockchip: Convert Anbernic RGxx3 to OF_UPSTREAM Chris Morgan
2024-10-25 12:04   ` Kever Yang
2024-09-19 14:00 ` Chris Morgan [this message]
2024-09-23 11:21   ` [PATCH V2 2/4] board: rockchip: Add vdd_cpu reg fixup for RGXX3 Series Quentin Schulz
2024-09-23 17:36     ` Chris Morgan
2024-09-24 10:24       ` Quentin Schulz
2024-09-26  0:35         ` Chris Morgan
2024-10-25 12:04   ` Kever Yang
2024-09-19 14:00 ` [PATCH V2 3/4] board: rockchip: Remove ARM SCMI Support from RGxx3 Chris Morgan
2024-10-25 12:04   ` Kever Yang
2024-09-19 14:00 ` [PATCH V2 4/4] board: rockchip: Enable PD_VO before driver access Chris Morgan
2024-09-23 11:24   ` Quentin Schulz
2024-09-23 17:38     ` Chris Morgan
2024-09-24  9:19       ` Quentin Schulz
2024-09-26  0:23         ` Chris Morgan
2024-10-25 12:04   ` Kever Yang
2024-09-22 13:43 ` [PATCH V2 0/4] Anbernic RGxx3 Bootloader Fixes Peter Robinson
2024-09-23 17:42   ` Chris Morgan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240919140022.511067-3-macroalpha82@gmail.com \
    --to=macroalpha82@gmail.com \
    --cc=dsimic@manjaro.org \
    --cc=jonas@kwiboo.se \
    --cc=kever.yang@rock-chips.com \
    --cc=macromorgan@hotmail.com \
    --cc=philipp.tomsich@vrull.eu \
    --cc=quentin.schulz@cherry.de \
    --cc=sjg@chromium.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox