Skip to content

Commit

Permalink
net: phy: adin: add adi,phy-mode-override property
Browse files Browse the repository at this point in the history
Override phy-mode property for adin. This is useful when a single
device tree supports an adin PHY (e.g. ADIN1300) or another PHY
(e.g. AR8033) at the same address, but they require different phy-modes.

Signed-off-by: Nate Drude <nate.d@variscite.com>
  • Loading branch information
nsdrude authored and m-p-s committed May 6, 2022
1 parent 5995006 commit 82776e5
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Documentation/devicetree/bindings/net/adi,adin.yaml
Expand Up @@ -36,6 +36,12 @@ properties:
enum: [ 4, 8, 12, 16, 20, 24 ]
default: 8

adi,phy-mode-override:
description: |
Override phy-mode property for adin. This is useful when a single device tree
supports an adin PHY (e.g. ADIN1300) or another PHY (e.g. AR8033) at the same
address, but they require different phy-modes.
examples:
- |
ethernet {
Expand All @@ -49,6 +55,7 @@ examples:
adi,rx-internal-delay-ps = <1800>;
adi,tx-internal-delay-ps = <2200>;
adi,phy-mode-override = "rgmii-id";
};
};
- |
Expand Down
39 changes: 39 additions & 0 deletions drivers/net/phy/adin.c
Expand Up @@ -13,6 +13,7 @@
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/property.h>
#include <linux/of.h>

#define PHY_ID_ADIN1200 0x0283bc20
#define PHY_ID_ADIN1300 0x0283bc30
Expand Down Expand Up @@ -180,6 +181,39 @@ struct adin_priv {
u64 stats[ARRAY_SIZE(adin_hw_stats)];
};

/**
* adin_get_phy_mode_override - Get phy-mode override for adin PHY
*
* The function gets phy-mode string from property 'adi,phy-mode-override'
* and return its index in phy_modes table, or errno in error case.
*/
int adin_get_phy_mode_override(struct phy_device *phydev)
{
struct device *dev = &phydev->mdio.dev;
struct device_node *of_node = dev->of_node;
const char *phy_mode_override;
const char *prop_phy_mode_override = "adi,phy-mode-override";
int err, i;

err = of_property_read_string(of_node, prop_phy_mode_override,
&phy_mode_override);
if (err < 0)
return err;

phydev_info(phydev,
"%s = '%s'\n", prop_phy_mode_override, phy_mode_override);

for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
if (!strcasecmp(phy_mode_override, phy_modes(i)))
return i;

phydev_err(phydev,
"%s = '%s' is not valid\n",
prop_phy_mode_override, phy_mode_override);

return -ENODEV;
}

static int adin_lookup_reg_value(const struct adin_cfg_reg_map *tbl, int cfg)
{
size_t i;
Expand Down Expand Up @@ -219,6 +253,11 @@ static int adin_config_rgmii_mode(struct phy_device *phydev)
{
u32 val;
int reg;
int phy_mode_override = adin_get_phy_mode_override(phydev);

if (phy_mode_override >= 0) {
phydev->interface = (phy_interface_t) phy_mode_override;
}

if (!phy_interface_is_rgmii(phydev))
return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
Expand Down

0 comments on commit 82776e5

Please sign in to comment.