From 2210347c11f42c71917df428f4638c9b5769c4b1 Mon Sep 17 00:00:00 2001 From: Vijayavardhan Vennapusa Date: Wed, 18 Jan 2012 14:16:55 +0530 Subject: [PATCH] USB: core: Add support for OTG automated compliance tests 1. Add OTG PET device to TPL. OTG device shall support this device for allowing compliance automated testing. 2. Add otg_srp_reqd filed to gadget. OTG B-device shall enable this flag when OTG PET (Protocol and Electrical Tester) that acts as A-device sends Set Feature TEST_MODE with wIndex high byte value = 0x06. OTG PET expects B-device to initiate SRP after the end of current session. 3. Add otg_vbus_off to usb_bus. USB core enables this flag when OTG PET enumerates with bcdDevice[0] field in its Device Descriptor is equal to 1. OTG PET expects A-device to turn off the VBUS with in 5 sec of its disconnection which allows it to initiate SRP. 3. Add support to identify OTG PET and start HNP quickly. Change-Id: Ib1f4d835d00ca29ff8f980c94d75a3890507dedc Signed-off-by: Pavankumar Kondeti Signed-off-by: Vijayavardhan Vennapusa --- drivers/usb/core/hub.c | 8 ++++++++ drivers/usb/core/otg_whitelist.h | 5 +++++ drivers/usb/core/quirks.c | 3 +++ include/linux/usb.h | 7 +++++++ include/linux/usb/ch9.h | 9 +++++++++ include/linux/usb/gadget.h | 3 +++ include/linux/usb/quirks.h | 2 ++ 7 files changed, 37 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 396a3886685..5dceb41ead3 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1803,6 +1803,7 @@ static int usb_enumerate_device_otg(struct usb_device *udev) int err = 0; #ifdef CONFIG_USB_OTG + bool old_otg = false; /* * 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 @@ -1868,6 +1869,13 @@ static int usb_enumerate_device_otg(struct usb_device *udev) } } out: + if ((udev->quirks & USB_QUIRK_OTG_PET)) { + if (le16_to_cpu(udev->descriptor.bcdDevice) & + OTG_TTST_VBUS_OFF) + udev->bus->otg_vbus_off = 1; + if (udev->bus->is_b_host || old_otg) + udev->bus->quick_hnp = 1; + } if (!is_targeted(udev)) { diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h index cec41675a69..7bb6747b4f1 100644 --- a/drivers/usb/core/otg_whitelist.h +++ b/drivers/usb/core/otg_whitelist.h @@ -59,6 +59,11 @@ static int is_targeted(struct usb_device *dev) le16_to_cpu(dev->descriptor.idProduct) == 0xbadd)) return 0; + /* OTG PET device is always targeted (see OTG 2.0 ECN 6.4.2) */ + if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a && + le16_to_cpu(dev->descriptor.idProduct) == 0x0200)) + return 1; + /* NOTE: can't use usb_match_id() since interface caches * aren't set up yet. this is cut/paste from that code. */ diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 4c65eb6a867..200dc9bfeec 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -150,6 +150,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* INTEL VALUE SSD */ { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Protocol and OTG Electrical Test Device */ + { USB_DEVICE(0x1a0a, 0x0200), .driver_info = USB_QUIRK_OTG_PET }, + { } /* terminating entry must be last */ }; diff --git a/include/linux/usb.h b/include/linux/usb.h index 50356598a78..5b38bca2e59 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -332,6 +332,13 @@ struct usb_bus { unsigned is_b_host:1; /* true during some HNP roleswitches */ unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ unsigned hnp_support:1; /* OTG: HNP is supported on OTG port */ + unsigned quick_hnp:1; /* OTG: Indiacates if hnp is required + irrespective of host_request flag + */ + unsigned otg_vbus_off:1; /* OTG: OTG test device feature bit that + * tells A-device to turn off VBUS after + * B-device is disconnected. + */ struct delayed_work hnp_polling;/* OTG: HNP polling work */ unsigned sg_tablesize; /* 0 or largest number of sg list entries */ diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h index d97153e5061..c918b7465a8 100644 --- a/include/linux/usb/ch9.h +++ b/include/linux/usb/ch9.h @@ -134,6 +134,12 @@ #define TEST_PACKET 4 #define TEST_FORCE_EN 5 +/* OTG test mode feature bits + * See ECN OTG2.0 spec Table 6-8 + */ +#define TEST_OTG_SRP_REQD 6 +#define TEST_OTG_HNP_REQD 7 + /* * New Feature Selectors as added by USB 3.0 * See USB 3.0 spec Table 9-6 @@ -155,6 +161,9 @@ #define OTG_STATUS_SELECTOR 0xF000 #define HOST_REQUEST_FLAG 0 #define THOST_REQ_POLL 1500 /* msec (1000 - 2000) */ +#define OTG_TTST_SUSP 70 /* msec (0 - 100) */ + +#define OTG_TTST_VBUS_OFF 1 /* Bit array elements as returned by the USB_REQ_GET_STATUS request. */ #define USB_DEV_STAT_U1_ENABLED 2 /* transition into U1 state */ diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 30cf7b7696d..da6a2c579de 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -500,6 +500,8 @@ struct usb_gadget_ops { * @b_hnp_enable: OTG device feature flag, indicating that the A-Host * enabled HNP support. * @host_request: A flag set by user when wishes to take up host role. + * @otg_srp_reqd: OTG test mode feature to initiate SRP after the end of + * current session. * @name: Identifies the controller hardware type. Used in diagnostics * and sometimes configuration. * @dev: Driver model state for this abstract device. @@ -536,6 +538,7 @@ struct usb_gadget { unsigned a_hnp_support:1; unsigned a_alt_hnp_support:1; unsigned host_request:1; + unsigned otg_srp_reqd:1; const char *name; struct device dev; }; diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h index 3e93de7ecbc..fb1ca8c299d 100644 --- a/include/linux/usb/quirks.h +++ b/include/linux/usb/quirks.h @@ -30,4 +30,6 @@ descriptor */ #define USB_QUIRK_DELAY_INIT 0x00000040 +#define USB_QUIRK_OTG_PET 0x00000080 + #endif /* __LINUX_USB_QUIRKS_H */