public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* RFC PATCH
@ 2007-05-29 12:02 Felipe Balbi
  2007-05-29 12:02 ` [PATCH] USB: Disable file_storage USB_CONFIG_ATT_WAKEUP Felipe Balbi
  0 siblings, 1 reply; 20+ messages in thread
From: Felipe Balbi @ 2007-05-29 12:02 UTC (permalink / raw)
  To: linux-omap-open-source

The following patch series is a work in progress and we have a lot to fix.
But still, it fixes some issues and implement some nice features.

TODO:
SRP should be automatic
Vbus should be turned off if we're not using the bus.
mdelay() should be fixed
0008-*.diff shouldn't be applied is just a way to run the HSET tests from linux
0010-*.diff leave GPIO[7:6] pullups enabled as they're the default wake-up source for tusb6010
            Without this patch we can't turn on Vbus if there's any load between Vbus and GND

I think that's all. Hope anyone can test/comment on this patch series.



felipebalbi@users.sourceforge.net

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

* [PATCH] USB: Disable file_storage USB_CONFIG_ATT_WAKEUP
  2007-05-29 12:02 RFC PATCH Felipe Balbi
@ 2007-05-29 12:02 ` Felipe Balbi
  2007-05-29 12:02   ` [PATCH] musb_hdrc: Implement workaround for tusb3.0 wbus bug rev2 Felipe Balbi
  0 siblings, 1 reply; 20+ messages in thread
From: Felipe Balbi @ 2007-05-29 12:02 UTC (permalink / raw)
  To: linux-omap-open-source

From: Tony Lindgren <tony@atomide.com>

Disable file_storage USB_CONFIG_ATT_WAKEUP as it requires
user interaction during Chapter 9 tests.

Signed-off-by: Tony Lindgren <tony@atomide.com
Signed-off-by: Felipe Balbi <felipe.lima@indt.org.br>
---

diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index c6b6479..de85c8b 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -3965,8 +3965,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 #endif
 
 	if (gadget->is_otg) {
-		otg_desc.bmAttributes |= USB_OTG_HNP,
-		config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+		otg_desc.bmAttributes |= USB_OTG_HNP;
 	}
 
 	rc = -ENOMEM;
-- 
1.5.2.rc3.39.gaf9b

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

* [PATCH] musb_hdrc: Implement workaround for tusb3.0 wbus bug rev2
  2007-05-29 12:02 ` [PATCH] USB: Disable file_storage USB_CONFIG_ATT_WAKEUP Felipe Balbi
@ 2007-05-29 12:02   ` Felipe Balbi
  2007-05-29 12:02     ` [PATCH] musb_hdrc: Add SRP Interface and control it through sysfs Felipe Balbi
  0 siblings, 1 reply; 20+ messages in thread
From: Felipe Balbi @ 2007-05-29 12:02 UTC (permalink / raw)
  To: linux-omap-open-source

From: Tony Lindgren <tony@atomide.com>

Without this workaround tusb3.0 will wake-up spontaneously
on USB suspend.

Patch also moves revision functions to the top of the file.

Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Felipe Balbi <felipe.lima@indt.org.br>
---

Index: linux-omap-2.6/drivers/usb/musb/tusb6010.c
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/tusb6010.c	2007-05-25 14:12:31.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/tusb6010.c	2007-05-25 14:12:34.000000000 +0300
@@ -25,6 +25,67 @@
 
 #include "musbdefs.h"
 
+/*
+ * Checks the revision. We need to use the DMA register as 3.0 does not
+ * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV.
+ */
+static u8 tusb_get_revision(struct musb *musb)
+{
+	void __iomem	*base = musb->ctrl_base;
+
+	return musb_readl(base, TUSB_DMA_CTRL_REV) & 0xff;
+}
+
+#define TUSB_REV_MAJOR(reg_val)		((reg_val >> 4) & 0xf)
+#define TUSB_REV_MINOR(reg_val)		(reg_val & 0xf)
+
+static int __init tusb_print_revision(struct musb *musb)
+{
+	void __iomem	*base = musb->ctrl_base;
+
+	pr_info("tusb: Revisions: %s%i.%i %s%i.%i %s%i.%i %s%i.%i\n",
+		"prcm",
+		TUSB_REV_MAJOR(musb_readl(base, TUSB_PRCM_REV)),
+		TUSB_REV_MINOR(musb_readl(base, TUSB_PRCM_REV)),
+		"int",
+		TUSB_REV_MAJOR(musb_readl(base, TUSB_INT_CTRL_REV)),
+		TUSB_REV_MINOR(musb_readl(base, TUSB_INT_CTRL_REV)),
+		"gpio",
+		TUSB_REV_MAJOR(musb_readl(base, TUSB_GPIO_REV)),
+		TUSB_REV_MINOR(musb_readl(base, TUSB_GPIO_REV)),
+		"dma",
+		TUSB_REV_MAJOR(musb_readl(base, TUSB_DMA_CTRL_REV)),
+		TUSB_REV_MINOR(musb_readl(base, TUSB_DMA_CTRL_REV)));
+
+	return TUSB_REV_MAJOR(musb_readl(base, TUSB_INT_CTRL_REV));
+}
+
+static void tusb_wbus_quirk(struct musb *musb, int enabled)
+{
+	void __iomem	*base = musb->ctrl_base;
+	static u32	phy_otg_ctrl = 0;
+
+	if (enabled) {
+		DBG(2, "Enabling tusb wbus quirk\n");
+		musb_writel(base, TUSB_PHY_OTG_CTRL_ENABLE,
+				TUSB_PHY_OTG_CTRL_WRPROTECT |
+				TUSB_PHY_OTG_CTRL_TESTM2 |
+				TUSB_PHY_OTG_CTRL_TESTM1 |
+				TUSB_PHY_OTG_CTRL_TESTM0);
+		phy_otg_ctrl = musb_readl(base, TUSB_PHY_OTG_CTRL);
+		musb_writel(base, TUSB_PHY_OTG_CTRL,
+				TUSB_PHY_OTG_CTRL_WRPROTECT |
+				TUSB_PHY_OTG_CTRL_TESTM2);
+	} else if (musb_readl(base, TUSB_PHY_OTG_CTRL_ENABLE)
+			& TUSB_PHY_OTG_CTRL_TESTM2) {
+		DBG(3, "Disabling tusb wbus quirk\n");
+		musb_writel(base, TUSB_PHY_OTG_CTRL,
+			TUSB_PHY_OTG_CTRL_WRPROTECT | phy_otg_ctrl);
+		musb_writel(base, TUSB_PHY_OTG_CTRL_ENABLE,
+			TUSB_PHY_OTG_CTRL_WRPROTECT);
+		phy_otg_ctrl = 0;
+	}
+}
 
 /*
  * TUSB 6010 may use a parallel bus that doesn't support byte ops;
@@ -253,6 +314,11 @@
 	void __iomem	*base = musb->ctrl_base;
 	u32		reg;
 
+	if ((wakeup_enables & TUSB_PRCM_WBUS)
+			&& musb_platform_get_vbus_status(musb)
+			&& (tusb_get_revision(musb) == TUSB_REV_30))
+		tusb_wbus_quirk(musb, 1);
+
 	tusb_set_clock_source(musb, 0);
 
 	wakeup_enables |= TUSB_PRCM_WNORCS;
@@ -302,7 +368,7 @@
 		musb_writel(base, TUSB_PRCM_MNGMT, prcm_mngmt);
 	}
 
-	if (otg_stat & TUSB_DEV_OTG_STAT_VBUS_SENSE)
+	if (otg_stat & TUSB_DEV_OTG_STAT_VBUS_VALID)
 		ret = 1;
 
 	return ret;
@@ -651,6 +717,9 @@
 		u32	reg;
 		u32	i;
 
+		if (tusb_get_revision(musb) == TUSB_REV_30)
+			tusb_wbus_quirk(musb, 0);
+
 		/* there are issues re-locking the PLL on wakeup ... */
 
 		/* work around issue 8 */
@@ -829,30 +898,6 @@
 	musb_writel(base, TUSB_WAIT_COUNT, 1);
 }
 
-#define TUSB_REV_MAJOR(reg_val)		((reg_val >> 4) & 0xf)
-#define TUSB_REV_MINOR(reg_val)		(reg_val & 0xf)
-
-static int __init tusb_print_revision(struct musb *musb)
-{
-	void __iomem	*base = musb->ctrl_base;
-
-	pr_info("tusb: Revisions: %s%i.%i %s%i.%i %s%i.%i %s%i.%i\n",
-		"prcm",
-		TUSB_REV_MAJOR(musb_readl(base, TUSB_PRCM_REV)),
-		TUSB_REV_MINOR(musb_readl(base, TUSB_PRCM_REV)),
-		"int",
-		TUSB_REV_MAJOR(musb_readl(base, TUSB_INT_CTRL_REV)),
-		TUSB_REV_MINOR(musb_readl(base, TUSB_INT_CTRL_REV)),
-		"gpio",
-		TUSB_REV_MAJOR(musb_readl(base, TUSB_GPIO_REV)),
-		TUSB_REV_MINOR(musb_readl(base, TUSB_GPIO_REV)),
-		"dma",
-		TUSB_REV_MAJOR(musb_readl(base, TUSB_DMA_CTRL_REV)),
-		TUSB_REV_MINOR(musb_readl(base, TUSB_DMA_CTRL_REV)));
-
-	return TUSB_REV_MAJOR(musb_readl(base, TUSB_INT_CTRL_REV));
-}
-
 static int __init tusb_start(struct musb *musb)
 {
 	void __iomem	*base = musb->ctrl_base;
Index: linux-omap-2.6/drivers/usb/musb/tusb6010.h
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/tusb6010.h	2007-05-25 14:12:31.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/tusb6010.h	2007-05-25 14:12:34.000000000 +0300
@@ -216,6 +216,10 @@
 #define TUSB_PROD_TEST_RESET_VAL		0xa596
 #define TUSB_EP_FIFO(ep)			(TUSB_FIFO_BASE + (ep) * 0x20)
 
+#define TUSB_REV_1	0x10
+#define TUSB_REV_2	0x20
+#define TUSB_REV_30	0x30
+
 /*----------------------------------------------------------------------------*/
 
 #ifdef CONFIG_USB_TUSB6010

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

* [PATCH] musb_hdrc: Add SRP Interface and control it through sysfs
  2007-05-29 12:02   ` [PATCH] musb_hdrc: Implement workaround for tusb3.0 wbus bug rev2 Felipe Balbi
@ 2007-05-29 12:02     ` Felipe Balbi
  2007-05-29 12:02       ` [PATCH] Add Sysfs Interface to Control Vbus states Felipe Balbi
  2007-05-29 17:07       ` [PATCH] musb_hdrc: Add SRP Interface and control it through sysfs David Brownell
  0 siblings, 2 replies; 20+ messages in thread
From: Felipe Balbi @ 2007-05-29 12:02 UTC (permalink / raw)
  To: linux-omap-open-source

From: Felipe Balbi <felipe.lima@indt.org.br>

	This patch adds a method to start SRP and a userspace
	interface to control it through sysfs.

Signed-off-by: Felipe Balbi <felipe.lima@indt.org.br>
---

Index: linux-omap-2.6/drivers/usb/musb/musb_gadget.c
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/musb_gadget.c	2007-05-28 01:40:16.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/musb_gadget.c	2007-05-28 13:18:47.000000000 +0300
@@ -2056,3 +2056,29 @@
 	(void) musb_gadget_vbus_draw(&musb->g,
 			is_otg_enabled(musb) ? 8 : 100);
 }
