summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/android.c
diff options
context:
space:
mode:
authorBenoit Goby <benoit@android.com>2011-12-19 14:39:37 -0800
committerArve Hjønnevåg <arve@android.com>2013-07-01 13:40:38 -0700
commit9389147c6329c86899bd2a1ac8f084e8ccd99ebd (patch)
tree2276dcff0cb6f00ee41315cb637bdcb64efeaf9f /drivers/usb/gadget/android.c
parent17c12acd8fcee70df65a054ef711c8d4d5ecfb6e (diff)
downloadolio-linux-3.10-9389147c6329c86899bd2a1ac8f084e8ccd99ebd.tar.xz
olio-linux-3.10-9389147c6329c86899bd2a1ac8f084e8ccd99ebd.zip
usb: gadget: accessory: Add Android Accessory function
USB accessory mode allows users to connect USB host hardware specifically designed for Android-powered devices. The accessories must adhere to the Android accessory protocol outlined in the http://accessories.android.com documentation. This allows Android devices that cannot act as a USB host to still interact with USB hardware. When an Android device is in USB accessory mode, the attached Android USB accessory acts as the host, provides power to the USB bus, and enumerates connected devices. Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'drivers/usb/gadget/android.c')
-rw-r--r--drivers/usb/gadget/android.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index b9cb65d2be1..b39ae673762 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -47,6 +47,7 @@
#include "f_acm.c"
#include "f_adb.c"
#include "f_mtp.c"
+#include "f_accessory.c"
#define USB_ETH_RNDIS y
#include "f_rndis.c"
#include "rndis.c"
@@ -633,6 +634,39 @@ static struct android_usb_function mass_storage_function = {
};
+static int accessory_function_init(struct android_usb_function *f,
+ struct usb_composite_dev *cdev)
+{
+ return acc_setup();
+}
+
+static void accessory_function_cleanup(struct android_usb_function *f)
+{
+ acc_cleanup();
+}
+
+static int accessory_function_bind_config(struct android_usb_function *f,
+ struct usb_configuration *c)
+{
+ return acc_bind_config(c);
+}
+
+static int accessory_function_ctrlrequest(struct android_usb_function *f,
+ struct usb_composite_dev *cdev,
+ const struct usb_ctrlrequest *c)
+{
+ return acc_ctrlrequest(cdev, c);
+}
+
+static struct android_usb_function accessory_function = {
+ .name = "accessory",
+ .init = accessory_function_init,
+ .cleanup = accessory_function_cleanup,
+ .bind_config = accessory_function_bind_config,
+ .ctrlrequest = accessory_function_ctrlrequest,
+};
+
+
static struct android_usb_function *supported_functions[] = {
&adb_function,
&acm_function,
@@ -640,6 +674,7 @@ static struct android_usb_function *supported_functions[] = {
&ptp_function,
&rndis_function,
&mass_storage_function,
+ &accessory_function,
NULL
};
@@ -825,6 +860,10 @@ static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
struct usb_composite_dev *cdev = dev->cdev;
int enabled = 0;
+
+ if (!cdev)
+ return -ENODEV;
+
mutex_lock(&dev->mutex);
sscanf(buff, "%d", &enabled);
@@ -1072,6 +1111,12 @@ android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c)
}
}
+ /* Special case the accessory function.
+ * It needs to handle control requests before it is enabled.
+ */
+ if (value < 0)
+ value = acc_ctrlrequest(cdev, c);
+
if (value < 0)
value = composite_setup(gadget, c);