diff options
| author | Benoit Goby <benoit@android.com> | 2011-12-19 14:39:37 -0800 | 
|---|---|---|
| committer | Arve Hjønnevåg <arve@android.com> | 2013-07-01 13:40:38 -0700 | 
| commit | 9389147c6329c86899bd2a1ac8f084e8ccd99ebd (patch) | |
| tree | 2276dcff0cb6f00ee41315cb637bdcb64efeaf9f /drivers/usb/gadget/android.c | |
| parent | 17c12acd8fcee70df65a054ef711c8d4d5ecfb6e (diff) | |
| download | olio-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.c | 45 | 
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);  |