+
+/* called when we want to send a Session Request. Caller must hold the lock */
+void musb_g_srp(struct musb *musb)
+{
+	void __iomem	*base = musb->pRegs;
+	u8	devctl = musb_readb(base, MGC_O_HDRC_DEVCTL);
+
+	DBG(3, "Starting SRP\n");
+
+	musb_writeb(base, MGC_O_HDRC_DEVCTL, devctl | MGC_M_DEVCTL_BDEVICE);
+
+	/* In order to start SRP we need to ensure that Vbus is below the
+	 * Session Valid Threshold.
+	 * On MUSB this means that  MGC_M_DEVCTL_VBUS and MGC_S_DEVCTL_VBUS
+	 * are set to 00.
+	 */
+	devctl &= MGC_M_DEVCTL_VBUS & MGC_S_DEVCTL_VBUS;
+
+	if (!devctl) {
+		devctl = musb_readb(base, MGC_O_HDRC_DEVCTL);
+		devctl |= MGC_M_DEVCTL_SESSION | MGC_M_DEVCTL_BDEVICE;
+
+		musb_writeb(base, MGC_O_HDRC_DEVCTL, devctl);
+	} else
+		DBG(7, "Cannot Start SRP: devctl = %02x\n" , devctl);
+}
Index: linux-omap-2.6/drivers/usb/musb/musbdefs.h
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/musbdefs.h	2007-05-28 01:40:16.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/musbdefs.h	2007-05-28 13:18:47.000000000 +0300
@@ -124,6 +124,7 @@
 extern void musb_g_reset(struct musb *);
 extern void musb_g_suspend(struct musb *);
 extern void musb_g_resume(struct musb *);
+extern void musb_g_srp(struct musb *);
 extern void musb_g_disconnect(struct musb *);
 
 #else
@@ -134,6 +135,7 @@
 static inline void musb_g_reset(struct musb *m) {}
 static inline void musb_g_suspend(struct musb *m) {}
 static inline void musb_g_resume(struct musb *m) {}
+static inline void musb_g_srp(struct musb *m) {}
 static inline void musb_g_disconnect(struct musb *m) {}
 
 #endif
Index: linux-omap-2.6/drivers/usb/musb/plat_uds.c
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/plat_uds.c	2007-05-28 01:40:16.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/plat_uds.c	2007-05-28 13:18:47.000000000 +0300
@@ -1579,6 +1579,32 @@
 }
 static DEVICE_ATTR(cable, S_IRUGO, musb_cable_show, NULL);
 
+#ifdef CONFIG_USB_MUSB_OTG
+static ssize_t
+musb_srp_store(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t n)
+{
+	struct musb	*musb=dev_to_musb(dev);
+	unsigned long	flags;
+	unsigned short	srp;
+
+	if (sscanf(buf, "%hu", &srp) != 1
+			|| (srp != 1)) {
+		printk (KERN_ERR "SRP: Value must be 1\n");
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&musb->Lock, flags);
+	if (srp == 1){
+		musb_g_srp(musb);
+	}
+	spin_unlock_irqrestore(&musb->Lock, flags);
+
+	return n;
+}
+static DEVICE_ATTR(srp, 0644, NULL, musb_srp_store);
+#endif /* CONFIG_USB_MUSB_OTG */
+
 #endif
 
 /* Only used to provide cable state change events */
@@ -1648,6 +1674,9 @@
 #ifdef CONFIG_SYSFS
 	device_remove_file(musb->controller, &dev_attr_mode);
 	device_remove_file(musb->controller, &dev_attr_cable);
+#ifdef CONFIG_USB_MUSB_OTG
+	device_remove_file(musb->controller, &dev_attr_srp);
+#endif
 #endif
 
 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
@@ -1876,6 +1905,9 @@
 #ifdef CONFIG_SYSFS
 	status = device_create_file(dev, &dev_attr_mode);
 	status = device_create_file(dev, &dev_attr_cable);
+#ifdef CONFIG_USB_MUSB_OTG
+	status = device_create_file(dev, &dev_attr_srp);
+#endif /* CONFIG_USB_MUSB_OTG */
 	status = 0;
 #endif
 

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

* [PATCH] Add Sysfs Interface to Control Vbus states
  2007-05-29 12:02     ` [PATCH] musb_hdrc: Add SRP Interface and control it through sysfs Felipe Balbi
@ 2007-05-29 12:02       ` Felipe Balbi
  2007-05-29 12:02         ` [PATCH] Add more Test Modes Felipe Balbi
  2007-05-29 17:07       ` [PATCH] musb_hdrc: Add SRP Interface and control it through sysfs David Brownell
  1 sibling, 1 reply; 20+ messages in thread
From: Felipe Balbi @ 2007-05-29 12:02 UTC (permalink / raw)
  To: linux-omap-open-source

From: Felipe Balbi <felipe.lima@indt.org.br>

	We need to control Vbus in order to save power and
	let us test SRP features.
	This sysfs interface provides an easy way to control
	the Vbus states.

	HowTo use it:
	echo off > /sys/devices/platform/musb_hdrc/vbus
		or
	echo on > /sys/devices/platform/musb_hdrc/vbus

	Later improvements:
	* Check current Vbus state before setting new state.
	* Implement MUSB PM features and shutdown Vbus whenever we're
	  not using the Bus.

Signed-off-by: Felipe Balbi <felipe.lima@indt.org.br>
---

Index: linux-omap-2.6/drivers/usb/musb/plat_uds.c
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/plat_uds.c	2007-05-28 13:18:47.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/plat_uds.c	2007-05-28 13:18:52.000000000 +0300
@@ -1579,6 +1579,78 @@
 }
 static DEVICE_ATTR(cable, S_IRUGO, musb_cable_show, NULL);
 
+static ssize_t
+musb_vbus_store(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t n)
+{
+	struct musb	*musb = dev_to_musb(dev);
+	unsigned long	flags;
+	u8		devctl;
+
+	/* REVISIT the correct way to do it would be checking if we're
+	 * the Standard A device. B devices do not provide Vbus.
+	 */
+	spin_lock_irqsave(&musb->Lock, flags);
+	devctl = musb_readb(musb->pRegs, MGC_O_HDRC_DEVCTL);
+	if (!strncmp(buf, "on", 2)) {
+		u8 power = musb_readb(musb->pRegs, MGC_O_HDRC_POWER);
+
+		musb->xceiv.default_a = 1;
+		devctl |= MGC_M_DEVCTL_SESSION;
+		musb_writeb(musb->pRegs, MGC_O_HDRC_DEVCTL, devctl);
+		musb_set_vbus(musb, 1);
+
+		/* After turning on Vbus we need to generate a reset signal
+		 * on the bus. The following code treats this
+		 */
+		power &= 0xf0;
+		musb_writeb(musb->pRegs, MGC_O_HDRC_POWER,
+				power | MGC_M_POWER_RESET);
+		musb->port1_status |= USB_PORT_STAT_RESET;
+		musb->port1_status &= ~USB_PORT_STAT_ENABLE;
+		musb->rh_timer = jiffies + msecs_to_jiffies(20);
+
+		/* REVISIT after sending the reset signal during 20msecs
+		 * we need to clear the RESET bit in the power register
+		 */
+		if (time_after(jiffies, musb->rh_timer))
+			musb_writeb(musb->pRegs, MGC_O_HDRC_POWER,
+					power & ~MGC_M_POWER_RESET);
+
+	}
+	if (!strncmp(buf, "off", 3)) {
+		devctl |= ~MGC_M_DEVCTL_SESSION;
+		musb_writeb(musb->pRegs, MGC_O_HDRC_DEVCTL, devctl);
+		musb_set_vbus(musb, 0);
+	}
+	/* REVIST when shutting down Vbus we should enter A_IDLE state and not
+	 * B_IDLE. Check tusb_source_power() definition
+	 */
+	spin_unlock_irqrestore(&musb->Lock, flags);
+
+	return n;
+}
+
+static ssize_t
+musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct musb	*musb = dev_to_musb(dev);
+	unsigned long	flags;
+	int		vbus;
+	char		*ret;
+
+	spin_lock_irqsave(&musb->Lock, flags);
+	vbus = musb_platform_get_vbus_status(musb);
+	if (vbus)
+		ret = "Vbus on";
+	else
+		ret = "Vbus off";
+	spin_unlock_irqrestore(&musb->Lock, flags);
+
+	return sprintf(buf, "%s\n", ret);
+}
+static DEVICE_ATTR(vbus, 0644, musb_vbus_show, musb_vbus_store);
+
 #ifdef CONFIG_USB_MUSB_OTG
 static ssize_t
 musb_srp_store(struct device *dev, struct device_attribute *attr,
@@ -1674,6 +1746,7 @@
 #ifdef CONFIG_SYSFS
 	device_remove_file(musb->controller, &dev_attr_mode);
 	device_remove_file(musb->controller, &dev_attr_cable);
+	device_remove_file(musb->controller, &dev_attr_vbus);
 #ifdef CONFIG_USB_MUSB_OTG
 	device_remove_file(musb->controller, &dev_attr_srp);
 #endif
@@ -1905,6 +1978,7 @@
 #ifdef CONFIG_SYSFS
 	status = device_create_file(dev, &dev_attr_mode);
 	status = device_create_file(dev, &dev_attr_cable);
+	status = device_create_file(dev, &dev_attr_vbus);
 #ifdef CONFIG_USB_MUSB_OTG
 	status = device_create_file(dev, &dev_attr_srp);
 #endif /* CONFIG_USB_MUSB_OTG */

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

* [PATCH] Add more Test Modes
  2007-05-29 12:02       ` [PATCH] Add Sysfs Interface to Control Vbus states Felipe Balbi
@ 2007-05-29 12:02         ` Felipe Balbi
  2007-05-29 12:02           ` [PATCH] musb_hdrc: Make HNP work Felipe Balbi
  2007-05-29 17:16           ` [PATCH] Add more Test Modes David Brownell
  0 siblings, 2 replies; 20+ messages in thread
From: Felipe Balbi @ 2007-05-29 12:02 UTC (permalink / raw)
  To: linux-omap-open-source

From: Felipe Balbi <felipe.lima@indt.org.br>

	This patch adds missing TestMode to MUSB driver.
	Needed to run USB Certification Tests.

Signed-off-by: Felipe Balbi <felipe.lima@indt.org.br>
---

diff --git a/drivers/usb/musb/virthub.c b/drivers/usb/musb/virthub.c
index 6a65f4f..b86f034 100644
--- a/drivers/usb/musb/virthub.c
+++ b/drivers/usb/musb/virthub.c
@@ -362,7 +362,11 @@ int musb_hub_control(
 				temp = MGC_M_TEST_FORCE_HOST
 					| MGC_M_TEST_FORCE_HS;
 
-				/* FIXME and enable a session too */
+				musb_writeb(musb->pRegs, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION);
+				break;
+			case 6:
+				pr_debug("TEST_FIFO_ACCESS\n");
+				temp = MGC_M_TEST_FIFO_ACCESS;
 				break;
 			default:
 				goto error;
-- 
1.5.2.rc3.39.gaf9b

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

* [PATCH] musb_hdrc: Make HNP work
  2007-05-29 12:02         ` [PATCH] Add more Test Modes Felipe Balbi
@ 2007-05-29 12:02           ` Felipe Balbi
  2007-05-29 12:02             ` [PATCH] USB: Fix OTG HNP for hub.c Felipe Balbi
  2007-05-29 17:16           ` [PATCH] Add more Test Modes David Brownell
  1 sibling, 1 reply; 20+ messages in thread
From: Felipe Balbi @ 2007-05-29 12:02 UTC (permalink / raw)
  To: linux-omap-open-source

From: Tony Lindgren <tony@atomide.com>

This patch makes Host Negotiation Protocol (HNP) mostly work.
To enable HNP to turn B-device into B-host, do:

# echo 1 > /sys/devices/platform/musb_hdrc/hnp

To disable B-host:

# echo 0 > /sys/devices/platform/musb_hdrc/hnp

Currently you probably need to replug the B-device
after stopping HNP to have it detected.

Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Felipe Balbi <felipe.lima@indt.org.br>
---

Index: linux-omap-2.6/drivers/usb/musb/g_ep0.c
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/g_ep0.c	2007-05-28 01:39:42.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/g_ep0.c	2007-05-28 13:18:58.000000000 +0300
@@ -201,6 +201,21 @@
 }
 
 /*
+ * Tries to start B-device HNP negotiation if enabled via sysfs
+ */
+static inline void musb_try_b_hnp_enable(struct musb *musb)
+{
+	void __iomem	*pBase = musb->pRegs;
+	u8		devctl;
+
+	if (musb->is_hnp_enabled) {
+		DBG(1, "HNP: Setting HR\n");
+		devctl = musb_readb(pBase, MGC_O_HDRC_DEVCTL);
+		musb_writeb(pBase, MGC_O_HDRC_DEVCTL, devctl | MGC_M_DEVCTL_HR);
+	}
+}
+
+/*
  * Handle all control requests with no DATA stage, including standard
  * requests such as:
  * USB_REQ_SET_CONFIGURATION, USB_REQ_SET_INTERFACE, unrecognized
@@ -326,17 +341,8 @@
 				case USB_DEVICE_B_HNP_ENABLE:
 					if (!musb->g.is_otg)
 						goto stall;
-					{ u8 devctl;
 					musb->g.b_hnp_enable = 1;
-					devctl = musb_readb(pBase,
-							MGC_O_HDRC_DEVCTL);
-					/* NOTE:  at least DaVinci doesn't
-					 * like to set HR ...
-					 */
-					DBG(1, "set HR\n");
-					musb_writeb(pBase, MGC_O_HDRC_DEVCTL,
-						devctl | MGC_M_DEVCTL_HR);
-					}
+					musb_try_b_hnp_enable(musb);
 					break;
 				case USB_DEVICE_A_HNP_SUPPORT:
 					if (!musb->g.is_otg)
