summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe De Muyter <phdm@macqel.be>2014-02-19 17:21:59 +0100
committerJoe Hershberger <joe.hershberger@ni.com>2015-01-30 15:55:00 -0600
commitb7a5b0843812b7bd4a225951ce11e7d14398395c (patch)
tree3d9360609425a427275bec01c58a4ef4b4f993c0
parente9efe16da8e7233e59801e80f2770292a7fe4f77 (diff)
downloadu-boot-imx-b7a5b0843812b7bd4a225951ce11e7d14398395c.zip
u-boot-imx-b7a5b0843812b7bd4a225951ce11e7d14398395c.tar.gz
u-boot-imx-b7a5b0843812b7bd4a225951ce11e7d14398395c.tar.bz2
net: phy: micrel: add support for KSZ8895 switch in SMI mode
This patch adds a phy driver for the Micrel KSZ8895 switch. As the SoC MAC is directly connected to the switch MAC the link to the switch is always up. But the KSZ8895 switch can be hardwired in three configuration modes : - not configurable with eventually an eeprom-stored configuration - configurable by the mdio/mdc connection (SMI protocol) - configurable by a SPI connection. In not configurable mode, the switch starts automatically, but in the other modes, it must be started programmatically, by writing 1 in configuration register 1. We only support the not configurable and mdio/mdc (aka SMI) modes here. Signed-off-by: Philippe De Muyter <phdm@macqel.be> Cc: Christian Gmeiner <christian.gmeiner@gmail.com> Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
-rw-r--r--drivers/net/phy/micrel.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 507b9a3..1815b29 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -22,6 +22,63 @@ static struct phy_driver KSZ804_driver = {
.shutdown = &genphy_shutdown,
};
+/**
+ * KSZ8895
+ */
+
+static unsigned short smireg_to_phy(unsigned short reg)
+{
+ return ((reg & 0xc0) >> 3) + 0x06 + ((reg & 0x20) >> 5);
+}
+
+static unsigned short smireg_to_reg(unsigned short reg)
+{
+ return reg & 0x1F;
+}
+
+static void ksz8895_write_smireg(struct phy_device *phydev, int smireg, int val)
+{
+ phydev->bus->write(phydev->bus, smireg_to_phy(smireg), MDIO_DEVAD_NONE,
+ smireg_to_reg(smireg), val);
+}
+
+#if 0
+static int ksz8895_read_smireg(struct phy_device *phydev, int smireg)
+{
+ return phydev->bus->read(phydev->bus, smireg_to_phy(smireg),
+ MDIO_DEVAD_NONE, smireg_to_reg(smireg));
+}
+#endif
+
+int ksz8895_config(struct phy_device *phydev)
+{
+ /* we are connected directly to the switch without
+ * dedicated PHY. SCONF1 == 001 */
+ phydev->link = 1;
+ phydev->duplex = DUPLEX_FULL;
+ phydev->speed = SPEED_100;
+
+ /* Force the switch to start */
+ ksz8895_write_smireg(phydev, 1, 1);
+
+ return 0;
+}
+
+static int ksz8895_startup(struct phy_device *phydev)
+{
+ return 0;
+}
+
+static struct phy_driver ksz8895_driver = {
+ .name = "Micrel KSZ8895/KSZ8864",
+ .uid = 0x221450,
+ .mask = 0xffffe1,
+ .features = PHY_BASIC_FEATURES,
+ .config = &ksz8895_config,
+ .startup = &ksz8895_startup,
+ .shutdown = &genphy_shutdown,
+};
+
#ifndef CONFIG_PHY_MICREL_KSZ9021
/*
* I can't believe Micrel used the exact same part number
@@ -221,5 +278,6 @@ int phy_micrel_init(void)
phy_register(&KS8721_driver);
#endif
phy_register(&ksz9031_driver);
+ phy_register(&ksz8895_driver);
return 0;
}