diff options
author | Tom Rini <trini@konsulko.com> | 2022-04-04 10:45:33 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-04-04 10:48:44 -0400 |
commit | 01f1ab67f38882dc7665a0a6eca4bbeba6d84f81 (patch) | |
tree | 31b1febefe82731d94571f7442877c039efb602c /drivers/net/phy/ethernet_id.c | |
parent | e4b6ebd3de982ae7185dbf689a030e73fd06e0d2 (diff) | |
parent | 8221c52d88fbe84ca9692dc23827e21403c952e8 (diff) |
Merge branch 'next'
Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'drivers/net/phy/ethernet_id.c')
-rw-r--r-- | drivers/net/phy/ethernet_id.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/net/phy/ethernet_id.c b/drivers/net/phy/ethernet_id.c new file mode 100644 index 0000000000..5617ac3ad6 --- /dev/null +++ b/drivers/net/phy/ethernet_id.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Xilinx ethernet phy reset driver + * + * Copyright (C) 2022 Xilinx, Inc. + */ + +#include <common.h> +#include <dm/device_compat.h> +#include <phy.h> +#include <linux/delay.h> +#include <asm/gpio.h> + +struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev, + phy_interface_t interface) +{ + struct phy_device *phydev; + struct ofnode_phandle_args phandle_args; + struct gpio_desc gpio; + ofnode node; + u32 id, assert, deassert; + u16 vendor, device; + int ret; + + if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, + &phandle_args)) + return NULL; + + if (!ofnode_valid(phandle_args.node)) + return NULL; + + node = phandle_args.node; + + ret = ofnode_read_eth_phy_id(node, &vendor, &device); + if (ret) { + dev_err(dev, "Failed to read eth PHY id, err: %d\n", ret); + return NULL; + } + + ret = gpio_request_by_name_nodev(node, "reset-gpios", 0, &gpio, + GPIOD_ACTIVE_LOW); + if (!ret) { + assert = ofnode_read_u32_default(node, "reset-assert-us", 0); + deassert = ofnode_read_u32_default(node, + "reset-deassert-us", 0); + ret = dm_gpio_set_value(&gpio, 1); + if (ret) { + dev_err(dev, "Failed assert gpio, err: %d\n", ret); + return NULL; + } + + udelay(assert); + + ret = dm_gpio_set_value(&gpio, 0); + if (ret) { + dev_err(dev, "Failed deassert gpio, err: %d\n", ret); + return NULL; + } + + udelay(deassert); + } + + id = vendor << 16 | device; + phydev = phy_device_create(bus, 0, id, false, interface); + if (phydev) + phydev->node = node; + + return phydev; +} |