Index: linux-omap-2.6/drivers/usb/musb/musb_gadget.c
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/musb_gadget.c	2007-05-28 13:18:47.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/musb_gadget.c	2007-05-28 13:18:58.000000000 +0300
@@ -1872,6 +1872,11 @@
 	 */
 
 	spin_lock_irqsave(&musb->Lock, flags);
+
+#ifdef	CONFIG_USB_MUSB_OTG
+	musb_hnp_stop(musb);
+#endif
+
 	if (musb->pGadgetDriver == driver) {
 		musb->xceiv.state = OTG_STATE_UNDEFINED;
 		stop_activity(musb, driver);
@@ -1984,6 +1989,9 @@
 #ifdef	CONFIG_USB_MUSB_OTG
 		musb->xceiv.state = OTG_STATE_A_IDLE;
 		break;
+	case OTG_STATE_A_PERIPHERAL:
+		musb->xceiv.state = OTG_STATE_A_WAIT_VFALL;
+		break;
 	case OTG_STATE_B_WAIT_ACON:
 	case OTG_STATE_B_HOST:
 #endif
Index: linux-omap-2.6/drivers/usb/musb/musbdefs.h
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/musbdefs.h	2007-05-28 13:18:47.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/musbdefs.h	2007-05-28 13:18:58.000000000 +0300
@@ -469,6 +469,8 @@
 #ifdef CONFIG_USB_MUSB_OTG
 	/* FIXME this can't be OTG-specific ... ? */
 	u8 bDelayPortPowerOff;
+
+	unsigned		is_hnp_enabled:1;
 #endif
 
 #ifdef MUSB_CONFIG_PROC_FS
@@ -508,6 +510,8 @@
 extern void musb_platform_enable(struct musb *musb);
 extern void musb_platform_disable(struct musb *musb);
 
+extern void musb_hnp_stop(struct musb *musb);
+
 #ifdef CONFIG_USB_TUSB6010
 extern void musb_platform_try_idle(struct musb *musb);
 extern int musb_platform_get_vbus_status(struct musb *musb);
Index: linux-omap-2.6/drivers/usb/musb/plat_uds.c
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/plat_uds.c	2007-05-28 13:18:52.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/plat_uds.c	2007-05-28 13:18:58.000000000 +0300
@@ -281,6 +281,70 @@
 
 /*-------------------------------------------------------------------------*/
 
+#ifdef	CONFIG_USB_MUSB_OTG
+
+/*
+ * See also USB_OTG_1-3.pdf 6.6.5 Timers
+ * REVISIT: Are the other timers done in the hardware?
+ */
+#define TB_ASE0_BRST		100	/* Min 3.125 ms */
+
+/*
+ * Handles OTG hnp timeouts, such ad b_ase0_brst
+ */
+void musb_otg_timer_func(unsigned long data)
+{
+	struct musb	*musb = (struct musb *)data;
+	void __iomem	*pBase = musb->pRegs;
+	unsigned long	flags;
+	u8		devctl;
+
+	spin_lock_irqsave(&musb->Lock, flags);
+	if (musb->xceiv.state == OTG_STATE_B_WAIT_ACON) {
+		DBG(1, "HNP: B_WAIT_ACON timeout, going back to B_PERIPHERAL\n");
+		devctl = musb_readb(pBase, MGC_O_HDRC_DEVCTL);
+		musb_writeb(pBase, MGC_O_HDRC_DEVCTL, devctl & ~MGC_M_DEVCTL_HR);
+		musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
+	}
+	spin_unlock_irqrestore(&musb->Lock, flags);
+}
+
+static DEFINE_TIMER(musb_otg_timer, musb_otg_timer_func, 0, 0);
+
+/*
+ * Stops the B-device HNP state. Caller must take care of locking.
+ */
+void musb_hnp_stop(struct musb *musb)
+{
+	struct usb_hcd	*hcd = musb_to_hcd(musb);
+	void __iomem	*pBase = musb->pRegs;
+	u8	reg;
+
+	switch (musb->xceiv.state) {
+	case OTG_STATE_A_PERIPHERAL:
+	case OTG_STATE_A_WAIT_VFALL:
+		DBG(1, "HNP: Switching back to A-host\n");
+		musb_g_disconnect(musb);
+		musb->xceiv.state = OTG_STATE_B_IDLE;
+		/* REVISIT: Reset session here? Or wait for SESSION_REQUEST? */
+		break;
+	case OTG_STATE_B_HOST:
+		DBG(1, "HNP: Disabling HR\n");
+		hcd->self.is_b_host = 0;
+		musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
+		reg = musb_readb(pBase, MGC_O_HDRC_POWER);
+		reg |= MGC_M_POWER_SUSPENDM;
+		musb_writeb(pBase, MGC_O_HDRC_POWER, reg);
+		/* REVISIT: Start SESSION_REQUEST here? */
+		break;
+	default:
+		DBG(1, "HNP: Stopping in unknown state %s\n",
+			otg_state_string(musb));
+	}
+}
+
+#endif
+
 /*
  * Interrupt Service Routine to record USB "global" interrupts.
  * Since these do not happen often and signify things of
@@ -519,12 +583,16 @@
 		/* indicate new connection to OTG machine */
 		switch (pThis->xceiv.state) {
 		case OTG_STATE_B_WAIT_ACON:
+			DBG(1, "HNP: Waiting to switch to b_host state\n");
 			pThis->xceiv.state = OTG_STATE_B_HOST;
+			hcd->self.is_b_host = 1;
 			break;
 		default:
 			if ((devctl & MGC_M_DEVCTL_VBUS)
-					== (3 << MGC_S_DEVCTL_VBUS))
+					== (3 << MGC_S_DEVCTL_VBUS)) {
 				pThis->xceiv.state = OTG_STATE_A_HOST;
+				hcd->self.is_b_host = 0;
+			}
 			break;
 		}
 		DBG(1, "CONNECT (%s) devctl %02x\n",
@@ -631,8 +699,10 @@
 			break;
 #endif	/* HOST */
 #ifdef CONFIG_USB_MUSB_OTG
-		case OTG_STATE_A_PERIPHERAL:
 		case OTG_STATE_B_HOST:
+			musb_hnp_stop(pThis);
+			/* FALLTHROUGH */
+		case OTG_STATE_A_PERIPHERAL:
 			musb_root_disconnect(pThis);
 			/* FALLTHROUGH */
 		case OTG_STATE_B_WAIT_ACON:
@@ -657,13 +727,25 @@
 		handled = IRQ_HANDLED;
 
 		switch (pThis->xceiv.state) {
+		case OTG_STATE_A_PERIPHERAL:
+			musb_hnp_stop(pThis);
+			break;
 		case OTG_STATE_B_PERIPHERAL:
 			musb_g_suspend(pThis);
 			pThis->is_active = is_otg_enabled(pThis)
 					&& pThis->xceiv.gadget->b_hnp_enable;
 			if (pThis->is_active) {
 				pThis->xceiv.state = OTG_STATE_B_WAIT_ACON;
-				/* REVISIT timeout for b_ase0_brst, etc */
+#ifdef	CONFIG_USB_MUSB_OTG
+				/* Handle timeout for b_ase0_brst */
+				if (pThis->is_hnp_enabled == 0)
+					break;
+				DBG(1, "HNP: Setting timer for b_ase0_brst\n");
+				musb_otg_timer.data = (unsigned long)pThis;
+				musb_otg_timer.expires =
+					jiffies + msecs_to_jiffies(TB_ASE0_BRST);
+				add_timer(&musb_otg_timer);
+#endif
 			}
 			break;
 		case OTG_STATE_A_HOST:
@@ -671,6 +753,16 @@
 			pThis->is_active = is_otg_enabled(pThis)
 					&& pThis->xceiv.host->b_hnp_enable;
 			break;
+#if 0
+		case OTG_STATE_A_PERIPHERAL:
+			/* Transition to a_wait_vfall, see 6.8.1.6 p 41 */
+			DBG(1, "REVISIT: SUSPEND as A_PERIPHERAL\n");
+			break;
+#endif
+		case OTG_STATE_B_HOST:
+			/* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */
+			DBG(1, "REVISIT: SUSPEND as B_HOST\n");
+			break;
 		default:
 			/* "should not happen" */
 			pThis->is_active = 0;
@@ -1497,17 +1589,7 @@
 	int ret = -EINVAL;
 
 	spin_lock_irqsave(&musb->Lock, flags);
-	switch (musb->board_mode) {
-	case MUSB_HOST:
-		ret = sprintf(buf, "host\n");
-		break;
-	case MUSB_PERIPHERAL:
-		ret = sprintf(buf, "peripheral\n");
-		break;
-	case MUSB_OTG:
-		ret = sprintf(buf, "otg\n");
-		break;
-	}
+	ret = sprintf(buf, "%s\n", otg_state_string(musb));
 	spin_unlock_irqrestore(&musb->Lock, flags);
 
 	return ret;
@@ -1533,6 +1615,8 @@
 }
 static DEVICE_ATTR(mode, 0644, musb_mode_show, musb_mode_store);
 
+
+
 static ssize_t
 musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -1653,6 +1737,47 @@
 
 #ifdef CONFIG_USB_MUSB_OTG
 static ssize_t
+musb_hnp_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct musb *musb = dev_to_musb(dev);
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	spin_lock_irqsave(&musb->Lock, flags);
+	if (musb->is_hnp_enabled == 0)
+		ret = sprintf(buf, "disabled\n");
+	else
+		ret = sprintf(buf, "enabled\n");
+	spin_unlock_irqrestore(&musb->Lock, flags);
+
+	return ret;
+}
+
+static ssize_t
+musb_hnp_store(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t n)
+{
+	struct musb	*musb = dev_to_musb(dev);
+	unsigned long	flags;
+	unsigned short	val;
+
+	if (sscanf(buf, "%hu", &val) != 1
+			|| (val != 0 && val != 1)) {
+		printk(KERN_ERR "HNP: Value must be 0 or 1\n");
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&musb->Lock, flags);
+	if (val == 0 && musb->is_hnp_enabled != 0)
+		musb_hnp_stop(musb);
+	musb->is_hnp_enabled = val;
+	spin_unlock_irqrestore(&musb->Lock, flags);
+
+	return n;
+}
+static DEVICE_ATTR(hnp, 0644, musb_hnp_show, musb_hnp_store);
+
+static ssize_t
 musb_srp_store(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t n)
 {
@@ -1749,6 +1874,7 @@
 	device_remove_file(musb->controller, &dev_attr_vbus);
 #ifdef CONFIG_USB_MUSB_OTG
 	device_remove_file(musb->controller, &dev_attr_srp);
+	device_remove_file(musb->controller, &dev_attr_hnp);
 #endif
 #endif
 
@@ -1981,6 +2107,7 @@
 	status = device_create_file(dev, &dev_attr_vbus);
 #ifdef CONFIG_USB_MUSB_OTG
 	status = device_create_file(dev, &dev_attr_srp);
+	status = device_create_file(dev, &dev_attr_hnp);
 #endif /* CONFIG_USB_MUSB_OTG */
 	status = 0;
 #endif

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

* [PATCH] USB: Fix OTG HNP for hub.c
  2007-05-29 12:02           ` [PATCH] musb_hdrc: Make HNP work Felipe Balbi
@ 2007-05-29 12:02             ` Felipe Balbi
  2007-05-29 12:02               ` [PATCH] HSET tool for the MUSB Controler Felipe Balbi
  2007-05-29 19:21               ` [PATCH] USB: Fix OTG HNP for hub.c David Brownell
  0 siblings, 2 replies; 20+ messages in thread
From: Felipe Balbi @ 2007-05-29 12:02 UTC (permalink / raw)
  To: linux-omap-open-source

From: Tony Lindgren <tony@atomide.com>

This patch makes makes OTG Host Negotiation Protocol (HNP)
to behave.

Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Felipe Balbi <felipe.lima@indt.org.br>
---

Index: linux-omap-2.6/drivers/usb/core/hub.c
===================================================================
--- linux-omap-2.6.orig/drivers/usb/core/hub.c	2007-05-25 14:12:31.000000000 +0300
+++ linux-omap-2.6/drivers/usb/core/hub.c	2007-05-25 14:17:02.000000000 +0300
@@ -1252,6 +1252,81 @@
 #ifdef	CONFIG_USB_OTG
 #include "otg_whitelist.h"
 static int __usb_port_suspend(struct usb_device *, int port1);
+
+/*
+ * OTG-aware devices on OTG-capable root hubs may be able to use SRP,
+ * to wake us after we've powered off VBUS; and HNP, switching roles
+ * "host" to "peripheral".  The OTG descriptor helps figure this out.
+ */
+static int usb_new_device_offer_hnp(struct usb_device *udev)
+{
+	struct usb_bus			*bus = udev->bus;
+	unsigned			port1 = udev->portnum;
+	struct usb_otg_descriptor	*desc = 0;
+	int				err;
+
+	if (udev->bus->is_b_host || !udev->config
+			|| udev->parent != udev->bus->root_hub)
+		return 0;
+
+	/* Descriptor may appear anywhere in config */
+	err = __usb_get_extra_descriptor(udev->rawdescriptors[0],
+				le16_to_cpu(udev->config[0].desc.wTotalLength),
+				USB_DT_OTG, (void **) &desc);
+	if (err < 0)
+		return 0;
+
+	if (!(desc->bmAttributes & USB_OTG_HNP))
+		return 0;
+
+	dev_info(&udev->dev, "Dual-Role OTG device on %sHNP port\n",
+				(port1 == bus->otg_port) ? "" : "non-");
+
+	/* Tell B-device if we support HNP */
+	if (port1 == bus->otg_port)
+		bus->b_hnp_enable = 1;
+	err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+			USB_REQ_SET_FEATURE, 0,
+			bus->b_hnp_enable ? USB_DEVICE_B_HNP_ENABLE
+			: USB_DEVICE_A_ALT_HNP_SUPPORT,
+			0, NULL, 0, USB_CTRL_SET_TIMEOUT);
+	if (err < 0) {
+		/*
+		 * OTG MESSAGE: report errors here, customize to match your
+		 * product.
+		 */
+		dev_err(&udev->dev, "can't set HNP mode; %d\n", err);
+		bus->b_hnp_enable = 0;
+		return 0;
+	}
+
+	/* If B-device wants to do HNP, it will do it after we suspend */
+	if (bus->b_hnp_enable) {
+		dev_err(&udev->dev, "trying HNP, suspending bus\n");
+		err = __usb_port_suspend(udev, udev->bus->otg_port);
+		if (err < 0) {
+			dev_err(&udev->dev, "suspend for HNP failed\n");
+			return -ENODEV;
+		}
+
+		/* TB_ASE0_BRST, minimum 3.125 ms */
+		mdelay(4);
+
+		/* Failed resume means B-device took over the bus with HNP */
+		err = usb_port_resume(udev);
+		if (err < 0) {
+			dev_err(&udev->dev, "HNP success\n");
+			return -ENODEV;
+		}
+	}
+
+	/* HNP failed. Reject B-devices not in our whitelist */
+	if (!is_targeted(udev))
+		return -ENODEV;
+
+	return 0;
+}
+
 #endif
 
 /**
@@ -1305,63 +1380,8 @@
 	show_string(udev, "SerialNumber", udev->serial);
 
 #ifdef	CONFIG_USB_OTG
-	/*
-	 * OTG-aware devices on OTG-capable root hubs may be able to use SRP,
-	 * to wake us after we've powered off VBUS; and HNP, switching roles
-	 * "host" to "peripheral".  The OTG descriptor helps figure this out.
-	 */
-	if (!udev->bus->is_b_host
-			&& udev->config
-			&& udev->parent == udev->bus->root_hub) {
-		struct usb_otg_descriptor	*desc = 0;
-		struct usb_bus			*bus = udev->bus;
-
-		/* descriptor may appear anywhere in config */
-		if (__usb_get_extra_descriptor (udev->rawdescriptors[0],
-					le16_to_cpu(udev->config[0].desc.wTotalLength),
-					USB_DT_OTG, (void **) &desc) == 0) {
-			if (desc->bmAttributes & USB_OTG_HNP) {
-				unsigned		port1 = udev->portnum;
-
-				dev_info(&udev->dev,
-					"Dual-Role OTG device on %sHNP port\n",
-					(port1 == bus->otg_port)
-						? "" : "non-");
-
-				/* enable HNP before suspend, it's simpler */
-				if (port1 == bus->otg_port)
-					bus->b_hnp_enable = 1;
-				err = usb_control_msg(udev,
-					usb_sndctrlpipe(udev, 0),
-					USB_REQ_SET_FEATURE, 0,
-					bus->b_hnp_enable
-						? USB_DEVICE_B_HNP_ENABLE
-						: USB_DEVICE_A_ALT_HNP_SUPPORT,
-					0, NULL, 0, USB_CTRL_SET_TIMEOUT);
-				if (err < 0) {
-					/* OTG MESSAGE: report errors here,
-					 * customize to match your product.
-					 */
-					dev_info(&udev->dev,
-						"can't set HNP mode; %d\n",
-						err);
-					bus->b_hnp_enable = 0;
-				}
-			}
-		}
-	}
-
-	if (!is_targeted(udev)) {
-
-		/* Maybe it can talk to us, though we can't talk to it.
-		 * (Includes HNP test device.)
-		 */
-		if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
-			err = __usb_port_suspend(udev, udev->bus->otg_port);
-			if (err < 0)
-				dev_dbg(&udev->dev, "HNP fail, %d\n", err);
-		}
-		err = -ENODEV;
+	err = usb_new_device_offer_hnp(udev);
+	if (err < 0) {
 		goto fail;
 	}
 #endif

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

