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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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 devicetree" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux