All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/8] Generic bitbanged MDIO library
@ 2007-08-28 20:11 Scott Wood
  2007-08-28 20:14 ` [PATCH v3 2/8] fs_enet: Whitespace cleanup Scott Wood
                   ` (32 more replies)
  0 siblings, 33 replies; 81+ messages in thread
From: Scott Wood @ 2007-08-28 20:11 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev

Previously, bitbanged MDIO was only supported in individual
hardware-specific drivers.  This code factors out the higher level
protocol implementation, reducing the hardware-specific portion to
functions setting direction, data, and clock.

Signed-off-by: Scott Wood <scottwood@freescale.com>
---
 drivers/net/phy/Kconfig        |    9 ++
 drivers/net/phy/Makefile       |    1 +
 drivers/net/phy/mdio-bitbang.c |  187 ++++++++++++++++++++++++++++++++++++++++
 include/linux/mdio-bitbang.h   |   42 +++++++++
 4 files changed, 239 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/phy/mdio-bitbang.c
 create mode 100644 include/linux/mdio-bitbang.h

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index dd09011..72a98dd 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -76,4 +76,13 @@ config FIXED_MII_100_FDX
 	bool "Emulation for 100M Fdx fixed PHY behavior"
 	depends on FIXED_PHY
 
+config MDIO_BITBANG
+	tristate "Support for bitbanged MDIO buses"
+	help
+	  This module implements the MDIO bus protocol in software,
+	  for use by low level drivers that export the ability to
+	  drive the relevant pins.
+
+	  If in doubt, say N.
+
 endif # PHYLIB
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 8885650..3d6cc7b 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_VITESSE_PHY)	+= vitesse.o
 obj-$(CONFIG_BROADCOM_PHY)	+= broadcom.o
 obj-$(CONFIG_ICPLUS_PHY)	+= icplus.o
 obj-$(CONFIG_FIXED_PHY)		+= fixed.o
+obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitbang.o
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
new file mode 100644
index 0000000..9bfc9ce
--- /dev/null
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -0,0 +1,187 @@
+/*
+ * Bitbanged MDIO support.
+ *
+ * Author: Scott Wood <scottwood@freescale.com>
+ * Copyright (c) 2007 Freescale Semiconductor
+ *
+ * Based on CPM2 MDIO code which is:
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ *  by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/mdio-bitbang.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+
+#define MDIO_READ 1
+#define MDIO_WRITE 0
+
+#define MDIO_SETUP_TIME 10
+#define MDIO_HOLD_TIME 10
+
+/* Minimum MDC period is 400 ns, plus some margin for error */
+#define MDIO_DELAY 250
+
+/* The PHY may take up to 300 ns to produce data, plus some margin
+ * for error.
+ */
+#define MDIO_READ_DELAY 350
+
+/* MDIO must already be configured as output. */
+static void mdio_bitbang_send_bit(struct mdio_bitbang_ctrl *ctrl, int val)
+{
+	const struct mdio_bitbang_ops *ops = ctrl->ops;
+
+	ops->set_mdio_data(ctrl, val);
+	ndelay(MDIO_DELAY);
+	ops->set_mdc(ctrl, 1);
+	ndelay(MDIO_DELAY);
+	ops->set_mdc(ctrl, 0);
+}
+
+/* MDIO must already be configured as input. */
+static int mdio_bitbang_get_bit(struct mdio_bitbang_ctrl *ctrl)
+{
+	const struct mdio_bitbang_ops *ops = ctrl->ops;
+
+	ndelay(MDIO_DELAY);
+	ops->set_mdc(ctrl, 1);
+	ndelay(MDIO_READ_DELAY);
+	ops->set_mdc(ctrl, 0);
+
+	return ops->get_mdio_data(ctrl);
+}
+
+/* MDIO must already be configured as output. */
+static void mdio_bitbang_send_num(struct mdio_bitbang_ctrl *ctrl,
+                                  u16 val, int bits)
+{
+	int i;
+
+	for (i = bits - 1; i >= 0; i--)
+		mdio_bitbang_send_bit(ctrl, (val >> i) & 1);
+}
+
+/* MDIO must already be configured as input. */
+static u16 mdio_bitbang_get_num(struct mdio_bitbang_ctrl *ctrl, int bits)
+{
+	int i;
+	u16 ret = 0;
+
+	for (i = bits - 1; i >= 0; i--) {
+		ret <<= 1;
+		ret |= mdio_bitbang_get_bit(ctrl);
+	}
+
+	return ret;
+}
+
+/* Utility to send the preamble, address, and
+ * register (common to read and write).
+ */
+static void mdio_bitbang_cmd(struct mdio_bitbang_ctrl *ctrl,
+                             int read, u8 phy, u8 reg)
+{
+	const struct mdio_bitbang_ops *ops = ctrl->ops;
+	int i;
+
+	ops->set_mdio_dir(ctrl, 1);
+
+	/*
+	 * Send a 32 bit preamble ('1's) with an extra '1' bit for good
+	 * measure.  The IEEE spec says this is a PHY optional
+	 * requirement.  The AMD 79C874 requires one after power up and
+	 * one after a MII communications error.  This means that we are
+	 * doing more preambles than we need, but it is safer and will be
+	 * much more robust.
+	 */
+
+	for (i = 0; i < 32; i++)
+		mdio_bitbang_send_bit(ctrl, 1);
+
+	/* send the start bit (01) and the read opcode (10) or write (10) */
+	mdio_bitbang_send_bit(ctrl, 0);
+	mdio_bitbang_send_bit(ctrl, 1);
+	mdio_bitbang_send_bit(ctrl, read);
+	mdio_bitbang_send_bit(ctrl, !read);
+
+	mdio_bitbang_send_num(ctrl, phy, 5);
+	mdio_bitbang_send_num(ctrl, reg, 5);
+}
+
+
+static int mdio_bitbang_read(struct mii_bus *bus, int phy, int reg)
+{
+	struct mdio_bitbang_ctrl *ctrl = bus->priv;
+	int ret, i;
+
+	mdio_bitbang_cmd(ctrl, MDIO_READ, phy, reg);
+	ctrl->ops->set_mdio_dir(ctrl, 0);
+
+	/* check the turnaround bit: the PHY should be driving it to zero */
+	if (mdio_bitbang_get_bit(ctrl) != 0) {
+		/* PHY didn't drive TA low -- flush any bits it
+		 * may be trying to send.
+		 */
+		for (i = 0; i < 32; i++)
+			mdio_bitbang_get_bit(ctrl);
+
+		return 0xffff;
+	}
+
+	ret = mdio_bitbang_get_num(ctrl, 16);
+	mdio_bitbang_get_bit(ctrl);
+	return ret;
+}
+
+static int mdio_bitbang_write(struct mii_bus *bus, int phy, int reg, u16 val)
+{
+	struct mdio_bitbang_ctrl *ctrl = bus->priv;
+
+	mdio_bitbang_cmd(ctrl, MDIO_WRITE, phy, reg);
+
+	/* send the turnaround (10) */
+	mdio_bitbang_send_bit(ctrl, 1);
+	mdio_bitbang_send_bit(ctrl, 0);
+
+	mdio_bitbang_send_num(ctrl, val, 16);
+
+	ctrl->ops->set_mdio_dir(ctrl, 0);
+	mdio_bitbang_get_bit(ctrl);
+	return 0;
+}
+
+struct mii_bus *alloc_mdio_bitbang(struct mdio_bitbang_ctrl *ctrl)
+{
+	struct mii_bus *bus;
+
+	bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
+	if (!bus)
+		return NULL;
+
+	__module_get(ctrl->ops->owner);
+
+	bus->read = mdio_bitbang_read;
+	bus->write = mdio_bitbang_write;
+	bus->priv = ctrl;
+
+	return bus;
+}
+
+void free_mdio_bitbang(struct mii_bus *bus)
+{
+	struct mdio_bitbang_ctrl *ctrl = bus->priv;
+
+	module_put(ctrl->ops->owner);
+	kfree(bus);
+}
diff --git a/include/linux/mdio-bitbang.h b/include/linux/mdio-bitbang.h
new file mode 100644
index 0000000..63a11dd
--- /dev/null
+++ b/include/linux/mdio-bitbang.h
@@ -0,0 +1,42 @@
+#ifndef __LINUX_MDIO_BITBANG_H
+#define __LINUX_MDIO_BITBANG_H
+
+#include <linux/phy.h>
+#include <linux/module.h>
+
+struct mdio_bitbang_ctrl;
+
+struct mdio_bitbang_ops {
+	struct module *owner;
+
+	/* Set the Management Data Clock high if level is one,
+	 * low if level is zero.
+	 */
+	void (*set_mdc)(struct mdio_bitbang_ctrl *ctrl, int level);
+
+	/* Configure the Management Data I/O pin as an input if
+	 * "output" is zero, or an output if "output" is one.
+	 */
+	void (*set_mdio_dir)(struct mdio_bitbang_ctrl *ctrl, int output);
+
+	/* Set the Management Data I/O pin high if value is one,
+	 * low if "value" is zero.  This may only be called
+	 * when the MDIO pin is configured as an output.
+	 */
+	void (*set_mdio_data)(struct mdio_bitbang_ctrl *ctrl, int value);
+
+	/* Retrieve the state Management Data I/O pin. */
+	int (*get_mdio_data)(struct mdio_bitbang_ctrl *ctrl);
+};
+
+struct mdio_bitbang_ctrl {
+	const struct mdio_bitbang_ops *ops;
+};
+
+/* The returned bus is not yet registered with the phy layer. */
+struct mii_bus *alloc_mdio_bitbang(struct mdio_bitbang_ctrl *ctrl);
+
+/* The bus must already have been unregistered. */
+void free_mdio_bitbang(struct mii_bus *bus);
+
+#endif
-- 
1.5.0.3