* [PATCH] HSET tool for the MUSB Controler
  2007-05-29 12:02             ` [PATCH] USB: Fix OTG HNP for hub.c Felipe Balbi
@ 2007-05-29 12:02               ` Felipe Balbi
  2007-05-29 12:02                 ` [PATCH] Leave GPIO[7:6] pullups enabled Felipe Balbi
  2007-05-29 19:21               ` [PATCH] USB: Fix OTG HNP for hub.c David Brownell
  1 sibling, 1 reply; 20+ messages in thread
From: Felipe Balbi @ 2007-05-29 12:02 UTC (permalink / raw)
  To: linux-omap-open-source

From: Vikram Pandita <vikram.pandita@ti.com>

	This patch was took from linux-usb-devel mailing list.

	It will help us until I finish developing a userspace application
	such as USBHSET.exe tool from usb.org/developer/tools.

	We need to provide such tool for the USB Certification Lab.

Signed-off-by: Felipe Balbi <felipe.lima@indt.org.br>
---

Index: linux-omap-2.6/drivers/usb/musb/Makefile
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/Makefile	2007-05-09 14:38:23.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/Makefile	2007-05-25 14:17:05.000000000 +0300
@@ -23,7 +23,7 @@
 endif
 
 ifeq ($(CONFIG_USB_MUSB_HDRC_HCD),y)
-	musb_hdrc-objs		+= virthub.o musb_host.o
+	musb_hdrc-objs		+= virthub.o musb_host.o musb_hset.o
 endif
 
 # the kconfig must guarantee that only one of the
