aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorSakethram Bommisetti <sakethram.bommisetti@stericsson.com>2011-01-25 16:45:35 +0530
committerJonas ABERG <jonas.aberg@stericsson.com>2011-02-04 12:47:20 +0100
commite30b21316e1de5ca9255f7c644e20ae6b8372584 (patch)
treef8bcb9d9f28c23ca2093008310d21acabab9449c /drivers/usb
parente7605f04bd6ebafec097e5cc734ff9affbc17158 (diff)
Android:USB:Adding support for OTG 1.3 and OTG 2.0 compliance
Added missing support for OTG 1.3 compliance for OPT and OTG 2.0 support For 2.0 added the following: HNP Polling ADP Test modes ST-Ericsson ID:WP 256721 ST-Ericsson FOSS-OUT ID: STETL-FOSS-OUT-10054 Change-Id: I6441212a19a4e430543df56db85e9c49ebf833ff Signed-off-by: Sakethram Bommisetti <sakethram.bommisetti@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/14268 Reviewed-by: QATOOLS Reviewed-by: Praveena NADAHALLY <praveen.nadahally@stericsson.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/driver.c4
-rw-r--r--drivers/usb/core/hcd.c2
-rw-r--r--drivers/usb/core/hub.c149
-rw-r--r--drivers/usb/core/otg_whitelist.h58
-rw-r--r--drivers/usb/core/usb.h6
-rw-r--r--drivers/usb/gadget/Kconfig17
-rw-r--r--drivers/usb/gadget/android.c20
-rw-r--r--drivers/usb/gadget/composite.c14
-rw-r--r--drivers/usb/gadget/multi.c4
-rw-r--r--drivers/usb/gadget/zero.c3
-rw-r--r--drivers/usb/musb/musb_core.h9
-rw-r--r--drivers/usb/musb/musb_gadget.c6
-rw-r--r--drivers/usb/musb/stm_musb.c12
13 files changed, 284 insertions, 20 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index ddb7b47d3c9..20757dfb429 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1209,6 +1209,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
*/
} else {
#ifdef CONFIG_USB_OTG
+#ifdef CONFIG_USB_OTG_20
/* According to OTG supplement Rev 2.0 section 6.3
* Unless an A-device enables b_hnp_enable before entering
* suspend it shall also continue polling while the bus is
@@ -1221,6 +1222,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
udev->portnum == udev->bus->otg_port)
cancel_delayed_work(&udev->bus->hnp_polling);
#endif
+#endif
udev->can_submit = 0;
for (i = 0; i < 16; ++i) {
usb_hcd_flush_endpoint(udev, udev->ep_out[i]);
@@ -1284,6 +1286,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg)
}
#ifdef CONFIG_USB_OTG
+#ifdef CONFIG_USB_OTG_20
void usb_hnp_polling_work(struct work_struct *work)
{
int ret;
@@ -1325,6 +1328,7 @@ out:
kfree(status);
}
#endif
+#endif
static void choose_wakeup(struct usb_device *udev, pm_message_t msg)
{
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 9524c8c6146..834684afbea 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -871,8 +871,10 @@ static void usb_bus_init (struct usb_bus *bus)
INIT_LIST_HEAD (&bus->bus_list);
#ifdef CONFIG_USB_OTG
+#ifdef CONFIG_USB_OTG_20
INIT_DELAYED_WORK(&bus->hnp_polling, usb_hnp_polling_work);
#endif
+#endif
}
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 3e248eb72a3..9b9777c5f72 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -128,12 +128,19 @@ MODULE_PARM_DESC(initial_descriptor_timeout,
* otherwise the new scheme is used. If that fails and "use_both_schemes"
* is set, then the driver will make another attempt, using the other scheme.
*/
+#ifndef CONFIG_USB_OTG_13
static int old_scheme_first = 0;
+#else
+static int old_scheme_first = 1;
+#endif
module_param(old_scheme_first, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(old_scheme_first,
"start with the old device initialization scheme");
-
+#ifndef CONFIG_USB_OTG_13
static int use_both_schemes = 1;
+#else
+static int use_both_schemes;
+#endif
module_param(use_both_schemes, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(use_both_schemes,
"try the other device initialization scheme if the "
@@ -1581,11 +1588,13 @@ void usb_disconnect(struct usb_device **pdev)
dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum);
#ifdef CONFIG_USB_OTG
+#ifdef CONFIG_USB_OTG_20
if (udev->bus->hnp_support && udev->portnum == udev->bus->otg_port) {
cancel_delayed_work_sync(&udev->bus->hnp_polling);
udev->bus->hnp_support = 0;
}
#endif
+#endif
usb_lock_device(udev);
/* Free up all the children before we remove this device */
@@ -1689,8 +1698,11 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
"Dual-Role OTG device on %sHNP port\n",
(port1 == bus->otg_port)
? "" : "non-");
-
-
+#ifndef CONFIG_USB_OTG_20
+ /* enable HNP before suspend, it's simpler */
+ if (port1 == bus->otg_port)
+ bus->b_hnp_enable = 1;
+#else
/* a_alt_hnp_support is obsoleted */
if (port1 != bus->otg_port)
goto fail;
@@ -1711,12 +1723,17 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
* selecting configuration. b_hnp_enable
* is set before suspending the port.
*/
-
+#endif
err = usb_control_msg(udev,
usb_sndctrlpipe(udev, 0),
USB_REQ_SET_FEATURE, 0,
- USB_DEVICE_A_HNP_SUPPORT,
-
+#ifndef CONFIG_USB_OTG_20
+ bus->b_hnp_enable
+ ? USB_DEVICE_B_HNP_ENABLE
+ : USB_DEVICE_A_ALT_HNP_SUPPORT,
+#else
+ USB_DEVICE_A_HNP_SUPPORT,
+#endif
0, NULL, 0, USB_CTRL_SET_TIMEOUT);
if (err < 0) {
/* OTG MESSAGE: report errors here,
@@ -1725,25 +1742,122 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
dev_info(&udev->dev,
"can't set HNP mode: %d\n",
err);
+#ifndef CONFIG_USB_OTG_20
+ bus->b_hnp_enable = 0;
+#else
bus->hnp_support = 0;
-
+#endif
}
}
}
}
+
+#ifdef CONFIG_USB_OTG_20
out:
- if (!is_targeted(udev)) {
+#endif
+
+#ifdef CONFIG_USB_OTG
+ {
+ u16 idVendor = le16_to_cpu(udev->descriptor.idVendor);
+ if (idVendor == USB_OTG_TEST_MODE_VID) {
+ u16 wValue, typeReq, wIndex;
+ u32 set_feature = 0;
+ struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+ u16 idProduct = le16_to_cpu(
+ udev->descriptor.idProduct);
+ /* Convert the Test Mode Request to control request*/
+ wValue = USB_PORT_FEAT_TEST;
+ typeReq = SetPortFeature;
+ wIndex = 1;
+
+ switch (idProduct) {
+ case USB_OTG_TEST_SE0_NAK_PID:
+ wIndex |= USB_OTG_TEST_SE0_NAK << 8;
+ set_feature = 1;
+ break;
+ case USB_OTG_TEST_J_PID:
+ wIndex |= USB_OTG_TEST_J << 8;
+ set_feature = 1;
+ break;
+ case USB_OTG_TEST_K_PID:
+ wIndex |= USB_OTG_TEST_K << 8;
+ set_feature = 1;
+ break;
+ case USB_OTG_TEST_PACKET_PID:
+ wIndex |= USB_OTG_TEST_PACKET << 8;
+ set_feature = 1;
+ break;
+ case USB_OTG_TEST_HS_HOST_PORT_SUSPEND_RESUME_PID:
+ /* Sleep for 15 sec. Suspend for 15 Sec, Then Resume */
+ ssleep(15);
+
+ err = usb_port_suspend(udev, PMSG_SUSPEND);
+ if (err < 0)
+ dev_err(&udev->dev, "OTG TEST_MODE:"
+ "Suspend Fail, %d\n", err);
+ ssleep(15);
+ err = usb_autoresume_device(udev);
+ if (err < 0) {
+ dev_err(&udev->dev,
+ "can't autoresume for"
+ "OTG TEST_MODE: %d\n", err);
+ }
+ break;
+ case USB_OTG_TEST_SINGLE_STEP_GET_DEV_DESC_PID:
+ /* Sleep for 15 Sec. Issue the GetDeviceDescriptor */
+ ssleep(15);
+ err = usb_get_device_descriptor(udev,
+ sizeof(udev->descriptor));
+ if (err < 0) {
+ dev_err(&udev->dev, "can't re-read"
+ "device descriptor for "
+ "OTG TEST MODE: %d\n", err);
+ }
+ break;
+ case USB_OTG_TEST_SINGLE_STEP_GET_DEV_DESC_DATA_PID:
+ /* Issue GetDeviceDescriptor, Sleep for 15 Sec. */
+ err = usb_get_device_descriptor(udev,
+ sizeof(udev->descriptor));
+ if (err < 0) {
+ dev_err(&udev->dev, "can't re-read"
+ "device descriptor for "
+ "OTG TEST MODE: %d\n", err);
+ }
+ ssleep(15);
+ break;
+ default:
+ /* is_targeted() will take care for wrong PID */
+ dev_dbg(&udev->dev, "OTG TEST_MODE:Wrong PID %d\n",
+ idProduct);
+ break;
+ }
+ if (set_feature) {
+ err = hcd->driver->hub_control(hcd,
+ typeReq, wValue, wIndex,
+ NULL, 0);
+ }
+ }
+ }
+#endif
+
+ if (!is_targeted(udev)) {
/* Maybe it can talk to us, though we can't talk to it.
- * (Includes HNP test device.)
+ *(Includes HNP test device.)
*/
- if (udev->bus->hnp_support) {
- err = usb_port_suspend(udev, PMSG_SUSPEND);
- if (err < 0)
- dev_dbg(&udev->dev, "HNP fail, %d\n", err);
-
+ if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
+#ifdef CONFIG_USB_OTG_20
+ if (udev->bus->hnp_support) {
+#endif
+ err = usb_port_suspend(udev, PMSG_SUSPEND);
+ if (err < 0)
+ dev_dbg(&udev->dev, "HNP fail, %d\n"
+ , err);
+ }
err = -ENOTSUPP;
-
+#ifndef CONFIG_USB_OTG_20
+ goto fail;
+#else
} else if (udev->bus->hnp_support &&
udev->portnum == udev->bus->otg_port) {
/* HNP polling is introduced in OTG supplement Rev 2.0
@@ -1754,6 +1868,7 @@ out:
schedule_delayed_work(&udev->bus->hnp_polling,
msecs_to_jiffies(THOST_REQ_POLL));
}
+#endif
}
fail:
#endif
@@ -2235,6 +2350,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
}
}
#ifdef CONFIG_USB_OTG
+#ifdef CONFIG_USB_OTG_20
if (!udev->bus->is_b_host && udev->bus->hnp_support &&
udev->portnum == udev->bus->otg_port) {
status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
@@ -2248,6 +2364,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
udev->bus->b_hnp_enable = 1;
}
#endif
+#endif
/* see 7.1.7.6 */
status = set_port_feature(hub->hdev, port1, USB_PORT_FEAT_SUSPEND);
@@ -2392,10 +2509,12 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
u16 portchange, portstatus;
#ifdef CONFIG_USB_OTG
+#ifdef CONFIG_USB_OTG_20
if (!udev->bus->is_b_host && udev->bus->hnp_support &&
udev->portnum == udev->bus->otg_port)
udev->bus->b_hnp_enable = 0;
#endif
+#endif
/* Skip the initial Clear-Suspend step for a remote wakeup */
status = hub_port_status(hub, port1, &portstatus, &portchange);
if (status == 0 && !(portstatus & USB_PORT_STAT_SUSPEND))
diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h
index e8cdce571bb..9cbac092e77 100644
--- a/drivers/usb/core/otg_whitelist.h
+++ b/drivers/usb/core/otg_whitelist.h
@@ -43,12 +43,43 @@ static struct usb_device_id whitelist_table [] = {
{ USB_DEVICE(0x0525, 0xa4a0), },
#endif
+#if defined(CONFIG_USB_OTG_20)
+{ USB_DEVICE_INFO(8, 6, 80) },/* Mass Storage Devices */
+#endif
+{ USB_DEVICE(0x4CC, 0x2323), },/* U8500 Board */
+{ USB_DEVICE(0x4D9, 0x1702), },/* HP Keyboard */
+{ USB_DEVICE(0x4E8, 0x1F06), },/* USB Hard disk */
+{ USB_DEVICE(0x46D, 0x0A0C), },/*USB Headset */
+{ USB_DEVICE(0x93A, 0x2510), },/* USB mouse */
+
{ } /* Terminating entry */
};
+/* The TEST_MODE Definition for OTG as per 6.4 of OTG Rev 2.0 */
+
+#ifdef CONFIG_USB_OTG
+#define USB_OTG_TEST_MODE_VID 0x1A0A
+#define USB_OTG_TEST_SE0_NAK_PID 0x0101
+#define USB_OTG_TEST_J_PID 0x0102
+#define USB_OTG_TEST_K_PID 0x0103
+#define USB_OTG_TEST_PACKET_PID 0x0104
+#define USB_OTG_TEST_HS_HOST_PORT_SUSPEND_RESUME_PID 0x0106
+#define USB_OTG_TEST_SINGLE_STEP_GET_DEV_DESC_PID 0x0107
+#define USB_OTG_TEST_SINGLE_STEP_GET_DEV_DESC_DATA_PID 0x0108
+
+#define USB_OTG_TEST_SE0_NAK 0x01
+#define USB_OTG_TEST_J 0x02
+#define USB_OTG_TEST_K 0x03
+#define USB_OTG_TEST_PACKET 0x04
+#endif
+
static int is_targeted(struct usb_device *dev)
{
struct usb_device_id *id = whitelist_table;
+#ifdef CONFIG_USB_OTG_20
+ u8 number_configs = 0;
+ u8 number_interface = 0;
+#endif
/* possible in developer configs only! */
if (!dev->bus->otg_port)
@@ -97,6 +128,33 @@ static int is_targeted(struct usb_device *dev)
}
/* add other match criteria here ... */
+#ifdef CONFIG_USB_OTG_20
+/* Checking class,subclass and protocal at interface level */
+for (number_configs = dev->descriptor.bNumConfigurations;
+ number_configs > 0; number_configs--)
+ for (number_interface = dev->config->desc.bNumInterfaces;
+ number_interface > 0; number_interface--)
+ for (id = whitelist_table; id->match_flags; id++) {
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
+ (id->bDeviceClass !=
+ dev->config->intf_cache[number_interface-1]
+ ->altsetting[0].desc.bInterfaceClass))
+ continue;
+ if ((id->match_flags &
+ USB_DEVICE_ID_MATCH_DEV_SUBCLASS)
+ && (id->bDeviceSubClass !=
+ dev->config->intf_cache[number_interface-1]
+ ->altsetting[0].desc.bInterfaceSubClass))
+ continue;
+ if ((id->match_flags &
+ USB_DEVICE_ID_MATCH_DEV_PROTOCOL)
+ && (id->bDeviceProtocol !=
+ dev->config->intf_cache[number_interface-1]
+ ->altsetting[0].desc.bInterfaceProtocol))
+ continue;
+ return 1;
+ }
+#endif
/* OTG MESSAGE: report errors here, customize to match your product */
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 56423909dff..94ca94a4c83 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -73,7 +73,13 @@ static inline int usb_port_resume(struct usb_device *udev, pm_message_t msg)
#endif
#ifdef CONFIG_USB_OTG
+#ifdef CONFIG_USB_OTG_20
extern void usb_hnp_polling_work(struct work_struct *work);
+#else
+static inline void usb_hnp_polling_work(struct work_struct *work)
+{
+}
+#endif
#endif
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 5a9cf40d832..f510dae8a65 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -982,4 +982,21 @@ config USB_G_WEBCAM
endchoice
+config USB_OTG_13
+ bool "OTG 1.3 USB SUPPORT"
+ select PM_RUNTIME
+ select USB_OTG_WHITELIST
+ select USB_SUSPEND
+ help
+ Enabling the whitelist (Target Peripheral List-TPL) and runtime power
+ management at system level and usb level for OTG 1.3.
+
+config USB_OTG_20
+ bool "OTG 2.0 USB SUPPORT"
+ select PM_RUNTIME
+ select USB_OTG_WHITELIST
+ select USB_SUSPEND
+ help
+ Enabling the whitelist (Target Peripheral List-TPL) and runtime power
+ management at system level and usb level for OTG 2.0.
endif # USB_GADGET
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index d8cf4c97468..7d0d93fd5ca 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -108,6 +108,19 @@ static struct usb_device_descriptor device_desc = {
.bNumConfigurations = 1,
};
+#if defined(CONFIG_USB_OTG_20) || defined(CONFIG_USB_OTG_13)
+static struct usb_otg_descriptor otg_descriptor = {
+ .bLength = sizeof otg_descriptor,
+ .bDescriptorType = USB_DT_OTG,
+ .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
+};
+
+static struct usb_descriptor_header *otg_desc[] = {
+ (struct usb_descriptor_header *) &otg_descriptor,
+ NULL,
+};
+#endif
+
static struct list_head _functions = LIST_HEAD_INIT(_functions);
static int _registered_function_count = 0;
@@ -165,6 +178,12 @@ static int android_bind_config(struct usb_configuration *c)
struct android_dev *dev = _android_dev;
printk(KERN_DEBUG "android_bind_config\n");
+#if defined(CONFIG_USB_OTG_20) || defined(CONFIG_USB_OTG_13)
+ if (gadget_is_otg(c->cdev->gadget)) {
+ c->descriptors = otg_desc;
+ c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+ }
+#endif
dev->config = c;
/* bind our functions if they have all registered */
@@ -273,6 +292,7 @@ static int android_bind(struct usb_composite_dev *cdev)
strings_dev[STRING_SERIAL_IDX].id = id;
device_desc.iSerialNumber = id;
+
/*
* As per USB compliance update, a device that is actively drawing
* more than 100mA from USB must report itself as bus-powered in
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index f95c855786f..6a3ca69515b 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1016,7 +1016,10 @@ static void composite_disconnect(struct usb_gadget *gadget)
struct usb_composite_dev *cdev = get_gadget_data(gadget);
unsigned long flags;
+#ifdef CONFIG_USB_OTG_20
gadget->host_request = 0;
+#endif
+
/* REVISIT: should we have config and device level
* disconnect callbacks?
*/
@@ -1045,7 +1048,7 @@ static ssize_t composite_show_suspended(struct device *dev,
static DEVICE_ATTR(suspended, 0444, composite_show_suspended, NULL);
-
+#ifdef CONFIG_USB_OTG_20
static ssize_t composite_set_host_request(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -1062,7 +1065,7 @@ static ssize_t composite_set_host_request(struct device *dev,
}
static DEVICE_ATTR(host_request, S_IWUSR, NULL, composite_set_host_request);
-
+#endif
static void
composite_unbind(struct usb_gadget *gadget)
@@ -1109,8 +1112,11 @@ composite_unbind(struct usb_gadget *gadget)
usb_ep_free_request(gadget->ep0, cdev->req);
}
- device_remove_file(&gadget->dev, &dev_attr_host_request);
switch_dev_unregister(&cdev->sdev);
+#ifdef CONFIG_USB_OTG_20
+ device_remove_file(&gadget->dev, &dev_attr_host_request);
+#endif
+
kfree(cdev);
set_gadget_data(gadget, NULL);
device_remove_file(&gadget->dev, &dev_attr_suspended);
@@ -1216,9 +1222,11 @@ static int composite_bind(struct usb_gadget *gadget)
goto fail;
INIT_WORK(&cdev->switch_work, composite_switch_work);
+#ifdef CONFIG_USB_OTG_20
status = device_create_file(&gadget->dev, &dev_attr_host_request);
if (status)
DBG(cdev, "unable to create host_request sysfs file\n");
+#endif
cdev->desc = *composite->dev;
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index a930d7fd7e7..fe1ed688518 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -107,7 +107,11 @@ static struct usb_otg_descriptor otg_descriptor = {
/* REVISIT SRP-only hardware is possible, although
* it would not be called "OTG" ...
*/
+#ifndef USB_OTG_20
.bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
+#else
+ .bmAttributes = USB_OTG_SRP | USB_OTG_HNP | USB_OTG_ADP,
+#endif
};
static const struct usb_descriptor_header *otg_desc[] = {
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index fc5e261e31e..a7c60c23265 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -292,9 +292,10 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
device_desc.iSerialNumber = id;
setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);
-
+#ifdef CONFIG_USB_OTG_20
if (gadget_is_otg2(cdev->gadget))
otg_descriptor.bcdOTG = __constant_cpu_to_le16(0x0200);
+#endif
/* Register primary, then secondary configuration. Note that
* SH3 only allows one config...
*/
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 82b3fa22adc..7a62a3fc8de 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -610,6 +610,15 @@ extern int musb_platform_get_vbus_status(struct musb *musb);
#define musb_platform_get_vbus_status(x) 0
#endif
+#if defined(CONFIG_ARCH_U8500)
+extern void musb_platform_device_en(int enable);
+extern void musb_platform_session_req();
+#else
+#define musb_platform_device_en(x)
+#define musb_platform_session_req()
+#endif
+
+
extern int __init musb_platform_init(struct musb *musb, void *board_data);
extern int musb_platform_exit(struct musb *musb);
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 6c7bf7bf529..0809a152333 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -52,7 +52,7 @@
#ifdef CONFIG_ARCH_U8500
#include "ste_config.h"
#endif
-
+#define USB_ENABLE_PHY 1
/* MUSB PERIPHERAL status 3-mar-2006:
*
* - EP0 seems solid. It passes both USBCV and usbtest control cases.
@@ -1561,6 +1561,10 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget)
u8 power, devctl;
int retries;
+
+ musb_platform_device_en(USB_ENABLE_PHY);
+ musb_platform_session_req();
+
spin_lock_irqsave(&musb->lock, flags);
switch (musb->xceiv->state) {
diff --git a/drivers/usb/musb/stm_musb.c b/drivers/usb/musb/stm_musb.c
index c56653bdbe6..4e812d8d81a 100644
--- a/drivers/usb/musb/stm_musb.c
+++ b/drivers/usb/musb/stm_musb.c
@@ -32,6 +32,7 @@ static u8 ulpi_write_register(struct musb *musb, u8 address, u8 data);
static struct musb *musb_status;
static spinlock_t musb_ulpi_spinlock;
static unsigned musb_power;
+static int userrequest;
/**
* musb_set_session() - Start the USB session
@@ -69,6 +70,17 @@ ab8500_bm_usb_state_changed_wrapper(u8 bm_usb_state)
ab8500_charger_usb_state_changed(bm_usb_state, musb_power);
}
+#ifdef CONFIG_USB_OTG_20
+int musb_adp(void)
+{
+ if (userrequest == 0)
+ return 0;
+ else
+ return 1;
+}
+EXPORT_SYMBOL(musb_adp);
+#endif
+
/* Sys interfaces */
static struct kobject *usbstatus_kobj;
static ssize_t usb_cable_status