From 6eb66891e94ff6ef35ca5ef487d10d5d7998e858 Mon Sep 17 00:00:00 2001 From: Jon Sturm Date: Sat, 16 Jul 2011 22:23:39 -0500 Subject: [PATCH 2/2] USB: sholes: enable usb accessory mode for sholes and fix build with it enabled --- arch/arm/mach-omap2/board-sholes.c | 33 +++++++++++++++++++++++++++++++++ drivers/usb/gadget/android.c | 14 ++++++++++++++ drivers/usb/gadget/composite.c | 24 ++++++++++++++++++++++++ include/linux/usb/android_composite.h | 1 + include/linux/usb/composite.h | 4 ++++ 5 files changed, 76 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/board-sholes.c b/arch/arm/mach-omap2/board-sholes.c index 1b687d8..21e0d88 100644 --- a/arch/arm/mach-omap2/board-sholes.c +++ b/arch/arm/mach-omap2/board-sholes.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include "cm-regbits-34xx.h" @@ -495,11 +496,29 @@ static char *usb_functions_rndis_adb[] = { "rndis", "adb", }; +static char *usb_functions_accessory[] = { +#ifdef CONFIG_USB_ANDROID_ACCESSORY +"accessory", +#endif +}; +static char *usb_functions_accessory_adb[] = { +#ifdef CONFIG_USB_ANDROID_ACCESSORY +"accessory", +#endif +#ifdef CONFIG_USB_ANDROID_ADB +"adb", +#endif +}; + + static char *usb_functions_all[] = { #ifdef CONFIG_USB_ANDROID_RNDIS "rndis", #endif +#ifdef CONFIG_USB_ANDROID_ACCESSORY + "accessory", +#endif "usb_mass_storage", "adb", #ifdef CONFIG_USB_ANDROID_ACM @@ -528,6 +547,20 @@ static struct android_usb_product usb_products[] = { .num_functions = ARRAY_SIZE(usb_functions_rndis_adb), .functions = usb_functions_rndis_adb, }, +#ifdef CONFIG_USB_ANDROID_ACCESSORY + { + .vendor_id = USB_ACCESSORY_VENDOR_ID, + .product_id = USB_ACCESSORY_PRODUCT_ID, + .num_functions = ARRAY_SIZE(usb_functions_accessory), + .functions = usb_functions_accessory, + }, + { + .vendor_id = USB_ACCESSORY_VENDOR_ID, + .product_id = USB_ACCESSORY_ADB_PRODUCT_ID, + .num_functions = ARRAY_SIZE(usb_functions_accessory_adb), + .functions = usb_functions_accessory_adb, + }, +#endif }; static char *factory_usb_functions[] = { diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c index 25860ca..f1f11d1 100644 --- a/drivers/usb/gadget/android.c +++ b/drivers/usb/gadget/android.c @@ -65,6 +65,7 @@ struct android_dev { int num_functions; char **functions; + int vender_id; int product_id; int version; }; @@ -366,6 +367,19 @@ void android_enable_function(struct usb_function *f, int enable) } } #endif +#ifdef CONFIG_USB_ANDROID_ACCESSORY + if (!strcmp(f->name, "accessory") && enable) { + struct usb_function *func; + + /* disable everything else (and keep adb for now) */ + list_for_each_entry(func, &android_config_driver.functions, list) { + if (strcmp(func->name, "accessory") + && strcmp(func->name, "adb")) { + usb_function_set_enabled(func, 0); + } + } + } +#endif product_id = get_product_id(dev); device_desc.idProduct = __constant_cpu_to_le16(product_id); diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 821cc17..7c09092 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -97,6 +97,30 @@ static ssize_t enable_store( static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store); +void usb_function_set_enabled(struct usb_function *f, int enabled) +{ + f->disabled = !enabled; + kobject_uevent(&f->dev->kobj, KOBJ_CHANGE); +} + + +void usb_composite_force_reset(struct usb_composite_dev *cdev) +{ +unsigned long flags; + + spin_lock_irqsave(&cdev->lock, flags); + /* force reenumeration */ + if (cdev && cdev->gadget && cdev->gadget->speed != USB_SPEED_UNKNOWN) { + spin_unlock_irqrestore(&cdev->lock, flags); + + usb_gadget_disconnect(cdev->gadget); + msleep(10); + usb_gadget_connect(cdev->gadget); + } else { + spin_unlock_irqrestore(&cdev->lock, flags); + } +} + /** * usb_add_function() - add a function to a configuration diff --git a/include/linux/usb/android_composite.h b/include/linux/usb/android_composite.h index 50889ba..32aa3f3 100644 --- a/include/linux/usb/android_composite.h +++ b/include/linux/usb/android_composite.h @@ -28,6 +28,7 @@ struct android_usb_function { struct android_usb_product { /* Default product ID. */ + __u16 vendor_id; __u16 product_id; /* List of function names associated with this product. diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 2b7775f..e145b73 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -103,6 +103,9 @@ struct usb_function { struct usb_configuration *config; int hidden; + /* disabled is zero if the function is enabled */ + int disabled; + /* REVISIT: bind() functions can be marked __init, which * makes trouble for section mismatch analysis. See if * we can't restructure things to avoid mismatching. @@ -138,6 +141,7 @@ int usb_function_deactivate(struct usb_function *); int usb_function_activate(struct usb_function *); int usb_interface_id(struct usb_configuration *, struct usb_function *); +void usb_function_set_enabled(struct usb_function *, int); /** * ep_choose - select descriptor endpoint at current device speed -- 1.7.6