lkml.org 
[lkml]   [2022]   [Jun]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH net-next v2 3/3] net: phy: dp83867: implement support for io_impedance_ctrl nvmem cell
    Date
    We have a board where measurements indicate that the current three
    options - leaving IO_IMPEDANCE_CTRL at the (factory calibrated) reset
    value or using one of the two boolean properties to set it to the
    min/max value - are too coarse.

    Implement support for the newly added binding allowing device tree to
    specify an nvmem cell containing an appropriate value for this
    specific board.

    Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
    ---
    drivers/net/phy/dp83867.c | 55 ++++++++++++++++++++++++++++++++++-----
    1 file changed, 49 insertions(+), 6 deletions(-)

    diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
    index 8561f2d4443b..45d8a9298251 100644
    --- a/drivers/net/phy/dp83867.c
    +++ b/drivers/net/phy/dp83867.c
    @@ -14,6 +14,7 @@
    #include <linux/netdevice.h>
    #include <linux/etherdevice.h>
    #include <linux/bitfield.h>
    +#include <linux/nvmem-consumer.h>

    #include <dt-bindings/net/ti-dp83867.h>

    @@ -521,6 +522,51 @@ static int dp83867_verify_rgmii_cfg(struct phy_device *phydev)
    }

    #if IS_ENABLED(CONFIG_OF_MDIO)
    +static int dp83867_of_init_io_impedance(struct phy_device *phydev)
    +{
    + struct dp83867_private *dp83867 = phydev->priv;
    + struct device *dev = &phydev->mdio.dev;
    + struct device_node *of_node = dev->of_node;
    + struct nvmem_cell *cell;
    + u8 *buf, val;
    + int ret;
    +
    + cell = of_nvmem_cell_get(of_node, "io_impedance_ctrl");
    + if (IS_ERR(cell)) {
    + ret = PTR_ERR(cell);
    + if (ret != -ENOENT)
    + return phydev_err_probe(phydev, ret,
    + "failed to get nvmem cell io_impedance_ctrl\n");
    +
    + /* If no nvmem cell, check for the boolean properties. */
    + if (of_property_read_bool(of_node, "ti,max-output-impedance"))
    + dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX;
    + else if (of_property_read_bool(of_node, "ti,min-output-impedance"))
    + dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN;
    + else
    + dp83867->io_impedance = -1; /* leave at default */
    +
    + return 0;
    + }
    +
    + buf = nvmem_cell_read(cell, NULL);
    + nvmem_cell_put(cell);
    +
    + if (IS_ERR(buf))
    + return PTR_ERR(buf);
    +
    + val = *buf;
    + kfree(buf);
    +
    + if ((val & DP83867_IO_MUX_CFG_IO_IMPEDANCE_MASK) != val) {
    + phydev_err(phydev, "nvmem cell 'io_impedance_ctrl' contents out of range\n");
    + return -ERANGE;
    + }
    + dp83867->io_impedance = val;
    +
    + return 0;
    +}
    +
    static int dp83867_of_init(struct phy_device *phydev)
    {
    struct dp83867_private *dp83867 = phydev->priv;
    @@ -548,12 +594,9 @@ static int dp83867_of_init(struct phy_device *phydev)
    }
    }

    - if (of_property_read_bool(of_node, "ti,max-output-impedance"))
    - dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX;
    - else if (of_property_read_bool(of_node, "ti,min-output-impedance"))
    - dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN;
    - else
    - dp83867->io_impedance = -1; /* leave at default */
    + ret = dp83867_of_init_io_impedance(phydev);
    + if (ret)
    + return ret;

    dp83867->rxctrl_strap_quirk = of_property_read_bool(of_node,
    "ti,dp83867-rxctrl-strap-quirk");
    --
    2.31.1
    \
     
     \ /
      Last update: 2022-06-14 10:48    [W:4.740 / U:0.280 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site