Index: linux-omap-2.6/drivers/usb/musb/musb_hset.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-omap-2.6/drivers/usb/musb/musb_hset.c	2007-05-25 14:17:05.000000000 +0300
@@ -0,0 +1,597 @@
+/*
+ * HS USB Host-mode HSET driver for Mentor USB Controller
+ *
+ * Copyright (C) 2005 Mentor Graphics Corporation
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *      Nishant Kamat <nskamat@ti.com>
+ *      Vikram Pandita <vikram.pandita@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ * This driver is based on the USB Skeleton driver-2.0
+ * (drivers/usb/usb-skeleton.c) written by Greg Kroah-Hartman (greg@kroah.com)
+ *
+ * Notes:
+ * There are 2 ways this driver can be used:
+ *	1 - By attaching a HS OPT (OTG Protocol Tester) card.
+ * 	    The OPT test application contains scripts to test each mode.
+ *	    Each script attaches the OPT with a distinct VID/PID. Depending on
+ *	    the VID/PID this driver go into a particular test mode.
+ *	2 - Through /proc/drivers/musb_HSET interface.
+ *	    This is a forceful method, and rather more useful.
+ *	    Any USB device can be attached to the Host.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kref.h>
+#include <linux/usb.h>
+#include <linux/timer.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+#include <linux/workqueue.h>
+#include "../core/usb.h"
+#include "musbdefs.h"
+
+
+
+/* ULPI pass-through */
+#define MGC_O_HDRC_ULPI_VBUSCTL	0x70
+#define MGC_O_HDRC_ULPI_REGDATA 0x74
+#define MGC_O_HDRC_ULPI_REGADDR 0x75
+#define MGC_O_HDRC_ULPI_REGCTL	0x76
+
+/* extended config & PHY control */
+#define MGC_O_HDRC_ENDCOUNT	0x78
+#define MGC_O_HDRC_DMARAMCFG	0x79
+#define MGC_O_HDRC_PHYWAIT	0x7A
+#define MGC_O_HDRC_PHYVPLEN	0x7B	/* units of 546.1 us */
+#define MGC_O_HDRC_HSEOF1	0x7C	/* units of 133.3 ns */
+#define MGC_O_HDRC_FSEOF1	0x7D	/* units of 533.3 ns */
+#define MGC_O_HDRC_LSEOF1	0x7E	/* units of 1.067 us */
+
+/* Added in HDRC 1.9(?) & MHDRC 1.4 */
+/* ULPI */
+#define MGC_M_ULPI_VBUSCTL_USEEXTVBUSIND    0x02
+#define MGC_M_ULPI_VBUSCTL_USEEXTVBUS	    0x01
+#define MGC_M_ULPI_REGCTL_INT_ENABLE	    0x08
+#define MGC_M_ULPI_REGCTL_READNOTWRITE	    0x04
+#define MGC_M_ULPI_REGCTL_COMPLETE	    0x02
+#define MGC_M_ULPI_REGCTL_REG		    0x01
+/* extended config & PHY control */
+#define MGC_M_ENDCOUNT_TXENDS	0x0f
+#define MGC_S_ENDCOUNT_TXENDS	0
+#define MGC_M_ENDCOUNT_RXENDS	0xf0
+#define MGC_S_ENDCOUNT_RXENDS	4
+#define MGC_M_DMARAMCFG_RAMBITS	0x0f	    /* RAMBITS-1 */
+#define MGC_S_DMARAMCFG_RAMBITS	0
+#define MGC_M_DMARAMCFG_DMACHS	0xf0
+#define MGC_S_DMARAMCFG_DMACHS	4
+#define MGC_M_PHYWAIT_WAITID	0x0f	    /* units of 4.369 ms */
+#define MGC_S_PHYWAIT_WAITID	0
+#define MGC_M_PHYWAIT_WAITCON	0xf0	    /* units of 533.3 ns */
+#define MGC_S_PHYWAIT_WAITCON	4
+
+/*---------------------------------------------------------------------------*/
+/* This is the list of VID/PID that the HS OPT card will use. */
+static struct usb_device_id hset_table [] = {
+	{ USB_DEVICE(6666, 0x0101) },	/* TEST_SE0_NAK */
+	{ USB_DEVICE(6666, 0x0102) },	/* TEST_J */
+	{ USB_DEVICE(6666, 0x0103) },	/* TEST_K */
+	{ USB_DEVICE(6666, 0x0104) },	/* TEST_PACKET */
+	{ USB_DEVICE(6666, 0x0105) },	/* TEST_FORCE_ENABLE */
+	{ USB_DEVICE(6666, 0x0106) },	/* HS_HOST_PORT_SUSPEND_RESUME */
+	{ USB_DEVICE(6666, 0x0107) },	/* SINGLE_STEP_GET_DEV_DESC */
+	{ USB_DEVICE(6666, 0x0108) },	/* SINGLE_STEP_SET_FEATURE */
+	{ }				/* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, hset_table);
+
+/* Structure to hold all of our device specific stuff */
+struct usb_hset {
+	struct usb_device *	udev;	/* the usb device for this device */
+	struct usb_interface *	interface; /* the interface for this device */
+	struct kref		kref;
+	struct musb *		musb; /* the controller */
+	struct proc_dir_entry* pde;
+};
+#define to_hset_dev(d) container_of(d, struct usb_hset, kref)
+
+static struct usb_hset *the_hset;
+static struct usb_driver hset_driver;
+static struct proc_dir_entry *
+	hset_proc_create(char *name, struct usb_hset *hset);
+static void hset_proc_delete(char *name, struct usb_hset *hset);
+
+/*---------------------------------------------------------------------------*/
+/* Test routines */
+
+static int musb_write_ulpi_reg(struct musb *musb, u8 address, u8 value);
+static void test_musb(struct musb *musb, u8 mode)
+{
+	void __iomem *pBase = musb->pRegs;
+
+	if (mode == MGC_M_TEST_J || mode == MGC_M_TEST_K)
+		/* write 0x50 to Function Control Register (@ 0x04) of the PHY
+		 * 0x50 => OpMode = 10b => Disable bit-stuff and NRZI encoding
+		 * 	   SuspendM = 1b => Powered
+		 */
+		musb_write_ulpi_reg(musb, 0x04, 0x50);
+
+	if (mode == MGC_M_TEST_PACKET) {
+		MGC_SelectEnd(pBase, 0);
+		musb_writew(musb->aLocalEnd[0].regs, MGC_O_HDRC_CSR0, 0);
+		musb_write_fifo(&musb->aLocalEnd[0], sizeof(musb_test_packet),
+				musb_test_packet);
+		/* need to set test mode before enabling FIFO, as otherwise
+		 * the packet goes out and the FIFO empties before the test
+		 * mode is set
+		 */
+		musb_writeb(pBase, MGC_O_HDRC_TESTMODE, mode);
+		musb_writew(musb->aLocalEnd[0].regs, MGC_O_HDRC_CSR0,
+						MGC_M_CSR0_TXPKTRDY);
+	} else
+		musb_writeb(pBase, MGC_O_HDRC_TESTMODE, mode);
+}
+
+static inline void test_se0_nak(struct usb_hset *hset)
+{
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+	test_musb(hset->musb, MGC_M_TEST_SE0_NAK);
+}
+
+static inline void test_j(struct usb_hset *hset)
+{
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+	test_musb(hset->musb, MGC_M_TEST_J);
+}
+
+static inline void test_k(struct usb_hset *hset)
+{
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+	test_musb(hset->musb, MGC_M_TEST_K);
+}
+
+static inline void test_packet(struct usb_hset *hset)
+{
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+	test_musb(hset->musb, MGC_M_TEST_PACKET);
+}
+
+static inline void test_force_enable(struct usb_hset *hset)
+{
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+	test_musb(hset->musb, MGC_M_TEST_FORCE_HOST);
+}
+
+static void suspend(struct usb_hset *hset)
+{
+	struct musb *musb = hset->musb;
+	void __iomem *pBase = musb->pRegs;
+	u8 power;
+
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+	power = musb_readb(pBase, MGC_O_HDRC_POWER);
+	musb_writeb(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_SUSPENDM);
+}
+
+static void resume(struct usb_hset *hset)
+{
+	struct musb *musb = hset->musb;
+	void __iomem *pBase = musb->pRegs;
+	u8 power;
+
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+	power = musb_readb(pBase, MGC_O_HDRC_POWER);
+	if (power & MGC_M_POWER_SUSPENDM) {
+		power &= ~(MGC_M_POWER_SUSPENDM | MGC_M_POWER_RESUME);
+		musb_writeb(pBase, MGC_O_HDRC_POWER, power | MGC_M_POWER_RESUME);
+		msleep(20);
+		power = musb_readb(pBase, MGC_O_HDRC_POWER);
+		musb_writeb(pBase, MGC_O_HDRC_POWER, power & ~MGC_M_POWER_RESUME);
+	} else
+		printk(KERN_DEBUG "not suspended??\n");
+}
+
+static void test_suspend_resume(struct usb_hset *hset)
+{
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+	suspend(hset);
+	msleep(15000);	/* Wait for 15 sec */
+	resume(hset);
+}
+
+static void test_single_step_get_dev_desc(struct usb_hset *hset)
+{
+	struct musb *musb = hset->musb;
+	struct usb_device *udev;
+	struct usb_bus *bus = hcd_to_bus(musb_to_hcd(musb));
+
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+	if (!musb || !bus || !bus->root_hub) {
+		printk(KERN_ERR "Host controller not ready!\n");
+		return;
+	}
+	udev = bus->root_hub->children[0];
+	if (!udev) {
+		printk(KERN_DEBUG "No device connected.\n");
+		return;
+	}
+	usb_get_device_descriptor(udev, sizeof(struct usb_device_descriptor));
+}
+
+static void test_single_step_set_feature(struct usb_hset *hset)
+{
+	struct musb *musb = hset->musb;
+	struct usb_device *udev;
+	struct usb_bus *bus = hcd_to_bus(musb_to_hcd(musb));
+
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+	if (!musb || !bus || !bus->root_hub) {
+		printk(KERN_ERR "Host controller not ready!\n");
+		return;
+	}
+
+	udev = bus->root_hub->children[0];
+	if (!udev) {
+		printk(KERN_DEBUG "No device connected.\n");
+		return;
+	}
+	usb_control_msg(udev,
+			usb_sndctrlpipe(udev, 0),
+			USB_REQ_SET_FEATURE, 0, 0,
+			0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+}
+
+static void enumerate_bus(struct work_struct *ignored)
+{
+	struct usb_hset *hset = the_hset;
+	struct musb *musb = hset->musb;
+	struct usb_device *udev;
+	struct usb_bus *bus = hcd_to_bus(musb_to_hcd(musb));
+
+	printk(KERN_INFO "%s\n", __FUNCTION__);
+	if (!musb || !bus || !bus->root_hub) {
+		printk(KERN_ERR "Host controller not ready!\n");
+		return;
+	}
+	udev = bus->root_hub->children[0];
+	if (udev)
+		usb_reset_device(udev);
+}
+
+DECLARE_WORK(enumerate, enumerate_bus);
+
+/*---------------------------------------------------------------------------*/
+
+/* This function can be called either by musb_init_hset() or usb_hset_probe().
+ * musb_init_hset() is called by the controller driver during its init(),
+ * while usb_hset_probe() is called when an OPT is attached. We take care not
+ * to allocate the usb_hset structure twice.
+ */
+static struct usb_hset* init_hset_dev(void *controller)
+{
+	struct usb_hset *hset = NULL;
+
+	/* if already allocated, just increment use count and return */
+	if (the_hset) {
+		kref_get(&the_hset->kref);
+		return the_hset;
+	}
+
+	hset = kmalloc(sizeof(*hset), GFP_KERNEL);
+	if (hset == NULL) {
+		err("Out of memory");
+		return NULL;
+	}
+	memset(hset, 0x00, sizeof(*hset));
+	hset->musb = (struct musb *)(controller);
+
+	kref_init(&hset->kref);
+	the_hset = hset;
+	return hset;
+}
+
+static void hset_delete(struct kref *kref)
+{
+	struct usb_hset *dev = to_hset_dev(kref);
+
+	kfree (dev);
+}
+/*---------------------------------------------------------------------------*/
+/* Usage of HS OPT */
+
+static inline struct musb *dev_to_musb(struct device *dev)
+{
+#ifdef CONFIG_USB_MUSB_HDRC_HCD
+        /* usbcore insists dev->driver_data is a "struct hcd *" */
+        return hcd_to_musb(dev_get_drvdata(dev));
+#else
+        return dev_get_drvdata(dev);
+#endif
+}
+
+/* Called when the HS OPT is attached as a device */
+static int hset_probe(struct usb_interface *interface,
+		      const struct usb_device_id *id)
+{
+	struct usb_hset *hset;
+	struct usb_device *udev;
+	struct usb_hcd *hcd;
+	int retval = -ENOMEM;
+
+	udev = usb_get_dev(interface_to_usbdev(interface));
+	hcd = udev->bus->controller->driver_data;
+	hset = init_hset_dev(hcd->hcd_priv);
+	if (!hset)
+		return retval;
+
+	hset->udev = udev;
+	hset->interface = interface;
+	usb_set_intfdata(interface, hset);
+
+	switch(id->idProduct) {
+	case 0x0101:
+		test_se0_nak(hset);
+		break;
+	case 0x0102:
+		test_j(hset);
+		break;
+	case 0x0103:
+		test_k(hset);
+		break;
+	case 0x0104:
+		test_packet(hset);
+		break;
+	case 0x0105:
+		test_force_enable(hset);
+		break;
+	case 0x0106:
+		test_suspend_resume(hset);
+		break;
+	case 0x0107:
+		msleep(15000);	/* SOFs for 15 sec */
+		test_single_step_get_dev_desc(hset);
+		break;
+	case 0x0108:
+		test_single_step_get_dev_desc(hset);
+		msleep(15000);	/* SOFs for 15 sec */
+		test_single_step_set_feature(hset);
+		break;
+	};
+	return 0;
+}
+
+static void hset_disconnect(struct usb_interface *interface)
+{
+	struct usb_hset *hset;
+
+	/* prevent hset_open() from racing hset_disconnect() */
+	lock_kernel();
+	hset = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
+	unlock_kernel();
+
+	usb_put_dev(hset->udev);
+	kref_put(&hset->kref, hset_delete);
+}
+
+static struct usb_driver hset_driver = {
+//	.owner =	THIS_MODULE,
+	.name =		"hset",
+	.probe =	hset_probe,
+	.disconnect =	hset_disconnect,
+	.id_table =	hset_table,
+};
+
+static int __init usb_hset_init(void)
+{
+	int result;
+
+	/* register this driver with the USB subsystem */
+	result = usb_register(&hset_driver);
+	if (result)
+		err("usb_register failed. Error number %d", result);
+
+	return result;
+}
+
+static void __exit usb_hset_exit(void)
+{
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&hset_driver);
+}
+
+module_init (usb_hset_init);
+module_exit (usb_hset_exit);
+
+MODULE_LICENSE("GPL");
+
+/*---------------------------------------------------------------------------*/
+/* Usage of /proc/drivers/musb_hset interface */
+
+void musb_init_hset(char *name, struct musb *musb)
+{
+	struct usb_hset *hset;
+	hset = init_hset_dev((void *)musb);
+	hset_proc_create(name, hset);
+}
+
+void musb_exit_hset(char *name, struct musb *musb)
+{
+	struct usb_hset *hset = the_hset;
+
+	if (!hset) {
+		printk(KERN_DEBUG "No hset device!\n");
+		return;
+	}
+	hset_proc_delete(name, hset);
+	kref_put(&hset->kref, hset_delete);
+}
+
+static int dump_menu(char *buffer)
+{
+	int count = 0;
+
+	*buffer = 0;
+	count = sprintf(buffer, "HOST-side high-speed electrical test modes:\n"
+				"J: Test_J\n"
+				"K: Test_K\n"
+				"S: Test_SE0_NAK\n"
+				"P: Test_PACKET\n"
+				"H: Test_FORCE_ENABLE\n"
+				"U: Test_SUSPEND_RESUME\n"
+				"G: Test_SINGLE_STEP_GET_DESC\n"
+				"F: Test_SINGLE_STEP_SET_FEATURE\n"
+				"E: Enumerate bus\n"
+				"D: Suspend bus\n"
+				"R: Resume bus\n"
+				"?: help menu\n");
+	if (count < 0)
+		return count;
+	buffer += count;
+	return count;
+}
+
+static int hset_proc_write(struct file *file, const char __user *buffer,
+			 unsigned long count, void *data)
+{
+	char cmd;
+	struct usb_hset *hset = (struct usb_hset *)data;
+	char help[500];
+	/* MOD_INC_USE_COUNT; */
+	//if (hset->musb->asleep)
+	//	return EBUSY;
+
+	if(copy_from_user(&cmd, buffer, 1))
+		return -EFAULT;
+	switch (cmd) {
+	case 'S':
+		test_se0_nak(hset);
+		break;
+	case 'J':
+		test_j(hset);
+		break;
+	case 'K':
+		test_k(hset);
+		break;
+	case 'P':
+		test_packet(hset);
+		break;
+	case 'H':
+		test_force_enable(hset);
+		break;
+	case 'U':
+		test_suspend_resume(hset);
+		break;
+	case 'G':
+		test_single_step_get_dev_desc(hset);
+		break;
+	case 'F':
+		test_single_step_set_feature(hset);
+		break;
+	case 'E':
+		schedule_work(&enumerate);
+		break;
+	case 'D':
+		suspend(hset);
+		break;
+	case 'R':
+		resume(hset);
+		break;
+	case '?':
+		dump_menu(help);
+		printk(KERN_INFO "%s", help);
+		break;
+	default:
+		printk(KERN_ERR "Command %c not implemented\n", cmd);
+		break;
+	}
+
+	return count;
+}
+
+static int hset_proc_read(char *page, char **start,
+			off_t off, int count, int *eof, void *data)
+{
+	char *buffer = page;
+	int code = 0;
+
+	count -= off;
+	count -= 1;		/* for NUL at end */
+	if (count < 0)
+		return -EINVAL;
+
+	code = dump_menu(buffer);
+	if (code > 0) {
+		buffer += code;
+		count -= code;
+	}
+
+	*eof = 1;
+	return (buffer - page) - off;
+}
+
+void hset_proc_delete(char *name, struct usb_hset *hset)
+{
+	if (hset->pde)
+		remove_proc_entry(name, NULL);
+}
+
+struct proc_dir_entry *hset_proc_create(char *name, struct usb_hset *hset)
+{
+	struct proc_dir_entry	*pde;
+
+	/* FIXME convert everything to seq_file; then later, debugfs */
+
+	if (!name || !hset)
+		return NULL;
+
+	hset->pde = pde = create_proc_entry(name,
+				     S_IFREG | S_IRUGO | S_IWUSR, NULL);
+	if (pde) {
+		pde->data = (void *)hset;
+		// pde->owner = THIS_MODULE;
+
+		pde->read_proc = hset_proc_read;
+		pde->write_proc = hset_proc_write;
+
+		pde->size = 0;
+
+		pr_debug("Registered /proc/%s\n", name);
+	} else {
+		pr_debug("Cannot create a valid proc file entry");
+	}
+
+	return pde;
+}
+
+static int musb_write_ulpi_reg(struct musb* musb, u8 address, u8 value)
+{
+	u8 ctl = 0;
+	u8* pBase = musb->pRegs;
+
+	/* ensure not powered down */
+	if(musb_readb(pBase, MGC_O_HDRC_POWER) & MGC_M_POWER_ENSUSPEND) {
+		return -ENODEV;
+	}
+
+	/* polled */
+	musb_writeb(pBase, MGC_O_HDRC_ULPI_REGADDR, address);
+	musb_writeb(pBase, MGC_O_HDRC_ULPI_REGDATA, value);
+	musb_writeb(pBase, MGC_O_HDRC_ULPI_REGCTL, MGC_M_ULPI_REGCTL_REG);
+
+	while(!(MGC_M_ULPI_REGCTL_COMPLETE & ctl)) {
+		ctl = musb_readb(pBase, MGC_O_HDRC_ULPI_REGCTL);
+	}
+
+	musb_writeb(pBase, MGC_O_HDRC_ULPI_REGCTL, 0);
+
+	return 0;
+}
Index: linux-omap-2.6/drivers/usb/musb/musbdefs.h
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/musbdefs.h	2007-05-25 14:16:59.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/musbdefs.h	2007-05-25 14:17:05.000000000 +0300
@@ -489,6 +489,16 @@
 }
 #endif
 
