2024-10-08 18:33:49 +00:00
|
|
|
From 5b605457b93d0979ab623ef2aa6eb456c46e511c Mon Sep 17 00:00:00 2001
|
2024-08-20 16:20:29 +00:00
|
|
|
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
2024-10-08 18:33:49 +00:00
|
|
|
Date: Fri, 4 Oct 2024 18:24:10 +0800
|
|
|
|
Subject: [PATCH 6/9] net: phy: mediatek: Hook LED helper functions in mtk-ge.c
|
2024-08-20 16:20:29 +00:00
|
|
|
|
|
|
|
We have mtk-phy-lib.c now so that we can use LED helper functions in
|
|
|
|
mtk-ge.c(mt7531 part). It also means that mt7531/mt7981/mt7988's
|
|
|
|
Giga ethernet phys share almost the same HW LED controller design.
|
|
|
|
Also, add probe function for mt7531 so that it can initialize LED state.
|
|
|
|
|
|
|
|
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
|
|
|
---
|
|
|
|
drivers/net/phy/mediatek/mtk-ge.c | 100 ++++++++++++++++++++++++++++++
|
|
|
|
1 file changed, 100 insertions(+)
|
|
|
|
|
|
|
|
--- a/drivers/net/phy/mediatek/mtk-ge.c
|
|
|
|
+++ b/drivers/net/phy/mediatek/mtk-ge.c
|
|
|
|
@@ -14,6 +14,10 @@
|
|
|
|
#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
|
|
|
|
#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
|
|
|
|
|
|
|
|
+struct mtk_gephy_priv {
|
|
|
|
+ unsigned long led_state;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
static void mtk_gephy_config_init(struct phy_device *phydev)
|
|
|
|
{
|
|
|
|
/* Disable EEE */
|
|
|
|
@@ -94,6 +98,96 @@ static int mt7531_phy_config_init(struct
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static int mt7531_phy_probe(struct phy_device *phydev)
|
|
|
|
+{
|
|
|
|
+ struct mtk_gephy_priv *priv;
|
|
|
|
+
|
|
|
|
+ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_gephy_priv),
|
|
|
|
+ GFP_KERNEL);
|
|
|
|
+ if (!priv)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ phydev->priv = priv;
|
|
|
|
+
|
|
|
|
+ mtk_phy_leds_state_init(phydev);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int mt753x_phy_led_blink_set(struct phy_device *phydev, u8 index,
|
|
|
|
+ unsigned long *delay_on,
|
|
|
|
+ unsigned long *delay_off)
|
|
|
|
+{
|
|
|
|
+ struct mtk_gephy_priv *priv = phydev->priv;
|
|
|
|
+ bool blinking = false;
|
|
|
|
+ int err = 0;
|
|
|
|
+
|
|
|
|
+ err = mtk_phy_led_num_dly_cfg(index, delay_on, delay_off, &blinking);
|
|
|
|
+ if (err < 0)
|
|
|
|
+ return err;
|
|
|
|
+
|
|
|
|
+ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state,
|
|
|
|
+ blinking);
|
|
|
|
+ if (err)
|
|
|
|
+ return err;
|
|
|
|
+
|
|
|
|
+ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
|
|
|
|
+ MTK_GPHY_LED_ON_MASK, false);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int mt753x_phy_led_brightness_set(struct phy_device *phydev,
|
|
|
|
+ u8 index, enum led_brightness value)
|
|
|
|
+{
|
|
|
|
+ struct mtk_gephy_priv *priv = phydev->priv;
|
|
|
|
+ int err;
|
|
|
|
+
|
|
|
|
+ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, false);
|
|
|
|
+ if (err)
|
|
|
|
+ return err;
|
|
|
|
+
|
|
|
|
+ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
|
|
|
|
+ MTK_GPHY_LED_ON_MASK, (value != LED_OFF));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static const unsigned long supported_triggers =
|
2024-10-08 18:33:49 +00:00
|
|
|
+ BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
|
|
|
|
+ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
|
|
|
|
+ BIT(TRIGGER_NETDEV_LINK) |
|
|
|
|
+ BIT(TRIGGER_NETDEV_LINK_10) |
|
|
|
|
+ BIT(TRIGGER_NETDEV_LINK_100) |
|
|
|
|
+ BIT(TRIGGER_NETDEV_LINK_1000) |
|
|
|
|
+ BIT(TRIGGER_NETDEV_RX) |
|
|
|
|
+ BIT(TRIGGER_NETDEV_TX);
|
2024-08-20 16:20:29 +00:00
|
|
|
+
|
|
|
|
+static int mt753x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
|
|
|
+ unsigned long rules)
|
|
|
|
+{
|
|
|
|
+ return mtk_phy_led_hw_is_supported(phydev, index, rules,
|
|
|
|
+ supported_triggers);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int mt753x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
|
|
|
|
+ unsigned long *rules)
|
|
|
|
+{
|
|
|
|
+ struct mtk_gephy_priv *priv = phydev->priv;
|
|
|
|
+
|
|
|
|
+ return mtk_phy_led_hw_ctrl_get(phydev, index, rules, &priv->led_state,
|
|
|
|
+ MTK_GPHY_LED_ON_SET,
|
|
|
|
+ MTK_GPHY_LED_RX_BLINK_SET,
|
|
|
|
+ MTK_GPHY_LED_TX_BLINK_SET);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static int mt753x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
|
|
|
|
+ unsigned long rules)
|
|
|
|
+{
|
|
|
|
+ struct mtk_gephy_priv *priv = phydev->priv;
|
|
|
|
+
|
|
|
|
+ return mtk_phy_led_hw_ctrl_set(phydev, index, rules, &priv->led_state,
|
|
|
|
+ MTK_GPHY_LED_ON_SET,
|
|
|
|
+ MTK_GPHY_LED_RX_BLINK_SET,
|
|
|
|
+ MTK_GPHY_LED_TX_BLINK_SET);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
static struct phy_driver mtk_gephy_driver[] = {
|
|
|
|
{
|
|
|
|
PHY_ID_MATCH_EXACT(0x03a29412),
|
|
|
|
@@ -112,6 +206,7 @@ static struct phy_driver mtk_gephy_drive
|
|
|
|
{
|
|
|
|
PHY_ID_MATCH_EXACT(0x03a29441),
|
|
|
|
.name = "MediaTek MT7531 PHY",
|
|
|
|
+ .probe = mt7531_phy_probe,
|
|
|
|
.config_init = mt7531_phy_config_init,
|
|
|
|
/* Interrupts are handled by the switch, not the PHY
|
|
|
|
* itself.
|
|
|
|
@@ -122,6 +217,11 @@ static struct phy_driver mtk_gephy_drive
|
|
|
|
.resume = genphy_resume,
|
|
|
|
.read_page = mtk_phy_read_page,
|
|
|
|
.write_page = mtk_phy_write_page,
|
|
|
|
+ .led_blink_set = mt753x_phy_led_blink_set,
|
|
|
|
+ .led_brightness_set = mt753x_phy_led_brightness_set,
|
|
|
|
+ .led_hw_is_supported = mt753x_phy_led_hw_is_supported,
|
|
|
|
+ .led_hw_control_set = mt753x_phy_led_hw_control_set,
|
|
|
|
+ .led_hw_control_get = mt753x_phy_led_hw_control_get,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|