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
adin1140_config_aneg(struct phy_device * phydev)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
adin1140_loopback(struct phy_device * phydev,bool enable,int speed)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
adin1140_read_status(struct phy_device * phydev)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