+/* for high speed test mode; see USB 2.0 spec */
+static const u8 musb_test_packet[53] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+	0xaa, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
+	0xee, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xbf, 0xdf,
+	0xef, 0xf7, 0xfb, 0xfd, 0xfc, 0x7e, 0xbf, 0xdf,
+	0xef, 0xf7, 0xfb, 0xfd, 0x7e
+};
 
 /***************************** Glue it together *****************************/
 
@@ -532,7 +542,8 @@
 extern struct proc_dir_entry *musb_debug_create(char *name,
 						    struct musb *data);
 extern void musb_debug_delete(char *name, struct musb *data);
-
+extern void musb_init_hset(char *name, struct musb *musb);
+extern void musb_exit_hset(char *name, struct musb *musb);
 #else
 static inline struct proc_dir_entry *musb_debug_create(char *name,
 							   struct musb *data)
@@ -542,6 +553,12 @@
 static inline void musb_debug_delete(char *name, struct musb *data)
 {
 }
+static inline void musb_init_hset(char *name, struct musb *musb)
+{
+}
+static inline void musb_exit_hset(char *name, struct musb *musb)
+{
+}
 #endif
 
 #endif	/* __MUSB_MUSBDEFS_H__ */
Index: linux-omap-2.6/drivers/usb/musb/plat_uds.c
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/plat_uds.c	2007-05-25 14:16:59.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/plat_uds.c	2007-05-25 14:17:05.000000000 +0300
@@ -248,27 +248,6 @@
 
 
 /*-------------------------------------------------------------------------*/
-
-/* for high speed test mode; see USB 2.0 spec 7.1.20 */
-static const u8 musb_test_packet[53] = {
-	/* implicit SYNC then DATA0 to start */
-
-	/* JKJKJKJK x9 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	/* JJKKJJKK x8 */
-	0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
-	/* JJJJKKKK x8 */
-	0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
-	/* JJJJJJJKKKKKKK x8 */
-	0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	/* JJJJJJJK x8 */
-	0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd,
-	/* JKKKKKKK x10, JK */
-	0xfc, 0x7e, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0x7e
-
-	/* implicit CRC16 then EOP to end */
-};
-
 void musb_load_testpacket(struct musb *musb)
 {
 	void __iomem	*regs = musb->aLocalEnd[0].regs;
@@ -2084,8 +2063,13 @@
 
 	}
 
-	if (status == 0)
+	if (status == 0) {
 		musb_debug_create("driver/musb_hdrc", pThis);
+#ifdef CONFIG_USB_MUSB_HDRC_HCD
+		musb_init_hset("driver/musb_HSET", pThis);
+#endif
+
+	}
 	else {
 fail:
 		if (pThis->clock)
@@ -2162,6 +2146,7 @@
 	musb_shutdown(pdev);
 	musb_debug_delete("driver/musb_hdrc", musb);
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
+	musb_exit_hset("driver/musb_HSET", musb);
 	if (musb->board_mode == MUSB_HOST)
 		usb_remove_hcd(musb_to_hcd(musb));
 #endif

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

* [PATCH] Leave GPIO[7:6] pullups enabled.
  2007-05-29 12:02               ` [PATCH] HSET tool for the MUSB Controler Felipe Balbi
@ 2007-05-29 12:02                 ` Felipe Balbi
       [not found]                   ` <11804401803413-git-send-email-felipebalbi@users.sourceforge.net>
  2007-06-05 11:02                   ` [PATCH] Leave GPIO[7:6] pullups enabled Tony Lindgren
  0 siblings, 2 replies; 20+ messages in thread
From: Felipe Balbi @ 2007-05-29 12:02 UTC (permalink / raw)
  To: linux-omap-open-source

From: Felipe Balbi <felipe.lima@indt.org.br>

GPIO7 and GPIO6 are configured as default wake-up sources for
tusb6010.

without this patch MUSB is not able to enumerate
any device that draw power from it.

After applying this patch, we're passing in almost
all OTG Electrical Tests.

Signed-off-by: Felipe Balbi <felipe.lima@indt.org.br>
---

Index: linux-omap-2.6/drivers/usb/musb/tusb6010.c
===================================================================
--- linux-omap-2.6.orig/drivers/usb/musb/tusb6010.c	2007-05-28 13:18:46.000000000 +0300
+++ linux-omap-2.6/drivers/usb/musb/tusb6010.c	2007-05-28 13:26:28.000000000 +0300
@@ -879,8 +879,11 @@
 {
 	void __iomem	*base = musb->ctrl_base;
 
-	/* Disable GPIO[7:0] pullups (used as output DMA requests) */
-	musb_writel(base, TUSB_PULLUP_1_CTRL, 0x000000FF);
+	/* GPIO[7:6] are the default wake-up sources for tusb6010.
+	 * We cannot disable their pullups.
+	 *
+	 * Disable GPIO[5:0] pullups (used as output DMA requests) */
+	musb_writel(base, TUSB_PULLUP_1_CTRL, 0x0000003F);
 	/* Disable all pullups on NOR IF, DMAREQ0 and DMAREQ1 */
 	musb_writel(base, TUSB_PULLUP_2_CTRL, 0x01FFFFFF);
 

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

* [PATCH] Make SRP passes in all Electrical Tests
       [not found]                   ` <11804401803413-git-send-email-felipebalbi@users.sourceforge.net>
@ 2007-05-29 12:02                     ` Felipe Balbi
  2007-05-29 14:39                       ` Dirk Behme
  0 siblings, 1 reply; 20+ messages in thread
From: Felipe Balbi @ 2007-05-29 12:02 UTC (permalink / raw)
  To: linux-omap-open-source



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

* Re: [PATCH] Make SRP passes in all Electrical Tests
  2007-05-29 12:02                     ` [PATCH] Make SRP passes in all Electrical Tests Felipe Balbi
@ 2007-05-29 14:39                       ` Dirk Behme
  0 siblings, 0 replies; 20+ messages in thread
From: Dirk Behme @ 2007-05-29 14:39 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: linux-omap-open-source

Felipe Balbi wrote:
> _______________________________________________
> Linux-omap-open-source mailing list
> Linux-omap-open-source@linux.omap.com
> http://linux.omap.com/mailman/listinfo/linux-omap-open-source

Mmmh, this is empty?

Dirk

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

* Re: [PATCH] musb_hdrc: Add SRP Interface and control it through sysfs
  2007-05-29 12:02     ` [PATCH] musb_hdrc: Add SRP Interface and control it through sysfs Felipe Balbi
  2007-05-29 12:02       ` [PATCH] Add Sysfs Interface to Control Vbus states Felipe Balbi
@ 2007-05-29 17:07       ` David Brownell
  1 sibling, 0 replies; 20+ messages in thread
From: David Brownell @ 2007-05-29 17:07 UTC (permalink / raw)
  To: linux-omap-open-source

On Tuesday 29 May 2007, Felipe Balbi wrote:
> --- linux-omap-2.6.orig/drivers/usb/musb/musb_gadget.c	2007-05-28 01:40:16.000000000 +0300
> +++ linux-omap-2.6/drivers/usb/musb/musb_gadget.c	2007-05-28 13:18:47.000000000 +0300
> @@ -2056,3 +2056,29 @@
>  	(void) musb_gadget_vbus_draw(&musb->g,
>  			is_otg_enabled(musb) ? 8 : 100);
>  }
> +
> +/* called when we want to send a Session Request. Caller must hold the lock */
> +void musb_g_srp(struct musb *musb)

This method should not be needed.  When you
invoke usb_gadget_wakeup(), that's supposed
to trigger SRP when there's no existing
power session.

Note also that SRP is *NOT* an OTG-only
capability ... so it's incorrect to wrap
calls to such a routine in an OTG #ifdef.
Any peripheral is allowed to issue SRP.



> --- linux-omap-2.6.orig/drivers/usb/musb/plat_uds.c	2007-05-28 01:40:16.000000000 +0300
> +++ linux-omap-2.6/drivers/usb/musb/plat_uds.c	2007-05-28 13:18:47.000000000 +0300
> @@ -1579,6 +1579,32 @@
>  }
>  static DEVICE_ATTR(cable, S_IRUGO, musb_cable_show, NULL);
>  
> +#ifdef CONFIG_USB_MUSB_OTG
> +static ssize_t
> +musb_srp_store(struct device *dev, struct device_attribute *attr,
> +		const char *buf, size_t n)
> +{
> +	struct musb	*musb=dev_to_musb(dev);
> +	unsigned long	flags;
> +	unsigned short	srp;
> +
> +	if (sscanf(buf, "%hu", &srp) != 1
> +			|| (srp != 1)) {
> +		printk (KERN_ERR "SRP: Value must be 1\n");
> +		return -EINVAL;
> +	}

I see no point to such input validation.  Why even bother?


> +
> +	spin_lock_irqsave(&musb->Lock, flags);
> +	if (srp == 1){
> +		musb_g_srp(musb);

Call the "resume" method, not a special SRP-only one.


> +	}
> +	spin_unlock_irqrestore(&musb->Lock, flags);
> +
> +	return n;
> +}
> +static DEVICE_ATTR(srp, 0644, NULL, musb_srp_store);
> +#endif /* CONFIG_USB_MUSB_OTG */
> +
>  #endif
>  
>  /* Only used to provide cable state change events */
> @@ -1648,6 +1674,9 @@
>  #ifdef CONFIG_SYSFS
>  	device_remove_file(musb->controller, &dev_attr_mode);
>  	device_remove_file(musb->controller, &dev_attr_cable);
> +#ifdef CONFIG_USB_MUSB_OTG

