1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Driver for Analog Devices, Inc. ADIN1140 10BASE-T1S PHY 4 * 5 * Copyright 2026 Analog Devices Inc. 6 */ 7 8 #include <linux/kernel.h> 9 #include <linux/module.h> 10 #include <linux/phy.h> 11 12 #define ADIN1140_PHY_ID 0x0283be00 13 14 #define ADIN1140_PCS_CTRL 0x08f3 15 #define ADIN1140_PCS_CTRL_LOOPBACK BIT(14) 16 17 static int adin1140_config_aneg(struct phy_device *phydev) 18 { 19 /* phylib tries to clear BIT(12) in MDIO_CTRL1, since AN is disabled. 20 * However, on the ADIN1140, that field is non-standard, being used 21 * to control the reset status of the PHY (thus it needs to remain set). 22 */ 23 return 0; 24 } 25 26 static int adin1140_loopback(struct phy_device *phydev, bool enable, int speed) 27 { 28 if (enable && speed) 29 return -EOPNOTSUPP; 30 31 return phy_modify_mmd(phydev, MDIO_MMD_PCS, ADIN1140_PCS_CTRL, 32 ADIN1140_PCS_CTRL_LOOPBACK, 33 enable ? ADIN1140_PCS_CTRL_LOOPBACK : 0); 34 } 35 36 static int adin1140_read_status(struct phy_device *phydev) 37 { 38 phydev->link = 1; 39 phydev->duplex = DUPLEX_HALF; 40 phydev->speed = SPEED_10; 41 phydev->autoneg = AUTONEG_DISABLE; 42 43 return 0; 44 } 45 46 static struct phy_driver adin1140_driver[] = { 47 { 48 PHY_ID_MATCH_EXACT(ADIN1140_PHY_ID), 49 .name = "ADIN1140_PHY", 50 .features = PHY_BASIC_T1S_P2MP_FEATURES, 51 .read_status = adin1140_read_status, 52 .config_aneg = adin1140_config_aneg, 53 .set_loopback = adin1140_loopback, 54 .read_mmd = genphy_read_mmd_c45, 55 .write_mmd = genphy_write_mmd_c45, 56 .get_plca_cfg = genphy_c45_plca_get_cfg, 57 .set_plca_cfg = genphy_c45_plca_set_cfg, 58 .get_plca_status = genphy_c45_plca_get_status, 59 }, 60 }; 61 module_phy_driver(adin1140_driver); 62 63 static const struct mdio_device_id __maybe_unused adin1140_tbl[] = { 64 { PHY_ID_MATCH_EXACT(ADIN1140_PHY_ID) }, 65 { } 66 }; 67 68 MODULE_DEVICE_TABLE(mdio, adin1140_tbl); 69 70 MODULE_DESCRIPTION("Analog Devices, Inc. ADIN1140 10BASE-T1S PHY"); 71 MODULE_AUTHOR("Ciprian Regus <ciprian.regus@analog.com>"); 72 MODULE_LICENSE("GPL"); 73