airoha: backport patch adding support for AN7581 Ethernet PHY
authorChristian Marangi <[email protected]>
Mon, 1 Sep 2025 16:19:57 +0000 (18:19 +0200)
committerChristian Marangi <[email protected]>
Tue, 2 Sep 2025 22:58:50 +0000 (00:58 +0200)
Backport patch adding support for AN7581 Ethernet PHY based on the same
Mediatek embedded Switch PHY.

Link: https://github.com/openwrt/openwrt/pull/19816
Signed-off-by: Christian Marangi <[email protected]>
target/linux/airoha/patches-6.6/060-v6.16-02-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch [new file with mode: 0644]

diff --git a/target/linux/airoha/patches-6.6/060-v6.16-02-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch b/target/linux/airoha/patches-6.6/060-v6.16-02-net-phy-mediatek-add-Airoha-PHY-ID-to-SoC-driver.patch
new file mode 100644 (file)
index 0000000..68d21dd
--- /dev/null
@@ -0,0 +1,129 @@
+From 6a325aed130bb68790e765f923e76ec5669d2da7 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <[email protected]>
+Date: Thu, 10 Apr 2025 12:04:04 +0200
+Subject: [PATCH 2/2] net: phy: mediatek: add Airoha PHY ID to SoC driver
+
+Airoha AN7581 SoC ship with a Switch based on the MT753x Switch embedded
+in other SoC like the MT7581 and the MT7988. Similar to these they
+require configuring some pin to enable LED PHYs.
+
+Add support for the PHY ID for the Airoha embedded Switch and define a
+simple probe function to toggle these pins. Also fill the LED functions
+and add dedicated function to define LED polarity.
+
+Reviewed-by: Andrew Lunn <[email protected]>
+Signed-off-by: Christian Marangi <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ drivers/net/phy/mediatek/Kconfig      |  4 +-
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 62 +++++++++++++++++++++++++++
+ 2 files changed, 65 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/mediatek/Kconfig
++++ b/drivers/net/phy/mediatek/Kconfig
+@@ -15,7 +15,9 @@ config MEDIATEK_GE_PHY
+ config MEDIATEK_GE_SOC_PHY
+       tristate "MediaTek SoC Ethernet PHYs"
+-      depends on (ARM64 && ARCH_MEDIATEK && NVMEM_MTK_EFUSE) || COMPILE_TEST
++      depends on ARM64 || COMPILE_TEST
++      depends on ARCH_AIROHA || (ARCH_MEDIATEK && NVMEM_MTK_EFUSE) || \
++                 COMPILE_TEST
+       select MTK_NET_PHYLIB
+       help
+         Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -10,8 +10,11 @@
+ #include "mtk.h"
++#define MTK_PHY_MAX_LEDS                      2
++
+ #define MTK_GPHY_ID_MT7981                    0x03a29461
+ #define MTK_GPHY_ID_MT7988                    0x03a29481
++#define MTK_GPHY_ID_AN7581                    0x03a294c1
+ #define MTK_EXT_PAGE_ACCESS                   0x1f
+ #define MTK_PHY_PAGE_STANDARD                 0x0000
+@@ -1405,6 +1408,53 @@ static int mt7981_phy_probe(struct phy_d
+       return mt798x_phy_calibration(phydev);
+ }
++static int an7581_phy_probe(struct phy_device *phydev)
++{
++      struct mtk_socphy_priv *priv;
++      struct pinctrl *pinctrl;
++
++      /* Toggle pinctrl to enable PHY LED */
++      pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
++      if (IS_ERR(pinctrl))
++              dev_err(&phydev->mdio.bus->dev,
++                      "Failed to setup PHY LED pinctrl\n");
++
++      priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
++      if (!priv)
++              return -ENOMEM;
++
++      phydev->priv = priv;
++
++      return 0;
++}
++
++static int an7581_phy_led_polarity_set(struct phy_device *phydev, int index,
++                                     unsigned long modes)
++{
++      u32 mode;
++      u16 val;
++
++      if (index >= MTK_PHY_MAX_LEDS)
++              return -EINVAL;
++
++      for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
++              switch (mode) {
++              case PHY_LED_ACTIVE_LOW:
++                      val = MTK_PHY_LED_ON_POLARITY;
++                      break;
++              case PHY_LED_ACTIVE_HIGH:
++                      val = 0;
++                      break;
++              default:
++                      return -EINVAL;
++              }
++      }
++
++      return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++                            MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
++                            MTK_PHY_LED_ON_POLARITY, val);
++}
++
+ static struct phy_driver mtk_socphy_driver[] = {
+       {
+               PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
+@@ -1440,6 +1490,17 @@ static struct phy_driver mtk_socphy_driv
+               .led_hw_control_set = mt798x_phy_led_hw_control_set,
+               .led_hw_control_get = mt798x_phy_led_hw_control_get,
+       },
++      {
++              PHY_ID_MATCH_EXACT(MTK_GPHY_ID_AN7581),
++              .name           = "Airoha AN7581 PHY",
++              .probe          = an7581_phy_probe,
++              .led_blink_set  = mt798x_phy_led_blink_set,
++              .led_brightness_set = mt798x_phy_led_brightness_set,
++              .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
++              .led_hw_control_set = mt798x_phy_led_hw_control_set,
++              .led_hw_control_get = mt798x_phy_led_hw_control_get,
++              .led_polarity_set = an7581_phy_led_polarity_set,
++      },
+ };
+ module_phy_driver(mtk_socphy_driver);
+@@ -1447,6 +1508,7 @@ module_phy_driver(mtk_socphy_driver);
+ static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = {
+       { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) },
+       { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) },
++      { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_AN7581) },
+       { }
+ };