This, and its sibling later, and the code above, should
all be #ifdeffed CONFIG_USB_GADGET_MUSB_HDRC ... since
any peripheral may issue SRP, not only OTG-capable ones.

> +	device_remove_file(musb->controller, &dev_attr_srp);
> +#endif
>  #endif
>  
>  #ifdef CONFIG_USB_GADGET_MUSB_HDRC
> @@ -1876,6 +1905,9 @@
>  #ifdef CONFIG_SYSFS
>  	status = device_create_file(dev, &dev_attr_mode);
>  	status = device_create_file(dev, &dev_attr_cable);
> +#ifdef CONFIG_USB_MUSB_OTG
> +	status = device_create_file(dev, &dev_attr_srp);
> +#endif /* CONFIG_USB_MUSB_OTG */
>  	status = 0;
>  #endif
>  
> _______________________________________________
> Linux-omap-open-source mailing list
> Linux-omap-open-source@linux.omap.com
> http://linux.omap.com/mailman/listinfo/linux-omap-open-source
> 

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

* Re: [PATCH] Add more Test Modes
  2007-05-29 12:02         ` [PATCH] Add more Test Modes Felipe Balbi
  2007-05-29 12:02           ` [PATCH] musb_hdrc: Make HNP work Felipe Balbi
@ 2007-05-29 17:16           ` David Brownell
  1 sibling, 0 replies; 20+ messages in thread
From: David Brownell @ 2007-05-29 17:16 UTC (permalink / raw)
  To: linux-omap-open-source

On Tuesday 29 May 2007, Felipe Balbi wrote:

> --- a/drivers/usb/musb/virthub.c
> +++ b/drivers/usb/musb/virthub.c
> @@ -362,7 +362,11 @@ int musb_hub_control(
>  				temp = MGC_M_TEST_FORCE_HOST
>  					| MGC_M_TEST_FORCE_HS;
>  
> -				/* FIXME and enable a session too */
> +				musb_writeb(musb->pRegs, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION);
> +				break;
> +			case 6:
> +				pr_debug("TEST_FIFO_ACCESS\n");
> +				temp = MGC_M_TEST_FIFO_ACCESS;

I don't see this defined in the USB 2.0 specification.
Table 11-24 shows values 1-5 only ... where is "6" defined?

FIFO access doesn't make sense as a portable test in any
case.  If it's needed for some musb-specific thing, this
should go into the vendor-specific range (0xc0 and up).

- Dave


>  				break;
>  			default:
>  				goto error;
> -- 
> 1.5.2.rc3.39.gaf9b
> 
> _______________________________________________
> Linux-omap-open-source mailing list
> Linux-omap-open-source@linux.omap.com
> http://linux.omap.com/mailman/listinfo/linux-omap-open-source
> 

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

* Re: [PATCH] USB: Fix OTG HNP for hub.c
  2007-05-29 12:02             ` [PATCH] USB: Fix OTG HNP for hub.c Felipe Balbi
  2007-05-29 12:02               ` [PATCH] HSET tool for the MUSB Controler Felipe Balbi
@ 2007-05-29 19:21               ` David Brownell
  2007-05-29 19:24                 ` Felipe Balbi
  1 sibling, 1 reply; 20+ messages in thread
From: David Brownell @ 2007-05-29 19:21 UTC (permalink / raw)
  To: linux-omap-open-source

On Tuesday 29 May 2007, Felipe Balbi wrote:
> From: Tony Lindgren <tony@atomide.com>
> 
> This patch makes makes OTG Host Negotiation Protocol (HNP)
> to behave.

Not really.  It makes it strongly *MIS* behave in fact,
since it always kicks off HNP ... even when it should not
do so, because the device is in the whitelist.  (Called
the "Targeted Peripherals List", TPL, in jargonese.)

The two blocks of code are in the wrong order ...


A more limited patch would help.  Specifically, just
fixing whatever bug was seen in the original code,
rather than abstracting it into a new subroutine and
changing the logic while doing so.

- Dave


> +	/* If B-device wants to do HNP, it will do it after we suspend */
> +	if (bus->b_hnp_enable) {
> +		dev_err(&udev->dev, "trying HNP, suspending bus\n");
> +		err = __usb_port_suspend(udev, udev->bus->otg_port);
> +		if (err < 0) {
> +			dev_err(&udev->dev, "suspend for HNP failed\n");
> +			return -ENODEV;
> +		}
> +
> +		/* TB_ASE0_BRST, minimum 3.125 ms */
> +		mdelay(4);
> +
> +		/* Failed resume means B-device took over the bus with HNP */
> +		err = usb_port_resume(udev);
> +		if (err < 0) {
> +			dev_err(&udev->dev, "HNP success\n");
> +			return -ENODEV;
> +		}
> +	}
> +
> +	/* HNP failed. Reject B-devices not in our whitelist */
> +	if (!is_targeted(udev))
> +		return -ENODEV;
> +

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

* Re: [PATCH] USB: Fix OTG HNP for hub.c
  2007-05-29 19:21               ` [PATCH] USB: Fix OTG HNP for hub.c David Brownell
@ 2007-05-29 19:24                 ` Felipe Balbi
  2007-05-29 20:34                   ` Tony Lindgren
  0 siblings, 1 reply; 20+ messages in thread
From: Felipe Balbi @ 2007-05-29 19:24 UTC (permalink / raw)
  To: David Brownell; +Cc: linux-omap-open-source

Hi,

On 5/29/07, David Brownell <david-b@pacbell.net> wrote:
> On Tuesday 29 May 2007, Felipe Balbi wrote:
> > From: Tony Lindgren <tony@atomide.com>
> >
> > This patch makes makes OTG Host Negotiation Protocol (HNP)
> > to behave.
>
> Not really.  It makes it strongly *MIS* behave in fact,
> since it always kicks off HNP ... even when it should not
> do so, because the device is in the whitelist.  (Called
> the "Targeted Peripherals List", TPL, in jargonese.)
>
> The two blocks of code are in the wrong order ...
>
>
> A more limited patch would help.  Specifically, just
> fixing whatever bug was seen in the original code,
> rather than abstracting it into a new subroutine and
> changing the logic while doing so.

Tony do you have any comments?
Do you mind if I try to re-work you patch?

>
> - Dave
>
>
> > +     /* If B-device wants to do HNP, it will do it after we suspend */
> > +     if (bus->b_hnp_enable) {
> > +             dev_err(&udev->dev, "trying HNP, suspending bus\n");
> > +             err = __usb_port_suspend(udev, udev->bus->otg_port);
> > +             if (err < 0) {
> > +                     dev_err(&udev->dev, "suspend for HNP failed\n");
> > +                     return -ENODEV;
> > +             }
> > +
> > +             /* TB_ASE0_BRST, minimum 3.125 ms */
> > +             mdelay(4);
> > +
> > +             /* Failed resume means B-device took over the bus with HNP */
> > +             err = usb_port_resume(udev);
> > +             if (err < 0) {
> > +                     dev_err(&udev->dev, "HNP success\n");
> > +                     return -ENODEV;
> > +             }
> > +     }
> > +
> > +     /* HNP failed. Reject B-devices not in our whitelist */
> > +     if (!is_targeted(udev))
> > +             return -ENODEV;
> > +
>
>


-- 
Best Regards,

Felipe Balbi
felipebalbi@users.sourceforge.net

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

* Re: [PATCH] USB: Fix OTG HNP for hub.c
  2007-05-29 19:24                 ` Felipe Balbi
@ 2007-05-29 20:34                   ` Tony Lindgren
  2007-05-29 21:11                     ` David Brownell
  0 siblings, 1 reply; 20+ messages in thread
From: Tony Lindgren @ 2007-05-29 20:34 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: linux-omap-open-source

* Felipe Balbi <felipebalbi@users.sourceforge.net> [070529 12:25]:
> Hi,
>
> On 5/29/07, David Brownell <david-b@pacbell.net> wrote:
>> On Tuesday 29 May 2007, Felipe Balbi wrote:
>> > From: Tony Lindgren <tony@atomide.com>
>> >
>> > This patch makes makes OTG Host Negotiation Protocol (HNP)
>> > to behave.
>>
>> Not really.  It makes it strongly *MIS* behave in fact,
>> since it always kicks off HNP ... even when it should not
>> do so, because the device is in the whitelist.  (Called
>> the "Targeted Peripherals List", TPL, in jargonese.)
>>
>> The two blocks of code are in the wrong order ...

Hmm, are you sure about that? My patch is based on
USB_TG_1-3.pdf and playing with usbcv13.exe and two N800s.

I'm under the impression that if the peripheral supports HNP, the
host must offer HNP at least once during the session.

And as I understand, the whitelist is for peripherals the host
supports, with HNP or no HNP.

With my patch, we offer to do HNP right in the beginning of the
session. Then the peripheral can use it or not use depending if
HNP is enabled on peripheral.

>> A more limited patch would help.  Specifically, just
>> fixing whatever bug was seen in the original code,
>> rather than abstracting it into a new subroutine and
>> changing the logic while doing so.

Dave, did you ever get HNP working with any device and test
it with usbcv13.exe and OPT?

> Tony do you have any comments?
> Do you mind if I try to re-work you patch?

Felipe I guess you're the only one with OPT right now, and that's
really what we should use for doing the HNP. So go ahead!

Regards,

Tony

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

* Re: [PATCH] USB: Fix OTG HNP for hub.c
  2007-05-29 20:34                   ` Tony Lindgren
@ 2007-05-29 21:11                     ` David Brownell
  2007-05-29 21:26                       ` Tony Lindgren
  0 siblings, 1 reply; 20+ messages in thread
From: David Brownell @ 2007-05-29 21:11 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-omap-open-source

