[PATCH net-next v2 2/5] net: phy: mxl-gpy: add MxL86211C VDDP supply
From: Robert Marko
Date: Fri Oct 16 2026 - 07:21:12 EST
Read the VDDP supply voltage and configure the MxL86211C MDIO, MDC,
and MDINT pads for the matching 1.8 V or 3.3 V level.
Keep the shared GPY driver buildable without regulator support; only
the MxL86211C probe requires the supply.
Signed-off-by: Robert Marko <robert.marko@xxxxxxxxxx>
---
Changes in v2:
- Replace the MDIO regulator provider with a VDDP supply consumer.
- Set the pad voltage from the supply's reported voltage.
- Keep the shared driver buildable with CONFIG_REGULATOR=n.
drivers/net/phy/mxl-gpy.c | 63 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c
index 089a1a9e5bc61..fbac7c49b4759 100644
--- a/drivers/net/phy/mxl-gpy.c
+++ b/drivers/net/phy/mxl-gpy.c
@@ -14,6 +14,7 @@
#include <linux/polynomial.h>
#include <linux/property.h>
#include <linux/netdevice.h>
+#include <linux/regulator/consumer.h>
/* PHY ID */
#define PHY_ID_GPYx15B_MASK 0xFFFFFFFC
@@ -110,6 +111,10 @@
#define VSPEC1_SGMII_ANEN_ANRS (VSPEC1_SGMII_CTRL_ANEN | \
VSPEC1_SGMII_CTRL_ANRS)
+/* Packet Manager Control */
+#define VSPEC1_PM_CTRL 0x0c
+#define VSPEC1_PM_CTRL_MDIO_VOL BIT(14)
+
/* Temperature sensor */
#define VSPEC1_TEMP_STA 0x0E
#define VSPEC1_TEMP_STA_DATA GENMASK(9, 0)
@@ -140,6 +145,7 @@ struct gpy_priv {
u8 fw_minor;
u32 wolopts;
u64 rx_errors;
+ struct regulator *vddp;
/* It takes 3 seconds to fully switch out of loopback mode before
* it can safely re-enter loopback mode. Record the time when
@@ -390,6 +396,61 @@ static int gpy_probe(struct phy_device *phydev)
return 0;
}
+static int mxl86211c_configure_mdio_voltage(struct phy_device *phydev,
+ struct regulator *vddp)
+{
+ int voltage;
+ int val;
+
+ voltage = regulator_get_voltage(vddp);
+ if (voltage < 0)
+ return voltage;
+
+ switch (voltage) {
+ case 1800000:
+ val = VSPEC1_PM_CTRL_MDIO_VOL;
+ break;
+ case 3300000:
+ val = 0;
+ break;
+ default:
+ phydev_err(phydev, "unsupported VDDP voltage: %d\n", voltage);
+ return -EINVAL;
+ }
+
+ return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_PM_CTRL,
+ VSPEC1_PM_CTRL_MDIO_VOL, val);
+}
+
+static int mxl86211c_probe(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ struct gpy_priv *priv;
+ struct regulator *vddp;
+ int ret;
+
+ vddp = devm_regulator_get(dev, "vddp");
+ if (IS_ERR(vddp))
+ return dev_err_probe(dev, PTR_ERR(vddp),
+ "failed to get VDDP supply\n");
+ if (!vddp)
+ return dev_err_probe(dev, -EOPNOTSUPP,
+ "VDDP supply requires regulator support\n");
+
+ ret = mxl86211c_configure_mdio_voltage(phydev, vddp);
+ if (ret)
+ return ret;
+
+ ret = gpy_probe(phydev);
+ if (ret)
+ return ret;
+
+ priv = phydev->priv;
+ priv->vddp = vddp;
+
+ return 0;
+}
+
static bool gpy_sgmii_need_reaneg(struct phy_device *phydev)
{
struct gpy_priv *priv = phydev->priv;
@@ -1406,7 +1467,7 @@ static struct phy_driver gpy_drivers[] = {
.name = "Maxlinear Ethernet MxL86211C",
.get_features = genphy_c45_pma_read_abilities,
.config_init = gpy21x_config_init,
- .probe = gpy_probe,
+ .probe = mxl86211c_probe,
.inband_caps = gpy_inband_caps,
.config_inband = gpy_config_inband,
.suspend = genphy_suspend,
--
2.56.0