[PATCH v3 1/2] Add support for ksz9031 PAD skew configuration over devicetree.

From: Hubert Chaumette
Date: Tue Apr 29 2014 - 05:34:42 EST


Adds support for ksz9031 PAD skew configuration over devicetree.

Signed-off-by: Hubert Chaumette <hchaumette@xxxxxxxxxxxxxxxxxxx>
---
drivers/net/phy/micrel.c | 167 +++++++++++++----------------------------------
1 file changed, 44 insertions(+), 123 deletions(-)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index df56b26..c936b72 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -271,156 +271,77 @@ static int ksz9031_extended_read(struct phy_device *phydev,
return phy_read(phydev, MII_KSZ9031RN_MMD_REGDATA_REG);
}

-/* Two 5-bit fields register */
-static int ksz9031_load_clk_skew_values(struct phy_device *phydev,
- struct device_node *of_node,
- char *field1, char *field2)
+static int ksz9031_of_load_skew_values(struct phy_device *phydev,
+ struct device_node *of_node,
+ u16 reg, size_t field_sz,
+ char *field[], u8 numfields)
{
- int val1 = -1;
- int val2 = -2;
- int newval;
+ int val[4] = {-1, -2, -3, -4};
int matches = 0;
+ u16 mask;
+ u16 maxval;
+ u16 newval;
+ int i;

- if (!of_property_read_u32(of_node, field1, &val1))
- matches++;
-
- if (!of_property_read_u32(of_node, field2, &val2))
- matches++;
+ for (i = 0; i < numfields; i++)
+ if (!of_property_read_u32(of_node, field[i], val + i))
+ matches++;

if (!matches)
return 0;

- if (matches < 2)
- newval = ksz9031_extended_read(phydev, OP_DATA, 2,
- MII_KSZ9031RN_CLK_PAD_SKEW);
- else
- newval = 0;
-
- if (val1 != -1)
- newval = (newval & 0xffe0) |
- ((val1 / KSZ9031_PS_TO_REG) & 0x1f);
-
- if (val2 != -2)
- newval = (newval & 0xfc1f) |
- (((val2 / KSZ9031_PS_TO_REG) & 0x1f) << 5);
-
- return ksz9031_extended_write(phydev, OP_DATA, 2,
- MII_KSZ9031RN_CLK_PAD_SKEW, newval);
-}
-
-/* Four 4-bit fields register */
-static int ksz9031_load_data_skew_values(struct phy_device *phydev,
- struct device_node *of_node, u16 reg,
- char *field1, char *field2,
- char *field3, char *field4)
-{
- int val1 = -1;
- int val2 = -2;
- int val3 = -3;
- int val4 = -4;
- int newval;
- int matches = 0;
-
- if (!of_property_read_u32(of_node, field1, &val1))
- matches++;
-
- if (!of_property_read_u32(of_node, field2, &val2))
- matches++;
-
- if (!of_property_read_u32(of_node, field3, &val3))
- matches++;
-
- if (!of_property_read_u32(of_node, field4, &val4))
- matches++;
-
- if (!matches)
- return 0;
-
- if (matches < 4)
+ if (matches < numfields)
newval = ksz9031_extended_read(phydev, OP_DATA, 2, reg);
else
newval = 0;

- if (val1 != -1)
- newval = (newval & 0xfff0) |
- (((val1 / KSZ9031_PS_TO_REG) & 0xf) << 0);
-
- if (val2 != -2)
- newval = (newval & 0xff0f) |
- (((val2 / KSZ9031_PS_TO_REG) & 0xf) << 4);
-
- if (val3 != -3)
- newval = (newval & 0xf0ff) |
- (((val3 / KSZ9031_PS_TO_REG) & 0xf) << 8);
-
- if (val4 != -4)
- newval = (newval & 0x0fff) |
- (((val4 / KSZ9031_PS_TO_REG) & 0xf) << 12);
+ maxval = (field_sz == 4) ? 0xf : 0x1f;
+ for (i = 0; i < numfields; i++)
+ if (val[i] != -(i + 1)) {
+ mask = 0xffff;
+ mask ^= maxval << (field_sz * i);
+ newval = (newval & mask) |
+ (((val[i] / KSZ9031_PS_TO_REG) & maxval)
+ << (field_sz * i));
+ }

return ksz9031_extended_write(phydev, OP_DATA, 2, reg, newval);
}

-/* Two 4-bit fields register */
-static int ksz9031_load_ctrl_skew_values(struct phy_device *phydev,
- struct device_node *of_node,
- char *field1, char *field2)
-{
- int val1 = -1;
- int val2 = -2;
- int newval;
- int matches = 0;
-
- if (!of_property_read_u32(of_node, field1, &val1))
- matches++;
-
- if (!of_property_read_u32(of_node, field2, &val2))
- matches++;
-
- if (!matches)
- return 0;
-
- if (matches < 2)
- newval = ksz9031_extended_read(phydev, OP_DATA, 2,
- MII_KSZ9031RN_CONTROL_PAD_SKEW);
- else
- newval = 0;
-
- if (val1 != -1)
- newval = (newval & 0xfff0) |
- (((val1 / KSZ9031_PS_TO_REG) & 0xf) << 0);
-
- if (val2 != -2)
- newval = (newval & 0xff0f) |
- (((val2 / KSZ9031_PS_TO_REG) & 0xf) << 4);
-
- return ksz9031_extended_write(phydev, OP_DATA, 2,
- MII_KSZ9031RN_CONTROL_PAD_SKEW, newval);
-}
-
static int ksz9031_config_init(struct phy_device *phydev)
{
struct device *dev = &phydev->dev;
struct device_node *of_node = dev->of_node;
+ char *clk_skews[2] = {"rxc-skew-ps", "txc-skew-ps"};
+ char *rx_data_skews[4] = {
+ "rxd0-skew-ps", "rxd1-skew-ps",
+ "rxd2-skew-ps", "rxd3-skew-ps"
+ };
+ char *tx_data_skews[4] = {
+ "txd0-skew-ps", "txd1-skew-ps",
+ "txd2-skew-ps", "txd3-skew-ps"
+ };
+ char *control_skews[2] = {"txen-skew-ps", "rxdv-skew-ps"};

if (!of_node && dev->parent->of_node)
of_node = dev->parent->of_node;

if (of_node) {
- ksz9031_load_clk_skew_values(phydev, of_node,
- "rxc-skew-ps", "txc-skew-ps");
+ ksz9031_of_load_skew_values(phydev, of_node,
+ MII_KSZ9031RN_CLK_PAD_SKEW, 5,
+ clk_skews, 2);

- ksz9031_load_data_skew_values(phydev, of_node,
- MII_KSZ9031RN_RX_DATA_PAD_SKEW,
- "rxd0-skew-ps", "rxd1-skew-ps",
- "rxd2-skew-ps", "rxd3-skew-ps");
+ ksz9031_of_load_skew_values(phydev, of_node,
+ MII_KSZ9031RN_CONTROL_PAD_SKEW, 4,
+ control_skews, 2);

- ksz9031_load_data_skew_values(phydev, of_node,
- MII_KSZ9031RN_TX_DATA_PAD_SKEW,
- "txd0-skew-ps", "txd1-skew-ps",
- "txd2-skew-ps", "txd3-skew-ps");
+ ksz9031_of_load_skew_values(phydev, of_node,
+ MII_KSZ9031RN_RX_DATA_PAD_SKEW, 4,
+ rx_data_skews, 4);

- ksz9031_load_ctrl_skew_values(phydev, of_node,
- "txen-skew-ps", "rxdv-skew-ps");
+ ksz9031_of_load_skew_values(phydev, of_node,
+ MII_KSZ9031RN_TX_DATA_PAD_SKEW, 4,
+ tx_data_skews, 4);
}
return 0;
}
--
1.9.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/