On Tuesday 29 May 2007, Tony Lindgren wrote:
> * Felipe Balbi <felipebalbi@users.sourceforge.net> [070529 12:25]:
> > Hi,
> >
> > On 5/29/07, David Brownell <david-b@pacbell.net> wrote:
> >> On Tuesday 29 May 2007, Felipe Balbi wrote:
> >> > From: Tony Lindgren <tony@atomide.com>
> >> >
> >> > This patch makes makes OTG Host Negotiation Protocol (HNP)
> >> > to behave.
> >>
> >> Not really.  It makes it strongly *MIS* behave in fact,
> >> since it always kicks off HNP ... even when it should not
> >> do so, because the device is in the whitelist.  (Called
> >> the "Targeted Peripherals List", TPL, in jargonese.)
> >>
> >> The two blocks of code are in the wrong order ...
> 
> Hmm, are you sure about that? My patch is based on
> USB_TG_1-3.pdf and playing with usbcv13.exe and two N800s.
> 
> I'm under the impression that if the peripheral supports HNP, the
> host must offer HNP at least once during the session.

See section 6.8.1.4 of the OTG 1.2 spec which says that the A-device
first sets up communication with the B-device, when it's on the TPL.

You might be thinking about the later part of 6.8.1.4 which says
that "before ending the session" the A-device gives the B-device
an opportunity to be the master.  That may be a "new" requirement,
added by OTG 1.2 and not in OTG 1.0a.  But in any case, that's
after having done normal "work" (if any).

The mechanism for that is to enter the A_SUSPEND state after
enabling HNP.  Right now I'd expect autosuspend to make that
happen ... that's a new mechanism, we may need to re-evaluate
stting B_HNP_ENABLE that early.


> And as I understand, the whitelist is for peripherals the host
> supports, with HNP or no HNP.

Yes ... and see 6.8.1.4 too.  Devices NOT on the whitelist get
the A_BUS_REQ = FALSE treatment, triggering HNP or disconnect.

But ones on the whitelist keep A_BUS_REQ = TRUE until they're
done getting work done.


> With my patch, we offer to do HNP right in the beginning of the
> session. Then the peripheral can use it or not use depending if
> HNP is enabled on peripheral.

There are two requirements.  For HNP the only requirement is to
try it by the end of the session.  But for devices that have not
been blacklisted, there's another requirement:  first, set up
normal communication with that peripheral.


> >> A more limited patch would help.  Specifically, just
> >> fixing whatever bug was seen in the original code,
> >> rather than abstracting it into a new subroutine and
> >> changing the logic while doing so.
> 
> Dave, did you ever get HNP working with any device and test
> it with usbcv13.exe and OPT?

HNP was certainly working on H2 back around 2.6.10/11 using
the original OPT ... that's before usbcv13.exe or the very
latest (mucho expensivo, high speed capable) OPT hardware.

I believe the OMAP tree has code changes in isp1301_omap (from
TI) which allegedly made it work on H3, but broke it on H2.
(The OMAP1 OTG core changed a bit between OMAP 1611 and 1710.)
Those changes have not yet gone upstream, on the grounds that
they'd be a regression.

I may take that H2 out of storage and see how it behaves
on current kernels ... it's possible that usbcore changes
have broken that support.

- Dave


> > Tony do you have any comments?
> > Do you mind if I try to re-work you patch?
> 
> Felipe I guess you're the only one with OPT right now, and that's
> really what we should use for doing the HNP. So go ahead!
> 
> Regards,
> 
> Tony
> 

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

* Re: [PATCH] USB: Fix OTG HNP for hub.c
  2007-05-29 21:11                     ` David Brownell
@ 2007-05-29 21:26                       ` Tony Lindgren
  0 siblings, 0 replies; 20+ messages in thread
From: Tony Lindgren @ 2007-05-29 21:26 UTC (permalink / raw)
  To: David Brownell; +Cc: linux-omap-open-source

* David Brownell <david-b@pacbell.net> [070529 14:11]:
> On Tuesday 29 May 2007, Tony Lindgren wrote:
> > * Felipe Balbi <felipebalbi@users.sourceforge.net> [070529 12:25]:
> > > Hi,
> > >
> > > On 5/29/07, David Brownell <david-b@pacbell.net> wrote:
> > >> On Tuesday 29 May 2007, Felipe Balbi wrote:
> > >> > From: Tony Lindgren <tony@atomide.com>
> > >> >
> > >> > This patch makes makes OTG Host Negotiation Protocol (HNP)
> > >> > to behave.
> > >>
> > >> Not really.  It makes it strongly *MIS* behave in fact,
> > >> since it always kicks off HNP ... even when it should not
> > >> do so, because the device is in the whitelist.  (Called
> > >> the "Targeted Peripherals List", TPL, in jargonese.)
> > >>
> > >> The two blocks of code are in the wrong order ...
> > 
> > Hmm, are you sure about that? My patch is based on
> > USB_TG_1-3.pdf and playing with usbcv13.exe and two N800s.
> > 
> > I'm under the impression that if the peripheral supports HNP, the
> > host must offer HNP at least once during the session.
> 
> See section 6.8.1.4 of the OTG 1.2 spec which says that the A-device
> first sets up communication with the B-device, when it's on the TPL.
> 
> You might be thinking about the later part of 6.8.1.4 which says
> that "before ending the session" the A-device gives the B-device
> an opportunity to be the master.  That may be a "new" requirement,
> added by OTG 1.2 and not in OTG 1.0a.  But in any case, that's
> after having done normal "work" (if any).

But HNP can also be offered early in addition to autosuspend
(which I have missed). Does "sets up communications with b-device"
really mean use it as a peripheral? Or does it mean set up
communications to configure b-device?

If the b-device has b_host mode enabled, it does not want to be
a peripheral at that point.

> The mechanism for that is to enter the A_SUSPEND state after
> enabling HNP.  Right now I'd expect autosuspend to make that
> happen ... that's a new mechanism, we may need to re-evaluate
> stting B_HNP_ENABLE that early.
> 
> 
> > And as I understand, the whitelist is for peripherals the host
> > supports, with HNP or no HNP.
> 
> Yes ... and see 6.8.1.4 too.  Devices NOT on the whitelist get
> the A_BUS_REQ = FALSE treatment, triggering HNP or disconnect.
> 
> But ones on the whitelist keep A_BUS_REQ = TRUE until they're
> done getting work done.

Yes, I still don't see a conflict with my patch and 6.8.1.4,
if we assume communcations with b-device means just configure it.

> > With my patch, we offer to do HNP right in the beginning of the
> > session. Then the peripheral can use it or not use depending if
> > HNP is enabled on peripheral.
> 
> There are two requirements.  For HNP the only requirement is to
> try it by the end of the session.  But for devices that have not
> been blacklisted, there's another requirement:  first, set up
> normal communication with that peripheral.

Hmmm, I ended up doing it this way to get usbcv13.exe OTG tests
to pass. I guess it boils down what "sets up communication with
b-device" means.

> > >> A more limited patch would help.  Specifically, just
> > >> fixing whatever bug was seen in the original code,
> > >> rather than abstracting it into a new subroutine and
> > >> changing the logic while doing so.
> > 
> > Dave, did you ever get HNP working with any device and test
> > it with usbcv13.exe and OPT?
> 
> HNP was certainly working on H2 back around 2.6.10/11 using
> the original OPT ... that's before usbcv13.exe or the very
> latest (mucho expensivo, high speed capable) OPT hardware.

OK, that's good to hear.

> I believe the OMAP tree has code changes in isp1301_omap (from
> TI) which allegedly made it work on H3, but broke it on H2.
> (The OMAP1 OTG core changed a bit between OMAP 1611 and 1710.)
> Those changes have not yet gone upstream, on the grounds that
> they'd be a regression.
> 
> I may take that H2 out of storage and see how it behaves
> on current kernels ... it's possible that usbcore changes
> have broken that support.

Yeh, I suspect it will fail at least usbcv13.exe OTG tests.

Regards,

Tony

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

* Re: [PATCH] Leave GPIO[7:6] pullups enabled.
  2007-05-29 12:02                 ` [PATCH] Leave GPIO[7:6] pullups enabled Felipe Balbi
       [not found]                   ` <11804401803413-git-send-email-felipebalbi@users.sourceforge.net>
@ 2007-06-05 11:02                   ` Tony Lindgren
  1 sibling, 0 replies; 20+ messages in thread
From: Tony Lindgren @ 2007-06-05 11:02 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: linux-omap-open-source

* Felipe Balbi <felipebalbi@users.sourceforge.net> [070529 05:04]:
> From: Felipe Balbi <felipe.lima@indt.org.br>
> 
> GPIO7 and GPIO6 are configured as default wake-up sources for
> tusb6010.
> 
> without this patch MUSB is not able to enumerate
> any device that draw power from it.
> 
> After applying this patch, we're passing in almost
> all OTG Electrical Tests.
> 
> Signed-off-by: Felipe Balbi <felipe.lima@indt.org.br>
> ---
> 
> Index: linux-omap-2.6/drivers/usb/musb/tusb6010.c
> ===================================================================
> --- linux-omap-2.6.orig/drivers/usb/musb/tusb6010.c	2007-05-28 13:18:46.000000000 +0300
> +++ linux-omap-2.6/drivers/usb/musb/tusb6010.c	2007-05-28 13:26:28.000000000 +0300
> @@ -879,8 +879,11 @@
>  {
>  	void __iomem	*base = musb->ctrl_base;
>  
> -	/* Disable GPIO[7:0] pullups (used as output DMA requests) */
> -	musb_writel(base, TUSB_PULLUP_1_CTRL, 0x000000FF);
> +	/* GPIO[7:6] are the default wake-up sources for tusb6010.
> +	 * We cannot disable their pullups.
> +	 *
> +	 * Disable GPIO[5:0] pullups (used as output DMA requests) */
> +	musb_writel(base, TUSB_PULLUP_1_CTRL, 0x0000003F);
>  	/* Disable all pullups on NOR IF, DMAREQ0 and DMAREQ1 */
>  	musb_writel(base, TUSB_PULLUP_2_CTRL, 0x01FFFFFF);
>  

Pushing this one today, I edited the comments a bit.

Tony

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

end of thread, other threads:[~2007-06-05 11:02 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-29 12:02 RFC PATCH Felipe Balbi
2007-05-29 12:02 ` [PATCH] USB: Disable file_storage USB_CONFIG_ATT_WAKEUP Felipe Balbi
2007-05-29 12:02   ` [PATCH] musb_hdrc: Implement workaround for tusb3.0 wbus bug rev2 Felipe Balbi
2007-05-29 12:02     ` [PATCH] musb_hdrc: Add SRP Interface and control it through sysfs Felipe Balbi
2007-05-29 12:02       ` [PATCH] Add Sysfs Interface to Control Vbus states Felipe Balbi
2007-05-29 12:02         ` [PATCH] Add more Test Modes Felipe Balbi
2007-05-29 12:02           ` [PATCH] musb_hdrc: Make HNP work Felipe Balbi
2007-05-29 12:02             ` [PATCH] USB: Fix OTG HNP for hub.c Felipe Balbi
2007-05-29 12:02               ` [PATCH] HSET tool for the MUSB Controler Felipe Balbi
2007-05-29 12:02                 ` [PATCH] Leave GPIO[7:6] pullups enabled Felipe Balbi
     [not found]                   ` <11804401803413-git-send-email-felipebalbi@users.sourceforge.net>
2007-05-29 12:02                     ` [PATCH] Make SRP passes in all Electrical Tests Felipe Balbi
2007-05-29 14:39                       ` Dirk Behme
2007-06-05 11:02                   ` [PATCH] Leave GPIO[7:6] pullups enabled Tony Lindgren
2007-05-29 19:21               ` [PATCH] USB: Fix OTG HNP for hub.c David Brownell
2007-05-29 19:24                 ` Felipe Balbi
2007-05-29 20:34                   ` Tony Lindgren
2007-05-29 21:11                     ` David Brownell
2007-05-29 21:26                       ` Tony Lindgren
2007-05-29 17:16           ` [PATCH] Add more Test Modes David Brownell
2007-05-29 17:07       ` [PATCH] musb_hdrc: Add SRP Interface and control it through sysfs David Brownell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox