Thread (9 messages) 9 messages, 5 authors, 2024-11-12
STALE611d

[PATCH 1/2] net: phy: micrel: add LED control on KSZ9131

From: Ivan Mikhaylov <hidden>
Date: 2020-12-09 14:01:13
Also in: linux-devicetree, lkml
Subsystem: ethernet phy library, networking drivers, the rest · Maintainers: Andrew Lunn, Heiner Kallweit, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

Add the possibility to read the LED configuration via DTS properties from
KSZ9131 PHY node. Add the new proprties and handle for them:
micrel,led-mode-behavior
micrel,led-mode-select

Signed-off-by: Ivan Mikhaylov <redacted>
---
 drivers/net/phy/micrel.c | 69 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 3fe552675dd2..117f3a3b9dd6 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -71,6 +71,11 @@
 #define MII_KSZPHY_RX_DATA_PAD_SKEW             0x105
 #define MII_KSZPHY_TX_DATA_PAD_SKEW             0x106
 
+/* KSZ9131 LED registers */
+#define MII_KSZPHY_LED_MODE_SELECT		0x16
+#define MII_KSZPHY_LED_BEHAVIOR			0x17
+#define MII_KSZPHY_LED_MODE			0x1a
+
 #define PS_TO_REG				200
 
 struct kszphy_hw_stat {
@@ -86,6 +91,8 @@ static struct kszphy_hw_stat kszphy_hw_stats[] = {
 
 struct kszphy_type {
 	u32 led_mode_reg;
+	u32 led_mode_behavior_reg;
+	u32 led_mode_select_reg;
 	u16 interrupt_level_mask;
 	bool has_broadcast_disable;
 	bool has_nand_tree_disable;
@@ -95,6 +102,8 @@ struct kszphy_type {
 struct kszphy_priv {
 	const struct kszphy_type *type;
 	int led_mode;
+	int led_mode_behavior;
+	int led_mode_select;
 	bool rmii_ref_clk_sel;
 	bool rmii_ref_clk_sel_val;
 	u64 stats[ARRAY_SIZE(kszphy_hw_stats)];
@@ -131,6 +140,13 @@ static const struct kszphy_type ksz9021_type = {
 	.interrupt_level_mask	= BIT(14),
 };
 
+static const struct kszphy_type ksz9131_type = {
+	.led_mode_reg		= MII_KSZPHY_LED_MODE,
+	.led_mode_behavior_reg	= MII_KSZPHY_LED_BEHAVIOR,
+	.led_mode_select_reg	= MII_KSZPHY_LED_MODE_SELECT,
+	.interrupt_level_mask	= BIT(14),
+};
+
 static int kszphy_extended_write(struct phy_device *phydev,
 				u32 regnum, u16 val)
 {
@@ -204,6 +220,7 @@ static int kszphy_setup_led(struct phy_device *phydev, u32 reg, int val)
 
 	switch (reg) {
 	case MII_KSZPHY_CTRL_1:
+	case MII_KSZPHY_LED_MODE:
 		shift = 14;
 		break;
 	case MII_KSZPHY_CTRL_2:
@@ -286,6 +303,26 @@ static int kszphy_config_reset(struct phy_device *phydev)
 	if (priv->led_mode >= 0)
 		kszphy_setup_led(phydev, priv->type->led_mode_reg, priv->led_mode);
 
+	if (priv->led_mode_behavior >= 0) {
+		ret = phy_write(phydev, priv->type->led_mode_behavior_reg,
+				priv->led_mode_behavior);
+		if (ret) {
+			phydev_err(phydev,
+				   "failed to set led mode behavior reg\n");
+			return ret;
+		}
+	}
+
+	if (priv->led_mode_select >= 0) {
+		ret = phy_write(phydev, priv->type->led_mode_select_reg,
+				priv->led_mode_select);
+		if (ret) {
+			phydev_err(phydev,
+				   "failed to set led mode select reg\n");
+			return ret;
+		}
+	}
+
 	return 0;
 }
 
@@ -1122,6 +1159,36 @@ static int kszphy_probe(struct phy_device *phydev)
 		priv->led_mode = -1;
 	}
 
+	if (type->led_mode_behavior_reg) {
+		ret = of_property_read_u32(np, "micrel,led-mode-behavior",
+					   &priv->led_mode_behavior);
+		if (!ret) {
+			ret = phy_write(phydev, type->led_mode_behavior_reg,
+					priv->led_mode_behavior);
+			if (ret)
+				phydev_err(phydev,
+					   "invalid led mode behavior: 0x%x\n",
+					   priv->led_mode_behavior);
+		}
+	} else {
+		priv->led_mode_behavior = -1;
+	}
+
+	if (type->led_mode_select_reg) {
+		ret = of_property_read_u32(np, "micrel,led-mode-select",
+					   &priv->led_mode_select);
+		if (!ret) {
+			ret = phy_write(phydev, type->led_mode_select_reg,
+					priv->led_mode_select);
+			if (ret)
+				phydev_err(phydev,
+					   "invalid led mode select: 0x%x\n",
+					   priv->led_mode_select);
+		}
+	} else {
+		priv->led_mode_select = -1;
+	}
+
 	clk = devm_clk_get(&phydev->mdio.dev, "rmii-ref");
 	/* NOTE: clk may be NULL if building without CONFIG_HAVE_CLK */
 	if (!IS_ERR_OR_NULL(clk)) {
@@ -1319,7 +1386,7 @@ static struct phy_driver ksphy_driver[] = {
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
 	.name		= "Microchip KSZ9131 Gigabit PHY",
 	/* PHY_GBIT_FEATURES */
-	.driver_data	= &ksz9021_type,
+	.driver_data	= &ksz9131_type,
 	.probe		= kszphy_probe,
 	.config_init	= ksz9131_config_init,
 	.read_status	= genphy_read_status,
-- 
2.21.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help