ARM Sunxi Platform Development
 help / color / mirror / Atom feed
From: Andre Przywara <andre.przywara@arm.com>
To: Lee Jones <lee@kernel.org>, Chen-Yu Tsai <wens@csie.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Jernej Skrabec <jernej.skrabec@gmail.com>,
	Samuel Holland <samuel@sholland.org>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Mark Brown <broonie@kernel.org>
Cc: devicetree@vger.kernel.org, linux-sunxi@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	Mikhail Kalashnikov <iuncuim@gmail.com>
Subject: [RFC PATCH 2/5] mfd: axp20x: Refactor axp20x_is_polyphase_slave()
Date: Fri, 19 Sep 2025 01:00:17 +0100	[thread overview]
Message-ID: <20250919000020.16969-3-andre.przywara@arm.com> (raw)
In-Reply-To: <20250919000020.16969-1-andre.przywara@arm.com>

Some X-Powers AXP PMICs allow to combine certain DC/DC rails together in
a multi-phase fashion. So far we don't actively program those
connections, but we detect the existing setup, and prevent the connected
regulators from being re-programmed or turned off. At the moment this is
done in a switch/case construct, listing the known regulator pairs for
those PMICs supported.

To get rid of this ever growing code section, create a data structure
that describes the relationship, and have generic code that iterates
over the entries and checks for matches.

This not only cleans that function up and makes extensions much simpler,
but also allows to reuse this information for the upcoming programming
of those poly-phase setups.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 drivers/regulator/axp20x-regulator.c | 91 ++++++++++++++--------------
 1 file changed, 45 insertions(+), 46 deletions(-)

diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index da891415efc0b..19c9a98d1835a 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -1481,70 +1481,69 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
 	return regmap_update_bits(rdev->regmap, reg, mask, workmode);
 }
 