^ permalink raw reply related	[flat|nested] 81+ messages in thread

end of thread, other threads:[~2007-09-15  2:25 UTC | newest]

Thread overview: 81+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-28 20:11 [PATCH v3 1/8] Generic bitbanged MDIO library Scott Wood
2007-08-28 20:14 ` [PATCH v3 2/8] fs_enet: Whitespace cleanup Scott Wood
2007-08-28 20:14 ` [PATCH v3 3/8] fs_enet: Include linux/string.h from linux/fs_enet_pd.h Scott Wood
2007-08-28 20:14 ` [PATCH v3 4/8] fs_enet: Don't share the interrupt Scott Wood
2007-08-28 20:14 ` [PATCH v3 5/8] fs_enet: mac-fcc: Eliminate __fcc-* macros Scott Wood
2007-08-28 20:14 ` [PATCH v3 6/8] fs_enet: Align receive buffers Scott Wood
2007-08-28 20:14 ` [PATCH v3 7/8] fs_enet: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set Scott Wood
2007-08-28 20:14 ` [PATCH v3 8/8] fs_enet: sparse fixes Scott Wood
2007-08-28 20:16 ` [PATCH 1/3] fsl_soc.c cleanup Scott Wood
2007-08-29  5:30   ` David Gibson
2007-09-11  5:35   ` Kumar Gala
2007-09-11 13:57     ` Scott Wood
2007-09-11 15:48       ` Kumar Gala
2007-09-11 15:51         ` Scott Wood
2007-09-11 16:22           ` Kumar Gala
2007-09-11 16:24             ` Scott Wood
2007-09-11 16:45               ` SOC registers/immr determination from device tree (was Re: [PATCH 1/3] fsl_soc.c cleanup) Kumar Gala
2007-09-11 17:03                 ` Scott Wood
2007-09-11 17:08                   ` Josh Boyer
2007-09-11 17:54                   ` Kumar Gala
2007-08-28 20:16 ` [PATCH 2/3] Introduce new CPM device bindings Scott Wood
2007-08-29  5:39   ` David Gibson
2007-08-29 13:58     ` Scott Wood
2007-08-30  0:55       ` David Gibson
2007-08-30  5:48         ` Scott Wood
2007-08-30  5:58           ` David Gibson
2007-08-30 14:10             ` Scott Wood
2007-08-31  2:48               ` David Gibson
2007-08-28 20:16 ` [PATCH 3/3] Add early debug console for CPM serial ports Scott Wood
2007-08-29  5:45   ` David Gibson
2007-08-29 14:02     ` Scott Wood
2007-08-29 19:58       ` Scott Wood
2007-08-30  0:58         ` David Gibson
2007-08-30  0:57       ` David Gibson
2007-08-28 20:16 ` [PATCH 1/4] ppc: Add clrbits8 and setbits8 Scott Wood
2007-08-28 20:16 ` [PATCH 2/4] cpm_uart: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set Scott Wood
2007-08-28 20:16 ` [PATCH 3/4] cpm_uart: sparse fixes Scott Wood
2007-08-28 20:16 ` [PATCH 4/4] cpm_uart: Issue STOP_TX command before initializing console Scott Wood
2007-08-28 20:17 ` [PATCH 1/9] 8xx: Fix CONFIG_PIN_TLB Scott Wood
2007-08-29 21:09   ` Vitaly Bordug
2007-08-28 20:17 ` [PATCH 2/9] 8xx: Infrastructure code cleanup Scott Wood
2007-09-13  7:11   ` David Gibson
2007-09-13  8:16     ` Vitaly Bordug
2007-09-14  4:09       ` David Gibson
2007-09-14  8:21         ` Vitaly Bordug
2007-09-15  2:25           ` David Gibson
2007-09-13 14:40     ` Scott Wood
2007-08-28 20:17 ` [PATCH 3/9] 8xx: Add pin and clock setting functions Scott Wood
2007-08-29 21:38   ` Vitaly Bordug
2007-08-31 20:44     ` Scott Wood
2007-09-05  7:39       ` Vitaly Bordug
2007-09-05 17:37         ` Scott Wood
2007-08-28 20:17 ` [PATCH 4/9] 8xx: Work around CPU15 erratum Scott Wood
2007-08-28 20:17 ` [PATCH 5/9] 8xx: Don't call non-existent Soft_emulate_8xx from SoftwareEmulation Scott Wood
2007-08-28 20:17 ` [PATCH 6/9] 8xx: Set initial memory limit John Traill
2007-08-28 20:19 ` Scott Wood
2007-08-28 20:19 ` [PATCH 7/9] 8xx: mpc885ads cleanup Scott Wood
2007-08-29 22:03   ` Vitaly Bordug
2007-08-28 20:19 ` [PATCH 8/9] 8xx: Embedded Planet EP88xC support Scott Wood
2007-08-28 20:19 ` [PATCH 9/9] 8xx: Adder 875 support Scott Wood
2007-08-28 20:19 ` [PATCH 1/9] cpm2: Infrastructure code cleanup Scott Wood
2007-08-28 20:19 ` [PATCH 2/9] cpm2: Fix off-by-one error in setbrg() Scott Wood
2007-08-29 22:09   ` Vitaly Bordug
2007-08-30 20:13     ` Scott Wood
2007-08-30 21:52       ` Vitaly Bordug
2007-08-28 20:19 ` [PATCH 3/9] cpm2: Add SCCs to cpm2_clk_setup(), and cpm2_smc_clk_setup() Scott Wood
2007-08-29 22:25   ` Vitaly Bordug
2007-08-30 20:15     ` Scott Wood
2007-09-04 20:43       ` Vitaly Bordug
2007-08-28 20:19 ` [PATCH 4/9] cpm2: Add cpm2_set_pin() Scott Wood
2007-09-04 20:51   ` Vitaly Bordug
2007-08-28 20:19 ` [PATCH 5/9] mpc82xx: Remove a bunch of cruft that duplicates generic functionality Scott Wood
2007-08-28 20:19 ` [PATCH 6/9] mpc82xx: Rename mpc82xx_ads to mpc8272_ads Scott Wood
2007-08-29  5:55   ` David Gibson
2007-08-28 20:19 ` [PATCH 7/9] mpc8272ads: Change references from 82xx_ADS to 8272_ADS Scott Wood
2007-08-28 20:19 ` [PATCH 8/9] mpc82xx: Update mpc8272ads, and factor out PCI and reset Scott Wood
2007-08-29 22:41   ` Kumar Gala
2007-08-30  5:56     ` Scott Wood
2007-08-30 14:56       ` Kumar Gala
2007-08-30 15:17         ` Scott Wood
2007-08-28 20:19 ` [PATCH 9/9] mpc82xx: Add pq2fads board support Scott Wood

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.