Re: [PATCH RFC 10/26] phy: add I2C mdio bus

2015-12-11 Thread Russell King - ARM Linux
On Tue, Dec 08, 2015 at 10:15:08AM -0800, Florian Fainelli wrote:
> On 07/12/15 09:38, Russell King wrote:
> > Add an I2C MDIO bus bridge library, to allow phylib to access PHYs which
> > are connected to an I2C bus instead of the more conventional MDIO bus.
> > Such PHYs can be found in SFP adapters and SFF modules.
> > 
> > Signed-off-by: Russell King 
> > ---
> [snip]
> > +static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg)
> > +{
> > +   struct i2c_adapter *i2c = bus->priv;
> > +   struct i2c_msg msgs[2];
> > +   u8 data[2], dev_addr = reg;
> > +   int bus_addr, ret;
> > +
> > +   bus_addr = 0x40 + phy_id;
> > +   if (bus_addr == 0x50 || bus_addr == 0x51)
> > +   return 0x;
> 
> These could deserve a local definition for these specific addresses so
> we know why there is such logic here.

This is the only comment I've received on this series so far; I'm
waiting for further comments before addressing it.

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH RFC 10/26] phy: add I2C mdio bus

2015-12-08 Thread Florian Fainelli
On 07/12/15 09:38, Russell King wrote:
> Add an I2C MDIO bus bridge library, to allow phylib to access PHYs which
> are connected to an I2C bus instead of the more conventional MDIO bus.
> Such PHYs can be found in SFP adapters and SFF modules.
> 
> Signed-off-by: Russell King 
> ---
[snip]
> +static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg)
> +{
> + struct i2c_adapter *i2c = bus->priv;
> + struct i2c_msg msgs[2];
> + u8 data[2], dev_addr = reg;
> + int bus_addr, ret;
> +
> + bus_addr = 0x40 + phy_id;
> + if (bus_addr == 0x50 || bus_addr == 0x51)
> + return 0x;

These could deserve a local definition for these specific addresses so
we know why there is such logic here.

> +
> + msgs[0].addr = bus_addr;
> + msgs[0].flags = 0;
> + msgs[0].len = 1;
> + msgs[0].buf = _addr;
> + msgs[1].addr = bus_addr;
> + msgs[1].flags = I2C_M_RD;
> + msgs[1].len = sizeof(data);
> + msgs[1].buf = data;
> +
> + ret = i2c_transfer(i2c, msgs, ARRAY_SIZE(msgs));
> + if (ret != ARRAY_SIZE(msgs))
> + return 0x;
> +
> + return data[0] << 8 | data[1];
> +}
> +
> +static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
> +{
> + struct i2c_adapter *i2c = bus->priv;
> + struct i2c_msg msg;
> + int bus_addr, ret;
> + u8 data[3];
> +
> + bus_addr = 0x40 + phy_id;
> + if (bus_addr == 0x50 || bus_addr == 0x51)
> + return 0;

Same here.
-- 
Florian
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC 10/26] phy: add I2C mdio bus

2015-12-07 Thread Russell King
Add an I2C MDIO bus bridge library, to allow phylib to access PHYs which
are connected to an I2C bus instead of the more conventional MDIO bus.
Such PHYs can be found in SFP adapters and SFF modules.

Signed-off-by: Russell King 
---
 drivers/net/phy/Kconfig| 10 ++
 drivers/net/phy/Makefile   |  1 +
 drivers/net/phy/mdio-i2c.c | 90 ++
 drivers/net/phy/mdio-i2c.h | 19 ++
 4 files changed, 120 insertions(+)
 create mode 100644 drivers/net/phy/mdio-i2c.c
 create mode 100644 drivers/net/phy/mdio-i2c.h

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index c59f957fc282..c475531a542e 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -187,6 +187,16 @@ config MDIO_GPIO
  To compile this driver as a module, choose M here: the module
  will be called mdio-gpio.
 