+struct dualphase_regulator {
+	int axp_id;
+	int reg1, reg2;
+	unsigned int polyphase_reg;
+	unsigned int bitmask;
+} dualphase_regulators[] = {
+	{ AXP323_ID, AXP313A_DCDC1, AXP313A_DCDC2,
+		AXP323_DCDC_MODE_CTRL2, BIT(1), },
+	{ AXP803_ID, AXP803_DCDC2, AXP803_DCDC3, AXP803_POLYPHASE_CTRL,
+		AXP803_DCDC23_POLYPHASE_DUAL, },
+	{ AXP803_ID, AXP803_DCDC5, AXP803_DCDC6, AXP803_POLYPHASE_CTRL,
+		AXP803_DCDC56_POLYPHASE_DUAL, },
+	/* AXP806's DCDC-A/B/C is a tri-phase regulator */
+	{ AXP806_ID, AXP806_DCDCD, AXP806_DCDCE, AXP806_DCDC_MODE_CTRL2,
+		AXP806_DCDCDE_POLYPHASE_DUAL, },
+	{ AXP813_ID, AXP803_DCDC2, AXP803_DCDC3, AXP803_POLYPHASE_CTRL,
+		AXP803_DCDC23_POLYPHASE_DUAL, },
+	{ AXP813_ID, AXP803_DCDC5, AXP803_DCDC6, AXP803_POLYPHASE_CTRL,
+		AXP803_DCDC56_POLYPHASE_DUAL, },
+	{ AXP15060_ID, AXP15060_DCDC2, AXP15060_DCDC3, AXP15060_DCDC_MODE_CTRL1,
+		AXP15060_DCDC23_POLYPHASE_DUAL_MASK, },
+	{ AXP15060_ID, AXP15060_DCDC4, AXP15060_DCDC6, AXP15060_DCDC_MODE_CTRL1,
+		AXP15060_DCDC46_POLYPHASE_DUAL_MASK, },
+};
+
 /*
  * This function checks whether a regulator is part of a poly-phase
  * output setup based on the registers settings. Returns true if it is.
  */
 static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
 {
+	struct dualphase_regulator *dpreg;
 	u32 reg = 0;
+	int i;
 
-	/*
-	 * Currently in our supported AXP variants, only AXP803, AXP806,
-	 * AXP813 and AXP15060 have polyphase regulators.
-	 */
-	switch (axp20x->variant) {
-	case AXP803_ID:
-	case AXP813_ID:
-		regmap_read(axp20x->regmap, AXP803_POLYPHASE_CTRL, &reg);
+	for (i = 0; i < ARRAY_SIZE(dualphase_regulators); i++) {
+		dpreg = &dualphase_regulators[i];
 
-		switch (id) {
-		case AXP803_DCDC3:
-			return !!(reg & AXP803_DCDC23_POLYPHASE_DUAL);
-		case AXP803_DCDC6:
-			return !!(reg & AXP803_DCDC56_POLYPHASE_DUAL);
+		if (axp20x->variant != dpreg->axp_id)
+			continue;
+		/* Is this the second regulator from a dual-phase pair? */
+		if (id == dpreg->reg2) {
+			regmap_read(axp20x->regmap, dpreg->polyphase_reg, &reg);
+
+			return !!(reg & dpreg->bitmask);
 		}
-		break;
+	}
 
-	case AXP806_ID:
+	/*
+	 * DCDC-A/B/C can be configured either as a dual-phase (A+B) or
+	 * as a triple-phase regulator (A+B+C), but not in any other
+	 * combination. Treat this as a special case here.
+	 */
+	if (axp20x->variant == AXP806_ID) {
 		regmap_read(axp20x->regmap, AXP806_DCDC_MODE_CTRL2, &reg);
-
-		switch (id) {
-		case AXP806_DCDCB:
+		if (id == AXP806_DCDCB)
 			return (((reg & AXP806_DCDCABC_POLYPHASE_MASK) ==
 				AXP806_DCDCAB_POLYPHASE_DUAL) ||
 				((reg & AXP806_DCDCABC_POLYPHASE_MASK) ==
 				AXP806_DCDCABC_POLYPHASE_TRI));
-		case AXP806_DCDCC:
+		if (id == AXP806_DCDCC)
 			return ((reg & AXP806_DCDCABC_POLYPHASE_MASK) ==
 				AXP806_DCDCABC_POLYPHASE_TRI);
-		case AXP806_DCDCE:
-			return !!(reg & AXP806_DCDCDE_POLYPHASE_DUAL);
-		}
-		break;
-
-	case AXP15060_ID:
-		regmap_read(axp20x->regmap, AXP15060_DCDC_MODE_CTRL1, &reg);
-
-		switch (id) {
-		case AXP15060_DCDC3:
-			return !!(reg & AXP15060_DCDC23_POLYPHASE_DUAL_MASK);
-		case AXP15060_DCDC6:
-			return !!(reg & AXP15060_DCDC46_POLYPHASE_DUAL_MASK);
-		}
-		break;
-
-	case AXP323_ID:
-		regmap_read(axp20x->regmap, AXP323_DCDC_MODE_CTRL2, &reg);
-
-		switch (id) {
-		case AXP313A_DCDC2:
-			return !!(reg & BIT(1));
-		}
-		break;
-
-	default:
-		return false;
 	}
 
 	return false;
-- 
2.46.4


  parent reply	other threads:[~2025-09-19  0:01 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-19  0:00 [RFC PATCH 0/5] mfd: axp20x: program poly-phased regulators Andre Przywara
2025-09-19  0:00 ` [RFC PATCH 1/5] dt-bindings: mfd: x-powers,axp152: Add polyphased property Andre Przywara
2025-09-22 18:16   ` Rob Herring
2025-09-25 14:52     ` Chen-Yu Tsai
2025-09-25 15:02       ` Mark Brown
2025-09-19  0:00 ` Andre Przywara [this message]
2025-11-03 17:40   ` [RFC PATCH 2/5] mfd: axp20x: Refactor axp20x_is_polyphase_slave() Chen-Yu Tsai
2025-09-19  0:00 ` [RFC PATCH 3/5] mfd: axp20x: Allow programming dual-phase regulator pairs Andre Przywara
2025-09-19  0:00 ` [RFC PATCH 4/5] mfd: axp20x: Support tri-phase setup Andre Przywara
2025-09-19 13:02   ` Mark Brown
2025-09-19 13:02   ` Mark Brown
2025-09-19  0:00 ` [RFC PATCH 5/5] arm64: dts: allwinner: a523: Mark dual-phased regulators Andre Przywara

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=20250919000020.16969-3-andre.przywara@arm.com \
    --to=andre.przywara@arm.com \
    --cc=broonie@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=iuncuim@gmail.com \
    --cc=jernej.skrabec@gmail.com \
    --cc=krzk+dt@kernel.org \
    --cc=lee@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sunxi@lists.linux.dev \
    --cc=robh@kernel.org \
    --cc=samuel@sholland.org \
    --cc=wens@csie.org \
    /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