Add exact PHY ID matching and optional 125 MHz CLKOUT configuration for the Maxio MAE0621A Gigabit Ethernet PHY. Preserve the existing hardware configuration when the firmware property is absent. Signed-off-by: Liu Changjie --- drivers/net/phy/Kconfig | 8 +++ drivers/net/phy/Makefile | 1 + drivers/net/phy/maxio.c | 103 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 drivers/net/phy/maxio.c diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 099f25dce..32e1a035b 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -283,6 +283,14 @@ config MARVELL_88X2222_PHY Support for the Marvell 88X2222 Dual-port Multi-speed Ethernet Transceiver. +config MAXIO_PHY + tristate "Maxio Ethernet PHYs" + help + Support for Maxio Ethernet PHYs. Currently this driver supports the + MAE0621A Gigabit Ethernet PHY. The driver optionally selects a 125 MHz + clock on the CLKOUT pin while preserving the hardware configuration on + boards which do not request it. + config MAXLINEAR_GPHY tristate "Maxlinear Ethernet PHYs" select POLYNOMIAL if HWMON diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index de660ae94..7fb3626f0 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_MARVELL_10G_PHY) += marvell10g.o obj-$(CONFIG_MARVELL_PHY) += marvell.o obj-$(CONFIG_MARVELL_88Q2XXX_PHY) += marvell-88q2xxx.o obj-$(CONFIG_MARVELL_88X2222_PHY) += marvell-88x2222.o +obj-$(CONFIG_MAXIO_PHY) += maxio.o obj-$(CONFIG_MAXLINEAR_GPHY) += mxl-gpy.o obj-$(CONFIG_MAXLINEAR_86110_PHY) += mxl-86110.o obj-y += mediatek/ diff --git a/drivers/net/phy/maxio.c b/drivers/net/phy/maxio.c new file mode 100644 index 000000000..d2cb23895 --- /dev/null +++ b/drivers/net/phy/maxio.c @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Driver for Maxio Ethernet PHYs. */ + +#include +#include +#include +#include + +#define MAXIO_MAE0621A_PHY_ID 0x7b744412 + +#define MAXIO_PAGE_SELECT 0x1f +#define MAXIO_MAE0621A_PHYCR2_PAGE 0xa43 +#define MAXIO_MAE0621A_PHYCR2 0x19 +#define MAXIO_MAE0621A_CLKOUT_125M BIT(11) +#define MAXIO_MAE0621A_CLKOUT_ENABLE BIT(0) + +struct maxio_priv { + bool clk_out_125m; +}; + +static int maxio_read_page(struct phy_device *phydev) +{ + return __phy_read(phydev, MAXIO_PAGE_SELECT); +} + +static int maxio_write_page(struct phy_device *phydev, int page) +{ + return __phy_write(phydev, MAXIO_PAGE_SELECT, page); +} + +static int maxio_mae0621a_probe(struct phy_device *phydev) +{ + struct device *dev = &phydev->mdio.dev; + struct maxio_priv *priv; + u32 frequency; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + phydev->priv = priv; + + ret = device_property_read_u32(dev, "maxio,clk-out-frequency-hz", + &frequency); + if (ret == -EINVAL) + return 0; + if (ret) + return ret; + + if (frequency != 125000000) { + phydev_err(phydev, "invalid CLKOUT frequency %u\n", frequency); + return -EINVAL; + } + + priv->clk_out_125m = true; + + return 0; +} + +static int maxio_mae0621a_config_init(struct phy_device *phydev) +{ + struct maxio_priv *priv = phydev->priv; + int ret; + + if (!priv->clk_out_125m) + return 0; + + ret = phy_modify_paged_changed(phydev, MAXIO_MAE0621A_PHYCR2_PAGE, + MAXIO_MAE0621A_PHYCR2, + MAXIO_MAE0621A_CLKOUT_ENABLE | + MAXIO_MAE0621A_CLKOUT_125M, + MAXIO_MAE0621A_CLKOUT_ENABLE | + MAXIO_MAE0621A_CLKOUT_125M); + if (ret <= 0) + return ret; + + return genphy_soft_reset(phydev); +} + +static struct phy_driver maxio_drivers[] = { + { + PHY_ID_MATCH_EXACT(MAXIO_MAE0621A_PHY_ID), + .name = "Maxio MAE0621A", + .probe = maxio_mae0621a_probe, + .config_init = maxio_mae0621a_config_init, + .suspend = genphy_suspend, + .resume = genphy_resume, + .read_page = maxio_read_page, + .write_page = maxio_write_page, + }, +}; +module_phy_driver(maxio_drivers); + +static const struct mdio_device_id __maybe_unused maxio_tbl[] = { + { PHY_ID_MATCH_EXACT(MAXIO_MAE0621A_PHY_ID) }, + { } +}; +MODULE_DEVICE_TABLE(mdio, maxio_tbl); + +MODULE_AUTHOR("Liu Changjie "); +MODULE_DESCRIPTION("Maxio Ethernet PHY driver"); +MODULE_LICENSE("GPL"); -- 2.55.0