+config MDIO_I2C
+   tristate
+   depends on I2C
+   help
+ Support I2C based PHYs.  This provides a MDIO bus bridged
+ to I2C to allow PHYs connected in I2C mode to be accessed
+ using the existing infrastructure.
+
+ This is library mode.
+
 config MDIO_OCTEON
tristate "Support for MDIO buses on Octeon and ThunderX SOCs"
depends on 64BIT
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 31bdf193adbd..d5c3ff625fbe 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
 obj-$(CONFIG_FIXED_PHY)+= fixed_phy.o
 obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o
 obj-$(CONFIG_MDIO_GPIO)+= mdio-gpio.o
+obj-$(CONFIG_MDIO_I2C) += mdio-i2c.o
 obj-$(CONFIG_NATIONAL_PHY) += national.o
 obj-$(CONFIG_DP83640_PHY)  += dp83640.o
 obj-$(CONFIG_DP83848_PHY)  += dp83848.o
diff --git a/drivers/net/phy/mdio-i2c.c b/drivers/net/phy/mdio-i2c.c
new file mode 100644
index ..57b5de8c5a3e
--- /dev/null
+++ b/drivers/net/phy/mdio-i2c.c
@@ -0,0 +1,90 @@
+/*
+ * MDIO I2C bridge
+ *
+ * Copyright (C) 2015 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include 
+#include 
+
+#include "mdio-i2c.h"
+
+static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg)
+{
+   struct i2c_adapter *i2c = bus->priv;
+   struct i2c_msg msgs[2];
+   u8 data[2], dev_addr = reg;
+   int bus_addr, ret;
+
+   bus_addr = 0x40 + phy_id;
+   if (bus_addr == 0x50 || bus_addr == 0x51)
+   return 0x;
+
+   msgs[0].addr = bus_addr;
+   msgs[0].flags = 0;
+   msgs[0].len = 1;
+   msgs[0].buf = _addr;
+   msgs[1].addr = bus_addr;
+   msgs[1].flags = I2C_M_RD;
+   msgs[1].len = sizeof(data);
+   msgs[1].buf = data;
+
+   ret = i2c_transfer(i2c, msgs, ARRAY_SIZE(msgs));
+   if (ret != ARRAY_SIZE(msgs))
+   return 0x;
+
+   return data[0] << 8 | data[1];
+}
+
+static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
+{
+   struct i2c_adapter *i2c = bus->priv;
+   struct i2c_msg msg;
+   int bus_addr, ret;
+   u8 data[3];
+
+   bus_addr = 0x40 + phy_id;
+   if (bus_addr == 0x50 || bus_addr == 0x51)
+   return 0;
+
+   data[0] = reg;
+   data[1] = val >> 8;
+   data[2] = val;
+
+   msg.addr = bus_addr;
+   msg.flags = 0;
+   msg.len = 3;
+   msg.buf = data;
+
+   ret = i2c_transfer(i2c, , 1);
+
+   return ret < 0 ? ret : 0;
+}
+
+struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c)
+{
+   struct mii_bus *mii;
+
+   if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
+   return ERR_PTR(-EINVAL);
+
+   mii = mdiobus_alloc();
+   if (!mii)
+   return ERR_PTR(-ENOMEM);
+
+   snprintf(mii->id, MII_BUS_ID_SIZE, "i2c:%s", dev_name(parent));
+   mii->parent = parent;
+   mii->read = i2c_mii_read;
+   mii->write = i2c_mii_write;
+   mii->priv = i2c;
+
+   return mii;
+}
+EXPORT_SYMBOL_GPL(mdio_i2c_alloc);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("MDIO I2C bridge library");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/phy/mdio-i2c.h b/drivers/net/phy/mdio-i2c.h
new file mode 100644
index ..889ab57d7f3e
--- /dev/null
+++ b/drivers/net/phy/mdio-i2c.h
@@ -0,0 +1,19 @@
+/*
+ * MDIO I2C bridge
+ *
+ * Copyright (C) 2015 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef MDIO_I2C_H
+#define MDIO_I2C_H
+
+struct device;
+struct i2c_adapter;
+struct mii_bus;
+
+struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c);
+